mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Fix for bug 768692 (Move DOM list binding generation to the new DOM binding codegen). r=bzbarsky.
--HG-- extra : rebase_source : 651a0fac4c9a87ef1c0a9cd91588c6421fd050c4
This commit is contained in:
parent
75ae552319
commit
13f425b97c
@ -2399,10 +2399,7 @@ nsScriptSecurityManager::old_doGetObjectPrincipal(JSObject *aObj,
|
||||
if (!(~jsClass->flags & (JSCLASS_HAS_PRIVATE |
|
||||
JSCLASS_PRIVATE_IS_NSISUPPORTS))) {
|
||||
priv = (nsISupports *) js::GetObjectPrivate(aObj);
|
||||
} else if (IsDOMClass(jsClass) &&
|
||||
DOMJSClass::FromJSClass(jsClass)->mDOMObjectIsISupports) {
|
||||
priv = UnwrapDOMObject<nsISupports>(aObj);
|
||||
} else {
|
||||
} else if (!UnwrapDOMObjectToISupports(aObj, priv)) {
|
||||
priv = nullptr;
|
||||
}
|
||||
|
||||
|
@ -391,7 +391,7 @@ JSObject*
|
||||
nsChildContentList::WrapObject(JSContext *cx, JSObject *scope,
|
||||
bool *triedToWrap)
|
||||
{
|
||||
return mozilla::dom::binding::NodeList::create(cx, scope, this, triedToWrap);
|
||||
return mozilla::dom::oldproxybindings::NodeList::create(cx, scope, this, triedToWrap);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -162,7 +162,7 @@ JSObject*
|
||||
nsSimpleContentList::WrapObject(JSContext *cx, JSObject *scope,
|
||||
bool *triedToWrap)
|
||||
{
|
||||
return mozilla::dom::binding::NodeList::create(cx, scope, this, triedToWrap);
|
||||
return mozilla::dom::oldproxybindings::NodeList::create(cx, scope, this, triedToWrap);
|
||||
}
|
||||
|
||||
// nsFormContentList
|
||||
@ -478,7 +478,7 @@ nsContentList::~nsContentList()
|
||||
JSObject*
|
||||
nsContentList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
|
||||
{
|
||||
return mozilla::dom::binding::HTMLCollection::create(cx, scope, this,
|
||||
return mozilla::dom::oldproxybindings::HTMLCollection::create(cx, scope, this,
|
||||
triedToWrap);
|
||||
}
|
||||
|
||||
|
@ -688,7 +688,7 @@ JSObject*
|
||||
nsDOMFileList::WrapObject(JSContext *cx, JSObject *scope,
|
||||
bool *triedToWrap)
|
||||
{
|
||||
return mozilla::dom::binding::FileList::create(cx, scope, this, triedToWrap);
|
||||
return mozilla::dom::oldproxybindings::FileList::create(cx, scope, this, triedToWrap);
|
||||
}
|
||||
|
||||
nsIDOMFile*
|
||||
|
@ -51,6 +51,6 @@ JSObject*
|
||||
nsDOMSettableTokenList::WrapObject(JSContext *cx, JSObject *scope,
|
||||
bool *triedToWrap)
|
||||
{
|
||||
return mozilla::dom::binding::DOMSettableTokenList::create(cx, scope, this,
|
||||
return mozilla::dom::oldproxybindings::DOMSettableTokenList::create(cx, scope, this,
|
||||
triedToWrap);
|
||||
}
|
||||
|
@ -272,7 +272,7 @@ nsDOMTokenList::ToString(nsAString& aResult)
|
||||
JSObject*
|
||||
nsDOMTokenList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
|
||||
{
|
||||
return mozilla::dom::binding::DOMTokenList::create(cx, scope, this,
|
||||
return mozilla::dom::oldproxybindings::DOMTokenList::create(cx, scope, this,
|
||||
triedToWrap);
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ public:
|
||||
virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
|
||||
bool *triedToWrap)
|
||||
{
|
||||
return mozilla::dom::binding::PaintRequestList::create(cx, scope, this,
|
||||
return mozilla::dom::oldproxybindings::PaintRequestList::create(cx, scope, this,
|
||||
triedToWrap);
|
||||
}
|
||||
|
||||
|
@ -108,7 +108,7 @@ JSObject*
|
||||
HTMLPropertiesCollection::WrapObject(JSContext* cx, JSObject* scope,
|
||||
bool* triedToWrap)
|
||||
{
|
||||
return mozilla::dom::binding::HTMLPropertiesCollection::create(cx, scope, this,
|
||||
return mozilla::dom::oldproxybindings::HTMLPropertiesCollection::create(cx, scope, this,
|
||||
triedToWrap);
|
||||
}
|
||||
|
||||
@ -426,7 +426,7 @@ JSObject*
|
||||
PropertyNodeList::WrapObject(JSContext *cx, JSObject *scope,
|
||||
bool *triedToWrap)
|
||||
{
|
||||
return mozilla::dom::binding::PropertyNodeList::create(cx, scope, this,
|
||||
return mozilla::dom::oldproxybindings::PropertyNodeList::create(cx, scope, this,
|
||||
triedToWrap);
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ nsClientRectList::GetItemAt(uint32_t aIndex)
|
||||
JSObject*
|
||||
nsClientRectList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
|
||||
{
|
||||
return mozilla::dom::binding::ClientRectList::create(cx, scope, this,
|
||||
return mozilla::dom::oldproxybindings::ClientRectList::create(cx, scope, this,
|
||||
triedToWrap);
|
||||
}
|
||||
|
||||
|
@ -121,7 +121,7 @@ public:
|
||||
virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
|
||||
bool *triedToWrap)
|
||||
{
|
||||
return mozilla::dom::binding::HTMLCollection::create(cx, scope, this,
|
||||
return mozilla::dom::oldproxybindings::HTMLCollection::create(cx, scope, this,
|
||||
triedToWrap);
|
||||
}
|
||||
|
||||
|
@ -2015,7 +2015,7 @@ JSObject*
|
||||
nsHTMLOptionCollection::WrapObject(JSContext *cx, JSObject *scope,
|
||||
bool *triedToWrap)
|
||||
{
|
||||
return mozilla::dom::binding::HTMLOptionsCollection::create(cx, scope, this,
|
||||
return mozilla::dom::oldproxybindings::HTMLOptionsCollection::create(cx, scope, this,
|
||||
triedToWrap);
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ public:
|
||||
virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
|
||||
bool *triedToWrap)
|
||||
{
|
||||
return mozilla::dom::binding::HTMLCollection::create(cx, scope, this,
|
||||
return mozilla::dom::oldproxybindings::HTMLCollection::create(cx, scope, this,
|
||||
triedToWrap);
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,7 @@ NS_INTERFACE_MAP_END
|
||||
JSObject*
|
||||
DOMSVGLengthList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
|
||||
{
|
||||
return mozilla::dom::binding::SVGLengthList::create(cx, scope, this,
|
||||
return mozilla::dom::oldproxybindings::SVGLengthList::create(cx, scope, this,
|
||||
triedToWrap);
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ NS_INTERFACE_MAP_END
|
||||
JSObject*
|
||||
DOMSVGNumberList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
|
||||
{
|
||||
return mozilla::dom::binding::SVGNumberList::create(cx, scope, this,
|
||||
return mozilla::dom::oldproxybindings::SVGNumberList::create(cx, scope, this,
|
||||
triedToWrap);
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,7 @@ DOMSVGPathSegList::~DOMSVGPathSegList()
|
||||
JSObject*
|
||||
DOMSVGPathSegList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
|
||||
{
|
||||
return mozilla::dom::binding::SVGPathSegList::create(cx, scope, this,
|
||||
return mozilla::dom::oldproxybindings::SVGPathSegList::create(cx, scope, this,
|
||||
triedToWrap);
|
||||
}
|
||||
|
||||
|
@ -103,7 +103,7 @@ DOMSVGPointList::~DOMSVGPointList()
|
||||
JSObject*
|
||||
DOMSVGPointList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
|
||||
{
|
||||
return mozilla::dom::binding::SVGPointList::create(cx, scope, this,
|
||||
return mozilla::dom::oldproxybindings::SVGPointList::create(cx, scope, this,
|
||||
triedToWrap);
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ JSObject*
|
||||
DOMSVGTransformList::WrapObject(JSContext *cx, JSObject *scope,
|
||||
bool *triedToWrap)
|
||||
{
|
||||
return mozilla::dom::binding::SVGTransformList::create(cx, scope, this,
|
||||
return mozilla::dom::oldproxybindings::SVGTransformList::create(cx, scope, this,
|
||||
triedToWrap);
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ public:
|
||||
virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
|
||||
bool *triedToWrap)
|
||||
{
|
||||
return mozilla::dom::binding::NodeList::create(cx, scope, this,
|
||||
return mozilla::dom::oldproxybindings::NodeList::create(cx, scope, this,
|
||||
triedToWrap);
|
||||
}
|
||||
|
||||
|
@ -543,6 +543,7 @@ using mozilla::dom::indexedDB::IDBWrapperCache;
|
||||
#undef None // something included above defines this preprocessor symbol, maybe Xlib headers
|
||||
#include "WebGLContext.h"
|
||||
#include "nsICanvasRenderingContextInternal.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
@ -4575,12 +4576,13 @@ nsDOMClassInfo::Init()
|
||||
sDisableGlobalScopePollutionSupport =
|
||||
Preferences::GetBool("browser.dom.global_scope_pollution.disabled");
|
||||
|
||||
// Proxy bindings
|
||||
mozilla::dom::binding::Register(nameSpaceManager);
|
||||
|
||||
// Non-proxy bindings
|
||||
mozilla::dom::Register(nameSpaceManager);
|
||||
|
||||
// This needs to happen after the call to mozilla::dom::Register, because we
|
||||
// overwrite some values.
|
||||
mozilla::dom::oldproxybindings::Register(nameSpaceManager);
|
||||
|
||||
if (!AzureCanvasEnabled()) {
|
||||
nameSpaceManager->RegisterDefineDOMInterface(NS_LITERAL_STRING("CanvasRenderingContext2D"), NULL);
|
||||
}
|
||||
@ -6746,7 +6748,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
|
||||
name_struct->mType == nsGlobalNameStruct::eTypeClassProto ||
|
||||
name_struct->mType == nsGlobalNameStruct::eTypeClassConstructor) {
|
||||
// Lookup new DOM bindings.
|
||||
mozilla::dom::binding::DefineInterface define =
|
||||
mozilla::dom::DefineInterface define =
|
||||
name_struct->mDefineDOMInterface;
|
||||
if (define) {
|
||||
if (name_struct->mType == nsGlobalNameStruct::eTypeClassConstructor &&
|
||||
@ -6754,7 +6756,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mozilla::dom::binding::DefineConstructor(cx, obj, define, &rv)) {
|
||||
if (mozilla::dom::DefineConstructor(cx, obj, define, &rv)) {
|
||||
*did_resolve = NS_SUCCEEDED(rv);
|
||||
|
||||
return rv;
|
||||
@ -8791,9 +8793,9 @@ nsHTMLDocumentSH::GetDocumentAllNodeList(JSContext *cx, JSObject *obj,
|
||||
if (!JSVAL_IS_PRIMITIVE(collection)) {
|
||||
// We already have a node list in our reserved slot, use it.
|
||||
JSObject *obj = JSVAL_TO_OBJECT(collection);
|
||||
if (mozilla::dom::binding::HTMLCollection::objIsWrapper(obj)) {
|
||||
if (mozilla::dom::oldproxybindings::HTMLCollection::objIsWrapper(obj)) {
|
||||
nsIHTMLCollection *native =
|
||||
mozilla::dom::binding::HTMLCollection::getNative(obj);
|
||||
mozilla::dom::oldproxybindings::HTMLCollection::getNative(obj);
|
||||
NS_ADDREF(*nodeList = static_cast<nsContentList*>(native));
|
||||
}
|
||||
else {
|
||||
|
@ -781,7 +781,7 @@ nsScriptNameSpaceManager::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
|
||||
void
|
||||
nsScriptNameSpaceManager::RegisterDefineDOMInterface(const nsAFlatString& aName,
|
||||
mozilla::dom::binding::DefineInterface aDefineDOMInterface)
|
||||
mozilla::dom::DefineInterface aDefineDOMInterface)
|
||||
{
|
||||
nsGlobalNameStruct *s = AddToHash(&mGlobalNames, &aName);
|
||||
if (s) {
|
||||
|
@ -67,7 +67,7 @@ struct nsGlobalNameStruct
|
||||
};
|
||||
|
||||
// For new style DOM bindings.
|
||||
mozilla::dom::binding::DefineInterface mDefineDOMInterface;
|
||||
mozilla::dom::DefineInterface mDefineDOMInterface;
|
||||
|
||||
private:
|
||||
|
||||
@ -139,7 +139,7 @@ public:
|
||||
nsGlobalNameStruct* GetConstructorProto(const nsGlobalNameStruct* aStruct);
|
||||
|
||||
void RegisterDefineDOMInterface(const nsAFlatString& aName,
|
||||
mozilla::dom::binding::DefineInterface aDefineDOMInterface);
|
||||
mozilla::dom::DefineInterface aDefineDOMInterface);
|
||||
|
||||
private:
|
||||
// Adds a new entry to the hash and returns the nsGlobalNameStruct
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "BindingUtils.h"
|
||||
|
||||
#include "WrapperFactory.h"
|
||||
#include "xpcprivate.h"
|
||||
#include "XPCQuickStubs.h"
|
||||
|
||||
@ -242,7 +243,7 @@ JSObject*
|
||||
CreateInterfaceObjects(JSContext* cx, JSObject* global, JSObject *receiver,
|
||||
JSObject* protoProto, JSClass* protoClass,
|
||||
JSClass* constructorClass, JSNative constructor,
|
||||
unsigned ctorNargs, JSClass* instanceClass,
|
||||
unsigned ctorNargs, const DOMClass* domClass,
|
||||
Prefable<JSFunctionSpec>* methods,
|
||||
Prefable<JSPropertySpec>* properties,
|
||||
Prefable<ConstantSpec>* constants,
|
||||
@ -267,7 +268,7 @@ CreateInterfaceObjects(JSContext* cx, JSObject* global, JSObject *receiver,
|
||||
}
|
||||
|
||||
js::SetReservedSlot(proto, DOM_PROTO_INSTANCE_CLASS_SLOT,
|
||||
JS::PrivateValue(instanceClass));
|
||||
JS::PrivateValue(const_cast<DOMClass*>(domClass)));
|
||||
}
|
||||
else {
|
||||
proto = NULL;
|
||||
@ -333,10 +334,8 @@ JSBool
|
||||
InstanceClassHasProtoAtDepth(JSHandleObject protoObject, uint32_t protoID,
|
||||
uint32_t depth)
|
||||
{
|
||||
JSClass* instanceClass = static_cast<JSClass*>(
|
||||
const DOMClass* domClass = static_cast<DOMClass*>(
|
||||
js::GetReservedSlot(protoObject, DOM_PROTO_INSTANCE_CLASS_SLOT).toPrivate());
|
||||
MOZ_ASSERT(IsDOMClass(instanceClass));
|
||||
DOMJSClass* domClass = DOMJSClass::FromJSClass(instanceClass);
|
||||
return (uint32_t)domClass->mInterfaceChain[depth] == protoID;
|
||||
}
|
||||
|
||||
@ -377,14 +376,11 @@ QueryInterface(JSContext* cx, unsigned argc, JS::Value* vp)
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
JSClass* clasp = js::GetObjectJSClass(obj);
|
||||
if (!IsDOMClass(clasp) ||
|
||||
!DOMJSClass::FromJSClass(clasp)->mDOMObjectIsISupports) {
|
||||
nsISupports* native;
|
||||
if (!UnwrapDOMObjectToISupports(obj, native)) {
|
||||
return Throw<true>(cx, NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
nsISupports* native = UnwrapDOMObject<nsISupports>(obj);
|
||||
|
||||
if (argc < 1) {
|
||||
return Throw<true>(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
|
||||
}
|
||||
@ -451,8 +447,9 @@ XrayResolveProperty(JSContext* cx, JSObject* wrapper, jsid id,
|
||||
JSFunction *fun = JS_NewFunctionById(cx, methodSpecs[i].call.op,
|
||||
methodSpecs[i].nargs, 0,
|
||||
wrapper, id);
|
||||
if (!fun)
|
||||
if (!fun) {
|
||||
return false;
|
||||
}
|
||||
SET_JITINFO(fun, methodSpecs[i].call.info);
|
||||
JSObject *funobj = JS_GetFunctionObject(fun);
|
||||
desc->value.setObject(*funobj);
|
||||
@ -590,5 +587,46 @@ XrayEnumerateProperties(JS::AutoIdVector& props,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GetPropertyOnPrototype(JSContext* cx, JSObject* proxy, jsid id, bool* found,
|
||||
JS::Value* vp)
|
||||
{
|
||||
JSObject* proto = js::GetObjectProto(proxy);
|
||||
if (!proto) {
|
||||
*found = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
JSBool hasProp;
|
||||
if (!JS_HasPropertyById(cx, proto, id, &hasProp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*found = hasProp;
|
||||
if (!hasProp || !vp) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return JS_ForwardGetPropertyTo(cx, proto, id, proxy, vp);
|
||||
}
|
||||
|
||||
bool
|
||||
HasPropertyOnPrototype(JSContext* cx, JSObject* proxy, DOMProxyHandler* handler,
|
||||
jsid id)
|
||||
{
|
||||
JSAutoEnterCompartment ac;
|
||||
if (xpc::WrapperFactory::IsXrayWrapper(proxy)) {
|
||||
proxy = js::UnwrapObject(proxy);
|
||||
if (!ac.enter(cx, proxy)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT(js::IsProxy(proxy) && js::GetProxyHandler(proxy) == handler);
|
||||
|
||||
bool found;
|
||||
// We ignore an error from GetPropertyOnPrototype.
|
||||
return !GetPropertyOnPrototype(cx, proxy, id, &found, NULL) || found;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define mozilla_dom_BindingUtils_h__
|
||||
|
||||
#include "mozilla/dom/DOMJSClass.h"
|
||||
#include "mozilla/dom/DOMJSProxyHandler.h"
|
||||
#include "mozilla/dom/workers/Workers.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
|
||||
@ -78,13 +79,34 @@ IsDOMClass(const js::Class* clasp)
|
||||
return IsDOMClass(Jsvalify(clasp));
|
||||
}
|
||||
|
||||
// It's ok for eRegularDOMObject and eProxyDOMObject to be the same, but
|
||||
// eNonDOMObject should always be different from the other two. This enum
|
||||
// shouldn't be used to differentiate between non-proxy and proxy bindings.
|
||||
enum DOMObjectSlot {
|
||||
eNonDOMObject = -1,
|
||||
eRegularDOMObject = DOM_OBJECT_SLOT,
|
||||
eProxyDOMObject = DOM_PROXY_OBJECT_SLOT
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline T*
|
||||
UnwrapDOMObject(JSObject* obj)
|
||||
UnwrapDOMObject(JSObject* obj, DOMObjectSlot slot)
|
||||
{
|
||||
MOZ_ASSERT(IsDOMClass(JS_GetClass(obj)));
|
||||
MOZ_ASSERT(slot != eNonDOMObject,
|
||||
"Don't pass non-DOM objects to this function");
|
||||
|
||||
JS::Value val = js::GetReservedSlot(obj, DOM_OBJECT_SLOT);
|
||||
#ifdef DEBUG
|
||||
if (IsDOMClass(js::GetObjectClass(obj))) {
|
||||
MOZ_ASSERT(slot == eRegularDOMObject);
|
||||
} else {
|
||||
MOZ_ASSERT(js::IsObjectProxyClass(js::GetObjectClass(obj)) ||
|
||||
js::IsFunctionProxyClass(js::GetObjectClass(obj)));
|
||||
MOZ_ASSERT(js::GetProxyHandler(obj)->family() == ProxyFamily());
|
||||
MOZ_ASSERT(slot == eProxyDOMObject);
|
||||
}
|
||||
#endif
|
||||
|
||||
JS::Value val = js::GetReservedSlot(obj, slot);
|
||||
// XXXbz/khuey worker code tries to unwrap interface objects (which have
|
||||
// nothing here). That needs to stop.
|
||||
// XXX We don't null-check UnwrapObject's result; aren't we going to crash
|
||||
@ -96,6 +118,62 @@ UnwrapDOMObject(JSObject* obj)
|
||||
return static_cast<T*>(val.toPrivate());
|
||||
}
|
||||
|
||||
// Only use this with a new DOM binding object (either proxy or regular).
|
||||
inline const DOMClass*
|
||||
GetDOMClass(JSObject* obj)
|
||||
{
|
||||
js::Class* clasp = js::GetObjectClass(obj);
|
||||
if (IsDOMClass(clasp)) {
|
||||
return &DOMJSClass::FromJSClass(clasp)->mClass;
|
||||
}
|
||||
|
||||
js::BaseProxyHandler* handler = js::GetProxyHandler(obj);
|
||||
MOZ_ASSERT(handler->family() == ProxyFamily());
|
||||
return &static_cast<DOMProxyHandler*>(handler)->mClass;
|
||||
}
|
||||
|
||||
inline DOMObjectSlot
|
||||
GetDOMClass(JSObject* obj, const DOMClass*& result)
|
||||
{
|
||||
js::Class* clasp = js::GetObjectClass(obj);
|
||||
if (IsDOMClass(clasp)) {
|
||||
result = &DOMJSClass::FromJSClass(clasp)->mClass;
|
||||
return eRegularDOMObject;
|
||||
}
|
||||
|
||||
if (js::IsObjectProxyClass(clasp) || js::IsFunctionProxyClass(clasp)) {
|
||||
js::BaseProxyHandler* handler = js::GetProxyHandler(obj);
|
||||
if (handler->family() == ProxyFamily()) {
|
||||
result = &static_cast<DOMProxyHandler*>(handler)->mClass;
|
||||
return eProxyDOMObject;
|
||||
}
|
||||
}
|
||||
|
||||
return eNonDOMObject;
|
||||
}
|
||||
|
||||
inline bool
|
||||
UnwrapDOMObjectToISupports(JSObject* obj, nsISupports*& result)
|
||||
{
|
||||
const DOMClass* clasp;
|
||||
DOMObjectSlot slot = GetDOMClass(obj, clasp);
|
||||
if (slot == eNonDOMObject || !clasp->mDOMObjectIsISupports) {
|
||||
return false;
|
||||
}
|
||||
|
||||
result = UnwrapDOMObject<nsISupports>(obj, slot);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool
|
||||
IsDOMObject(JSObject* obj)
|
||||
{
|
||||
js::Class* clasp = js::GetObjectClass(obj);
|
||||
return IsDOMClass(clasp) ||
|
||||
((js::IsObjectProxyClass(clasp) || js::IsFunctionProxyClass(clasp)) &&
|
||||
js::GetProxyHandler(obj)->family() == ProxyFamily());
|
||||
}
|
||||
|
||||
// Some callers don't want to set an exception when unwrappin fails
|
||||
// (for example, overload resolution uses unwrapping to tell what sort
|
||||
// of thing it's looking at).
|
||||
@ -105,8 +183,9 @@ inline nsresult
|
||||
UnwrapObject(JSContext* cx, JSObject* obj, U& value)
|
||||
{
|
||||
/* First check to see whether we have a DOM object */
|
||||
JSClass* clasp = js::GetObjectJSClass(obj);
|
||||
if (!IsDOMClass(clasp)) {
|
||||
const DOMClass* domClass;
|
||||
DOMObjectSlot slot = GetDOMClass(obj, domClass);
|
||||
if (slot == eNonDOMObject) {
|
||||
/* Maybe we have a security wrapper or outer window? */
|
||||
if (!js::IsWrapper(obj)) {
|
||||
/* Not a DOM object, not a wrapper, just bail */
|
||||
@ -118,22 +197,19 @@ UnwrapObject(JSContext* cx, JSObject* obj, U& value)
|
||||
return NS_ERROR_XPC_SECURITY_MANAGER_VETO;
|
||||
}
|
||||
MOZ_ASSERT(!js::IsWrapper(obj));
|
||||
clasp = js::GetObjectJSClass(obj);
|
||||
if (!IsDOMClass(clasp)) {
|
||||
slot = GetDOMClass(obj, domClass);
|
||||
if (slot == eNonDOMObject) {
|
||||
/* We don't have a DOM object */
|
||||
return NS_ERROR_XPC_BAD_CONVERT_JS;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(IsDOMClass(clasp));
|
||||
|
||||
/* This object is a DOM object. Double-check that it is safely
|
||||
castable to T by checking whether it claims to inherit from the
|
||||
class identified by protoID. */
|
||||
DOMJSClass* domClass = DOMJSClass::FromJSClass(clasp);
|
||||
if (domClass->mInterfaceChain[PrototypeTraits<PrototypeID>::Depth] ==
|
||||
PrototypeID) {
|
||||
value = UnwrapDOMObject<T>(obj);
|
||||
value = UnwrapDOMObject<T>(obj, slot);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -309,7 +385,7 @@ JSObject*
|
||||
CreateInterfaceObjects(JSContext* cx, JSObject* global, JSObject* receiver,
|
||||
JSObject* protoProto, JSClass* protoClass,
|
||||
JSClass* constructorClass, JSNative constructor,
|
||||
unsigned ctorNargs, JSClass* instanceClass,
|
||||
unsigned ctorNargs, const DOMClass* domClass,
|
||||
Prefable<JSFunctionSpec>* methods,
|
||||
Prefable<JSPropertySpec>* properties,
|
||||
Prefable<ConstantSpec>* constants,
|
||||
@ -555,6 +631,22 @@ GetParentPointer(const ParentObject& aObject)
|
||||
return ToSupports(aObject.mObject);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void
|
||||
ClearWrapper(T* p, nsWrapperCache* cache)
|
||||
{
|
||||
cache->ClearWrapper();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void
|
||||
ClearWrapper(T* p, void*)
|
||||
{
|
||||
nsWrapperCache* cache;
|
||||
CallQueryInterface(p, &cache);
|
||||
ClearWrapper(p, cache);
|
||||
}
|
||||
|
||||
// Can only be called with the immediate prototype of the instance object. Can
|
||||
// only be called on the prototype of an object known to be a DOM instance.
|
||||
JSBool
|
||||
@ -700,6 +792,14 @@ QueryInterface(JSContext* cx, unsigned argc, JS::Value* vp);
|
||||
JSBool
|
||||
ThrowingConstructor(JSContext* cx, unsigned argc, JS::Value* vp);
|
||||
|
||||
bool
|
||||
GetPropertyOnPrototype(JSContext* cx, JSObject* proxy, jsid id, bool* found,
|
||||
JS::Value* vp);
|
||||
|
||||
bool
|
||||
HasPropertyOnPrototype(JSContext* cx, JSObject* proxy, DOMProxyHandler* handler,
|
||||
jsid id);
|
||||
|
||||
template<class T>
|
||||
class NonNull
|
||||
{
|
||||
|
@ -301,6 +301,52 @@ DOMInterfaces = {
|
||||
'register': False
|
||||
},
|
||||
|
||||
|
||||
'TestIndexedGetterInterface' : {
|
||||
'nativeType': 'mozilla::dom::TestIndexedGetterInterface',
|
||||
'headerFile': 'TestBindingHeader.h',
|
||||
'register': False,
|
||||
'infallible': [ 'length' ]
|
||||
},
|
||||
|
||||
'TestNamedGetterInterface' : {
|
||||
'nativeType': 'mozilla::dom::TestNamedGetterInterface',
|
||||
'headerFile': 'TestBindingHeader.h',
|
||||
'register': False
|
||||
},
|
||||
|
||||
'TestIndexedAndNamedGetterInterface' : {
|
||||
'nativeType': 'mozilla::dom::TestIndexedAndNamedGetterInterface',
|
||||
'headerFile': 'TestBindingHeader.h',
|
||||
'register': False,
|
||||
'infallible': [ 'length' ]
|
||||
},
|
||||
|
||||
'TestIndexedSetterInterface' : {
|
||||
'nativeType': 'mozilla::dom::TestIndexedSetterInterface',
|
||||
'headerFile': 'TestBindingHeader.h',
|
||||
'register': False
|
||||
},
|
||||
|
||||
'TestNamedSetterInterface' : {
|
||||
'nativeType': 'mozilla::dom::TestNamedSetterInterface',
|
||||
'headerFile': 'TestBindingHeader.h',
|
||||
'register': False
|
||||
},
|
||||
|
||||
'TestIndexedAndNamedSetterInterface' : {
|
||||
'nativeType': 'mozilla::dom::TestIndexedAndNamedSetterInterface',
|
||||
'headerFile': 'TestBindingHeader.h',
|
||||
'register': False
|
||||
},
|
||||
|
||||
'TestIndexedAndNamedGetterAndSetterInterface' : {
|
||||
'nativeType': 'mozilla::dom::TestIndexedAndNamedGetterAndSetterInterface',
|
||||
'headerFile': 'TestBindingHeader.h',
|
||||
'register': False,
|
||||
'infallible': [ 'length', '__stringifier' ],
|
||||
'binaryNames': { '__stringifier': 'Stringify' }
|
||||
},
|
||||
}
|
||||
|
||||
# These are temporary, until they've been converted to use new DOM bindings
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -147,13 +147,63 @@ class Descriptor(DescriptorProvider):
|
||||
|
||||
# If we're concrete, we need to crawl our ancestor interfaces and mark
|
||||
# them as having a concrete descendant.
|
||||
self.concrete = desc.get('concrete', True)
|
||||
self.concrete = desc.get('concrete', not self.interface.isExternal())
|
||||
if self.concrete:
|
||||
self.proxy = False
|
||||
operations = {
|
||||
'IndexedGetter': None,
|
||||
'IndexedSetter': None,
|
||||
'IndexedCreator': None,
|
||||
'IndexedDeleter': None,
|
||||
'NamedGetter': None,
|
||||
'NamedSetter': None,
|
||||
'NamedCreator': None,
|
||||
'NamedDeleter': None,
|
||||
'Stringifier': None
|
||||
}
|
||||
iface = self.interface
|
||||
while iface:
|
||||
for m in iface.members:
|
||||
if not m.isMethod():
|
||||
continue
|
||||
|
||||
def addOperation(operation, m):
|
||||
if not operations[operation]:
|
||||
operations[operation] = m
|
||||
def addIndexedOrNamedOperation(operation, m):
|
||||
self.proxy = True
|
||||
if m.isIndexed():
|
||||
operation = 'Indexed' + operation
|
||||
else:
|
||||
assert m.isNamed()
|
||||
operation = 'Named' + operation
|
||||
addOperation(operation, m)
|
||||
|
||||
if m.isStringifier():
|
||||
addOperation('Stringifier', m)
|
||||
else:
|
||||
if m.isGetter():
|
||||
addIndexedOrNamedOperation('Getter', m)
|
||||
if m.isSetter():
|
||||
addIndexedOrNamedOperation('Setter', m)
|
||||
if m.isCreator():
|
||||
addIndexedOrNamedOperation('Creator', m)
|
||||
if m.isDeleter():
|
||||
addIndexedOrNamedOperation('Deleter', m)
|
||||
raise TypeError("deleter specified on %s but we "
|
||||
"don't support deleters yet" %
|
||||
self.interface.identifier.name)
|
||||
|
||||
iface.setUserData('hasConcreteDescendant', True)
|
||||
iface = iface.parent
|
||||
|
||||
if self.proxy:
|
||||
self.operations = operations
|
||||
iface = self.interface
|
||||
while iface:
|
||||
iface.setUserData('hasProxyDescendant', True)
|
||||
iface = iface.parent
|
||||
|
||||
if self.interface.isExternal() and 'prefable' in desc:
|
||||
raise TypeError("%s is external but has a prefable setting" %
|
||||
self.interface.identifier.name)
|
||||
@ -188,7 +238,13 @@ class Descriptor(DescriptorProvider):
|
||||
elif isinstance(config, list):
|
||||
add('all', config, attribute)
|
||||
else:
|
||||
assert isinstance(config, string)
|
||||
assert isinstance(config, str)
|
||||
if config == '*':
|
||||
iface = self.interface
|
||||
while iface:
|
||||
add('all', map(lambda m: m.name, iface.members), attribute)
|
||||
iface = iface.parent
|
||||
else:
|
||||
add('all', [config], attribute)
|
||||
|
||||
for attribute in ['infallible', 'implicitJSContext', 'resultNotAddRefed']:
|
||||
|
@ -45,6 +45,21 @@ struct NativePropertyHooks
|
||||
const NativePropertyHooks *mProtoHooks;
|
||||
};
|
||||
|
||||
struct DOMClass
|
||||
{
|
||||
// A list of interfaces that this object implements, in order of decreasing
|
||||
// derivedness.
|
||||
const prototypes::ID mInterfaceChain[prototypes::id::_ID_Count];
|
||||
|
||||
// We store the DOM object in reserved slot with index DOM_OBJECT_SLOT or in
|
||||
// the proxy private if we use a proxy object.
|
||||
// Sometimes it's an nsISupports and sometimes it's not; this class tells
|
||||
// us which it is.
|
||||
const bool mDOMObjectIsISupports;
|
||||
|
||||
const NativePropertyHooks* mNativeHooks;
|
||||
};
|
||||
|
||||
// Special JSClass for reflected DOM objects.
|
||||
struct DOMJSClass
|
||||
{
|
||||
@ -53,9 +68,7 @@ struct DOMJSClass
|
||||
// only allows brace initialization for aggregate/POD types.
|
||||
JSClass mBase;
|
||||
|
||||
// A list of interfaces that this object implements, in order of decreasing
|
||||
// derivedness.
|
||||
const prototypes::ID mInterfaceChain[prototypes::id::_ID_Count];
|
||||
DOMClass mClass;
|
||||
|
||||
// We cache the VTable index of GetWrapperCache for objects that support it.
|
||||
//
|
||||
@ -63,13 +76,6 @@ struct DOMJSClass
|
||||
// XXXkhuey this is unused and needs to die.
|
||||
const int16_t mGetWrapperCacheVTableOffset;
|
||||
|
||||
// We store the DOM object in a reserved slot whose index is mNativeSlot.
|
||||
// Sometimes it's an nsISupports and sometimes it's not; this class tells
|
||||
// us which it is.
|
||||
const bool mDOMObjectIsISupports;
|
||||
|
||||
const NativePropertyHooks* mNativeHooks;
|
||||
|
||||
static DOMJSClass* FromJSClass(JSClass* base) {
|
||||
MOZ_ASSERT(base->flags & JSCLASS_IS_DOMJSCLASS);
|
||||
return reinterpret_cast<DOMJSClass*>(base);
|
||||
|
228
dom/bindings/DOMJSProxyHandler.cpp
Normal file
228
dom/bindings/DOMJSProxyHandler.cpp
Normal file
@ -0,0 +1,228 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: set ts=2 sw=2 et tw=99 ft=cpp: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/Util.h"
|
||||
|
||||
#include "DOMJSProxyHandler.h"
|
||||
#include "xpcpublic.h"
|
||||
#include "xpcprivate.h"
|
||||
#include "XPCQuickStubs.h"
|
||||
#include "XPCWrapper.h"
|
||||
#include "WrapperFactory.h"
|
||||
#include "nsDOMClassInfo.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "nsWrapperCacheInlines.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jsatom.h"
|
||||
|
||||
using namespace JS;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
jsid s_length_id = JSID_VOID;
|
||||
|
||||
bool
|
||||
DefineStaticJSVals(JSContext* cx)
|
||||
{
|
||||
JSAutoRequest ar(cx);
|
||||
|
||||
return InternJSString(cx, s_length_id, "length");
|
||||
}
|
||||
|
||||
|
||||
int HandlerFamily;
|
||||
|
||||
bool
|
||||
DefineConstructor(JSContext* cx, JSObject* obj, DefineInterface aDefine, nsresult* aResult)
|
||||
{
|
||||
bool enabled;
|
||||
bool defined = aDefine(cx, obj, &enabled);
|
||||
MOZ_ASSERT(!defined || enabled,
|
||||
"We defined a constructor but the new bindings are disabled?");
|
||||
*aResult = defined ? NS_OK : NS_ERROR_FAILURE;
|
||||
return enabled;
|
||||
}
|
||||
|
||||
// static
|
||||
JSObject*
|
||||
DOMProxyHandler::EnsureExpandoObject(JSContext* cx, JSObject* obj)
|
||||
{
|
||||
NS_ASSERTION(IsDOMProxy(obj), "expected a DOM proxy object");
|
||||
JSObject* expando = GetExpandoObject(obj);
|
||||
if (!expando) {
|
||||
expando = JS_NewObjectWithGivenProto(cx, nullptr, nullptr,
|
||||
js::GetObjectParent(obj));
|
||||
if (!expando) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
xpc::CompartmentPrivate* priv = xpc::GetCompartmentPrivate(obj);
|
||||
if (!priv->RegisterDOMExpandoObject(obj)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nsWrapperCache* cache;
|
||||
CallQueryInterface(UnwrapDOMObject<nsISupports>(obj, eProxyDOMObject), &cache);
|
||||
cache->SetPreservingWrapper(true);
|
||||
|
||||
js::SetProxyExtra(obj, JSPROXYSLOT_EXPANDO, ObjectValue(*expando));
|
||||
}
|
||||
return expando;
|
||||
}
|
||||
|
||||
bool
|
||||
DOMProxyHandler::getPropertyDescriptor(JSContext* cx, JSObject* proxy, jsid id, bool set,
|
||||
JSPropertyDescriptor* desc)
|
||||
{
|
||||
if (!getOwnPropertyDescriptor(cx, proxy, id, set, desc)) {
|
||||
return false;
|
||||
}
|
||||
if (desc->obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
JSObject* proto = js::GetObjectProto(proxy);
|
||||
if (!proto) {
|
||||
desc->obj = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
return JS_GetPropertyDescriptorById(cx, proto, id, JSRESOLVE_QUALIFIED, desc);
|
||||
}
|
||||
|
||||
bool
|
||||
DOMProxyHandler::defineProperty(JSContext* cx, JSObject* proxy, jsid id,
|
||||
JSPropertyDescriptor* desc)
|
||||
{
|
||||
if ((desc->attrs & JSPROP_GETTER) && desc->setter == JS_StrictPropertyStub) {
|
||||
return JS_ReportErrorFlagsAndNumber(cx,
|
||||
JSREPORT_WARNING | JSREPORT_STRICT |
|
||||
JSREPORT_STRICT_MODE_ERROR,
|
||||
js_GetErrorMessage, NULL,
|
||||
JSMSG_GETTER_ONLY);
|
||||
}
|
||||
|
||||
if (xpc::WrapperFactory::IsXrayWrapper(proxy)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
JSObject* expando = EnsureExpandoObject(cx, proxy);
|
||||
if (!expando) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return JS_DefinePropertyById(cx, expando, id, desc->value, desc->getter, desc->setter,
|
||||
desc->attrs);
|
||||
}
|
||||
|
||||
bool
|
||||
DOMProxyHandler::delete_(JSContext* cx, JSObject* proxy, jsid id, bool* bp)
|
||||
{
|
||||
JSBool b = true;
|
||||
|
||||
JSObject* expando;
|
||||
if (!xpc::WrapperFactory::IsXrayWrapper(proxy) && (expando = GetExpandoObject(proxy))) {
|
||||
Value v;
|
||||
if (!JS_DeletePropertyById2(cx, expando, id, &v) || !JS_ValueToBoolean(cx, v, &b)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
*bp = !!b;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DOMProxyHandler::enumerate(JSContext* cx, JSObject* proxy, AutoIdVector& props)
|
||||
{
|
||||
JSObject* proto = JS_GetPrototype(proxy);
|
||||
return getOwnPropertyNames(cx, proxy, props) &&
|
||||
(!proto || js::GetPropertyNames(cx, proto, 0, &props));
|
||||
}
|
||||
|
||||
bool
|
||||
DOMProxyHandler::fix(JSContext* cx, JSObject* proxy, Value* vp)
|
||||
{
|
||||
vp->setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DOMProxyHandler::has(JSContext* cx, JSObject* proxy, jsid id, bool* bp)
|
||||
{
|
||||
if (!hasOwn(cx, proxy, id, bp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*bp) {
|
||||
// We have the property ourselves; no need to worry about our prototype
|
||||
// chain.
|
||||
return true;
|
||||
}
|
||||
|
||||
// OK, now we have to look at the proto
|
||||
JSObject *proto = js::GetObjectProto(proxy);
|
||||
if (!proto) {
|
||||
return true;
|
||||
}
|
||||
JSBool protoHasProp;
|
||||
bool ok = JS_HasPropertyById(cx, proto, id, &protoHasProp);
|
||||
if (ok) {
|
||||
*bp = protoHasProp;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
// static
|
||||
JSString*
|
||||
DOMProxyHandler::obj_toString(JSContext* cx, const char* className)
|
||||
{
|
||||
size_t nchars = sizeof("[object ]") - 1 + strlen(className);
|
||||
jschar* chars = static_cast<jschar*>(JS_malloc(cx, (nchars + 1) * sizeof(jschar)));
|
||||
if (!chars) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* prefix = "[object ";
|
||||
nchars = 0;
|
||||
while ((chars[nchars] = (jschar)*prefix) != 0) {
|
||||
nchars++, prefix++;
|
||||
}
|
||||
while ((chars[nchars] = (jschar)*className) != 0) {
|
||||
nchars++, className++;
|
||||
}
|
||||
chars[nchars++] = ']';
|
||||
chars[nchars] = 0;
|
||||
|
||||
JSString* str = JS_NewUCString(cx, chars, nchars);
|
||||
if (!str) {
|
||||
JS_free(cx, chars);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
int32_t
|
||||
IdToInt32(JSContext* cx, jsid id)
|
||||
{
|
||||
JSAutoRequest ar(cx);
|
||||
|
||||
jsval idval;
|
||||
double array_index;
|
||||
int32_t i;
|
||||
if (!::JS_IdToValue(cx, id, &idval) ||
|
||||
!::JS_ValueToNumber(cx, idval, &array_index) ||
|
||||
!::JS_DoubleIsInt32(array_index, &i)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
109
dom/bindings/DOMJSProxyHandler.h
Normal file
109
dom/bindings/DOMJSProxyHandler.h
Normal file
@ -0,0 +1,109 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_DOMJSProxyHandler_h
|
||||
#define mozilla_dom_DOMJSProxyHandler_h
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jsatom.h"
|
||||
#include "jsproxy.h"
|
||||
#include "xpcpublic.h"
|
||||
#include "nsString.h"
|
||||
#include "mozilla/Likely.h"
|
||||
|
||||
#define DOM_PROXY_OBJECT_SLOT js::JSSLOT_PROXY_PRIVATE
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
enum {
|
||||
JSPROXYSLOT_EXPANDO = 0
|
||||
};
|
||||
|
||||
template<typename T> struct Prefable;
|
||||
|
||||
class DOMProxyHandler : public js::BaseProxyHandler
|
||||
{
|
||||
public:
|
||||
DOMProxyHandler(const DOMClass& aClass)
|
||||
: js::BaseProxyHandler(ProxyFamily()),
|
||||
mClass(aClass)
|
||||
{
|
||||
}
|
||||
|
||||
bool getPropertyDescriptor(JSContext* cx, JSObject* proxy, jsid id, bool set,
|
||||
JSPropertyDescriptor* desc);
|
||||
bool defineProperty(JSContext* cx, JSObject* proxy, jsid id,
|
||||
JSPropertyDescriptor* desc);
|
||||
bool delete_(JSContext* cx, JSObject* proxy, jsid id, bool* bp);
|
||||
bool enumerate(JSContext* cx, JSObject* proxy, JS::AutoIdVector& props);
|
||||
bool fix(JSContext* cx, JSObject* proxy, JS::Value* vp);
|
||||
bool has(JSContext* cx, JSObject* proxy, jsid id, bool* bp);
|
||||
using js::BaseProxyHandler::obj_toString;
|
||||
|
||||
static JSObject* GetExpandoObject(JSObject* obj)
|
||||
{
|
||||
MOZ_ASSERT(IsDOMProxy(obj), "expected a DOM proxy object");
|
||||
JS::Value v = js::GetProxyExtra(obj, JSPROXYSLOT_EXPANDO);
|
||||
return v.isUndefined() ? NULL : v.toObjectOrNull();
|
||||
}
|
||||
static JSObject* EnsureExpandoObject(JSContext* cx, JSObject* obj);
|
||||
|
||||
const DOMClass& mClass;
|
||||
|
||||
protected:
|
||||
static JSString* obj_toString(JSContext* cx, const char* className);
|
||||
};
|
||||
|
||||
extern jsid s_length_id;
|
||||
|
||||
int32_t IdToInt32(JSContext* cx, jsid id);
|
||||
|
||||
inline int32_t
|
||||
GetArrayIndexFromId(JSContext* cx, jsid id)
|
||||
{
|
||||
if (MOZ_LIKELY(JSID_IS_INT(id))) {
|
||||
return JSID_TO_INT(id);
|
||||
}
|
||||
if (MOZ_LIKELY(id == s_length_id)) {
|
||||
return -1;
|
||||
}
|
||||
if (MOZ_LIKELY(JSID_IS_ATOM(id))) {
|
||||
JSAtom* atom = JSID_TO_ATOM(id);
|
||||
jschar s = *js::GetAtomChars(atom);
|
||||
if (MOZ_LIKELY((unsigned)s >= 'a' && (unsigned)s <= 'z'))
|
||||
return -1;
|
||||
|
||||
uint32_t i;
|
||||
JSLinearString* str = js::AtomToLinearString(JSID_TO_ATOM(id));
|
||||
return js::StringIsArrayIndex(str, &i) ? i : -1;
|
||||
}
|
||||
return IdToInt32(cx, id);
|
||||
}
|
||||
|
||||
inline void
|
||||
FillPropertyDescriptor(JSPropertyDescriptor* desc, JSObject* obj, bool readonly)
|
||||
{
|
||||
desc->obj = obj;
|
||||
desc->attrs = (readonly ? JSPROP_READONLY : 0) | JSPROP_ENUMERATE;
|
||||
desc->getter = NULL;
|
||||
desc->setter = NULL;
|
||||
desc->shortid = 0;
|
||||
}
|
||||
|
||||
inline void
|
||||
FillPropertyDescriptor(JSPropertyDescriptor* desc, JSObject* obj, jsval v, bool readonly)
|
||||
{
|
||||
desc->value = v;
|
||||
FillPropertyDescriptor(desc, obj, readonly);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
EnsureExpandoObject(JSContext* cx, JSObject* obj);
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* mozilla_dom_DOMProxyHandler_h */
|
@ -25,3 +25,4 @@ MSG_DEF(MSG_NOT_OBJECT, 0, "Value not an object.")
|
||||
MSG_DEF(MSG_DOES_NOT_IMPLEMENT_INTERFACE, 1, "Value does not implement interface {0}.")
|
||||
MSG_DEF(MSG_NOT_IN_UNION, 1, "Value could not be converted to any of: {0}.")
|
||||
MSG_DEF(MSG_ILLEGAL_CONSTRUCTOR, 0, "Illegal constructor.")
|
||||
MSG_DEF(MSG_NO_PROPERTY_SETTER, 1, "{0} doesn't have an indexed property setter.")
|
@ -45,6 +45,7 @@ CPPSRCS = \
|
||||
$(linked_binding_cpp_files) \
|
||||
$(filter %.cpp, $(globalgen_targets)) \
|
||||
BindingUtils.cpp \
|
||||
DOMJSProxyHandler.cpp \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS_NAMESPACES = $(binding_include_path) mozilla
|
||||
@ -56,6 +57,7 @@ EXPORTS_mozilla = \
|
||||
EXPORTS_$(binding_include_path) = \
|
||||
BindingUtils.h \
|
||||
DOMJSClass.h \
|
||||
DOMJSProxyHandler.h \
|
||||
Errors.msg \
|
||||
Nullable.h \
|
||||
PrimitiveConversions.h \
|
||||
|
@ -2133,6 +2133,9 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
||||
def hasOverloads(self):
|
||||
return self._hasOverloads
|
||||
|
||||
def isIdentifierLess(self):
|
||||
return self.identifier.name[:2] == "__"
|
||||
|
||||
def resolve(self, parentScope):
|
||||
assert isinstance(parentScope, IDLScope)
|
||||
IDLObjectWithIdentifier.resolve(self, parentScope)
|
||||
|
@ -558,6 +558,102 @@ private:
|
||||
|
||||
};
|
||||
|
||||
class TestIndexedGetterInterface : public nsISupports,
|
||||
public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// We need a GetParentObject to make binding codegen happy
|
||||
virtual nsISupports* GetParentObject();
|
||||
|
||||
uint32_t IndexedGetter(uint32_t, bool&, ErrorResult&);
|
||||
uint32_t IndexedGetter(uint32_t, ErrorResult&) MOZ_DELETE;
|
||||
uint32_t Item(uint32_t, ErrorResult&);
|
||||
uint32_t Item(uint32_t, bool&, ErrorResult&) MOZ_DELETE;
|
||||
uint32_t GetLength();
|
||||
};
|
||||
|
||||
class TestNamedGetterInterface : public nsISupports,
|
||||
public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// We need a GetParentObject to make binding codegen happy
|
||||
virtual nsISupports* GetParentObject();
|
||||
|
||||
void NamedGetter(const nsAString&, bool&, nsAString&, ErrorResult&);
|
||||
};
|
||||
|
||||
class TestIndexedAndNamedGetterInterface : public nsISupports,
|
||||
public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// We need a GetParentObject to make binding codegen happy
|
||||
virtual nsISupports* GetParentObject();
|
||||
|
||||
uint32_t IndexedGetter(uint32_t, bool&, ErrorResult&);
|
||||
void NamedGetter(const nsAString&, bool&, nsAString&, ErrorResult&);
|
||||
void NamedItem(const nsAString&, nsAString&, ErrorResult&);
|
||||
uint32_t GetLength();
|
||||
};
|
||||
|
||||
class TestIndexedSetterInterface : public nsISupports,
|
||||
public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// We need a GetParentObject to make binding codegen happy
|
||||
virtual nsISupports* GetParentObject();
|
||||
|
||||
void IndexedSetter(uint32_t, const nsAString&, ErrorResult&);
|
||||
void SetItem(uint32_t, const nsAString&, ErrorResult&);
|
||||
};
|
||||
|
||||
class TestNamedSetterInterface : public nsISupports,
|
||||
public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// We need a GetParentObject to make binding codegen happy
|
||||
virtual nsISupports* GetParentObject();
|
||||
|
||||
void NamedSetter(const nsAString&, TestIndexedSetterInterface&, ErrorResult&);
|
||||
};
|
||||
|
||||
class TestIndexedAndNamedSetterInterface : public nsISupports,
|
||||
public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// We need a GetParentObject to make binding codegen happy
|
||||
virtual nsISupports* GetParentObject();
|
||||
|
||||
void IndexedSetter(uint32_t, TestIndexedSetterInterface&, ErrorResult&);
|
||||
void NamedSetter(const nsAString&, TestIndexedSetterInterface&, ErrorResult&);
|
||||
void SetNamedItem(const nsAString&, TestIndexedSetterInterface&, ErrorResult&);
|
||||
};
|
||||
|
||||
class TestIndexedAndNamedGetterAndSetterInterface : public TestIndexedSetterInterface
|
||||
{
|
||||
public:
|
||||
uint32_t IndexedGetter(uint32_t, bool&, ErrorResult&);
|
||||
uint32_t Item(uint32_t, ErrorResult&);
|
||||
void NamedGetter(const nsAString&, bool&, nsAString&, ErrorResult&);
|
||||
void NamedItem(const nsAString&, nsAString&, ErrorResult&);
|
||||
void IndexedSetter(uint32_t, int32_t&, ErrorResult&);
|
||||
void IndexedSetter(uint32_t, const nsAString&, ErrorResult&) MOZ_DELETE;
|
||||
void NamedSetter(const nsAString&, const nsAString&, ErrorResult&);
|
||||
void Stringify(nsAString&);
|
||||
uint32_t GetLength();
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -372,3 +372,40 @@ dictionary ParentDict : GrandparentDict {
|
||||
dictionary DictContainingDict {
|
||||
Dict memberDict;
|
||||
};
|
||||
|
||||
interface TestIndexedGetterInterface {
|
||||
getter long item(unsigned long index);
|
||||
readonly attribute unsigned long length;
|
||||
};
|
||||
|
||||
interface TestNamedGetterInterface {
|
||||
getter DOMString (DOMString name);
|
||||
};
|
||||
|
||||
interface TestIndexedAndNamedGetterInterface {
|
||||
getter long (unsigned long index);
|
||||
getter DOMString namedItem(DOMString name);
|
||||
readonly attribute unsigned long length;
|
||||
};
|
||||
|
||||
interface TestIndexedSetterInterface {
|
||||
setter creator void setItem(unsigned long index, DOMString item);
|
||||
};
|
||||
|
||||
interface TestNamedSetterInterface {
|
||||
setter creator void (DOMString name, TestIndexedSetterInterface item);
|
||||
};
|
||||
|
||||
interface TestIndexedAndNamedSetterInterface {
|
||||
setter creator void (unsigned long index, TestIndexedSetterInterface item);
|
||||
setter creator void setNamedItem(DOMString name, TestIndexedSetterInterface item);
|
||||
};
|
||||
|
||||
interface TestIndexedAndNamedGetterAndSetterInterface : TestIndexedSetterInterface {
|
||||
getter long item(unsigned long index);
|
||||
getter DOMString namedItem(DOMString name);
|
||||
setter creator void (unsigned long index, long item);
|
||||
setter creator void (DOMString name, DOMString item);
|
||||
stringifier DOMString ();
|
||||
readonly attribute unsigned long length;
|
||||
};
|
||||
|
@ -233,7 +233,8 @@ private:
|
||||
Finalize(JSFreeOp* aFop, JSObject* aObj)
|
||||
{
|
||||
JS_ASSERT(JS_GetClass(aObj) == Class());
|
||||
WorkerPrivate* worker = UnwrapDOMObject<WorkerPrivate>(aObj);
|
||||
WorkerPrivate* worker =
|
||||
UnwrapDOMObject<WorkerPrivate>(aObj, eRegularDOMObject);
|
||||
if (worker) {
|
||||
worker->_finalize(aFop);
|
||||
}
|
||||
@ -243,7 +244,8 @@ private:
|
||||
Trace(JSTracer* aTrc, JSObject* aObj)
|
||||
{
|
||||
JS_ASSERT(JS_GetClass(aObj) == Class());
|
||||
WorkerPrivate* worker = UnwrapDOMObject<WorkerPrivate>(aObj);
|
||||
WorkerPrivate* worker =
|
||||
UnwrapDOMObject<WorkerPrivate>(aObj, eRegularDOMObject);
|
||||
if (worker) {
|
||||
worker->_trace(aTrc);
|
||||
}
|
||||
@ -303,9 +305,13 @@ DOMJSClass Worker::sClass = {
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, Finalize,
|
||||
NULL, NULL, NULL, NULL, Trace
|
||||
},
|
||||
{
|
||||
{ prototypes::id::EventTarget_workers, prototypes::id::_ID_Count,
|
||||
prototypes::id::_ID_Count },
|
||||
-1, false, &sNativePropertyHooks
|
||||
false,
|
||||
&sNativePropertyHooks
|
||||
},
|
||||
-1
|
||||
};
|
||||
|
||||
JSPropertySpec Worker::sProperties[] = {
|
||||
@ -376,7 +382,7 @@ private:
|
||||
if (aObj) {
|
||||
JSClass* classPtr = JS_GetClass(aObj);
|
||||
if (classPtr == Class()) {
|
||||
return UnwrapDOMObject<WorkerPrivate>(aObj);
|
||||
return UnwrapDOMObject<WorkerPrivate>(aObj, eRegularDOMObject);
|
||||
}
|
||||
}
|
||||
|
||||
@ -393,7 +399,8 @@ private:
|
||||
Finalize(JSFreeOp* aFop, JSObject* aObj)
|
||||
{
|
||||
JS_ASSERT(JS_GetClass(aObj) == Class());
|
||||
WorkerPrivate* worker = UnwrapDOMObject<WorkerPrivate>(aObj);
|
||||
WorkerPrivate* worker =
|
||||
UnwrapDOMObject<WorkerPrivate>(aObj, eRegularDOMObject);
|
||||
if (worker) {
|
||||
worker->_finalize(aFop);
|
||||
}
|
||||
@ -403,7 +410,8 @@ private:
|
||||
Trace(JSTracer* aTrc, JSObject* aObj)
|
||||
{
|
||||
JS_ASSERT(JS_GetClass(aObj) == Class());
|
||||
WorkerPrivate* worker = UnwrapDOMObject<WorkerPrivate>(aObj);
|
||||
WorkerPrivate* worker =
|
||||
UnwrapDOMObject<WorkerPrivate>(aObj, eRegularDOMObject);
|
||||
if (worker) {
|
||||
worker->_trace(aTrc);
|
||||
}
|
||||
@ -423,9 +431,13 @@ DOMJSClass ChromeWorker::sClass = {
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, Finalize,
|
||||
NULL, NULL, NULL, NULL, Trace,
|
||||
},
|
||||
{
|
||||
{ prototypes::id::EventTarget_workers, prototypes::id::_ID_Count,
|
||||
prototypes::id::_ID_Count },
|
||||
-1, false, &sNativePropertyHooks
|
||||
false,
|
||||
&sNativePropertyHooks
|
||||
},
|
||||
-1
|
||||
};
|
||||
|
||||
WorkerPrivate*
|
||||
@ -434,7 +446,7 @@ Worker::GetInstancePrivate(JSContext* aCx, JSObject* aObj,
|
||||
{
|
||||
JSClass* classPtr = JS_GetClass(aObj);
|
||||
if (classPtr == Class() || classPtr == ChromeWorker::Class()) {
|
||||
return UnwrapDOMObject<WorkerPrivate>(aObj);
|
||||
return UnwrapDOMObject<WorkerPrivate>(aObj, eRegularDOMObject);
|
||||
}
|
||||
|
||||
JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO,
|
||||
|
@ -768,7 +768,8 @@ private:
|
||||
{
|
||||
JSClass* classPtr = JS_GetClass(aObj);
|
||||
if (classPtr == Class()) {
|
||||
return UnwrapDOMObject<DedicatedWorkerGlobalScope>(aObj);
|
||||
return UnwrapDOMObject<DedicatedWorkerGlobalScope>(aObj,
|
||||
eRegularDOMObject);
|
||||
}
|
||||
|
||||
JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL,
|
||||
@ -803,7 +804,7 @@ private:
|
||||
{
|
||||
JS_ASSERT(JS_GetClass(aObj) == Class());
|
||||
DedicatedWorkerGlobalScope* scope =
|
||||
UnwrapDOMObject<DedicatedWorkerGlobalScope>(aObj);
|
||||
UnwrapDOMObject<DedicatedWorkerGlobalScope>(aObj, eRegularDOMObject);
|
||||
if (scope) {
|
||||
DestroyProtoOrIfaceCache(aObj);
|
||||
scope->_finalize(aFop);
|
||||
@ -815,7 +816,7 @@ private:
|
||||
{
|
||||
JS_ASSERT(JS_GetClass(aObj) == Class());
|
||||
DedicatedWorkerGlobalScope* scope =
|
||||
UnwrapDOMObject<DedicatedWorkerGlobalScope>(aObj);
|
||||
UnwrapDOMObject<DedicatedWorkerGlobalScope>(aObj, eRegularDOMObject);
|
||||
if (scope) {
|
||||
mozilla::dom::TraceProtoOrIfaceCache(aTrc, aObj);
|
||||
scope->_trace(aTrc);
|
||||
@ -859,9 +860,13 @@ DOMJSClass DedicatedWorkerGlobalScope::sClass = {
|
||||
JS_EnumerateStub, reinterpret_cast<JSResolveOp>(Resolve), JS_ConvertStub,
|
||||
Finalize, NULL, NULL, NULL, NULL, Trace
|
||||
},
|
||||
{
|
||||
{ prototypes::id::EventTarget_workers, prototypes::id::_ID_Count,
|
||||
prototypes::id::_ID_Count },
|
||||
-1, false, &sNativePropertyHooks
|
||||
false,
|
||||
&sNativePropertyHooks
|
||||
},
|
||||
-1
|
||||
};
|
||||
|
||||
JSPropertySpec DedicatedWorkerGlobalScope::sProperties[] = {
|
||||
@ -890,7 +895,7 @@ WorkerGlobalScope::GetInstancePrivate(JSContext* aCx, JSObject* aObj,
|
||||
JS_ASSERT(classPtr != Class());
|
||||
|
||||
if (classPtr == DedicatedWorkerGlobalScope::Class()) {
|
||||
return UnwrapDOMObject<DedicatedWorkerGlobalScope>(aObj);
|
||||
return UnwrapDOMObject<DedicatedWorkerGlobalScope>(aObj, eRegularDOMObject);
|
||||
}
|
||||
|
||||
JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO,
|
||||
|
@ -75,12 +75,7 @@ XPCConvert::GetISupportsFromJSObject(JSObject* obj, nsISupports** iface)
|
||||
*iface = (nsISupports*) xpc_GetJSPrivate(obj);
|
||||
return true;
|
||||
}
|
||||
if (jsclass && IsDOMClass(jsclass) &&
|
||||
DOMJSClass::FromJSClass(jsclass)->mDOMObjectIsISupports) {
|
||||
*iface = UnwrapDOMObject<nsISupports>(obj);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return UnwrapDOMObjectToISupports(obj, *iface);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -482,15 +482,10 @@ nsJSIID::HasInstance(nsIXPConnectWrappedNative *wrapper,
|
||||
}
|
||||
|
||||
nsISupports *identity;
|
||||
if (mozilla::dom::binding::instanceIsProxy(obj)) {
|
||||
if (mozilla::dom::oldproxybindings::instanceIsProxy(obj)) {
|
||||
identity =
|
||||
static_cast<nsISupports*>(js::GetProxyPrivate(obj).toPrivate());
|
||||
} else if (mozilla::dom::IsDOMClass(js::GetObjectJSClass(obj)) &&
|
||||
mozilla::dom::DOMJSClass::FromJSClass(
|
||||
js::GetObjectJSClass(obj))->mDOMObjectIsISupports) {
|
||||
identity =
|
||||
mozilla::dom::UnwrapDOMObject<nsISupports>(obj);
|
||||
} else {
|
||||
} else if (!mozilla::dom::UnwrapDOMObjectToISupports(obj, identity)) {
|
||||
identity = nullptr;
|
||||
}
|
||||
|
||||
|
@ -447,15 +447,14 @@ SuspectDOMExpandos(nsPtrHashKey<JSObject> *key, void *arg)
|
||||
Closure *closure = static_cast<Closure*>(arg);
|
||||
JSObject* obj = key->GetKey();
|
||||
nsISupports* native = nullptr;
|
||||
if (js::IsProxy(obj)) {
|
||||
NS_ASSERTION(dom::binding::instanceIsProxy(obj),
|
||||
"Not a DOM proxy?");
|
||||
if (dom::oldproxybindings::instanceIsProxy(obj)) {
|
||||
native = static_cast<nsISupports*>(js::GetProxyPrivate(obj).toPrivate());
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION(dom::DOMJSClass::FromJSClass(JS_GetClass(obj))->mDOMObjectIsISupports,
|
||||
"Someone added a wrapper for a non-nsISupports native to DOMExpandos!");
|
||||
native = dom::UnwrapDOMObject<nsISupports>(obj);
|
||||
const dom::DOMClass* clasp;
|
||||
dom::DOMObjectSlot slot = GetDOMClass(obj, clasp);
|
||||
MOZ_ASSERT(slot != dom::eNonDOMObject && clasp->mDOMObjectIsISupports);
|
||||
native = dom::UnwrapDOMObject<nsISupports>(obj, slot);
|
||||
}
|
||||
closure->cb->NoteXPCOMRoot(native);
|
||||
return PL_DHASH_NEXT;
|
||||
@ -2294,7 +2293,8 @@ XPCJSRuntime::OnJSContextNew(JSContext *cx)
|
||||
}
|
||||
}
|
||||
|
||||
ok = mozilla::dom::binding::DefineStaticJSVals(cx);
|
||||
ok = mozilla::dom::DefineStaticJSVals(cx) &&
|
||||
mozilla::dom::oldproxybindings::DefineStaticJSVals(cx);
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
|
@ -697,9 +697,7 @@ getWrapper(JSContext *cx,
|
||||
*cur = nullptr;
|
||||
*tearoff = nullptr;
|
||||
|
||||
js::Class* clasp = js::GetObjectClass(obj);
|
||||
if (dom::IsDOMClass(clasp) ||
|
||||
dom::binding::instanceIsProxy(obj)) {
|
||||
if (dom::IsDOMObject(obj)) {
|
||||
*cur = obj;
|
||||
|
||||
return NS_OK;
|
||||
@ -711,6 +709,7 @@ getWrapper(JSContext *cx,
|
||||
// object reflection of a particular interface (ie, |foo.nsIBar|). These
|
||||
// JS objects are parented to their wrapper, so we snag the tearoff object
|
||||
// along the way (if desired), and then set |obj| to its parent.
|
||||
js::Class* clasp = js::GetObjectClass(obj);
|
||||
if (clasp == &XPC_WN_Tearoff_JSClass) {
|
||||
*tearoff = (XPCWrappedNativeTearOff*) js::GetObjectPrivate(obj);
|
||||
obj = js::GetObjectParent(obj);
|
||||
@ -751,23 +750,14 @@ castNative(JSContext *cx,
|
||||
} else if (cur) {
|
||||
nsISupports *native;
|
||||
QITableEntry *entries;
|
||||
js::Class* clasp = js::GetObjectClass(cur);
|
||||
if (dom::IsDOMClass(clasp)) {
|
||||
dom::DOMJSClass* domClass = dom::DOMJSClass::FromJSClass(clasp);
|
||||
if (!domClass->mDOMObjectIsISupports) {
|
||||
*pThisRef = nullptr;
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
native = dom::UnwrapDOMObject<nsISupports>(cur);
|
||||
if (mozilla::dom::UnwrapDOMObjectToISupports(cur, native)) {
|
||||
entries = nullptr;
|
||||
} else if (dom::binding::instanceIsProxy(cur)) {
|
||||
native = static_cast<nsISupports*>(js::GetProxyPrivate(cur).toPrivate());
|
||||
entries = nullptr;
|
||||
} else if (IS_WRAPPER_CLASS(clasp) && IS_SLIM_WRAPPER_OBJECT(cur)) {
|
||||
} else if (IS_SLIM_WRAPPER(cur)) {
|
||||
native = static_cast<nsISupports*>(xpc_GetJSPrivate(cur));
|
||||
entries = GetOffsetsFromSlimWrapper(cur);
|
||||
} else {
|
||||
MOZ_NOT_REACHED("what kind of wrapper is this?");
|
||||
*pThisRef = nullptr;
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(getNative(native, entries, cur, iid, ppThis, pThisRef, vp))) {
|
||||
|
@ -31,10 +31,9 @@ bool
|
||||
xpc_OkToHandOutWrapper(nsWrapperCache *cache)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(cache->GetWrapper(), "Must have wrapper");
|
||||
NS_ABORT_IF_FALSE(cache->IsDOMBinding() || IS_WN_WRAPPER(cache->GetWrapper()),
|
||||
"Must have proxy or XPCWrappedNative wrapper");
|
||||
return cache->IsDOMBinding() ?
|
||||
mozilla::dom::binding::instanceIsProxy(cache->GetWrapper()) :
|
||||
NS_ABORT_IF_FALSE(IS_WN_WRAPPER(cache->GetWrapper()),
|
||||
"Must have XPCWrappedNative wrapper");
|
||||
return
|
||||
!static_cast<XPCWrappedNative*>(xpc_GetJSPrivate(cache->GetWrapper()))->
|
||||
NeedsSOW();
|
||||
}
|
||||
|
@ -217,23 +217,20 @@ XPCWrappedNativeScope::SetGlobal(XPCCallContext& ccx, JSObject* aGlobal,
|
||||
native = aNative;
|
||||
} else {
|
||||
const JSClass *jsClass = js::GetObjectJSClass(aGlobal);
|
||||
nsISupports *priv;
|
||||
if (!(~jsClass->flags & (JSCLASS_HAS_PRIVATE |
|
||||
JSCLASS_PRIVATE_IS_NSISUPPORTS))) {
|
||||
// Our global has an nsISupports native pointer. Let's
|
||||
// see whether it's what we want.
|
||||
priv = static_cast<nsISupports*>(xpc_GetJSPrivate(aGlobal));
|
||||
} else if (dom::IsDOMClass(jsClass) &&
|
||||
dom::DOMJSClass::FromJSClass(jsClass)->mDOMObjectIsISupports) {
|
||||
priv = dom::UnwrapDOMObject<nsISupports>(aGlobal);
|
||||
} else {
|
||||
priv = nullptr;
|
||||
}
|
||||
nsISupports *priv =
|
||||
static_cast<nsISupports*>(xpc_GetJSPrivate(aGlobal));
|
||||
nsCOMPtr<nsIXPConnectWrappedNative> wn = do_QueryInterface(priv);
|
||||
if (wn)
|
||||
native = static_cast<XPCWrappedNative*>(wn.get())->GetIdentityObject();
|
||||
else
|
||||
native = priv;
|
||||
native = nullptr;
|
||||
} else if (!mozilla::dom::UnwrapDOMObjectToISupports(aGlobal, native)) {
|
||||
native = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Now init our script object principal, if the new global has one.
|
||||
|
@ -293,6 +293,8 @@ def outParamForm(name, type):
|
||||
if type.specialtype == 'jsval':
|
||||
return 'vp'
|
||||
elif type.modifier == 'ref':
|
||||
if isStringType(type):
|
||||
return '(nsAString&)' + name
|
||||
return name
|
||||
else:
|
||||
return '&' + name
|
||||
|
@ -26,7 +26,7 @@ using namespace mozilla::dom;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace binding {
|
||||
namespace oldproxybindings {
|
||||
|
||||
enum {
|
||||
JSPROXYSLOT_EXPANDO = 0
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace binding {
|
||||
namespace oldproxybindings {
|
||||
|
||||
class ProxyHandler : public js::BaseProxyHandler {
|
||||
protected:
|
||||
|
@ -375,7 +375,7 @@ def writeHeaderFile(filename, config):
|
||||
|
||||
f.write("namespace mozilla {\n"
|
||||
"namespace dom {\n"
|
||||
"namespace binding {\n\n")
|
||||
"namespace oldproxybindings {\n\n")
|
||||
f.write("bool\n"
|
||||
"DefinePropertyStaticJSVals(JSContext *cx);\n\n")
|
||||
|
||||
@ -638,7 +638,7 @@ def writeStubFile(filename, config, interfaces):
|
||||
|
||||
f.write("namespace mozilla {\n"
|
||||
"namespace dom {\n"
|
||||
"namespace binding {\n\n")
|
||||
"namespace oldproxybindings {\n\n")
|
||||
|
||||
f.write("// Property name ids\n\n")
|
||||
|
||||
@ -712,7 +712,7 @@ def writeStubFile(filename, config, interfaces):
|
||||
else:
|
||||
setterName = "NULL"
|
||||
|
||||
propertiesList.append(" { s_length_id, length_getter, %s }" % setterName)
|
||||
propertiesList.append(" { mozilla::dom::s_length_id, length_getter, %s }" % setterName)
|
||||
continue
|
||||
|
||||
isAttr = (member.kind == 'attribute')
|
||||
|
@ -836,18 +836,19 @@ NoteGCThingXPCOMChildren(js::Class *clasp, JSObject *obj,
|
||||
clasp->flags & JSCLASS_PRIVATE_IS_NSISUPPORTS) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "xpc_GetJSPrivate(obj)");
|
||||
cb.NoteXPCOMChild(static_cast<nsISupports*>(xpc_GetJSPrivate(obj)));
|
||||
} else if (binding::instanceIsProxy(obj)) {
|
||||
} else if (oldproxybindings::instanceIsProxy(obj)) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "js::GetProxyPrivate(obj)");
|
||||
nsISupports *identity =
|
||||
static_cast<nsISupports*>(js::GetProxyPrivate(obj).toPrivate());
|
||||
cb.NoteXPCOMChild(identity);
|
||||
} else if (IsDOMClass(clasp) &&
|
||||
DOMJSClass::FromJSClass(clasp)->mDOMObjectIsISupports) {
|
||||
} else {
|
||||
nsISupports *identity;
|
||||
if (UnwrapDOMObjectToISupports(obj, identity)) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "UnwrapDOMObject(obj)");
|
||||
nsISupports *identity = UnwrapDOMObject<nsISupports>(obj);
|
||||
cb.NoteXPCOMChild(identity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum TraverseSelect {
|
||||
TRAVERSE_CPP,
|
||||
@ -1419,7 +1420,8 @@ nsXPConnect::GetNativeOfWrapper(JSContext * aJSContext,
|
||||
if (obj2)
|
||||
return (nsISupports*)xpc_GetJSPrivate(obj2);
|
||||
|
||||
if (mozilla::dom::binding::instanceIsProxy(aJSObj)) {
|
||||
if (mozilla::dom::IsDOMProxy(aJSObj) ||
|
||||
mozilla::dom::oldproxybindings::instanceIsProxy(aJSObj)) {
|
||||
// FIXME: Provide a fast non-refcounting way to get the canonical
|
||||
// nsISupports from the proxy.
|
||||
nsISupports *supports =
|
||||
@ -1457,7 +1459,8 @@ nsXPConnect::GetJSObjectOfWrapper(JSContext * aJSContext,
|
||||
*_retval = obj2;
|
||||
return NS_OK;
|
||||
}
|
||||
if (mozilla::dom::binding::instanceIsProxy(aJSObj)) {
|
||||
if (mozilla::dom::IsDOMProxy(aJSObj) ||
|
||||
mozilla::dom::oldproxybindings::instanceIsProxy(aJSObj)) {
|
||||
*_retval = aJSObj;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ xpc_FastGetCachedWrapper(nsWrapperCache *cache, JSObject *scope, jsval *vp)
|
||||
"Should never have a slim wrapper when IsDOMBinding()");
|
||||
if (wrapper &&
|
||||
js::GetObjectCompartment(wrapper) == js::GetObjectCompartment(scope) &&
|
||||
(IS_SLIM_WRAPPER(wrapper) ||
|
||||
(IS_SLIM_WRAPPER(wrapper) || cache->IsDOMBinding() ||
|
||||
xpc_OkToHandOutWrapper(cache))) {
|
||||
*vp = OBJECT_TO_JSVAL(wrapper);
|
||||
return wrapper;
|
||||
@ -306,11 +306,10 @@ xpc_JSCompartmentParticipant();
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace binding {
|
||||
|
||||
extern int HandlerFamily;
|
||||
inline void* ProxyFamily() { return &HandlerFamily; }
|
||||
inline bool instanceIsProxy(JSObject *obj)
|
||||
inline bool IsDOMProxy(JSObject *obj)
|
||||
{
|
||||
return js::IsProxy(obj) &&
|
||||
js::GetProxyHandler(obj)->family() == ProxyFamily();
|
||||
@ -327,7 +326,22 @@ extern bool
|
||||
DefineConstructor(JSContext *cx, JSObject *obj, DefineInterface aDefine,
|
||||
nsresult *aResult);
|
||||
|
||||
} // namespace binding
|
||||
namespace oldproxybindings {
|
||||
|
||||
extern int HandlerFamily;
|
||||
inline void* ProxyFamily() { return &HandlerFamily; }
|
||||
inline bool instanceIsProxy(JSObject *obj)
|
||||
{
|
||||
return js::IsProxy(obj) &&
|
||||
js::GetProxyHandler(obj)->family() == ProxyFamily();
|
||||
}
|
||||
extern bool
|
||||
DefineStaticJSVals(JSContext *cx);
|
||||
void
|
||||
Register(nsScriptNameSpaceManager* aNameSpaceManager);
|
||||
|
||||
} // namespace oldproxybindings
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -299,7 +299,7 @@ GetXrayType(JSObject *obj)
|
||||
if (mozilla::dom::IsDOMClass(Jsvalify(clasp))) {
|
||||
return XrayForDOMObject;
|
||||
}
|
||||
if (mozilla::dom::binding::instanceIsProxy(obj)) {
|
||||
if (mozilla::dom::oldproxybindings::instanceIsProxy(obj)) {
|
||||
return XrayForDOMProxyObject;
|
||||
}
|
||||
if (IS_WRAPPER_CLASS(clasp) || clasp->ext.innerObject) {
|
||||
@ -385,7 +385,7 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *obj, JSObject *wrappedProto, JSO
|
||||
wrapper = &FilteringWrapper<Xray, LocationPolicy>::singleton;
|
||||
else
|
||||
wrapper = &FilteringWrapper<Xray, CrossOriginAccessiblePropertiesOnly>::singleton;
|
||||
} else if (mozilla::dom::binding::instanceIsProxy(obj)) {
|
||||
} else if (mozilla::dom::oldproxybindings::instanceIsProxy(obj)) {
|
||||
wrapper = &FilteringWrapper<XrayProxy, CrossOriginAccessiblePropertiesOnly>::singleton;
|
||||
} else if (mozilla::dom::IsDOMClass(JS_GetClass(obj))) {
|
||||
wrapper = &FilteringWrapper<XrayDOM, CrossOriginAccessiblePropertiesOnly>::singleton;
|
||||
|
@ -1057,7 +1057,7 @@ DOMXrayTraits::resolveNativeProperty(JSContext *cx, JSObject *wrapper, JSObject
|
||||
{
|
||||
JSObject *obj = getInnerObject(wrapper);
|
||||
const NativePropertyHooks *nativeHooks =
|
||||
DOMJSClass::FromJSClass(JS_GetClass(obj))->mNativeHooks;
|
||||
DOMJSClass::FromJSClass(JS_GetClass(obj))->mClass.mNativeHooks;
|
||||
|
||||
do {
|
||||
if (nativeHooks->mResolveProperty(cx, wrapper, id, set, desc) &&
|
||||
@ -1108,7 +1108,7 @@ DOMXrayTraits::enumerateNames(JSContext *cx, JSObject *wrapper, unsigned flags,
|
||||
|
||||
JSObject *obj = getInnerObject(wrapper);
|
||||
const NativePropertyHooks *nativeHooks =
|
||||
DOMJSClass::FromJSClass(JS_GetClass(obj))->mNativeHooks;
|
||||
DOMJSClass::FromJSClass(JS_GetClass(obj))->mClass.mNativeHooks;
|
||||
|
||||
do {
|
||||
if (!nativeHooks->mEnumerateProperties(props)) {
|
||||
@ -1184,7 +1184,7 @@ XrayToString(JSContext *cx, unsigned argc, jsval *vp)
|
||||
|
||||
nsAutoString result(NS_LITERAL_STRING("[object XrayWrapper "));
|
||||
JSObject *obj = &js::GetProxyPrivate(wrapper).toObject();
|
||||
if (mozilla::dom::binding::instanceIsProxy(obj)) {
|
||||
if (IsDOMProxy(obj) || oldproxybindings::instanceIsProxy(obj)) {
|
||||
JSString *wrapperStr = js::GetProxyHandler(wrapper)->obj_toString(cx, wrapper);
|
||||
size_t length;
|
||||
const jschar* chars = JS_GetStringCharsAndLength(cx, wrapperStr, &length);
|
||||
|
Loading…
Reference in New Issue
Block a user