Bug 933681 - Always stash resolved constructors in global slots, and kill markStandardClassInitializedNoProto. r=jorendorff

This is necessary to see this stuff over Xrays.
This commit is contained in:
Bobby Holley 2013-11-22 10:55:41 -08:00
parent e1d2e60498
commit 4b939b99c3
6 changed files with 13 additions and 20 deletions

View File

@ -2042,7 +2042,7 @@ js_InitIntlClass(JSContext *cx, HandleObject obj)
return nullptr;
}
global->markStandardClassInitializedNoProto(&IntlClass);
global->setConstructor(JSProto_Intl, ObjectValue(*Intl));
return Intl;
}

View File

@ -1945,7 +1945,7 @@ GlobalObject::initIteratorClasses(JSContext *cx, Handle<GlobalObject *> global)
if (!DefineConstructorAndPrototype(cx, global, JSProto_StopIteration, proto, proto))
return false;
global->markStandardClassInitializedNoProto(&StopIterationObject::class_);
global->setConstructor(JSProto_StopIteration, ObjectValue(*proto));
}
return true;

View File

@ -1489,7 +1489,7 @@ js_InitMathClass(JSContext *cx, HandleObject obj)
if (!JS_DefineConstDoubles(cx, Math, math_constants))
return nullptr;
obj->as<GlobalObject>().markStandardClassInitializedNoProto(&MathClass);
obj->as<GlobalObject>().setConstructor(JSProto_Math, ObjectValue(*Math));
return Math;
}

View File

@ -885,7 +885,7 @@ js_InitJSONClass(JSContext *cx, HandleObject obj)
if (!JS_DefineFunctions(cx, JSON, json_static_methods))
return nullptr;
global->markStandardClassInitializedNoProto(&JSONClass);
global->setConstructor(JSProto_JSON, ObjectValue(*JSON));
return JSON;
}

View File

@ -3367,6 +3367,6 @@ js_InitProxyClass(JSContext *cx, HandleObject obj)
return nullptr;
}
global->markStandardClassInitializedNoProto(&ProxyObject::uncallableClass_);
global->setConstructor(JSProto_Proxy, ObjectValue(*ctor));
return ctor;
}

View File

@ -200,29 +200,22 @@ class GlobalObject : public JSObject
/*
* Lazy standard classes need a way to indicate they have been initialized.
* Otherwise, when we delete them, we might accidentally recreate them via
* a lazy initialization. We use the presence of a ctor or proto in the
* global object's slot to indicate that they've been constructed, but this
* only works for classes which have a proto and ctor. Classes which don't
* have one can call markStandardClassInitializedNoProto(), and we can
* always check whether a class is initialized by calling
* isStandardClassResolved().
* a lazy initialization. We use the presence of an object in the
* getConstructor(key) reserved slot to indicate that they've been
* initialized.
*
* Note: A few builtin objects, like JSON and Math, are not constructors,
* so getConstructor is a bit of a misnomer.
*/
bool isStandardClassResolved(const js::Class *clasp) const {
JSProtoKey key = JSCLASS_CACHED_PROTO_KEY(clasp);
// If the constructor is undefined, then it hasn't been initialized.
MOZ_ASSERT(getConstructor(key).isUndefined() ||
getConstructor(key).isObject());
return !getConstructor(key).isUndefined();
}
void markStandardClassInitializedNoProto(const js::Class *clasp) {
JSProtoKey key = JSCLASS_CACHED_PROTO_KEY(clasp);
// We use true so that it's obvious what we're doing (instead of, say,
// null, which might be miscontrued as an error in setting Undefined).
if (getConstructor(key).isUndefined())
setConstructor(key, BooleanValue(true));
}
private:
void setDetailsForKey(JSProtoKey key, JSObject *ctor, JSObject *proto) {
JS_ASSERT(getConstructor(key).isUndefined());