mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-03 10:33:33 +00:00
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:
parent
f0b7d81451
commit
16b3a0fe7d
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user