Bug 923836 - Set aside the first 3 reserved slots of global objects for application use. r=Waldo.

--HG--
extra : rebase_source : 027d8ed582b276845ff49c19b867d82b058542e1
This commit is contained in:
Jason Orendorff 2013-10-14 15:24:11 -05:00
Родитель 73c2ff5b85
Коммит 807f7ead19
13 изменённых файлов: 152 добавлений и 129 удалений

Просмотреть файл

@ -558,9 +558,9 @@ struct JSClass {
//
// Implementing this efficiently requires that global objects have classes
// with the following flags. Failure to use JSCLASS_GLOBAL_FLAGS was
// prevously allowed, but is now an ES5 violation and thus unsupported.
// previously allowed, but is now an ES5 violation and thus unsupported.
//
#define JSCLASS_GLOBAL_SLOT_COUNT (JSProto_LIMIT * 3 + 26)
#define JSCLASS_GLOBAL_SLOT_COUNT (3 + JSProto_LIMIT * 3 + 26)
#define JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(n) \
(JSCLASS_IS_GLOBAL | JSCLASS_HAS_RESERVED_SLOTS(JSCLASS_GLOBAL_SLOT_COUNT + (n)))
#define JSCLASS_GLOBAL_FLAGS \

Просмотреть файл

@ -2038,7 +2038,7 @@ js_InitIntlClass(JSContext *cx, HandleObject obj)
return nullptr;
}
MarkStandardClassInitializedNoProto(global, &IntlClass);
global->markStandardClassInitializedNoProto(&IntlClass);
return Intl;
}
@ -2052,6 +2052,6 @@ GlobalObject::initIntlObject(JSContext *cx, Handle<GlobalObject*> global)
if (!Intl)
return false;
global->setReservedSlot(JSProto_Intl, ObjectValue(*Intl));
global->setConstructor(JSProto_Intl, ObjectValue(*Intl));
return true;
}

Просмотреть файл

@ -1333,7 +1333,7 @@ GlobalObject::initDataObject(JSContext *cx, Handle<GlobalObject *> global)
DataCtor, DataProto))
return false;
global->setReservedSlot(JSProto_Data, ObjectValue(*DataCtor));
global->setConstructor(JSProto_Data, ObjectValue(*DataCtor));
return true;
}
@ -1358,7 +1358,7 @@ GlobalObject::initTypeObject(JSContext *cx, Handle<GlobalObject *> global)
TypeCtor, TypeProto))
return false;
global->setReservedSlot(JSProto_Type, ObjectValue(*TypeCtor));
global->setConstructor(JSProto_Type, ObjectValue(*TypeCtor));
return true;
}
@ -1369,7 +1369,7 @@ GlobalObject::initArrayTypeObject(JSContext *cx, Handle<GlobalObject *> global)
global->createConstructor(cx, ArrayType::construct,
cx->names().ArrayType, 2));
global->setReservedSlot(JSProto_ArrayTypeObject, ObjectValue(*ctor));
global->setConstructor(JSProto_ArrayTypeObject, ObjectValue(*ctor));
return true;
}

Просмотреть файл

@ -1553,6 +1553,7 @@ JS_ResolveStandardClass(JSContext *cx, HandleObject obj, HandleId id, bool *reso
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj, id);
JS_ASSERT(obj->is<GlobalObject>());
*resolved = false;
rt = cx->runtime();
@ -1622,11 +1623,10 @@ JS_ResolveStandardClass(JSContext *cx, HandleObject obj, HandleId id, bool *reso
* If this standard class is anonymous, then we don't want to resolve
* by name.
*/
JS_ASSERT(obj->is<GlobalObject>());
if (stdnm->clasp->flags & JSCLASS_IS_ANONYMOUS)
return true;
if (IsStandardClassResolved(obj, stdnm->clasp))
if (obj->as<GlobalObject>().isStandardClassResolved(stdnm->clasp))
return true;
if (!stdnm->init(cx, obj))
@ -1642,6 +1642,7 @@ JS_EnumerateStandardClasses(JSContext *cx, HandleObject obj)
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj);
MOZ_ASSERT(obj->is<GlobalObject>());
/*
* Check whether we need to bind 'undefined' and define it if so.
@ -1659,7 +1660,7 @@ JS_EnumerateStandardClasses(JSContext *cx, HandleObject obj)
/* Initialize any classes that have not been initialized yet. */
for (unsigned i = 0; standard_class_atoms[i].init; i++) {
const JSStdName &stdnm = standard_class_atoms[i];
if (!js::IsStandardClassResolved(obj, stdnm.clasp)) {
if (!obj->as<GlobalObject>().isStandardClassResolved(stdnm.clasp)) {
if (!stdnm.init(cx, obj))
return false;
}

Просмотреть файл

@ -1949,8 +1949,8 @@ GlobalObject::initIteratorClasses(JSContext *cx, Handle<GlobalObject *> global)
return false;
global->setSlot(STAR_GENERATOR_OBJECT_PROTO, ObjectValue(*genObjectProto));
global->setSlot(JSProto_GeneratorFunction, ObjectValue(*genFunction));
global->setSlot(JSProto_GeneratorFunction + JSProto_LIMIT, ObjectValue(*genFunctionProto));
global->setConstructor(JSProto_GeneratorFunction, ObjectValue(*genFunction));
global->setPrototype(JSProto_GeneratorFunction, ObjectValue(*genFunctionProto));
}
if (global->getPrototype(JSProto_StopIteration).isUndefined()) {
@ -1962,7 +1962,7 @@ GlobalObject::initIteratorClasses(JSContext *cx, Handle<GlobalObject *> global)
if (!DefineConstructorAndPrototype(cx, global, JSProto_StopIteration, proto, proto))
return false;
MarkStandardClassInitializedNoProto(global, &StopIterationObject::class_);
global->markStandardClassInitializedNoProto(&StopIterationObject::class_);
}
return true;

Просмотреть файл

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

Просмотреть файл

@ -2186,8 +2186,9 @@ DefineStandardSlot(JSContext *cx, HandleObject obj, JSProtoKey key, JSAtom *atom
JS_ASSERT(obj->isNative());
if (!obj->nativeLookup(cx, id)) {
uint32_t slot = 2 * JSProto_LIMIT + key;
obj->setReservedSlot(slot, v);
obj->as<GlobalObject>().setConstructorPropertySlot(key, v);
uint32_t slot = GlobalObject::constructorPropertySlot(key);
if (!JSObject::addProperty(cx, obj, id, JS_PropertyStub, JS_StrictPropertyStub, slot, attrs, 0, 0))
return false;
AddTypePropertyId(cx, obj, id, v);
@ -2209,8 +2210,8 @@ SetClassObject(JSObject *obj, JSProtoKey key, JSObject *cobj, JSObject *proto)
if (!obj->is<GlobalObject>())
return;
obj->setReservedSlot(key, ObjectOrNullValue(cobj));
obj->setReservedSlot(JSProto_LIMIT + key, ObjectOrNullValue(proto));
obj->as<GlobalObject>().setConstructor(key, ObjectOrNullValue(cobj));
obj->as<GlobalObject>().setPrototype(key, ObjectOrNullValue(proto));
}
static void
@ -2220,8 +2221,8 @@ ClearClassObject(JSObject *obj, JSProtoKey key)
if (!obj->is<GlobalObject>())
return;
obj->setSlot(key, UndefinedValue());
obj->setSlot(JSProto_LIMIT + key, UndefinedValue());
obj->as<GlobalObject>().setConstructor(key, UndefinedValue());
obj->as<GlobalObject>().setPrototype(key, UndefinedValue());
}
JSObject *
@ -2361,37 +2362,6 @@ bad:
return nullptr;
}
/*
* Lazy standard classes need a way to indicate if 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().
*/
bool
js::IsStandardClassResolved(JSObject *obj, const 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());
}
void
js::MarkStandardClassInitializedNoProto(JSObject *obj, 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 (obj->getReservedSlot(key) == UndefinedValue())
obj->setSlot(key, BooleanValue(true));
}
JSObject *
js_InitClass(JSContext *cx, HandleObject obj, JSObject *protoProto_,
const Class *clasp, Native constructor, unsigned nargs,
@ -3044,13 +3014,9 @@ js::SetClassAndProto(JSContext *cx, HandleObject obj,
bool
js_GetClassObject(ExclusiveContext *cxArg, JSObject *obj, JSProtoKey key, MutableHandleObject objp)
{
RootedObject global(cxArg, &obj->global());
if (!global->is<GlobalObject>()) {
objp.set(nullptr);
return true;
}
Rooted<GlobalObject*> global(cxArg, &obj->global());
Value v = global->getReservedSlot(key);
Value v = global->getConstructor(key);
if (v.isObject()) {
objp.set(&v.toObject());
return true;
@ -3074,7 +3040,7 @@ js_GetClassObject(ExclusiveContext *cxArg, JSObject *obj, JSProtoKey key, Mutabl
if (ClassInitializerOp init = lazy_prototype_init[key]) {
if (!init(cx, global))
return false;
v = global->getReservedSlot(key);
v = global->getConstructor(key);
if (v.isObject())
cobj = &v.toObject();
}
@ -3097,8 +3063,8 @@ js_IdentifyClassPrototype(JSObject *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);
GlobalObject &global = obj->global();
Value v = global.getPrototype(key);
if (v.isObject() && obj == &v.toObject())
return key;
@ -5239,7 +5205,7 @@ js::GetClassPrototypePure(GlobalObject *global, JSProtoKey protoKey)
JS_ASSERT(protoKey < JSProto_LIMIT);
if (protoKey != JSProto_Null) {
const Value &v = global->getReservedSlot(JSProto_LIMIT + protoKey);
const Value &v = global->getPrototype(protoKey);
if (v.isObject())
return &v.toObject();
}

Просмотреть файл

@ -1251,12 +1251,6 @@ HasOwnProperty(JSContext *cx, LookupGenericOp lookup,
typename MaybeRooted<JSObject*, allowGC>::MutableHandleType objp,
typename MaybeRooted<Shape*, allowGC>::MutableHandleType propp);
bool
IsStandardClassResolved(JSObject *obj, const js::Class *clasp);
void
MarkStandardClassInitializedNoProto(JSObject *obj, const js::Class *clasp);
typedef JSObject *(*ClassInitializerOp)(JSContext *cx, JS::HandleObject obj);
} /* namespace js */

Просмотреть файл

@ -936,15 +936,15 @@ DefineConstructorAndPrototype(JSContext *cx, Handle<GlobalObject*> global,
JS_ASSERT(!global->nativeLookup(cx, id));
/* Set these first in case AddTypePropertyId looks for this class. */
global->setSlot(key, ObjectValue(*ctor));
global->setSlot(key + JSProto_LIMIT, ObjectValue(*proto));
global->setSlot(key + JSProto_LIMIT * 2, ObjectValue(*ctor));
global->setConstructor(key, ObjectValue(*ctor));
global->setPrototype(key, ObjectValue(*proto));
global->setConstructorPropertySlot(key, ObjectValue(*ctor));
types::AddTypePropertyId(cx, global, id, ObjectValue(*ctor));
if (!global->addDataProperty(cx, id, key + JSProto_LIMIT * 2, 0)) {
global->setSlot(key, UndefinedValue());
global->setSlot(key + JSProto_LIMIT, UndefinedValue());
global->setSlot(key + JSProto_LIMIT * 2, UndefinedValue());
if (!global->addDataProperty(cx, id, GlobalObject::constructorPropertySlot(key), 0)) {
global->setConstructor(key, UndefinedValue());
global->setPrototype(key, UndefinedValue());
global->setConstructorPropertySlot(key, UndefinedValue());
return false;
}

Просмотреть файл

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

Просмотреть файл

@ -3293,7 +3293,7 @@ static const JSFunctionSpec static_methods[] = {
JS_FRIEND_API(JSObject *)
js_InitProxyClass(JSContext *cx, HandleObject obj)
{
Rooted<GlobalObject*> global(cx);
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
RootedFunction ctor(cx);
ctor = global->createConstructor(cx, proxy, cx->names().Proxy, 2);
if (!ctor)
@ -3306,6 +3306,6 @@ js_InitProxyClass(JSContext *cx, HandleObject obj)
return nullptr;
}
MarkStandardClassInitializedNoProto(obj, &ProxyObject::uncallableClass_);
global->markStandardClassInitializedNoProto(&ProxyObject::uncallableClass_);
return ctor;
}

Просмотреть файл

@ -361,9 +361,9 @@ GlobalObject::initFunctionAndObjectClasses(JSContext *cx)
}
/* Add the global Function and Object properties now. */
if (!self->addDataProperty(cx, cx->names().Object, JSProto_Object + JSProto_LIMIT * 2, 0))
if (!self->addDataProperty(cx, cx->names().Object, constructorPropertySlot(JSProto_Object), 0))
return nullptr;
if (!self->addDataProperty(cx, cx->names().Function, JSProto_Function + JSProto_LIMIT * 2, 0))
if (!self->addDataProperty(cx, cx->names().Function, constructorPropertySlot(JSProto_Function), 0))
return nullptr;
/* Heavy lifting done, but lingering tasks remain. */

Просмотреть файл

@ -35,31 +35,39 @@ class Debugger;
/*
* Global object slots are reserved as follows:
*
* [0, JSProto_LIMIT)
* [0, APPLICATION_SLOTS)
* Pre-reserved slots in all global objects set aside for the embedding's
* use. As with all reserved slots these start out as UndefinedValue() and
* are traced for GC purposes. Apart from that the engine never touches
* these slots, so the embedding can do whatever it wants with them.
* [APPLICATION_SLOTS, APPLICATION_SLOTS + JSProto_LIMIT)
* Stores the original value of the constructor for the corresponding
* JSProtoKey.
* [JSProto_LIMIT, 2 * JSProto_LIMIT)
* [APPLICATION_SLOTS + JSProto_LIMIT, APPLICATION_SLOTS + 2 * JSProto_LIMIT)
* Stores the prototype, if any, for the constructor for the corresponding
* JSProtoKey offset from JSProto_LIMIT.
* [2 * JSProto_LIMIT, 3 * JSProto_LIMIT)
* [APPLICATION_SLOTS + 2 * JSProto_LIMIT, APPLICATION_SLOTS + 3 * JSProto_LIMIT)
* Stores the current value of the global property named for the JSProtoKey
* for the corresponding JSProtoKey offset from 2 * JSProto_LIMIT.
* [3 * JSProto_LIMIT, RESERVED_SLOTS)
* [APPLICATION_SLOTS + 3 * JSProto_LIMIT, RESERVED_SLOTS)
* Various one-off values: ES5 13.2.3's [[ThrowTypeError]], RegExp statics,
* the original eval for this global object (implementing |var eval =
* otherWindow.eval; eval(...)| as an indirect eval), a bit indicating
* whether this object has been cleared (see JS_ClearScope), and a cache for
* whether eval is allowed (per the global's Content Security Policy).
*
* The first two ranges are necessary to implement js::FindClassObject,
* and spec language speaking in terms of "the original Array prototype
* object", or "as if by the expression new Array()" referring to the original
* Array constructor. The third range stores the (writable and even deletable)
* Object, Array, &c. properties (although a slot won't be used again if its
* property is deleted and readded).
* The first two JSProto_LIMIT-sized ranges are necessary to implement
* js::FindClassObject, and spec language speaking in terms of "the original
* Array prototype object", or "as if by the expression new Array()" referring
* to the original Array constructor. The third range stores the (writable and
* even deletable) Object, Array, &c. properties (although a slot won't be used
* again if its property is deleted and readded).
*/
class GlobalObject : public JSObject
{
/* Count of slots set aside for application use. */
static const unsigned APPLICATION_SLOTS = 3;
/*
* Count of slots to store built-in constructors, prototypes, and initial
* visible properties for the constructors.
@ -67,7 +75,7 @@ class GlobalObject : public JSObject
static const unsigned STANDARD_CLASS_SLOTS = JSProto_LIMIT * 3;
/* Various function values needed by the engine. */
static const unsigned EVAL = STANDARD_CLASS_SLOTS;
static const unsigned EVAL = APPLICATION_SLOTS + STANDARD_CLASS_SLOTS;
static const unsigned CREATE_DATAVIEW_FOR_THIS = EVAL + 1;
static const unsigned THROWTYPEERROR = CREATE_DATAVIEW_FOR_THIS + 1;
static const unsigned PROTO_GETTER = THROWTYPEERROR + 1;
@ -122,23 +130,6 @@ class GlobalObject : public JSObject
JSObject *
initFunctionAndObjectClasses(JSContext *cx);
void setDetailsForKey(JSProtoKey key, JSObject *ctor, JSObject *proto) {
JS_ASSERT(getSlotRef(key).isUndefined());
JS_ASSERT(getSlotRef(JSProto_LIMIT + key).isUndefined());
JS_ASSERT(getSlotRef(2 * JSProto_LIMIT + key).isUndefined());
setSlot(key, ObjectValue(*ctor));
setSlot(JSProto_LIMIT + key, ObjectValue(*proto));
setSlot(2 * JSProto_LIMIT + key, ObjectValue(*ctor));
}
void setObjectClassDetails(JSFunction *ctor, JSObject *proto) {
setDetailsForKey(JSProto_Object, ctor, proto);
}
void setFunctionClassDetails(JSFunction *ctor, JSObject *proto) {
setDetailsForKey(JSProto_Function, ctor, proto);
}
void setThrowTypeError(JSFunction *fun) {
JS_ASSERT(getSlotRef(THROWTYPEERROR).isUndefined());
setSlot(THROWTYPEERROR, ObjectValue(*fun));
@ -159,14 +150,38 @@ class GlobalObject : public JSObject
setSlot(INTRINSICS, ObjectValue(*obj));
}
public:
Value getConstructor(JSProtoKey key) const {
JS_ASSERT(key <= JSProto_LIMIT);
return getSlot(key);
return getSlot(APPLICATION_SLOTS + key);
}
void setConstructor(JSProtoKey key, const Value &v) {
JS_ASSERT(key <= JSProto_LIMIT);
setSlot(APPLICATION_SLOTS + key, v);
}
Value getPrototype(JSProtoKey key) const {
JS_ASSERT(key <= JSProto_LIMIT);
return getSlot(JSProto_LIMIT + key);
return getSlot(APPLICATION_SLOTS + JSProto_LIMIT + key);
}
void setPrototype(JSProtoKey key, const Value &value) {
JS_ASSERT(key <= JSProto_LIMIT);
setSlot(APPLICATION_SLOTS + JSProto_LIMIT + key, value);
}
static uint32_t constructorPropertySlot(JSProtoKey key) {
JS_ASSERT(key <= JSProto_LIMIT);
return APPLICATION_SLOTS + JSProto_LIMIT * 2 + key;
}
Value getConstructorPropertySlot(JSProtoKey key) {
return getSlot(constructorPropertySlot(key));
}
void setConstructorPropertySlot(JSProtoKey key, const Value &ctor) {
setSlot(constructorPropertySlot(key), ctor);
}
bool classIsInitialized(JSProtoKey key) const {
@ -181,6 +196,50 @@ class GlobalObject : public JSObject
return inited;
}
/*
* 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().
*/
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.
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());
JS_ASSERT(getPrototype(key).isUndefined());
JS_ASSERT(getConstructorPropertySlot(key).isUndefined());
setConstructor(key, ObjectValue(*ctor));
setPrototype(key, ObjectValue(*proto));
setConstructorPropertySlot(key, ObjectValue(*ctor));
}
void setObjectClassDetails(JSFunction *ctor, JSObject *proto) {
setDetailsForKey(JSProto_Object, ctor, proto);
}
void setFunctionClassDetails(JSFunction *ctor, JSObject *proto) {
setDetailsForKey(JSProto_Function, ctor, proto);
}
bool arrayClassInitialized() const {
return classIsInitialized(JSProto_Array);
}
@ -349,7 +408,24 @@ class GlobalObject : public JSObject
}
JSObject *getOrCreateIntlObject(JSContext *cx) {
return getOrCreateObject(cx, JSProto_Intl, initIntlObject);
return getOrCreateObject(cx, APPLICATION_SLOTS + JSProto_Intl, initIntlObject);
}
JSObject *getIteratorPrototype() {
return &getPrototype(JSProto_Iterator).toObject();
}
JSObject *getOrCreateDataObject(JSContext *cx) {
return getOrCreateObject(cx, APPLICATION_SLOTS + JSProto_Data, initDataObject);
}
JSObject *getOrCreateTypeObject(JSContext *cx) {
return getOrCreateObject(cx, APPLICATION_SLOTS + JSProto_Type, initTypeObject);
}
JSObject *getOrCreateArrayTypeObject(JSContext *cx) {
return getOrCreateObject(cx, APPLICATION_SLOTS + JSProto_ArrayTypeObject,
initArrayTypeObject);
}
JSObject *getOrCreateCollatorPrototype(JSContext *cx) {
@ -364,22 +440,6 @@ class GlobalObject : public JSObject
return getOrCreateObject(cx, DATE_TIME_FORMAT_PROTO, initDateTimeFormatProto);
}
JSObject *getIteratorPrototype() {
return &getPrototype(JSProto_Iterator).toObject();
}
JSObject *getOrCreateDataObject(JSContext *cx) {
return getOrCreateObject(cx, JSProto_Data, initDataObject);
}
JSObject *getOrCreateTypeObject(JSContext *cx) {
return getOrCreateObject(cx, JSProto_Type, initTypeObject);
}
JSObject *getOrCreateArrayTypeObject(JSContext *cx) {
return getOrCreateObject(cx, JSProto_ArrayTypeObject, initArrayTypeObject);
}
private:
typedef bool (*ObjectInitOp)(JSContext *cx, Handle<GlobalObject*> global);
@ -395,7 +455,8 @@ class GlobalObject : public JSObject
public:
JSObject *getOrCreateIteratorPrototype(JSContext *cx) {
return getOrCreateObject(cx, JSProto_LIMIT + JSProto_Iterator, initIteratorClasses);
return getOrCreateObject(cx, APPLICATION_SLOTS + JSProto_LIMIT + JSProto_Iterator,
initIteratorClasses);
}
JSObject *getOrCreateElementIteratorPrototype(JSContext *cx) {
@ -411,12 +472,13 @@ class GlobalObject : public JSObject
}
JSObject *getOrCreateStarGeneratorFunctionPrototype(JSContext *cx) {
return getOrCreateObject(cx, JSProto_LIMIT + JSProto_GeneratorFunction,
return getOrCreateObject(cx, APPLICATION_SLOTS + JSProto_LIMIT + JSProto_GeneratorFunction,
initIteratorClasses);
}
JSObject *getOrCreateStarGeneratorFunction(JSContext *cx) {
return getOrCreateObject(cx, JSProto_GeneratorFunction, initIteratorClasses);
return getOrCreateObject(cx, APPLICATION_SLOTS + JSProto_GeneratorFunction,
initIteratorClasses);
}
JSObject *getOrCreateMapIteratorPrototype(JSContext *cx) {