diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 086ac19dcb3..e40504b7626 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -2750,158 +2750,9 @@ JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto, JSPropertySpec *ps, JSFunctionSpec *fs, JSPropertySpec *static_ps, JSFunctionSpec *static_fs) { - return JS_InitTraceableClass(cx, obj, parent_proto, clasp, constructor, nargs, - ps, fs, static_ps, static_fs, NULL); -} - -JS_PUBLIC_API(JSObject *) -JS_InitTraceableClass(JSContext *cx, JSObject *obj, JSObject *parent_proto, - JSClass *clasp, JSNative constructor, uintN nargs, - JSPropertySpec *ps, JSFunctionSpec *fs, - JSPropertySpec *static_ps, JSFunctionSpec *static_fs, - JSTraceableNative *trcinfo) -{ - JSAtom *atom; - JSProtoKey key; - JSObject *proto, *ctor; - JSTempValueRooter tvr; - jsval cval, rval; - JSBool named; - JSFunction *fun; - CHECK_REQUEST(cx); - atom = js_Atomize(cx, clasp->name, strlen(clasp->name), 0); - if (!atom) - return NULL; - - /* - * When initializing a standard class, if no parent_proto (grand-proto of - * instances of the class, parent-proto of the class's prototype object) - * is given, we must use Object.prototype if it is available. Otherwise, - * we could look up the wrong binding for a class name in obj. Example: - * - * String = Array; - * print("hi there".join); - * - * should print undefined, not Array.prototype.join. This is required by - * ECMA-262, alas. It might have been better to make String readonly and - * permanent in the global object, instead -- but that's too big a change - * to swallow at this point. - */ - key = JSCLASS_CACHED_PROTO_KEY(clasp); - if (key != JSProto_Null && - !parent_proto && - !js_GetClassPrototype(cx, obj, INT_TO_JSID(JSProto_Object), - &parent_proto)) { - return NULL; - } - - /* Create a prototype object for this class. */ - proto = js_NewObject(cx, clasp, parent_proto, obj, 0); - if (!proto) - return NULL; - - /* After this point, control must exit via label bad or out. */ - JS_PUSH_TEMP_ROOT_OBJECT(cx, proto, &tvr); - - if (!constructor) { - JS_ASSERT(!trcinfo); - - /* - * Lacking a constructor, name the prototype (e.g., Math) unless this - * class (a) is anonymous, i.e. for internal use only; (b) the class - * of obj (the global object) is has a reserved slot indexed by key; - * and (c) key is not the null key. - */ - if ((clasp->flags & JSCLASS_IS_ANONYMOUS) && - (OBJ_GET_CLASS(cx, obj)->flags & JSCLASS_IS_GLOBAL) && - key != JSProto_Null) { - named = JS_FALSE; - } else { - named = OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(atom), - OBJECT_TO_JSVAL(proto), - JS_PropertyStub, JS_PropertyStub, - (clasp->flags & JSCLASS_IS_ANONYMOUS) - ? JSPROP_READONLY | JSPROP_PERMANENT - : 0, - NULL); - if (!named) - goto bad; - } - - ctor = proto; - } else { - /* Define the constructor function in obj's scope. */ - fun = js_DefineFunction(cx, obj, atom, constructor, nargs, - JSFUN_STUB_GSOPS); - named = (fun != NULL); - if (!fun) - goto bad; - - /* - * Remember the class this function is a constructor for so that - * we know to create an object of this class when we call the - * constructor. - */ - FUN_CLASP(fun) = clasp; - - /* - * If we have a traceable native constructor, update the function to - * point at the given trcinfo and flag it. - */ - if (trcinfo) { - fun->u.n.trcinfo = trcinfo; - fun->flags |= JSFUN_TRACEABLE; - } - - /* - * Optionally construct the prototype object, before the class has - * been fully initialized. Allow the ctor to replace proto with a - * different object, as is done for operator new -- and as at least - * XML support requires. - */ - ctor = FUN_OBJECT(fun); - if (clasp->flags & JSCLASS_CONSTRUCT_PROTOTYPE) { - cval = OBJECT_TO_JSVAL(ctor); - if (!js_InternalConstruct(cx, proto, cval, 0, NULL, &rval)) - goto bad; - if (!JSVAL_IS_PRIMITIVE(rval) && JSVAL_TO_OBJECT(rval) != proto) - proto = JSVAL_TO_OBJECT(rval); - } - - /* Connect constructor and prototype by named properties. */ - if (!js_SetClassPrototype(cx, ctor, proto, - JSPROP_READONLY | JSPROP_PERMANENT)) { - goto bad; - } - - /* Bootstrap Function.prototype (see also JS_InitStandardClasses). */ - if (OBJ_GET_CLASS(cx, ctor) == clasp) { - OBJ_SET_PROTO(cx, ctor, proto); - } - } - - /* Add properties and methods to the prototype and the constructor. */ - if ((ps && !JS_DefineProperties(cx, proto, ps)) || - (fs && !JS_DefineFunctions(cx, proto, fs)) || - (static_ps && !JS_DefineProperties(cx, ctor, static_ps)) || - (static_fs && !JS_DefineFunctions(cx, ctor, static_fs))) { - goto bad; - } - - /* If this is a standard class, cache its prototype. */ - if (key != JSProto_Null && !js_SetClassObject(cx, obj, key, ctor)) - goto bad; - -out: - JS_POP_TEMP_ROOT(cx, &tvr); - return proto; - -bad: - if (named) - (void) OBJ_DELETE_PROPERTY(cx, obj, ATOM_TO_JSID(atom), &rval); - proto = NULL; - goto out; + return js_InitClass(cx, obj, parent_proto, clasp, constructor, nargs, + ps, fs, static_ps, static_fs, NULL); } #ifdef JS_THREADSAFE diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 50835b0c4ce..db85fe47474 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -1568,13 +1568,6 @@ JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto, JSPropertySpec *ps, JSFunctionSpec *fs, JSPropertySpec *static_ps, JSFunctionSpec *static_fs); -extern JS_PUBLIC_API(JSObject *) -JS_InitTraceableClass(JSContext *cx, JSObject *obj, JSObject *parent_proto, - JSClass *clasp, JSNative constructor, uintN nargs, - JSPropertySpec *ps, JSFunctionSpec *fs, - JSPropertySpec *static_ps, JSFunctionSpec *static_fs, - JSTraceableNative *trcinfo); - #ifdef JS_THREADSAFE extern JS_PUBLIC_API(JSClass *) JS_GetClass(JSContext *cx, JSObject *obj); diff --git a/js/src/jsdate.cpp b/js/src/jsdate.cpp index d119e7a8809..017a8d17454 100644 --- a/js/src/jsdate.cpp +++ b/js/src/jsdate.cpp @@ -2175,29 +2175,17 @@ static JSObject* FASTCALL Date_tn(JSContext* cx, JSObject* proto) { JS_ASSERT(JS_ON_TRACE(cx)); - JSObject* obj = (JSObject*) js_NewGCThing(cx, GCX_OBJECT, sizeof(JSObject)); + JSObject* obj = js_NewNativeObject(cx, &js_DateClass, proto, JSSLOT_LOCAL_TIME + 1); if (!obj) return NULL; - JSClass* clasp = &js_DateClass; - obj->classword = jsuword(clasp); - - obj->fslots[JSSLOT_PROTO] = OBJECT_TO_JSVAL(proto); - obj->fslots[JSSLOT_PARENT] = proto->fslots[JSSLOT_PARENT]; - jsdouble* date = js_NewWeaklyRootedDouble(cx, 0.0); if (!date) return NULL; *date = date_now_tn(cx); + obj->fslots[JSSLOT_UTC_TIME] = DOUBLE_TO_JSVAL(date); obj->fslots[JSSLOT_LOCAL_TIME] = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); - for (unsigned i = JSSLOT_LOCAL_TIME + 1; i != JS_INITIAL_NSLOTS; ++i) - obj->fslots[i] = JSVAL_VOID; - - JS_ASSERT(!clasp->getObjectOps); - JS_ASSERT(proto->map->ops == &js_ObjectOps); - obj->map = js_HoldObjectMap(cx, proto->map); - obj->dslots = NULL; return obj; } @@ -2218,9 +2206,9 @@ js_InitDateClass(JSContext *cx, JSObject *obj) /* set static LocalTZA */ LocalTZA = -(PRMJ_LocalGMTDifference() * msPerSecond); - proto = JS_InitTraceableClass(cx, obj, NULL, &js_DateClass, js_Date, MAXARGS, - NULL, date_methods, NULL, date_static_methods, - js_Date_trcinfo); + proto = js_InitClass(cx, obj, NULL, &js_DateClass, js_Date, MAXARGS, + NULL, date_methods, NULL, date_static_methods, + js_Date_trcinfo); if (!proto) return NULL; diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 516f2807dc4..3784f033348 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -2002,9 +2002,11 @@ NewNativeObject(JSContext* cx, JSObject* proto, JSObject *parent) obj->classword = jsuword(&js_ObjectClass); obj->fslots[JSSLOT_PROTO] = OBJECT_TO_JSVAL(proto); obj->fslots[JSSLOT_PARENT] = OBJECT_TO_JSVAL(parent); - for (unsigned i = JSSLOT_PRIVATE; i != JS_INITIAL_NSLOTS; ++i) + for (unsigned i = JSSLOT_PRIVATE; i < JS_INITIAL_NSLOTS; ++i) obj->fslots[i] = JSVAL_VOID; + JS_ASSERT(!OBJ_GET_CLASS(cx, proto)->getObjectOps); + JS_ASSERT(proto->map->ops == &js_ObjectOps); obj->map = js_HoldObjectMap(cx, proto->map); obj->dslots = NULL; return obj; @@ -2644,9 +2646,157 @@ js_InitEval(JSContext *cx, JSObject *obj) JSObject * js_InitObjectClass(JSContext *cx, JSObject *obj) { - return JS_InitTraceableClass(cx, obj, NULL, &js_ObjectClass, js_Object, 1, - object_props, object_methods, NULL, object_static_methods, - js_Object_trcinfo); + return js_InitClass(cx, obj, NULL, &js_ObjectClass, js_Object, 1, + object_props, object_methods, NULL, object_static_methods, + js_Object_trcinfo); +} + +JSObject * +js_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto, + JSClass *clasp, JSNative constructor, uintN nargs, + JSPropertySpec *ps, JSFunctionSpec *fs, + JSPropertySpec *static_ps, JSFunctionSpec *static_fs, + JSTraceableNative *trcinfo) +{ + JSAtom *atom; + JSProtoKey key; + JSObject *proto, *ctor; + JSTempValueRooter tvr; + jsval cval, rval; + JSBool named; + JSFunction *fun; + + atom = js_Atomize(cx, clasp->name, strlen(clasp->name), 0); + if (!atom) + return NULL; + + /* + * When initializing a standard class, if no parent_proto (grand-proto of + * instances of the class, parent-proto of the class's prototype object) + * is given, we must use Object.prototype if it is available. Otherwise, + * we could look up the wrong binding for a class name in obj. Example: + * + * String = Array; + * print("hi there".join); + * + * should print undefined, not Array.prototype.join. This is required by + * ECMA-262, alas. It might have been better to make String readonly and + * permanent in the global object, instead -- but that's too big a change + * to swallow at this point. + */ + key = JSCLASS_CACHED_PROTO_KEY(clasp); + if (key != JSProto_Null && + !parent_proto && + !js_GetClassPrototype(cx, obj, INT_TO_JSID(JSProto_Object), + &parent_proto)) { + return NULL; + } + + /* Create a prototype object for this class. */ + proto = js_NewObject(cx, clasp, parent_proto, obj, 0); + if (!proto) + return NULL; + + /* After this point, control must exit via label bad or out. */ + JS_PUSH_TEMP_ROOT_OBJECT(cx, proto, &tvr); + + if (!constructor) { + JS_ASSERT(!trcinfo); + + /* + * Lacking a constructor, name the prototype (e.g., Math) unless this + * class (a) is anonymous, i.e. for internal use only; (b) the class + * of obj (the global object) is has a reserved slot indexed by key; + * and (c) key is not the null key. + */ + if ((clasp->flags & JSCLASS_IS_ANONYMOUS) && + (OBJ_GET_CLASS(cx, obj)->flags & JSCLASS_IS_GLOBAL) && + key != JSProto_Null) { + named = JS_FALSE; + } else { + named = OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(atom), + OBJECT_TO_JSVAL(proto), + JS_PropertyStub, JS_PropertyStub, + (clasp->flags & JSCLASS_IS_ANONYMOUS) + ? JSPROP_READONLY | JSPROP_PERMANENT + : 0, + NULL); + if (!named) + goto bad; + } + + ctor = proto; + } else { + /* Define the constructor function in obj's scope. */ + fun = js_DefineFunction(cx, obj, atom, constructor, nargs, + JSFUN_STUB_GSOPS); + named = (fun != NULL); + if (!fun) + goto bad; + + /* + * Remember the class this function is a constructor for so that + * we know to create an object of this class when we call the + * constructor. + */ + FUN_CLASP(fun) = clasp; + + /* + * If we have a traceable native constructor, update the function to + * point at the given trcinfo and flag it. + */ + if (trcinfo) { + fun->u.n.trcinfo = trcinfo; + fun->flags |= JSFUN_TRACEABLE; + } + + /* + * Optionally construct the prototype object, before the class has + * been fully initialized. Allow the ctor to replace proto with a + * different object, as is done for operator new -- and as at least + * XML support requires. + */ + ctor = FUN_OBJECT(fun); + if (clasp->flags & JSCLASS_CONSTRUCT_PROTOTYPE) { + cval = OBJECT_TO_JSVAL(ctor); + if (!js_InternalConstruct(cx, proto, cval, 0, NULL, &rval)) + goto bad; + if (!JSVAL_IS_PRIMITIVE(rval) && JSVAL_TO_OBJECT(rval) != proto) + proto = JSVAL_TO_OBJECT(rval); + } + + /* Connect constructor and prototype by named properties. */ + if (!js_SetClassPrototype(cx, ctor, proto, + JSPROP_READONLY | JSPROP_PERMANENT)) { + goto bad; + } + + /* Bootstrap Function.prototype (see also JS_InitStandardClasses). */ + if (OBJ_GET_CLASS(cx, ctor) == clasp) + OBJ_SET_PROTO(cx, ctor, proto); + } + + /* Add properties and methods to the prototype and the constructor. */ + if ((ps && !JS_DefineProperties(cx, proto, ps)) || + (fs && !JS_DefineFunctions(cx, proto, fs)) || + (static_ps && !JS_DefineProperties(cx, ctor, static_ps)) || + (static_fs && !JS_DefineFunctions(cx, ctor, static_fs))) { + goto bad; + } + + /* If this is a standard class, cache its prototype. */ + if (key != JSProto_Null && !js_SetClassObject(cx, obj, key, ctor)) + goto bad; + +out: + JS_POP_TEMP_ROOT(cx, &tvr); + return proto; + +bad: + if (named) + (void) OBJ_DELETE_PROPERTY(cx, obj, ATOM_TO_JSID(atom), &rval); + proto = NULL; + goto out; } void @@ -2928,7 +3078,7 @@ js_NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto, STOBJ_SET_PARENT(obj, parent); /* Initialize the remaining fixed slots. */ - for (i = JSSLOT_PRIVATE; i != JS_INITIAL_NSLOTS; ++i) + for (i = JSSLOT_PRIVATE; i < JS_INITIAL_NSLOTS; ++i) obj->fslots[i] = JSVAL_VOID; #ifdef DEBUG @@ -3022,6 +3172,28 @@ earlybad: return NULL; } +JSObject* +js_NewNativeObject(JSContext *cx, JSClass *clasp, JSObject *proto, uint32 slot) +{ + JSObject* obj = (JSObject*) js_NewGCThing(cx, GCX_OBJECT, sizeof(JSObject)); + if (!obj) + return NULL; + + obj->classword = jsuword(clasp); + obj->fslots[JSSLOT_PROTO] = OBJECT_TO_JSVAL(proto); + obj->fslots[JSSLOT_PARENT] = proto->fslots[JSSLOT_PARENT]; + + JS_ASSERT(slot > JSSLOT_PARENT); + while (slot < JS_INITIAL_NSLOTS) + obj->fslots[slot++] = JSVAL_VOID; + + JS_ASSERT(!clasp->getObjectOps); + JS_ASSERT(proto->map->ops == &js_ObjectOps); + obj->map = js_HoldObjectMap(cx, proto->map); + obj->dslots = NULL; + return obj; +} + JS_BEGIN_EXTERN_C static JSObject * diff --git a/js/src/jsobj.h b/js/src/jsobj.h index 293f6e096d4..27f9c0b1f68 100644 --- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -438,6 +438,13 @@ js_InitEval(JSContext *cx, JSObject *obj); extern JSObject * js_InitObjectClass(JSContext *cx, JSObject *obj); +extern JSObject * +js_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto, + JSClass *clasp, JSNative constructor, uintN nargs, + JSPropertySpec *ps, JSFunctionSpec *fs, + JSPropertySpec *static_ps, JSFunctionSpec *static_fs, + JSTraceableNative *trcinfo); + /* * Select Object.prototype method names shared between jsapi.cpp and jsobj.cpp. */ @@ -485,6 +492,19 @@ extern JSObject * js_NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent, uintN objectSize); +/* + * Allocate a new native object and initialize all fslots with JSVAL_VOID + * starting with the specified slot. The parent slot is set to the value of + * proto's parent slot. + * + * Note that this is the correct global object for native class instances, but + * not for user-defined functions called as constructors. Functions used as + * constructors must create instances parented by the parent of the function + * object, not by the parent of its .prototype object value. + */ +extern JSObject* +js_NewNativeObject(JSContext *cx, JSClass *clasp, JSObject *proto, uint32 slot); + /* * Fast access to immutable standard objects (constructors and prototypes). */ diff --git a/js/src/jsprvtd.h b/js/src/jsprvtd.h index 29881bfd4d2..a3ee7d2af45 100644 --- a/js/src/jsprvtd.h +++ b/js/src/jsprvtd.h @@ -125,6 +125,7 @@ typedef struct JSScopeProperty JSScopeProperty; typedef struct JSStackHeader JSStackHeader; typedef struct JSStringBuffer JSStringBuffer; typedef struct JSSubString JSSubString; +typedef struct JSTraceableNative JSTraceableNative; typedef struct JSXML JSXML; typedef struct JSXMLArray JSXMLArray; typedef struct JSXMLArrayCursor JSXMLArrayCursor; diff --git a/js/src/jspubtd.h b/js/src/jspubtd.h index aacc2a9a2f4..8b4caaaec6b 100644 --- a/js/src/jspubtd.h +++ b/js/src/jspubtd.h @@ -150,7 +150,6 @@ typedef struct JSRuntime JSTaskState; /* XXX deprecated name */ typedef struct JSScript JSScript; typedef struct JSStackFrame JSStackFrame; typedef struct JSString JSString; -typedef struct JSTraceableNative JSTraceableNative; typedef struct JSXDRState JSXDRState; typedef struct JSExceptionState JSExceptionState; typedef struct JSLocaleCallbacks JSLocaleCallbacks; diff --git a/js/src/jsregexp.cpp b/js/src/jsregexp.cpp index 2f3edba18c7..cbf3841eab1 100644 --- a/js/src/jsregexp.cpp +++ b/js/src/jsregexp.cpp @@ -4950,35 +4950,72 @@ RegExp(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) return regexp_compile_sub(cx, obj, argc, argv, rval); } +static JSObject* FASTCALL +RegExp_tn1(JSContext *cx, JSObject *proto, JSString *str) +{ + JSObject* obj = js_NewNativeObject(cx, &js_RegExpClass, proto, JSSLOT_PRIVATE); + if (!obj) + return NULL; + + jsval argv[] = { JSVAL_NULL, OBJECT_TO_JSVAL(obj), STRING_TO_JSVAL(str) }; + jsval rval; + + if (!regexp_compile_sub(cx, obj, 1, argv + 2, &rval)) + return NULL; + + JS_ASSERT(JSVAL_IS_OBJECT(rval)); + return JSVAL_TO_OBJECT(rval); +} + +static JSObject* FASTCALL +RegExp_tn2(JSContext *cx, JSObject *proto, JSString *str, JSString *opt) +{ + JSObject* obj = js_NewNativeObject(cx, &js_RegExpClass, proto, JSSLOT_PRIVATE); + if (!obj) + return NULL; + + jsval argv[] = { JSVAL_NULL, OBJECT_TO_JSVAL(obj), STRING_TO_JSVAL(str), STRING_TO_JSVAL(opt) }; + jsval rval; + + if (!regexp_compile_sub(cx, obj, 2, argv + 2, &rval)) + return NULL; + + JS_ASSERT(JSVAL_IS_OBJECT(rval)); + return JSVAL_TO_OBJECT(rval); +} + +JS_DEFINE_TRCINFO_2(RegExp, + (3, (extern, CONSTRUCTOR_RETRY, RegExp_tn1, CONTEXT, CALLEE_PROTOTYPE, STRING, 0, 0)), + (4, (extern, CONSTRUCTOR_RETRY, RegExp_tn2, CONTEXT, CALLEE_PROTOTYPE, STRING, STRING, 0, 0))) + JSObject * js_InitRegExpClass(JSContext *cx, JSObject *obj) { - JSObject *proto, *ctor; - jsval rval; + JSObject *proto = js_InitClass(cx, obj, NULL, &js_RegExpClass, RegExp, 1, + regexp_props, regexp_methods, + regexp_static_props, NULL, + RegExp_trcinfo); - proto = JS_InitClass(cx, obj, NULL, &js_RegExpClass, RegExp, 1, - regexp_props, regexp_methods, - regexp_static_props, NULL); - - if (!proto || !(ctor = JS_GetConstructor(cx, proto))) + if (!proto) return NULL; + + JSObject *ctor = JS_GetConstructor(cx, proto); + if (!ctor) + return NULL; + + /* Give RegExp.prototype private data so it matches the empty string. */ + jsval rval; if (!JS_AliasProperty(cx, ctor, "input", "$_") || !JS_AliasProperty(cx, ctor, "multiline", "$*") || !JS_AliasProperty(cx, ctor, "lastMatch", "$&") || !JS_AliasProperty(cx, ctor, "lastParen", "$+") || !JS_AliasProperty(cx, ctor, "leftContext", "$`") || - !JS_AliasProperty(cx, ctor, "rightContext", "$'")) { - goto bad; + !JS_AliasProperty(cx, ctor, "rightContext", "$'") || + !regexp_compile_sub(cx, proto, 0, NULL, &rval)) { + return NULL; } - /* Give RegExp.prototype private data so it matches the empty string. */ - if (!regexp_compile_sub(cx, proto, 0, NULL, &rval)) - goto bad; return proto; - -bad: - JS_DeleteProperty(cx, obj, js_RegExpClass.name); - return NULL; } JSObject * diff --git a/js/src/jstracer.cpp b/js/src/jstracer.cpp index 2aa35a23448..fd95293bd70 100644 --- a/js/src/jstracer.cpp +++ b/js/src/jstracer.cpp @@ -3002,7 +3002,7 @@ js_CheckGlobalObjectShape(JSContext* cx, JSTraceMonitor* tm, JSObject* globalObj AUDIT(globalShapeMismatchAtEntry); debug_only_v(printf("Global shape mismatch (%u vs. %u), flushing cache.\n", globalShape, ti->globalShape);) - return false; + return false; } if (shape) *shape = globalShape; @@ -3013,7 +3013,6 @@ js_CheckGlobalObjectShape(JSContext* cx, JSTraceMonitor* tm, JSObject* globalObj /* No recorder, search for a tracked global-state (or allocate one). */ for (size_t i = 0; i < MONITOR_N_GLOBAL_STATES; ++i) { - GlobalState &state = tm->globalStates[i]; if (state.globalShape == (uint32) -1) {