Bug 787070 - Expandos on the xray of DOM prototypes should have effect on xrays of DOM nodes, add a named properties object type to DOMObjectType and how to get the parent prototype object in DOMIfaceAndProtoJSClass. r=bz, r=bholley.

--HG--
extra : rebase_source : fdd72f5027b365554ab0b986de685204c8030c58
This commit is contained in:
Peter Van der Beken 2014-09-09 15:19:10 +02:00
parent f0b7d81451
commit 16b3a0fe7d
7 changed files with 256 additions and 85 deletions

View File

@ -5900,7 +5900,7 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
JSAutoCompartment ac(aCx, global);
JS::Handle<JSObject*> htmlProto(
HTMLElementBinding::GetProtoObject(aCx, global));
HTMLElementBinding::GetProtoObjectHandle(aCx, global));
if (!htmlProto) {
rv.Throw(NS_ERROR_OUT_OF_MEMORY);
return;
@ -5946,7 +5946,7 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
}
JS::Handle<JSObject*> svgProto(
SVGElementBinding::GetProtoObject(aCx, global));
SVGElementBinding::GetProtoObjectHandle(aCx, global));
if (!svgProto) {
rv.Throw(NS_ERROR_OUT_OF_MEMORY);
return;

View File

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WindowNamedPropertiesHandler.h"
#include "mozilla/dom/EventTargetBinding.h"
#include "mozilla/dom/WindowBinding.h"
#include "nsDOMClassInfo.h"
#include "nsGlobalWindow.h"
@ -219,11 +220,12 @@ static const DOMIfaceAndProtoJSClass WindowNamedPropertiesClass = {
PROXY_CLASS_DEF("WindowProperties",
DOM_INTERFACE_PROTO_SLOTS_BASE, /* extra slots */
0),
eInterfacePrototype,
eNamedPropertiesObject,
sWindowNamedPropertiesNativePropertyHooks,
"[object WindowProperties]",
prototypes::id::_ID_Count,
0,
EventTargetBinding::GetProtoObject
};
// static

View File

@ -1254,6 +1254,36 @@ XrayResolveOwnProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
bool isGlobal;
const NativePropertyHooks *nativePropertyHooks =
GetNativePropertyHooks(cx, obj, type, isGlobal);
ResolveOwnProperty resolveOwnProperty =
nativePropertyHooks->mResolveOwnProperty;
if (type == eNamedPropertiesObject) {
// None of these should be cached on the holder, since they're dynamic.
return resolveOwnProperty(cx, wrapper, obj, id, desc);
}
// Check for unforgeable properties first.
if (type == eInstance) {
const NativePropertiesHolder& nativeProperties =
nativePropertyHooks->mNativeProperties;
if (!XrayResolveUnforgeableProperty(cx, wrapper, obj, id, desc, cacheOnHolder,
nativeProperties.regular)) {
return false;
}
if (desc.object()) {
return true;
}
if (!XrayResolveUnforgeableProperty(cx, wrapper, obj, id, desc, cacheOnHolder,
nativeProperties.chromeOnly)) {
return false;
}
if (desc.object()) {
return true;
}
}
if (type != eInstance || (isGlobal && GlobalPropertiesAreOwn())) {
// For prototype objects and interface objects, just return their
@ -1264,36 +1294,27 @@ XrayResolveOwnProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
return false;
}
// For non-global non-instance Xrays there are no other properties, so
// return here for them whether we resolved the property or not.
if (!isGlobal || desc.object()) {
cacheOnHolder = true;
return true;
}
}
{
// Check for unforgeable properties before doing mResolveOwnProperty weirdness
const NativePropertiesHolder& nativeProperties =
nativePropertyHooks->mNativeProperties;
if (!XrayResolveUnforgeableProperty(cx, wrapper, obj, id, desc, cacheOnHolder,
nativeProperties.regular)) {
return false;
}
if (desc.object()) {
return true;
}
if (!XrayResolveUnforgeableProperty(cx, wrapper, obj, id, desc, cacheOnHolder,
nativeProperties.chromeOnly)) {
return false;
}
if (desc.object()) {
return true;
}
}
return !nativePropertyHooks->mResolveOwnProperty ||
nativePropertyHooks->mResolveOwnProperty(cx, wrapper, obj, id, desc);
if (type == eInstance) {
if (resolveOwnProperty) {
if (!resolveOwnProperty(cx, wrapper, obj, id, desc)) {
return false;
}
if (desc.object()) {
// None of these should be cached on the holder, since they're dynamic.
cacheOnHolder = false;
return true;
}
}
}
return true;
}
/* static */ bool
@ -1304,6 +1325,8 @@ XrayResolveNativeProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
JS::MutableHandle<JSPropertyDescriptor> desc,
bool& cacheOnHolder)
{
MOZ_ASSERT(type != eNamedPropertiesObject);
if (type == eInterface) {
if (IdEquals(id, "prototype")) {
return nativePropertyHooks->mPrototypeID == prototypes::id::_ID_Count ||
@ -1370,6 +1393,10 @@ XrayResolveNativeProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
const NativePropertyHooks* nativePropertyHooks =
GetNativePropertyHooks(cx, obj, type, isGlobal);
if (type == eNamedPropertiesObject) {
return true;
}
if (type == eInstance) {
// Global objects return their interfaces' properties from
// XrayResolveOwnProperty, so skip those.
@ -1459,6 +1486,8 @@ XrayEnumerateProperties(JSContext* cx, JS::Handle<JSObject*> wrapper,
DOMObjectType type, bool isGlobal,
const NativeProperties* nativeProperties)
{
MOZ_ASSERT(type != eNamedPropertiesObject);
if (type == eInstance) {
ENUMERATE_IF_DEFINED(unforgeableMethod);
ENUMERATE_IF_DEFINED(unforgeableAttribute);
@ -1499,6 +1528,8 @@ XrayEnumerateNativeProperties(JSContext* cx, JS::Handle<JSObject*> wrapper,
JS::Handle<JSObject*> obj, unsigned flags,
JS::AutoIdVector& props)
{
MOZ_ASSERT(type != eNamedPropertiesObject);
if (type == eInterface &&
nativePropertyHooks->mPrototypeID != prototypes::id::_ID_Count &&
!AddStringToIDVector(cx, props, "prototype")) {
@ -1540,11 +1571,16 @@ XrayEnumerateProperties(JSContext* cx, JS::Handle<JSObject*> wrapper,
bool isGlobal;
const NativePropertyHooks* nativePropertyHooks =
GetNativePropertyHooks(cx, obj, type, isGlobal);
EnumerateOwnProperties enumerateOwnProperties =
nativePropertyHooks->mEnumerateOwnProperties;
if (type == eNamedPropertiesObject) {
return enumerateOwnProperties(cx, wrapper, obj, props);
}
if (type == eInstance) {
if (nativePropertyHooks->mEnumerateOwnProperties &&
!nativePropertyHooks->mEnumerateOwnProperties(cx, wrapper, obj,
props)) {
if (enumerateOwnProperties &&
!enumerateOwnProperties(cx, wrapper, obj, props)) {
return false;
}

View File

@ -2370,6 +2370,43 @@ XrayEnumerateProperties(JSContext* cx, JS::Handle<JSObject*> wrapper,
JS::Handle<JSObject*> obj,
unsigned flags, JS::AutoIdVector& props);
/**
* Returns the prototype to use for an Xray for a DOM object, wrapped in cx's
* compartment. This always returns the prototype that would be used for a DOM
* object if we ignore any changes that might have been done to the prototype
* chain by JS, the XBL code or plugins.
*
* cx should be in the Xray's compartment.
* obj is the target object of the Xray, a binding's instance object or an
* interface or interface prototype object.
*/
inline bool
XrayGetNativeProto(JSContext* cx, JS::Handle<JSObject*> obj,
JS::MutableHandle<JSObject*> protop)
{
JS::Rooted<JSObject*> global(cx, js::GetGlobalForObjectCrossCompartment(obj));
{
JSAutoCompartment ac(cx, global);
const DOMJSClass* domClass = GetDOMClass(obj);
if (domClass) {
ProtoHandleGetter protoGetter = domClass->mGetProto;
if (protoGetter) {
protop.set(protoGetter(cx, global));
} else {
protop.set(JS_GetObjectPrototype(cx, global));
}
} else {
const js::Class* clasp = js::GetObjectClass(obj);
MOZ_ASSERT(IsDOMIfaceAndProtoClass(clasp));
ProtoGetter protoGetter =
DOMIfaceAndProtoJSClass::FromJSClass(clasp)->mGetParentProto;
protop.set(protoGetter(cx, global));
}
}
return JS_WrapObject(cx, protop);
}
extern NativePropertyHooks sWorkerNativePropertyHooks;
// We use one constructor JSNative to represent all DOM interface objects (so
@ -2839,7 +2876,7 @@ struct CreateGlobalOptions<nsGlobalWindow>
nsresult
RegisterDOMNames();
template <class T, ProtoGetter GetProto>
template <class T, ProtoHandleGetter GetProto>
bool
CreateGlobal(JSContext* aCx, T* aNative, nsWrapperCache* aCache,
const JSClass* aClass, JS::CompartmentOptions& aOptions,
@ -3025,6 +3062,13 @@ template<class T, template<typename> class SmartPtr, class S>
inline void
StrongOrRawPtr(SmartPtr<S>&& aPtr) MOZ_DELETE;
inline
JSObject*
GetErrorPrototype(JSContext* aCx, JS::Handle<JSObject*> aForObj)
{
return JS_GetErrorPrototype(aCx);
}
} // namespace dom
} // namespace mozilla

View File

@ -340,7 +340,7 @@ def DOMClass(descriptor):
IsBaseOf<nsISupports, ${nativeType} >::value,
${hooks},
GetParentObject<${nativeType}>::Get,
GetProtoObject,
GetProtoObjectHandle,
GetCCParticipant<${nativeType}>::Get()
""",
protoChain=', '.join(protoList),
@ -602,6 +602,36 @@ def CallOnUnforgeableHolder(descriptor, code, isXrayCheck=None,
code=code)
def InterfacePrototypeObjectProtoGetter(descriptor):
"""
Returns a tuple with two elements:
1) The name of the function to call to get the prototype to use for the
interface prototype object as a JSObject*.
2) The name of the function to call to get the prototype to use for the
interface prototype object as a JS::Handle<JSObject*> or None if no
such function exists.
"""
parentProtoName = descriptor.parentPrototypeName
if descriptor.hasNamedPropertiesObject:
protoGetter = "GetNamedPropertiesObject"
protoHandleGetter = None
elif parentProtoName is None:
if descriptor.interface.getExtendedAttribute("ArrayClass"):
protoGetter = "JS_GetArrayPrototype"
elif descriptor.interface.getExtendedAttribute("ExceptionClass"):
protoGetter = "GetErrorPrototype"
else:
protoGetter = "JS_GetObjectPrototype"
protoHandleGetter = None
else:
prefix = toBindingNamespace(parentProtoName)
protoGetter = prefix + "::GetProtoObject"
protoHandleGetter = prefix + "::GetProtoObjectHandle"
return (protoGetter, protoHandleGetter)
class CGPrototypeJSClass(CGThing):
def __init__(self, descriptor, properties):
CGThing.__init__(self)
@ -617,6 +647,7 @@ class CGPrototypeJSClass(CGThing):
slotCount = "DOM_INTERFACE_PROTO_SLOTS_BASE"
if UseHolderForUnforgeable(self.descriptor):
slotCount += " + 1 /* slot for the JSObject holding the unforgeable properties */"
(protoGetter, _) = InterfacePrototypeObjectProtoGetter(self.descriptor)
return fill(
"""
static const DOMIfaceAndProtoJSClass PrototypeClass = {
@ -643,19 +674,46 @@ class CGPrototypeJSClass(CGThing):
${hooks},
"[object ${name}Prototype]",
${prototypeID},
${depth}
${depth},
${protoGetter}
};
""",
name=self.descriptor.interface.identifier.name,
slotCount=slotCount,
hooks=NativePropertyHooks(self.descriptor),
prototypeID=prototypeID,
depth=depth)
depth=depth,
protoGetter=protoGetter)
def NeedsGeneratedHasInstance(descriptor):
return descriptor.hasXPConnectImpls or descriptor.interface.isConsequential()
def InterfaceObjectProtoGetter(descriptor):
"""
Returns a tuple with two elements:
1) The name of the function to call to get the prototype to use for the
interface object as a JSObject*.
2) The name of the function to call to get the prototype to use for the
interface prototype as a JS::Handle<JSObject*> or None if no such
function exists.
"""
parentWithInterfaceObject = descriptor.interface.parent
while (parentWithInterfaceObject and
not parentWithInterfaceObject.hasInterfaceObject()):
parentWithInterfaceObject = parentWithInterfaceObject.parent
if parentWithInterfaceObject:
parentIfaceName = parentWithInterfaceObject.identifier.name
parentDesc = descriptor.getDescriptor(parentIfaceName)
prefix = toBindingNamespace(parentDesc.name)
protoGetter = prefix + "::GetConstructorObject"
protoHandleGetter = prefix + "::GetConstructorObjectHandle"
else:
protoGetter = "JS_GetFunctionPrototype"
protoHandleGetter = None
return (protoGetter, protoHandleGetter)
class CGInterfaceObjectJSClass(CGThing):
def __init__(self, descriptor, properties):
@ -683,6 +741,8 @@ class CGInterfaceObjectJSClass(CGThing):
if len(self.descriptor.interface.namedConstructors) > 0:
slotCount += (" + %i /* slots for the named constructors */" %
len(self.descriptor.interface.namedConstructors))
(protoGetter, _) = InterfaceObjectProtoGetter(self.descriptor)
return fill(
"""
static const DOMIfaceAndProtoJSClass InterfaceObjectClass = {
@ -709,7 +769,8 @@ class CGInterfaceObjectJSClass(CGThing):
${hooks},
"function ${name}() {\\n [native code]\\n}",
${prototypeID},
${depth}
${depth},
${protoGetter}
};
""",
slotCount=slotCount,
@ -718,7 +779,8 @@ class CGInterfaceObjectJSClass(CGThing):
hooks=NativePropertyHooks(self.descriptor),
name=self.descriptor.interface.identifier.name,
prototypeID=prototypeID,
depth=depth)
depth=depth,
protoGetter=protoGetter)
class CGList(CGThing):
@ -2579,38 +2641,23 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
self.properties = properties
def definition_body(self):
parentProtoName = self.descriptor.parentPrototypeName
if self.descriptor.hasNamedPropertiesObject:
parentProtoType = "Handle"
getParentProto = "GetNamedPropertiesObject(aCx, aGlobal)"
elif parentProtoName is None:
(protoGetter, protoHandleGetter) = InterfacePrototypeObjectProtoGetter(self.descriptor)
if protoHandleGetter is None:
parentProtoType = "Rooted"
if self.descriptor.interface.getExtendedAttribute("ArrayClass"):
getParentProto = "aCx, JS_GetArrayPrototype(aCx, aGlobal)"
elif self.descriptor.interface.getExtendedAttribute("ExceptionClass"):
getParentProto = "aCx, JS_GetErrorPrototype(aCx)"
else:
getParentProto = "aCx, JS_GetObjectPrototype(aCx, aGlobal)"
getParentProto = "aCx, " + protoGetter
else:
parentProtoType = "Handle"
getParentProto = ("%s::GetProtoObject(aCx, aGlobal)" %
toBindingNamespace(parentProtoName))
getParentProto = protoHandleGetter
getParentProto = getParentProto + "(aCx, aGlobal)"
parentWithInterfaceObject = self.descriptor.interface.parent
while (parentWithInterfaceObject and
not parentWithInterfaceObject.hasInterfaceObject()):
parentWithInterfaceObject = parentWithInterfaceObject.parent
if parentWithInterfaceObject:
parentIfaceName = parentWithInterfaceObject.identifier.name
parentDesc = self.descriptor.getDescriptor(parentIfaceName)
if parentDesc.workers:
parentIfaceName += "_workers"
getConstructorProto = ("%s::GetConstructorObject(aCx, aGlobal)" %
toBindingNamespace(parentIfaceName))
constructorProtoType = "Handle"
else:
getConstructorProto = "aCx, JS_GetFunctionPrototype(aCx, aGlobal)"
(protoGetter, protoHandleGetter) = InterfaceObjectProtoGetter(self.descriptor)
if protoHandleGetter is None:
getConstructorProto = "aCx, " + protoGetter
constructorProtoType = "Rooted"
else:
getConstructorProto = protoHandleGetter
constructorProtoType = "Handle"
getConstructorProto += "(aCx, aGlobal)"
needInterfaceObject = self.descriptor.interface.hasInterfaceObject()
needInterfacePrototypeObject = self.descriptor.interface.hasInterfacePrototypeObject()
@ -2815,12 +2862,12 @@ class CGGetPerInterfaceObject(CGAbstractMethod):
id=self.id)
class CGGetProtoObjectMethod(CGGetPerInterfaceObject):
class CGGetProtoObjectHandleMethod(CGGetPerInterfaceObject):
"""
A method for getting the interface prototype object.
"""
def __init__(self, descriptor):
CGGetPerInterfaceObject.__init__(self, descriptor, "GetProtoObject",
CGGetPerInterfaceObject.__init__(self, descriptor, "GetProtoObjectHandle",
"prototypes::")
def definition_body(self):
@ -2832,13 +2879,25 @@ class CGGetProtoObjectMethod(CGGetPerInterfaceObject):
""") + CGGetPerInterfaceObject.definition_body(self)
class CGGetConstructorObjectMethod(CGGetPerInterfaceObject):
class CGGetProtoObjectMethod(CGAbstractMethod):
"""
A method for getting the interface prototype object.
"""
def __init__(self, descriptor):
CGAbstractMethod.__init__(
self, descriptor, "GetProtoObject", "JSObject*", [Argument('JSContext*', 'aCx'),
Argument('JS::Handle<JSObject*>', 'aGlobal')])
def definition_body(self):
return "return GetProtoObjectHandle(aCx, aGlobal);\n"
class CGGetConstructorObjectHandleMethod(CGGetPerInterfaceObject):
"""
A method for getting the interface constructor object.
"""
def __init__(self, descriptor):
CGGetPerInterfaceObject.__init__(
self, descriptor, "GetConstructorObject",
self, descriptor, "GetConstructorObjectHandle",
"constructors::",
extraArgs=[Argument("bool", "aDefineOnGlobal", "true")])
@ -2849,6 +2908,17 @@ class CGGetConstructorObjectMethod(CGGetPerInterfaceObject):
""") + CGGetPerInterfaceObject.definition_body(self)
class CGGetConstructorObjectMethod(CGAbstractMethod):
"""
A method for getting the interface constructor object.
"""
def __init__(self, descriptor):
CGAbstractMethod.__init__(
self, descriptor, "GetConstructorObject", "JSObject*", [Argument('JSContext*', 'aCx'),
Argument('JS::Handle<JSObject*>', 'aGlobal')])
def definition_body(self):
return "return GetConstructorObjectHandle(aCx, aGlobal);\n"
class CGGetNamedPropertiesObjectMethod(CGAbstractStaticMethod):
def __init__(self, descriptor):
@ -2856,7 +2926,7 @@ class CGGetNamedPropertiesObjectMethod(CGAbstractStaticMethod):
Argument('JS::Handle<JSObject*>', 'aGlobal')]
CGAbstractStaticMethod.__init__(self, descriptor,
'GetNamedPropertiesObject',
'JS::Handle<JSObject*>', args)
'JSObject*', args)
def definition_body(self):
parentProtoName = self.descriptor.parentPrototypeName
@ -2866,9 +2936,9 @@ class CGGetNamedPropertiesObjectMethod(CGAbstractStaticMethod):
else:
getParentProto = fill(
"""
JS::Rooted<JSObject*> parentProto(aCx, ${parent}::GetProtoObject(aCx, aGlobal));
JS::Rooted<JSObject*> parentProto(aCx, ${parent}::GetProtoObjectHandle(aCx, aGlobal));
if (!parentProto) {
return js::NullPtr();
return nullptr;
}
""",
parent=toBindingNamespace(parentProtoName))
@ -2877,7 +2947,7 @@ class CGGetNamedPropertiesObjectMethod(CGAbstractStaticMethod):
"""
/* Make sure our global is sane. Hopefully we can remove this sometime */
if (!(js::GetObjectClass(aGlobal)->flags & JSCLASS_DOM_GLOBAL)) {
return JS::NullPtr();
return nullptr;
}
/* Check to see whether the named properties object has already been created */
@ -2887,8 +2957,18 @@ class CGGetNamedPropertiesObjectMethod(CGAbstractStaticMethod):
if (!namedPropertiesObject) {
$*{getParentProto}
namedPropertiesObject = ${nativeType}::CreateNamedPropertiesObject(aCx, ${parentProto});
DebugOnly<const DOMIfaceAndProtoJSClass*> clasp =
DOMIfaceAndProtoJSClass::FromJSClass(js::GetObjectClass(namedPropertiesObject));
MOZ_ASSERT(clasp->mType == eNamedPropertiesObject,
"Expected ${nativeType}::CreateNamedPropertiesObject to return a named properties object");
MOZ_ASSERT(clasp->mNativeHooks,
"The named properties object for ${nativeType} should have NativePropertyHooks.");
MOZ_ASSERT(clasp->mNativeHooks->mResolveOwnProperty,
"Don't know how to resolve the properties of the named properties object for ${nativeType}.");
MOZ_ASSERT(clasp->mNativeHooks->mEnumerateOwnProperties,
"Don't know how to enumerate the properties of the named properties object for ${nativeType}.");
}
return JS::Handle<JSObject*>::fromMarkedLocation(namedPropertiesObject.address());
return namedPropertiesObject.get();
""",
getParentProto=getParentProto,
ifaceName=self.descriptor.name,
@ -2921,7 +3001,7 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod):
def definition_body(self):
if len(self.descriptor.interface.namedConstructors) > 0:
getConstructor = dedent("""
JSObject* interfaceObject = GetConstructorObject(aCx, aGlobal, aDefineOnGlobal);
JSObject* interfaceObject = GetConstructorObjectHandle(aCx, aGlobal, aDefineOnGlobal);
if (!interfaceObject) {
return nullptr;
}
@ -2934,7 +3014,7 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod):
return interfaceObject;
""")
else:
getConstructor = "return GetConstructorObject(aCx, aGlobal, aDefineOnGlobal);\n"
getConstructor = "return GetConstructorObjectHandle(aCx, aGlobal, aDefineOnGlobal);\n"
return getConstructor
@ -3215,7 +3295,7 @@ class CGWrapWithCacheMethod(CGAbstractMethod):
JSAutoCompartment ac(aCx, parent);
JS::Rooted<JSObject*> global(aCx, JS_GetGlobalForObject(aCx, parent));
JS::Handle<JSObject*> proto = GetProtoObject(aCx, global);
JS::Handle<JSObject*> proto = GetProtoObjectHandle(aCx, global);
if (!proto) {
return nullptr;
}
@ -3271,7 +3351,7 @@ class CGWrapNonWrapperCacheMethod(CGAbstractMethod):
$*{assertions}
JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
JS::Handle<JSObject*> proto = GetProtoObject(aCx, global);
JS::Handle<JSObject*> proto = GetProtoObjectHandle(aCx, global);
if (!proto) {
return nullptr;
}
@ -3333,7 +3413,7 @@ class CGWrapGlobalMethod(CGAbstractMethod):
"nsISupports must be on our primary inheritance chain");
JS::Rooted<JSObject*> obj(aCx);
CreateGlobal<${nativeType}, GetProtoObject>(aCx,
CreateGlobal<${nativeType}, GetProtoObjectHandle>(aCx,
aObject,
aCache,
Class.ToJSClass(),
@ -11135,8 +11215,11 @@ class CGDescriptor(CGThing):
# CGGetProtoObjectMethod and CGGetConstructorObjectMethod need
# to come after CGCreateInterfaceObjectsMethod.
if descriptor.interface.hasInterfacePrototypeObject():
cgThings.append(CGGetProtoObjectMethod(descriptor))
cgThings.append(CGGetProtoObjectHandleMethod(descriptor))
if descriptor.interface.hasChildInterfaces():
cgThings.append(CGGetProtoObjectMethod(descriptor))
if descriptor.interface.hasInterfaceObject():
cgThings.append(CGGetConstructorObjectHandleMethod(descriptor))
cgThings.append(CGGetConstructorObjectMethod(descriptor))
# See whether we need we need to generate an IsPermitted method

View File

@ -163,18 +163,22 @@ struct NativePropertyHooks
enum DOMObjectType {
eInstance,
eInterface,
eInterfacePrototype
eInterfacePrototype,
eNamedPropertiesObject
};
typedef JSObject* (*ParentGetter)(JSContext* aCx, JS::Handle<JSObject*> aObj);
typedef JSObject* (*ProtoGetter)(JSContext* aCx,
JS::Handle<JSObject*> aGlobal);
/**
* Returns a handle to the relevent WebIDL prototype object for the given global
* (which may be a handle to null on out of memory). Once allocated, the
* prototype object is guaranteed to exist as long as the global does, since the
* global traces its array of WebIDL prototypes and constructors.
*/
typedef JS::Handle<JSObject*> (*ProtoGetter)(JSContext* aCx,
JS::Handle<JSObject*> aGlobal);
typedef JS::Handle<JSObject*> (*ProtoHandleGetter)(JSContext* aCx,
JS::Handle<JSObject*> aGlobal);
// Special JSClass for reflected DOM objects.
struct DOMJSClass
@ -197,7 +201,7 @@ struct DOMJSClass
const NativePropertyHooks* mNativeHooks;
ParentGetter mGetParent;
ProtoGetter mGetProto;
ProtoHandleGetter mGetProto;
// This stores the CC participant for the native, null if this class is for a
// worker or for a native inheriting from nsISupports (we can get the CC
@ -225,7 +229,7 @@ struct DOMIfaceAndProtoJSClass
// initialization for aggregate/POD types.
const js::Class mBase;
// Either eInterface or eInterfacePrototype
// Either eInterface, eInterfacePrototype or eNamedPropertiesObject
DOMObjectType mType;
const NativePropertyHooks* mNativeHooks;
@ -237,6 +241,8 @@ struct DOMIfaceAndProtoJSClass
const prototypes::ID mPrototypeID;
const uint32_t mDepth;
ProtoGetter mGetParentProto;
static const DOMIfaceAndProtoJSClass* FromJSClass(const JSClass* base) {
MOZ_ASSERT(base->flags & JSCLASS_IS_DOMIFACEANDPROTOJSCLASS);
return reinterpret_cast<const DOMIfaceAndProtoJSClass*>(base);

View File

@ -210,7 +210,7 @@ nsXBLProtoImpl::InitTargetObjects(nsXBLPrototypeBinding* aBinding,
// Make sure the interface object is created before the prototype object
// so that XULElement is hidden from content. See bug 909340.
bool defineOnGlobal = dom::XULElementBinding::ConstructorEnabled(cx, global);
dom::XULElementBinding::GetConstructorObject(cx, global, defineOnGlobal);
dom::XULElementBinding::GetConstructorObjectHandle(cx, global, defineOnGlobal);
rv = nsContentUtils::WrapNative(cx, aBoundElement, &v,
/* aAllowWrapping = */ false);