Bug 1125567 - Remove FindClassPrototype/FindClassObject. r=jorendorff
This commit is contained in:
135
js/src/jsobj.cpp
135
js/src/jsobj.cpp
@@ -1163,106 +1163,10 @@ js::NewObjectWithGivenTaggedProto(ExclusiveContext* cxArg, const Class* clasp,
|
||||
return obj;
|
||||
}
|
||||
|
||||
static JSProtoKey
|
||||
ClassProtoKeyOrAnonymousOrNull(const js::Class* clasp)
|
||||
{
|
||||
JSProtoKey key = JSCLASS_CACHED_PROTO_KEY(clasp);
|
||||
if (key != JSProto_Null)
|
||||
return key;
|
||||
if (clasp->flags & JSCLASS_IS_ANONYMOUS)
|
||||
return JSProto_Object;
|
||||
return JSProto_Null;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
NativeGetPureInline(NativeObject* pobj, Shape* shape, Value* vp)
|
||||
{
|
||||
if (shape->hasSlot()) {
|
||||
*vp = pobj->getSlot(shape->slot());
|
||||
MOZ_ASSERT(!vp->isMagic());
|
||||
} else {
|
||||
vp->setUndefined();
|
||||
}
|
||||
|
||||
/* Fail if we have a custom getter. */
|
||||
return shape->hasDefaultGetter();
|
||||
}
|
||||
|
||||
static bool
|
||||
FindClassPrototype(ExclusiveContext* cx, MutableHandleObject protop, const Class* clasp)
|
||||
{
|
||||
protop.set(nullptr);
|
||||
|
||||
JSAtom* atom = Atomize(cx, clasp->name, strlen(clasp->name));
|
||||
if (!atom)
|
||||
return false;
|
||||
RootedId id(cx, AtomToId(atom));
|
||||
|
||||
RootedObject pobj(cx);
|
||||
RootedShape shape(cx);
|
||||
if (!NativeLookupProperty<CanGC>(cx, cx->global(), id, &pobj, &shape))
|
||||
return false;
|
||||
|
||||
RootedObject ctor(cx);
|
||||
if (shape && pobj->isNative()) {
|
||||
if (shape->hasSlot()) {
|
||||
RootedValue v(cx, pobj->as<NativeObject>().getSlot(shape->slot()));
|
||||
if (v.isObject())
|
||||
ctor = &v.toObject();
|
||||
}
|
||||
}
|
||||
|
||||
if (ctor && ctor->is<JSFunction>()) {
|
||||
JSFunction* nctor = &ctor->as<JSFunction>();
|
||||
RootedValue v(cx);
|
||||
if (cx->isJSContext()) {
|
||||
if (!GetProperty(cx->asJSContext(), ctor, ctor, cx->names().prototype, &v))
|
||||
return false;
|
||||
} else {
|
||||
Shape* shape = nctor->lookup(cx, cx->names().prototype);
|
||||
if (!shape || !NativeGetPureInline(nctor, shape, v.address()))
|
||||
return false;
|
||||
}
|
||||
if (v.isObject())
|
||||
protop.set(&v.toObject());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Find the appropriate proto for a class. There are three different ways to achieve this:
|
||||
// 1. Built-in classes have a cached proto and anonymous classes get Object.prototype.
|
||||
// 2. Lookup global[clasp->name].prototype
|
||||
// 3. Fallback to Object.prototype
|
||||
//
|
||||
// Step 2 is in some circumstances an observable operation, which is probably wrong
|
||||
// as a matter of specifications. It's legacy garbage that we're working to remove eventually.
|
||||
static bool
|
||||
FindProto(ExclusiveContext* cx, const js::Class* clasp, MutableHandleObject proto)
|
||||
{
|
||||
JSProtoKey protoKey = ClassProtoKeyOrAnonymousOrNull(clasp);
|
||||
if (protoKey != JSProto_Null)
|
||||
return GetBuiltinPrototype(cx, protoKey, proto);
|
||||
|
||||
if (!FindClassPrototype(cx, proto, clasp))
|
||||
return false;
|
||||
|
||||
if (!proto) {
|
||||
// We're looking for the prototype of a class that is currently being
|
||||
// resolved; the global object's resolve hook is on the
|
||||
// stack. js::FindClassPrototype detects this goofy case and returns
|
||||
// true with proto null. Fall back on Object.prototype.
|
||||
MOZ_ASSERT(JSCLASS_CACHED_PROTO_KEY(clasp) == JSProto_Null);
|
||||
return GetBuiltinPrototype(cx, JSProto_Object, proto);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
NewObjectWithClassProtoIsCachable(ExclusiveContext* cxArg,
|
||||
JSProtoKey protoKey, NewObjectKind newKind, const Class* clasp)
|
||||
NewObjectIsCachable(ExclusiveContext* cxArg, NewObjectKind newKind, const Class* clasp)
|
||||
{
|
||||
return cxArg->isJSContext() &&
|
||||
protoKey != JSProto_Null &&
|
||||
newKind == GenericObject &&
|
||||
clasp->isNative();
|
||||
}
|
||||
@@ -1282,18 +1186,7 @@ js::NewObjectWithClassProtoCommon(ExclusiveContext* cxArg, const Class* clasp,
|
||||
|
||||
Handle<GlobalObject*> global = cxArg->global();
|
||||
|
||||
/*
|
||||
* Use the object cache, except for classes without a cached proto key.
|
||||
* On these objects, FindProto will do a dynamic property lookup to get
|
||||
* global[className].prototype, where changes to either the className or
|
||||
* prototype property would render the cached lookup incorrect. For classes
|
||||
* with a proto key, the prototype created during class initialization is
|
||||
* stored in an immutable slot on the global (except for ClearScope, which
|
||||
* will flush the new object cache).
|
||||
*/
|
||||
JSProtoKey protoKey = ClassProtoKeyOrAnonymousOrNull(clasp);
|
||||
|
||||
bool isCachable = NewObjectWithClassProtoIsCachable(cxArg, protoKey, newKind, clasp);
|
||||
bool isCachable = NewObjectIsCachable(cxArg, newKind, clasp);
|
||||
if (isCachable) {
|
||||
JSContext* cx = cxArg->asJSContext();
|
||||
JSRuntime* rt = cx->runtime();
|
||||
@@ -1306,8 +1199,16 @@ js::NewObjectWithClassProtoCommon(ExclusiveContext* cxArg, const Class* clasp,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the appropriate proto for clasp. Built-in classes have a cached
|
||||
* proto on cx->global(); all others get %ObjectPrototype%.
|
||||
*/
|
||||
JSProtoKey protoKey = JSCLASS_CACHED_PROTO_KEY(clasp);
|
||||
if (protoKey == JSProto_Null)
|
||||
protoKey = JSProto_Object;
|
||||
|
||||
RootedObject proto(cxArg, protoArg);
|
||||
if (!FindProto(cxArg, clasp, &proto))
|
||||
if (!GetBuiltinPrototype(cxArg, protoKey, &proto))
|
||||
return nullptr;
|
||||
|
||||
Rooted<TaggedProto> taggedProto(cxArg, TaggedProto(proto));
|
||||
@@ -2923,6 +2824,20 @@ js::LookupPropertyPure(ExclusiveContext* cx, JSObject* obj, jsid id, JSObject**
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
NativeGetPureInline(NativeObject* pobj, Shape* shape, Value* vp)
|
||||
{
|
||||
if (shape->hasSlot()) {
|
||||
*vp = pobj->getSlot(shape->slot());
|
||||
MOZ_ASSERT(!vp->isMagic());
|
||||
} else {
|
||||
vp->setUndefined();
|
||||
}
|
||||
|
||||
/* Fail if we have a custom getter. */
|
||||
return shape->hasDefaultGetter();
|
||||
}
|
||||
|
||||
bool
|
||||
js::GetPropertyPure(ExclusiveContext* cx, JSObject* obj, jsid id, Value* vp)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user