mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 861022 part 1. Root the non-globals in WebIDL prototype and interface object setup. r=peterv,terrence
This commit is contained in:
parent
c3b61c3b32
commit
e418358f16
@ -2979,7 +2979,7 @@ nsObjectLoadingContent::SetupProtoChain(JSContext* aCx, JSObject* aObject)
|
||||
// If we got an xpconnect-wrapped plugin object, set obj's
|
||||
// prototype's prototype to the scriptable plugin.
|
||||
|
||||
JSObject *my_proto =
|
||||
JS::Handle<JSObject*> my_proto =
|
||||
GetDOMClass(aObject)->mGetProto(aCx, JS_GetGlobalForObject(aCx, aObject));
|
||||
MOZ_ASSERT(my_proto);
|
||||
|
||||
|
@ -294,7 +294,7 @@ CreateConstructor(JSContext* cx, JSObject* global, const char* name,
|
||||
|
||||
static bool
|
||||
DefineConstructor(JSContext* cx, JSObject* global, const char* name,
|
||||
JSObject* constructor)
|
||||
JS::Handle<JSObject*> constructor)
|
||||
{
|
||||
JSBool alreadyDefined;
|
||||
if (!JS_AlreadyHasOwnProperty(cx, global, name, &alreadyDefined)) {
|
||||
@ -312,12 +312,12 @@ CreateInterfaceObject(JSContext* cx, JSObject* global,
|
||||
JSClass* constructorClass,
|
||||
const JSNativeHolder* constructorNative,
|
||||
unsigned ctorNargs, const NamedConstructor* namedConstructors,
|
||||
JSObject* proto,
|
||||
JS::Handle<JSObject*> proto,
|
||||
const NativeProperties* properties,
|
||||
const NativeProperties* chromeOnlyProperties,
|
||||
const char* name)
|
||||
{
|
||||
JSObject* constructor;
|
||||
JS::Rooted<JSObject*> constructor(cx);
|
||||
bool isCallbackInterface = constructorClass == js::Jsvalify(&js::ObjectClass);
|
||||
if (constructorClass) {
|
||||
JSObject* constructorProto;
|
||||
@ -342,22 +342,23 @@ CreateInterfaceObject(JSContext* cx, JSObject* global,
|
||||
if (constructorClass && !isCallbackInterface) {
|
||||
// Have to shadow Function.prototype.toString, since that throws
|
||||
// on things that are not js::FunctionClass.
|
||||
JSFunction* toString = js::DefineFunctionWithReserved(cx, constructor,
|
||||
"toString",
|
||||
InterfaceObjectToString,
|
||||
0, 0);
|
||||
JS::Rooted<JSFunction*> toString(cx,
|
||||
js::DefineFunctionWithReserved(cx, constructor,
|
||||
"toString",
|
||||
InterfaceObjectToString,
|
||||
0, 0));
|
||||
if (!toString) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JSObject* toStringObj = JS_GetFunctionObject(toString);
|
||||
js::SetFunctionNativeReserved(toStringObj, TOSTRING_CLASS_RESERVED_SLOT,
|
||||
PRIVATE_TO_JSVAL(constructorClass));
|
||||
|
||||
JSString *str = ::JS_InternString(cx, name);
|
||||
if (!str) {
|
||||
return NULL;
|
||||
}
|
||||
JSObject* toStringObj = JS_GetFunctionObject(toString);
|
||||
js::SetFunctionNativeReserved(toStringObj, TOSTRING_CLASS_RESERVED_SLOT,
|
||||
PRIVATE_TO_JSVAL(constructorClass));
|
||||
|
||||
js::SetFunctionNativeReserved(toStringObj, TOSTRING_NAME_RESERVED_SLOT,
|
||||
STRING_TO_JSVAL(str));
|
||||
|
||||
@ -413,10 +414,10 @@ CreateInterfaceObject(JSContext* cx, JSObject* global,
|
||||
if (namedConstructors) {
|
||||
int namedConstructorSlot = DOM_INTERFACE_SLOTS_BASE;
|
||||
while (namedConstructors->mName) {
|
||||
JSObject* namedConstructor = CreateConstructor(cx, global,
|
||||
namedConstructors->mName,
|
||||
&namedConstructors->mHolder,
|
||||
namedConstructors->mNargs);
|
||||
JS::Rooted<JSObject*> namedConstructor(cx,
|
||||
CreateConstructor(cx, global, namedConstructors->mName,
|
||||
&namedConstructors->mHolder,
|
||||
namedConstructors->mNargs));
|
||||
if (!namedConstructor ||
|
||||
!JS_DefineProperty(cx, namedConstructor, "prototype",
|
||||
JS::ObjectValue(*proto), JS_PropertyStub,
|
||||
@ -453,12 +454,13 @@ DefineWebIDLBindingPropertiesOnXPCProto(JSContext* cx, JSObject* proto, const Na
|
||||
|
||||
static JSObject*
|
||||
CreateInterfacePrototypeObject(JSContext* cx, JSObject* global,
|
||||
JSObject* parentProto, JSClass* protoClass,
|
||||
JS::Handle<JSObject*> parentProto,
|
||||
JSClass* protoClass,
|
||||
const NativeProperties* properties,
|
||||
const NativeProperties* chromeOnlyProperties)
|
||||
{
|
||||
JSObject* ourProto = JS_NewObjectWithUniqueType(cx, protoClass, parentProto,
|
||||
global);
|
||||
JS::Rooted<JSObject*> ourProto(cx,
|
||||
JS_NewObjectWithUniqueType(cx, protoClass, parentProto, global));
|
||||
if (!ourProto) {
|
||||
return NULL;
|
||||
}
|
||||
@ -501,7 +503,8 @@ CreateInterfacePrototypeObject(JSContext* cx, JSObject* global,
|
||||
}
|
||||
|
||||
void
|
||||
CreateInterfaceObjects(JSContext* cx, JSObject* global, JSObject* protoProto,
|
||||
CreateInterfaceObjects(JSContext* cx, JSObject* global,
|
||||
JS::Handle<JSObject*> protoProto,
|
||||
JSClass* protoClass, JSObject** protoCache,
|
||||
JSClass* constructorClass, const JSNativeHolder* constructor,
|
||||
unsigned ctorNargs, const NamedConstructor* namedConstructors,
|
||||
@ -535,10 +538,11 @@ CreateInterfaceObjects(JSContext* cx, JSObject* global, JSObject* protoProto,
|
||||
"If, and only if, there is an interface object we need to cache "
|
||||
"it");
|
||||
|
||||
JSObject* proto;
|
||||
JS::Rooted<JSObject*> proto(cx);
|
||||
if (protoClass) {
|
||||
proto = CreateInterfacePrototypeObject(cx, global, protoProto, protoClass,
|
||||
properties, chromeOnlyProperties);
|
||||
proto =
|
||||
CreateInterfacePrototypeObject(cx, global, protoProto, protoClass,
|
||||
properties, chromeOnlyProperties);
|
||||
if (!proto) {
|
||||
return;
|
||||
}
|
||||
@ -549,7 +553,7 @@ CreateInterfaceObjects(JSContext* cx, JSObject* global, JSObject* protoProto,
|
||||
*protoCache = proto;
|
||||
}
|
||||
else {
|
||||
proto = NULL;
|
||||
MOZ_ASSERT(!proto);
|
||||
}
|
||||
|
||||
JSObject* interface;
|
||||
@ -1470,7 +1474,7 @@ ReparentWrapper(JSContext* aCx, JS::HandleObject aObjArg)
|
||||
// return early we must avoid ending up with two reflectors pointing to the
|
||||
// same native. Other than that, the objects we create will just go away.
|
||||
|
||||
JSObject *proto =
|
||||
JS::Handle<JSObject*> proto =
|
||||
(domClass->mGetProto)(aCx,
|
||||
js::GetGlobalForObjectCrossCompartment(newParent));
|
||||
if (!proto) {
|
||||
|
@ -331,7 +331,8 @@ struct NamedConstructor
|
||||
* |name|, which must also be non-null.
|
||||
*/
|
||||
void
|
||||
CreateInterfaceObjects(JSContext* cx, JSObject* global, JSObject* protoProto,
|
||||
CreateInterfaceObjects(JSContext* cx, JSObject* global,
|
||||
JS::Handle<JSObject*> protoProto,
|
||||
JSClass* protoClass, JSObject** protoCache,
|
||||
JSClass* constructorClass, const JSNativeHolder* constructor,
|
||||
unsigned ctorNargs, const NamedConstructor* namedConstructors,
|
||||
|
@ -1679,11 +1679,13 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
|
||||
def definition_body(self):
|
||||
protoChain = self.descriptor.prototypeChain
|
||||
if len(protoChain) == 1:
|
||||
getParentProto = "JS_GetObjectPrototype(aCx, aGlobal)"
|
||||
getParentProto = "aCx, JS_GetObjectPrototype(aCx, aGlobal)"
|
||||
parentProtoType = "Rooted"
|
||||
else:
|
||||
parentProtoName = self.descriptor.prototypeChain[-2]
|
||||
getParentProto = ("%s::GetProtoObject(aCx, aGlobal)" %
|
||||
toBindingNamespace(parentProtoName))
|
||||
parentProtoType = "Handle"
|
||||
|
||||
needInterfaceObject = self.descriptor.interface.hasInterfaceObject()
|
||||
needInterfacePrototypeObject = self.descriptor.interface.hasInterfacePrototypeObject()
|
||||
@ -1751,10 +1753,10 @@ if (!unforgeableHolder) {
|
||||
else:
|
||||
createUnforgeableHolder = None
|
||||
|
||||
getParentProto = ("JSObject* parentProto = %s;\n" +
|
||||
getParentProto = ("JS::%s<JSObject*> parentProto(%s);\n" +
|
||||
"if (!parentProto) {\n" +
|
||||
" return;\n" +
|
||||
"}\n") % getParentProto
|
||||
"}\n") % (parentProtoType, getParentProto)
|
||||
|
||||
if (needInterfaceObject and
|
||||
self.descriptor.needsConstructHookHolder()):
|
||||
@ -1842,25 +1844,24 @@ class CGGetPerInterfaceObject(CGAbstractMethod):
|
||||
def __init__(self, descriptor, name, idPrefix=""):
|
||||
args = [Argument('JSContext*', 'aCx'), Argument('JSObject*', 'aGlobal')]
|
||||
CGAbstractMethod.__init__(self, descriptor, name,
|
||||
'JSObject*', args, inline=True)
|
||||
'JS::Handle<JSObject*>', args, inline=True)
|
||||
self.id = idPrefix + "id::" + self.descriptor.name
|
||||
def definition_body(self):
|
||||
return """
|
||||
return ("""
|
||||
|
||||
/* Make sure our global is sane. Hopefully we can remove this sometime */
|
||||
if (!(js::GetObjectClass(aGlobal)->flags & JSCLASS_DOM_GLOBAL)) {
|
||||
return NULL;
|
||||
return JS::NullPtr();
|
||||
}
|
||||
/* Check to see whether the interface objects are already installed */
|
||||
JSObject** protoAndIfaceArray = GetProtoAndIfaceArray(aGlobal);
|
||||
JSObject* cachedObject = protoAndIfaceArray[%s];
|
||||
if (!cachedObject) {
|
||||
if (!protoAndIfaceArray[%s]) {
|
||||
CreateInterfaceObjects(aCx, aGlobal, protoAndIfaceArray);
|
||||
cachedObject = protoAndIfaceArray[%s];
|
||||
}
|
||||
|
||||
/* cachedObject might _still_ be null, but that's OK */
|
||||
return cachedObject;""" % (self.id, self.id)
|
||||
/* The object might _still_ be null, but that's OK */
|
||||
return JS::Handle<JSObject*>::fromMarkedLocation(&protoAndIfaceArray[%s]);""" %
|
||||
(self.id, self.id))
|
||||
|
||||
class CGGetProtoObjectMethod(CGGetPerInterfaceObject):
|
||||
"""
|
||||
@ -2113,7 +2114,7 @@ class CGWrapWithCacheMethod(CGAbstractMethod):
|
||||
|
||||
JSAutoCompartment ac(aCx, parent);
|
||||
JSObject* global = JS_GetGlobalForObject(aCx, parent);
|
||||
JSObject* proto = GetProtoObject(aCx, global);
|
||||
JS::Handle<JSObject*> proto = GetProtoObject(aCx, global);
|
||||
if (!proto) {
|
||||
return NULL;
|
||||
}
|
||||
@ -2160,7 +2161,7 @@ class CGWrapNonWrapperCacheMethod(CGAbstractMethod):
|
||||
def definition_body(self):
|
||||
return """%s
|
||||
JSObject* global = JS_GetGlobalForObject(aCx, aScope);
|
||||
JSObject* proto = GetProtoObject(aCx, global);
|
||||
JS::Handle<JSObject*> proto = GetProtoObject(aCx, global);
|
||||
if (!proto) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -157,7 +157,13 @@ enum DOMObjectType {
|
||||
};
|
||||
|
||||
typedef JSObject* (*ParentGetter)(JSContext* aCx, JS::Handle<JSObject*> aObj);
|
||||
typedef JSObject* (*ProtoGetter)(JSContext* aCx, 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, JSObject* aGlobal);
|
||||
|
||||
struct DOMClass
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user