Bug 651864 - Extract magic slot formula into inline functions (r=jwalden)

The global object has special slots for built-in objects' prototypes,
constructors and properties. This makes explicit the formula to calculate the
slot number for these special slots.
This commit is contained in:
Paul Biggar 2011-04-28 07:18:11 -07:00
parent 4011ba8b50
commit 0a4b3c92dd
4 changed files with 33 additions and 17 deletions

View File

@ -3805,7 +3805,7 @@ DefineStandardSlot(JSContext *cx, JSObject *obj, JSProtoKey key, JSAtom *atom,
const Shape *shape = obj->nativeLookup(id);
if (!shape) {
uint32 slot = 2 * JSProto_LIMIT + key;
uint32 slot = JS_GLOBAL_PROPERTY_SLOT(key);
if (!js_SetReservedSlot(cx, obj, slot, v))
return false;
if (!obj->addProperty(cx, id, PropertyStub, StrictPropertyStub, slot, attrs, 0, 0))
@ -3991,7 +3991,7 @@ IsStandardClassResolved(JSObject *obj, js::Class *clasp)
JSProtoKey key = JSCLASS_CACHED_PROTO_KEY(clasp);
/* If the constructor is undefined, then it hasn't been initialized. */
return (obj->getReservedSlot(key) != UndefinedValue());
return (!obj->getReservedSlot(JS_GLOBAL_CTOR_SLOT(key)).isUndefined());
}
void
@ -4003,7 +4003,7 @@ MarkStandardClassInitializedNoProto(JSObject* obj, js::Class *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 (obj->getReservedSlot(key) == UndefinedValue())
if (obj->getReservedSlot(JS_GLOBAL_CTOR_SLOT(key)).isUndefined())
obj->setSlot(key, BooleanValue(true));
}
@ -4217,7 +4217,7 @@ js_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key,
return true;
}
Value v = obj->getReservedSlot(key);
Value v = obj->getReservedSlot(JS_GLOBAL_CTOR_SLOT(key));
if (v.isObject()) {
*objp = &v.toObject();
return true;
@ -4234,7 +4234,7 @@ js_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key,
if (JSObjectOp init = lazy_prototype_init[key]) {
if (!init(cx, obj))
return false;
v = obj->getReservedSlot(key);
v = obj->getReservedSlot(JS_GLOBAL_CTOR_SLOT(key));
if (v.isObject())
cobj = &v.toObject();
}
@ -4250,8 +4250,8 @@ js_SetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key, JSObject *cobj,
if (!obj->isGlobal())
return JS_TRUE;
return js_SetReservedSlot(cx, obj, key, ObjectOrNullValue(cobj)) &&
js_SetReservedSlot(cx, obj, JSProto_LIMIT + key, ObjectOrNullValue(proto));
return js_SetReservedSlot(cx, obj, JS_GLOBAL_CTOR_SLOT(key), ObjectOrNullValue(cobj)) &&
js_SetReservedSlot(cx, obj, JS_GLOBAL_PROTO_SLOT(key), ObjectOrNullValue(proto));
}
JSBool
@ -4292,8 +4292,6 @@ js_FindClassObject(JSContext *cx, JSObject *start, JSProtoKey protoKey,
return JS_FALSE;
if (protoKey != JSProto_Null) {
JS_ASSERT(JSProto_Null < protoKey);
JS_ASSERT(protoKey < JSProto_LIMIT);
if (!js_GetClassObject(cx, obj, protoKey, &cobj))
return JS_FALSE;
if (cobj) {
@ -6200,7 +6198,7 @@ js_GetClassPrototype(JSContext *cx, JSObject *scopeobj, JSProtoKey protoKey,
}
scopeobj = scopeobj->getGlobal();
if (scopeobj->isGlobal()) {
const Value &v = scopeobj->getReservedSlot(JSProto_LIMIT + protoKey);
const Value &v = scopeobj->getReservedSlot(JS_GLOBAL_PROTO_SLOT(protoKey));
if (v.isObject()) {
*protop = &v.toObject();
return true;

View File

@ -1226,7 +1226,7 @@ NewBuiltinClassInstance(JSContext *cx, Class *clasp, gc::FinalizeKind kind)
}
JS_ASSERT(global->isGlobal());
const Value &v = global->getReservedSlot(JSProto_LIMIT + protoKey);
const Value &v = global->getReservedSlot(JS_GLOBAL_PROTO_SLOT(protoKey));
JSObject *proto;
if (v.isObject()) {
proto = &v.toObject();
@ -1477,12 +1477,12 @@ DefineConstructorAndPrototype(JSContext *cx, JSObject *global,
jsid id = ATOM_TO_JSID(cx->runtime->atomState.classAtoms[key]);
JS_ASSERT(!global->nativeLookup(id));
if (!global->addDataProperty(cx, id, key + JSProto_LIMIT * 2, 0))
if (!global->addDataProperty(cx, id, JS_GLOBAL_PROPERTY_SLOT(key), 0))
return false;
global->setSlot(key, ObjectValue(*ctor));
global->setSlot(key + JSProto_LIMIT, ObjectValue(*proto));
global->setSlot(key + JSProto_LIMIT * 2, ObjectValue(*ctor));
global->setSlot(JS_GLOBAL_CTOR_SLOT(key), ObjectValue(*ctor));
global->setSlot(JS_GLOBAL_PROTO_SLOT(key), ObjectValue(*proto));
global->setSlot(JS_GLOBAL_PROPERTY_SLOT(key), ObjectValue(*ctor));
return true;
}

View File

@ -107,6 +107,24 @@ typedef enum JSProtoKey {
JSProto_LIMIT
} JSProtoKey;
static void JS_CHECK_PROTOKEY_RANGE(JSProtoKey key) {
JS_ASSERT(key >= JSProto_Null);
JS_ASSERT(key < JSProto_LIMIT);
}
uintN inline JS_GLOBAL_CTOR_SLOT(JSProtoKey key) {
JS_CHECK_PROTOKEY_RANGE(key);
return key;
}
uintN inline JS_GLOBAL_PROTO_SLOT(JSProtoKey key) {
JS_CHECK_PROTOKEY_RANGE(key);
return key + JSProto_LIMIT;
}
uintN inline JS_GLOBAL_PROPERTY_SLOT(JSProtoKey key) {
JS_CHECK_PROTOKEY_RANGE(key);
return key + JSProto_LIMIT * 2;
}
/* js_CheckAccess mode enumeration. */
typedef enum JSAccessMode {
JSACC_PROTO = 0, /* XXXbe redundant w.r.t. id */

View File

@ -7385,7 +7385,7 @@ JSBool
js_GetAnyName(JSContext *cx, jsid *idp)
{
JSObject *global = cx->running() ? cx->fp()->scopeChain().getGlobal() : cx->globalObject;
Value v = global->getReservedSlot(JSProto_AnyName);
Value v = global->getReservedSlot(JS_GLOBAL_CTOR_SLOT(JSProto_AnyName));
if (v.isUndefined()) {
JSObject *obj = NewNonFunction<WithProto::Given>(cx, &js_AnyNameClass, NULL, global);
if (!obj)
@ -7398,7 +7398,7 @@ js_GetAnyName(JSContext *cx, jsid *idp)
METER(xml_stats.qname);
v.setObject(*obj);
if (!js_SetReservedSlot(cx, global, JSProto_AnyName, v))
if (!js_SetReservedSlot(cx, global, JS_GLOBAL_CTOR_SLOT(JSProto_AnyName), v))
return false;
}
*idp = OBJECT_TO_JSID(&v.toObject());