Bug 760109 - Add an API to lookup proto key via standard prototype objects and vice-versa.

This commit is contained in:
Bobby Holley 2012-07-27 12:15:46 +02:00
parent 122bba8b43
commit 128b0d834b
4 changed files with 60 additions and 0 deletions

View File

@ -2226,6 +2226,30 @@ JS_GetClassObject(JSContext *cx, JSObject *obj_, JSProtoKey key, JSObject **objp
return result;
}
JS_PUBLIC_API(JSBool)
JS_GetClassPrototype(JSContext *cx, JSProtoKey key, JSObject **objp_)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
RootedObject global(cx, cx->compartment->maybeGlobal());
if (!global)
return false;
RootedObject objp(cx);
bool result = js_GetClassPrototype(cx, global, key, &objp);
*objp_ = objp;
return result;
}
JS_PUBLIC_API(JSProtoKey)
JS_IdentifyClassPrototype(JSContext *cx, JSObject *obj)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj);
JS_ASSERT(!IsCrossCompartmentWrapper(obj));
return js_IdentifyClassPrototype(obj);
}
JS_PUBLIC_API(JSObject *)
JS_GetObjectPrototype(JSContext *cx, JSObject *forObj)
{

View File

@ -3284,6 +3284,12 @@ extern JS_PUBLIC_API(JSBool)
JS_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key,
JSObject **objp);
extern JS_PUBLIC_API(JSBool)
JS_GetClassPrototype(JSContext *cx, JSProtoKey key, JSObject **objp);
extern JS_PUBLIC_API(JSProtoKey)
JS_IdentifyClassPrototype(JSContext *cx, JSObject *obj);
/*
* Returns the original value of |Function.prototype| from the global object in
* which |forObj| was created.

View File

@ -3829,6 +3829,29 @@ js_GetClassObject(JSContext *cx, HandleObject obj, JSProtoKey key,
return true;
}
JSProtoKey
js_IdentifyClassPrototype(JSObject *obj)
{
// First, get the key off the JSClass. This tells us which prototype we
// _might_ be. But we still don't know for sure, since the prototype shares
// its JSClass with instances.
JSProtoKey key = JSCLASS_CACHED_PROTO_KEY(obj->getClass());
if (key == JSProto_Null)
return JSProto_Null;
// Now, see if the cached object matches |obj|.
//
// Note that standard class objects are cached in the range [0, JSProto_LIMIT),
// and the prototypes are cached in [JSProto_LIMIT, 2*JSProto_LIMIT).
JSObject &global = obj->global();
Value v = global.getReservedSlot(JSProto_LIMIT + key);
if (v.isObject() && obj == &v.toObject())
return key;
// False alarm - just an instance.
return JSProto_Null;
}
bool
js_FindClassObject(JSContext *cx, HandleObject start, JSProtoKey protoKey,
MutableHandleValue vp, Class *clasp)

View File

@ -1110,6 +1110,13 @@ extern bool
js_GetClassObject(JSContext *cx, js::HandleObject obj, JSProtoKey key,
js::MutableHandleObject objp);
/*
* Determine if the given object is a prototype for a standard class. If so,
* return the associated JSProtoKey. If not, return JSProto_Null.
*/
extern JSProtoKey
js_IdentifyClassPrototype(JSObject *obj);
/*
* If protoKey is not JSProto_Null, then clasp is ignored. If protoKey is
* JSProto_Null, clasp must non-null.