mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Remove JSObject::privateData, bug 693479.
This commit is contained in:
parent
f5a853bac0
commit
e9b876258d
@ -52,7 +52,6 @@ bool checkObjectFields(JSObject *savedCopy, JSObject *obj)
|
||||
CHECK(savedCopy->flags == obj->flags);
|
||||
CHECK(savedCopy->getProto() == obj->getProto());
|
||||
CHECK(savedCopy->parent == obj->parent);
|
||||
CHECK(savedCopy->privateData == obj->privateData);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1259,7 +1259,6 @@ Class js::ArrayClass = {
|
||||
|
||||
Class js::SlowArrayClass = {
|
||||
"Array",
|
||||
JSCLASS_HAS_PRIVATE |
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Array),
|
||||
slowarray_addProperty,
|
||||
JS_PropertyStub, /* delProperty */
|
||||
|
@ -191,19 +191,20 @@ struct Object {
|
||||
TypeObject *type;
|
||||
uint32 flags;
|
||||
JSObject *parent;
|
||||
void *privateData;
|
||||
js::Value *slots;
|
||||
js::Value *_1;
|
||||
#if JS_BITS_PER_WORD == 32
|
||||
js::Value *_2;
|
||||
#endif
|
||||
|
||||
static const uint32 FIXED_SLOTS_SHIFT = 27;
|
||||
|
||||
size_t numFixedSlots() const { return flags >> FIXED_SLOTS_SHIFT; }
|
||||
Value *fixedSlots() const {
|
||||
return (Value *)((jsuword) this + sizeof(shadow::Object));
|
||||
}
|
||||
|
||||
js::Value &slotRef(size_t slot) const {
|
||||
size_t nfixed = flags >> FIXED_SLOTS_SHIFT;
|
||||
size_t nfixed = numFixedSlots();
|
||||
if (slot < nfixed)
|
||||
return ((Value *)((jsuword) this + sizeof(shadow::Object)))[slot];
|
||||
return fixedSlots()[slot];
|
||||
return slots[slot - nfixed];
|
||||
}
|
||||
};
|
||||
@ -250,7 +251,9 @@ GetObjectProto(const JSObject *obj)
|
||||
inline void *
|
||||
GetObjectPrivate(const JSObject *obj)
|
||||
{
|
||||
return reinterpret_cast<const shadow::Object*>(obj)->privateData;
|
||||
const shadow::Object *nobj = reinterpret_cast<const shadow::Object*>(obj);
|
||||
void **addr = reinterpret_cast<void**>(&nobj->fixedSlots()[nobj->numFixedSlots()]);
|
||||
return *addr;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -199,7 +199,7 @@ ArgumentsObject::create(JSContext *cx, uint32 argc, JSObject &callee)
|
||||
|
||||
JS_STATIC_ASSERT(NormalArgumentsObject::RESERVED_SLOTS == 2);
|
||||
JS_STATIC_ASSERT(StrictArgumentsObject::RESERVED_SLOTS == 2);
|
||||
JSObject *obj = js_NewGCObject(cx, FINALIZE_OBJECT2);
|
||||
JSObject *obj = js_NewGCObject(cx, FINALIZE_OBJECT4);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
@ -215,7 +215,7 @@ ArgumentsObject::create(JSContext *cx, uint32 argc, JSObject &callee)
|
||||
SetValueRangeToUndefined(data->slots, argc);
|
||||
|
||||
/* Can't fail from here on, so initialize everything in argsobj. */
|
||||
obj->init(cx, type, proto->getParent(), NULL, false);
|
||||
obj->init(cx, type, proto->getParent(), false);
|
||||
obj->setInitialPropertyInfallible(emptyArgumentsShape);
|
||||
|
||||
ArgumentsObject *argsobj = obj->asArguments();
|
||||
@ -225,6 +225,9 @@ ArgumentsObject::create(JSContext *cx, uint32 argc, JSObject &callee)
|
||||
|
||||
argsobj->setCalleeAndData(callee, data);
|
||||
|
||||
JS_ASSERT(argsobj->numFixedSlots() == NormalArgumentsObject::NFIXED_SLOTS);
|
||||
JS_ASSERT(argsobj->numFixedSlots() == StrictArgumentsObject::NFIXED_SLOTS);
|
||||
|
||||
return argsobj;
|
||||
}
|
||||
|
||||
@ -768,8 +771,9 @@ NewDeclEnvObject(JSContext *cx, StackFrame *fp)
|
||||
EmptyShape *emptyDeclEnvShape = EmptyShape::getEmptyDeclEnvShape(cx);
|
||||
if (!emptyDeclEnvShape)
|
||||
return NULL;
|
||||
envobj->init(cx, type, &fp->scopeChain(), fp, false);
|
||||
envobj->init(cx, type, &fp->scopeChain(), false);
|
||||
envobj->setInitialPropertyInfallible(emptyDeclEnvShape);
|
||||
envobj->setPrivate(fp);
|
||||
|
||||
return envobj;
|
||||
}
|
||||
|
@ -100,7 +100,7 @@
|
||||
#define JSFUN_KINDMASK 0xc000 /* encode interp vs. native and closure
|
||||
optimization level -- see above */
|
||||
|
||||
struct JSFunction : public JSObject_Slots2
|
||||
struct JSFunction : public JSObject_Slots4
|
||||
{
|
||||
/* Functions always have two fixed slots (FUN_CLASS_RESERVED_SLOTS). */
|
||||
|
||||
|
@ -77,6 +77,15 @@ GetGCObjectKind(size_t numSlots)
|
||||
return slotsToThingKind[numSlots];
|
||||
}
|
||||
|
||||
static inline AllocKind
|
||||
GetGCObjectKind(Class *clasp)
|
||||
{
|
||||
uint32 nslots = JSCLASS_RESERVED_SLOTS(clasp);
|
||||
if (clasp->flags & JSCLASS_HAS_PRIVATE)
|
||||
nslots++;
|
||||
return GetGCObjectKind(nslots);
|
||||
}
|
||||
|
||||
/* As for GetGCObjectKind, but for dense array allocation. */
|
||||
static inline AllocKind
|
||||
GetGCArrayKind(size_t numSlots)
|
||||
@ -400,7 +409,7 @@ js_NewGCFunction(JSContext *cx)
|
||||
{
|
||||
JSFunction *fun = NewGCThing<JSFunction>(cx, js::gc::FINALIZE_FUNCTION, sizeof(JSFunction));
|
||||
if (fun)
|
||||
fun->earlyInit(JSObject::FUN_CLASS_RESERVED_SLOTS);
|
||||
fun->earlyInit(JSObject::FUN_CLASS_NFIXED_SLOTS + 1); /* Add one for private data. */
|
||||
|
||||
return fun;
|
||||
}
|
||||
|
@ -405,7 +405,7 @@ NewIteratorObject(JSContext *cx, uintN flags)
|
||||
* helper objects) expect it to have a non-null map pointer, so we
|
||||
* share an empty Enumerator scope in the runtime.
|
||||
*/
|
||||
JSObject *obj = js_NewGCObject(cx, FINALIZE_OBJECT0);
|
||||
JSObject *obj = js_NewGCObject(cx, FINALIZE_OBJECT2);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
@ -417,8 +417,10 @@ NewIteratorObject(JSContext *cx, uintN flags)
|
||||
if (!emptyEnumeratorShape)
|
||||
return NULL;
|
||||
|
||||
obj->init(cx, type, NULL, NULL, false);
|
||||
obj->init(cx, type, NULL, false);
|
||||
obj->setInitialPropertyInfallible(emptyEnumeratorShape);
|
||||
|
||||
JS_ASSERT(obj->numFixedSlots() == JSObject::ITER_CLASS_NFIXED_SLOTS);
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
@ -3464,13 +3464,13 @@ js_NewWithObject(JSContext *cx, JSObject *proto, JSObject *parent, jsint depth)
|
||||
if (!type)
|
||||
return NULL;
|
||||
|
||||
obj = js_NewGCObject(cx, FINALIZE_OBJECT2);
|
||||
obj = js_NewGCObject(cx, FINALIZE_OBJECT4);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
StackFrame *priv = js_FloatingFrameIfGenerator(cx, cx->fp());
|
||||
|
||||
obj->init(cx, type, parent, priv, false);
|
||||
obj->init(cx, type, parent, false);
|
||||
|
||||
EmptyShape *emptyWithShape = EmptyShape::getEmptyWithShape(cx);
|
||||
if (!emptyWithShape)
|
||||
@ -3479,6 +3479,8 @@ js_NewWithObject(JSContext *cx, JSObject *proto, JSObject *parent, jsint depth)
|
||||
obj->setInitialPropertyInfallible(emptyWithShape);
|
||||
OBJ_SET_BLOCK_DEPTH(cx, obj, depth);
|
||||
|
||||
obj->setPrivate(priv);
|
||||
|
||||
AutoObjectRooter tvr(cx, obj);
|
||||
JSObject *thisp = proto->thisObject(cx);
|
||||
if (!thisp)
|
||||
@ -3509,7 +3511,7 @@ js_NewBlockObject(JSContext *cx)
|
||||
if (!emptyBlockShape)
|
||||
return NULL;
|
||||
|
||||
blockObj->init(cx, type, NULL, NULL, false);
|
||||
blockObj->init(cx, type, NULL, false);
|
||||
blockObj->setInitialPropertyInfallible(emptyBlockShape);
|
||||
|
||||
return blockObj;
|
||||
@ -3757,7 +3759,7 @@ JS_CloneObject(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (obj->getClass()->flags & JSCLASS_HAS_PRIVATE)
|
||||
if (obj->hasPrivate())
|
||||
clone->setPrivate(obj->getPrivate());
|
||||
} else {
|
||||
JS_ASSERT(obj->isProxy());
|
||||
@ -3772,11 +3774,15 @@ struct JSObject::TradeGutsReserved {
|
||||
JSContext *cx;
|
||||
Vector<Value> avals;
|
||||
Vector<Value> bvals;
|
||||
uint32 newafixed;
|
||||
uint32 newbfixed;
|
||||
Value *newaslots;
|
||||
Value *newbslots;
|
||||
|
||||
TradeGutsReserved(JSContext *cx)
|
||||
: cx(cx), avals(cx), bvals(cx), newaslots(NULL), newbslots(NULL)
|
||||
: cx(cx), avals(cx), bvals(cx),
|
||||
newafixed(0), newbfixed(0),
|
||||
newaslots(NULL), newbslots(NULL)
|
||||
{}
|
||||
|
||||
~TradeGutsReserved()
|
||||
@ -3798,7 +3804,7 @@ JSObject::ReserveForTradeGuts(JSContext *cx, JSObject *a, JSObject *b,
|
||||
* swaps can be performed infallibly.
|
||||
*/
|
||||
|
||||
if (a->structSize() == b->structSize())
|
||||
if (a->structSize() == b->structSize() && a->hasPrivate() == b->hasPrivate())
|
||||
return true;
|
||||
|
||||
/*
|
||||
@ -3821,17 +3827,32 @@ JSObject::ReserveForTradeGuts(JSContext *cx, JSObject *a, JSObject *b,
|
||||
JS_ASSERT(a->elements == emptyObjectElements);
|
||||
JS_ASSERT(b->elements == emptyObjectElements);
|
||||
|
||||
/*
|
||||
* The newafixed/newbfixed hold the number of fixed slots in the objects
|
||||
* after the swap. Adjust these counts according to whether the objects
|
||||
* use their last fixed slot for storing private data.
|
||||
*/
|
||||
|
||||
reserved.newafixed = a->numFixedSlots();
|
||||
reserved.newbfixed = b->numFixedSlots();
|
||||
|
||||
if (a->hasPrivate()) {
|
||||
reserved.newafixed++;
|
||||
reserved.newbfixed--;
|
||||
}
|
||||
if (b->hasPrivate()) {
|
||||
reserved.newbfixed++;
|
||||
reserved.newafixed--;
|
||||
}
|
||||
|
||||
/*
|
||||
* The newaslots/newbslots arrays hold any dynamic slots for the objects
|
||||
* if they do not have enough fixed slots to accomodate the slots in the
|
||||
* other object.
|
||||
*/
|
||||
|
||||
unsigned afixed = a->numFixedSlots();
|
||||
unsigned bfixed = b->numFixedSlots();
|
||||
|
||||
unsigned adynamic = dynamicSlotsCount(afixed, b->slotSpan());
|
||||
unsigned bdynamic = dynamicSlotsCount(bfixed, a->slotSpan());
|
||||
unsigned adynamic = dynamicSlotsCount(reserved.newafixed, b->slotSpan());
|
||||
unsigned bdynamic = dynamicSlotsCount(reserved.newbfixed, a->slotSpan());
|
||||
|
||||
if (adynamic) {
|
||||
reserved.newaslots = (Value *) cx->malloc_(sizeof(Value) * adynamic);
|
||||
@ -3880,7 +3901,7 @@ JSObject::TradeGuts(JSContext *cx, JSObject *a, JSObject *b, TradeGutsReserved &
|
||||
|
||||
/* Trade the guts of the objects. */
|
||||
const size_t size = a->structSize();
|
||||
if (size == b->structSize()) {
|
||||
if (size == b->structSize() && a->hasPrivate() == b->hasPrivate()) {
|
||||
/*
|
||||
* If the objects are the same size, then we make no assumptions about
|
||||
* whether they have dynamically allocated slots and instead just copy
|
||||
@ -3914,21 +3935,25 @@ JSObject::TradeGuts(JSContext *cx, JSObject *a, JSObject *b, TradeGutsReserved &
|
||||
if (b->hasDynamicSlots())
|
||||
cx->free_(b->slots);
|
||||
|
||||
unsigned afixed = a->numFixedSlots();
|
||||
unsigned bfixed = b->numFixedSlots();
|
||||
void *apriv = a->hasPrivate() ? a->getPrivate() : NULL;
|
||||
void *bpriv = b->hasPrivate() ? b->getPrivate() : NULL;
|
||||
|
||||
JSObject tmp;
|
||||
memcpy(&tmp, a, sizeof tmp);
|
||||
memcpy(a, b, sizeof tmp);
|
||||
memcpy(b, &tmp, sizeof tmp);
|
||||
|
||||
a->updateFixedSlots(afixed);
|
||||
a->updateFixedSlots(reserved.newafixed);
|
||||
a->slots = reserved.newaslots;
|
||||
a->copySlotRange(0, reserved.bvals.begin(), bcap);
|
||||
if (a->hasPrivate())
|
||||
a->setPrivate(bpriv);
|
||||
|
||||
b->updateFixedSlots(bfixed);
|
||||
b->updateFixedSlots(reserved.newbfixed);
|
||||
b->slots = reserved.newbslots;
|
||||
b->copySlotRange(0, reserved.avals.begin(), acap);
|
||||
if (b->hasPrivate())
|
||||
b->setPrivate(apriv);
|
||||
|
||||
/* Make sure the destructor for reserved doesn't free the slots. */
|
||||
reserved.newaslots = NULL;
|
||||
@ -4495,6 +4520,19 @@ JSObject::updateSlotsForSpan(size_t oldSpan, size_t newSpan)
|
||||
invalidateSlotRange(newSpan, oldSpan - newSpan);
|
||||
}
|
||||
|
||||
inline void
|
||||
JSObject::initializePrivate()
|
||||
{
|
||||
size_t nfixed = numFixedSlots();
|
||||
JS_ASSERT(nfixed != 0);
|
||||
|
||||
/* Remove a fixed slot, to make room for the private data. */
|
||||
flags = flags ^ (nfixed << FIXED_SLOTS_SHIFT);
|
||||
flags |= (nfixed - 1) << FIXED_SLOTS_SHIFT;
|
||||
|
||||
setPrivate(NULL);
|
||||
}
|
||||
|
||||
bool
|
||||
JSObject::setInitialProperty(JSContext *cx, const js::Shape *shape)
|
||||
{
|
||||
@ -4502,6 +4540,9 @@ JSObject::setInitialProperty(JSContext *cx, const js::Shape *shape)
|
||||
JS_ASSERT(shape->compartment() == compartment());
|
||||
JS_ASSERT(!shape->inDictionary());
|
||||
|
||||
if (shape->getClass()->flags & JSCLASS_HAS_PRIVATE)
|
||||
initializePrivate();
|
||||
|
||||
size_t span = shape->slotSpan();
|
||||
|
||||
if (!span) {
|
||||
@ -4524,6 +4565,10 @@ JSObject::setInitialPropertyInfallible(const js::Shape *shape)
|
||||
JS_ASSERT(isNewborn());
|
||||
JS_ASSERT(shape->compartment() == compartment());
|
||||
JS_ASSERT(!shape->inDictionary());
|
||||
|
||||
if (shape->getClass()->flags & JSCLASS_HAS_PRIVATE)
|
||||
initializePrivate();
|
||||
|
||||
JS_ASSERT(dynamicSlotsCount(numFixedSlots(), shape->slotSpan()) == 0);
|
||||
|
||||
shape_ = const_cast<js::Shape *>(shape);
|
||||
|
@ -544,18 +544,12 @@ struct JSObject : js::gc::Cell
|
||||
};
|
||||
|
||||
uint32 flags; /* flags */
|
||||
|
||||
JSObject *parent; /* object's parent */
|
||||
void *privateData; /* private data */
|
||||
|
||||
private:
|
||||
js::Value *slots; /* Slots for object properties. */
|
||||
js::Value *elements; /* Slots for object elements. */
|
||||
|
||||
#if JS_BITS_PER_WORD == 32
|
||||
void *padding;
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
inline bool isNative() const;
|
||||
@ -668,6 +662,8 @@ struct JSObject : js::gc::Cell
|
||||
|
||||
inline size_t numFixedSlots() const;
|
||||
|
||||
static const uint32 MAX_FIXED_SLOTS = 16;
|
||||
|
||||
private:
|
||||
inline js::Value* fixedSlots() const;
|
||||
public:
|
||||
@ -685,6 +681,7 @@ struct JSObject : js::gc::Cell
|
||||
|
||||
/* JIT Accessors */
|
||||
static inline size_t getFixedSlotOffset(size_t slot);
|
||||
static inline size_t getPrivateDataOffset(size_t nfixed);
|
||||
static inline size_t offsetOfSlots() { return offsetof(JSObject, slots); }
|
||||
|
||||
/* Minimum size for dynamically allocated slots. */
|
||||
@ -891,7 +888,9 @@ struct JSObject : js::gc::Cell
|
||||
inline bool isGlobal() const;
|
||||
inline js::GlobalObject *asGlobal();
|
||||
|
||||
inline bool hasPrivate() const;
|
||||
inline void *getPrivate() const;
|
||||
inline void *getPrivate(size_t nfixed) const;
|
||||
inline void setPrivate(void *data);
|
||||
|
||||
/* N.B. Infallible: NULL means 'no principal', not an error. */
|
||||
@ -914,6 +913,9 @@ struct JSObject : js::gc::Cell
|
||||
|
||||
bool isSealedOrFrozen(JSContext *cx, ImmutabilityType it, bool *resultp);
|
||||
|
||||
inline void *&privateAddress(uint32 nfixed) const;
|
||||
inline void initializePrivate();
|
||||
|
||||
public:
|
||||
bool isExtensible() const { return !(flags & NOT_EXTENSIBLE); }
|
||||
bool preventExtensions(JSContext *cx, js::AutoIdVector *props);
|
||||
@ -1095,6 +1097,7 @@ struct JSObject : js::gc::Cell
|
||||
|
||||
public:
|
||||
static const uint32 FUN_CLASS_RESERVED_SLOTS = 2;
|
||||
static const uint32 FUN_CLASS_NFIXED_SLOTS = 3;
|
||||
|
||||
static size_t getFlatClosureUpvarsOffset() {
|
||||
return getFixedSlotOffset(JSSLOT_FLAT_CLOSURE_UPVARS);
|
||||
@ -1161,6 +1164,8 @@ struct JSObject : js::gc::Cell
|
||||
* Iterator-specific getters and setters.
|
||||
*/
|
||||
|
||||
static const uint32 ITER_CLASS_NFIXED_SLOTS = 1;
|
||||
|
||||
inline js::NativeIterator *getNativeIterator() const;
|
||||
inline void setNativeIterator(js::NativeIterator *);
|
||||
|
||||
@ -1236,7 +1241,7 @@ struct JSObject : js::gc::Cell
|
||||
|
||||
/* The last property is not initialized here and should be set separately. */
|
||||
void init(JSContext *cx, js::types::TypeObject *type,
|
||||
JSObject *parent, void *priv, bool denseArray);
|
||||
JSObject *parent, bool denseArray);
|
||||
|
||||
inline void finish(JSContext *cx);
|
||||
JS_ALWAYS_INLINE void finalize(JSContext *cx, bool background);
|
||||
@ -1433,7 +1438,6 @@ struct JSObject : js::gc::Cell
|
||||
JS_STATIC_ASSERT(offsetof(JSObject, shape_) == offsetof(js::shadow::Object, shape));
|
||||
JS_STATIC_ASSERT(offsetof(JSObject, flags) == offsetof(js::shadow::Object, flags));
|
||||
JS_STATIC_ASSERT(offsetof(JSObject, parent) == offsetof(js::shadow::Object, parent));
|
||||
JS_STATIC_ASSERT(offsetof(JSObject, privateData) == offsetof(js::shadow::Object, privateData));
|
||||
JS_STATIC_ASSERT(offsetof(JSObject, slots) == offsetof(js::shadow::Object, slots));
|
||||
JS_STATIC_ASSERT(offsetof(JSObject, type_) == offsetof(js::shadow::Object, type));
|
||||
JS_STATIC_ASSERT(sizeof(JSObject) == sizeof(js::shadow::Object));
|
||||
@ -1474,6 +1478,11 @@ JSObject::getFixedSlotOffset(size_t slot) {
|
||||
return sizeof(JSObject) + (slot * sizeof(js::Value));
|
||||
}
|
||||
|
||||
/* static */ inline size_t
|
||||
JSObject::getPrivateDataOffset(size_t nfixed) {
|
||||
return getFixedSlotOffset(nfixed);
|
||||
}
|
||||
|
||||
struct JSObject_Slots2 : JSObject { js::Value fslots[2]; };
|
||||
struct JSObject_Slots4 : JSObject { js::Value fslots[4]; };
|
||||
struct JSObject_Slots8 : JSObject { js::Value fslots[8]; };
|
||||
|
@ -93,25 +93,43 @@ JSObject::asGlobal()
|
||||
return reinterpret_cast<js::GlobalObject *>(this);
|
||||
}
|
||||
|
||||
inline void *
|
||||
JSObject::getPrivate() const
|
||||
inline bool
|
||||
JSObject::hasPrivate() const
|
||||
{
|
||||
JS_ASSERT(getClass()->flags & JSCLASS_HAS_PRIVATE);
|
||||
return privateData;
|
||||
return getClass()->flags & JSCLASS_HAS_PRIVATE;
|
||||
}
|
||||
|
||||
inline void *&
|
||||
JSObject::privateAddress(uint32 nfixed) const
|
||||
{
|
||||
/*
|
||||
* The private pointer of an object can hold any word sized value.
|
||||
* Private pointers are stored immediately after the last fixed slot of
|
||||
* the object.
|
||||
*/
|
||||
JS_ASSERT(nfixed == numFixedSlots());
|
||||
JS_ASSERT_IF(!isNewborn(), hasPrivate());
|
||||
js::Value *end = &fixedSlots()[nfixed];
|
||||
return *reinterpret_cast<void**>(end);
|
||||
}
|
||||
|
||||
inline void *
|
||||
JSObject::getPrivate() const { return privateAddress(numFixedSlots()); }
|
||||
|
||||
inline void *
|
||||
JSObject::getPrivate(size_t nfixed) const { return privateAddress(nfixed); }
|
||||
|
||||
inline JSFunction *
|
||||
JSObject::getFunctionPrivate() const
|
||||
{
|
||||
JS_ASSERT(isFunction());
|
||||
return reinterpret_cast<JSFunction *>(getPrivate());
|
||||
return reinterpret_cast<JSFunction *>(getPrivate(FUN_CLASS_NFIXED_SLOTS));
|
||||
}
|
||||
|
||||
inline void
|
||||
JSObject::setPrivate(void *data)
|
||||
{
|
||||
JS_ASSERT(getClass()->flags & JSCLASS_HAS_PRIVATE);
|
||||
privateData = data;
|
||||
privateAddress(numFixedSlots()) = data;
|
||||
}
|
||||
|
||||
inline bool
|
||||
@ -315,7 +333,7 @@ JSObject::initCall(JSContext *cx, const js::Bindings &bindings, JSObject *parent
|
||||
if (!type)
|
||||
return false;
|
||||
|
||||
init(cx, type, parent, NULL, false);
|
||||
init(cx, type, parent, false);
|
||||
if (!setInitialProperty(cx, bindings.lastShape()))
|
||||
return false;
|
||||
|
||||
@ -338,11 +356,13 @@ JSObject::initCall(JSContext *cx, const js::Bindings &bindings, JSObject *parent
|
||||
inline bool
|
||||
JSObject::initClonedBlock(JSContext *cx, js::types::TypeObject *type, js::StackFrame *frame)
|
||||
{
|
||||
init(cx, type, NULL, frame, false);
|
||||
init(cx, type, NULL, false);
|
||||
|
||||
if (!setInitialProperty(cx, getProto()->lastProperty()))
|
||||
return false;
|
||||
|
||||
setPrivate(frame);
|
||||
|
||||
JS_ASSERT(!inDictionaryMode());
|
||||
JS_ASSERT(isClonedBlock());
|
||||
|
||||
@ -929,10 +949,8 @@ JSObject::isQName() const
|
||||
|
||||
inline void
|
||||
JSObject::init(JSContext *cx, js::types::TypeObject *type,
|
||||
JSObject *parent, void *priv, bool denseArray)
|
||||
JSObject *parent, bool denseArray)
|
||||
{
|
||||
privateData = priv;
|
||||
|
||||
JS_STATIC_ASSERT(sizeof(js::ObjectElements) == 2 * sizeof(js::Value));
|
||||
|
||||
uint32 numSlots = numFixedSlots();
|
||||
@ -948,7 +966,6 @@ JSObject::init(JSContext *cx, js::types::TypeObject *type,
|
||||
new (getElementsHeader()) js::ObjectElements(numSlots - 2);
|
||||
} else {
|
||||
elements = js::emptyObjectElements;
|
||||
js::ClearValueRange(fixedSlots(), numSlots);
|
||||
}
|
||||
|
||||
setType(type);
|
||||
@ -972,7 +989,7 @@ JSObject::initSharingEmptyShape(JSContext *cx,
|
||||
void *privateValue,
|
||||
js::gc::AllocKind kind)
|
||||
{
|
||||
init(cx, type, parent, privateValue, false);
|
||||
init(cx, type, parent, false);
|
||||
|
||||
js::EmptyShape *empty = type->getEmptyShape(cx, aclasp, kind);
|
||||
if (!empty)
|
||||
@ -981,6 +998,9 @@ JSObject::initSharingEmptyShape(JSContext *cx,
|
||||
if (!setInitialProperty(cx, empty))
|
||||
return false;
|
||||
|
||||
if (privateValue)
|
||||
setPrivate(privateValue);
|
||||
|
||||
JS_ASSERT(!isDenseArray());
|
||||
return true;
|
||||
}
|
||||
@ -1132,9 +1152,10 @@ JSObject::hasPropertyTable() const
|
||||
inline size_t
|
||||
JSObject::structSize() const
|
||||
{
|
||||
return (isFunction() && !getPrivate())
|
||||
? sizeof(JSFunction)
|
||||
: (sizeof(JSObject) + sizeof(js::Value) * numFixedSlots());
|
||||
if (isFunction() && !getFunctionPrivate())
|
||||
return sizeof(JSFunction);
|
||||
uint32 nfixed = numFixedSlots() + (hasPrivate() ? 1 : 0);
|
||||
return sizeof(JSObject) + (nfixed * sizeof(js::Value));
|
||||
}
|
||||
|
||||
inline size_t
|
||||
@ -1424,7 +1445,7 @@ NewNativeClassInstance(JSContext *cx, Class *clasp, JSObject *proto,
|
||||
* the parent of the prototype's constructor.
|
||||
*/
|
||||
bool denseArray = (clasp == &ArrayClass);
|
||||
obj->init(cx, type, parent, NULL, denseArray);
|
||||
obj->init(cx, type, parent, denseArray);
|
||||
|
||||
JS_ASSERT(type->canProvideEmptyShape(clasp));
|
||||
js::EmptyShape *empty = type->getEmptyShape(cx, clasp, kind);
|
||||
@ -1437,7 +1458,7 @@ NewNativeClassInstance(JSContext *cx, Class *clasp, JSObject *proto,
|
||||
static inline JSObject *
|
||||
NewNativeClassInstance(JSContext *cx, Class *clasp, JSObject *proto, JSObject *parent)
|
||||
{
|
||||
gc::AllocKind kind = gc::GetGCObjectKind(JSCLASS_RESERVED_SLOTS(clasp));
|
||||
gc::AllocKind kind = gc::GetGCObjectKind(clasp);
|
||||
return NewNativeClassInstance(cx, clasp, proto, parent, kind);
|
||||
}
|
||||
|
||||
@ -1486,7 +1507,7 @@ NewBuiltinClassInstance(JSContext *cx, Class *clasp, gc::AllocKind kind)
|
||||
static inline JSObject *
|
||||
NewBuiltinClassInstance(JSContext *cx, Class *clasp)
|
||||
{
|
||||
gc::AllocKind kind = gc::GetGCObjectKind(JSCLASS_RESERVED_SLOTS(clasp));
|
||||
gc::AllocKind kind = gc::GetGCObjectKind(clasp);
|
||||
return NewBuiltinClassInstance(cx, clasp, kind);
|
||||
}
|
||||
|
||||
@ -1578,8 +1599,8 @@ NewObject(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent,
|
||||
if (!obj)
|
||||
goto out;
|
||||
|
||||
/* This needs to match up with the size of JSFunction::data_padding. */
|
||||
JS_ASSERT_IF(isFunction, kind == gc::FINALIZE_OBJECT2);
|
||||
/* This needs to match up with the superclass of JSFunction. */
|
||||
JS_ASSERT_IF(isFunction, kind == gc::FINALIZE_OBJECT4);
|
||||
|
||||
/*
|
||||
* Default parent to the parent of the prototype, which was set from
|
||||
@ -1587,7 +1608,7 @@ NewObject(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent,
|
||||
*/
|
||||
obj->init(cx, type,
|
||||
(!parent && proto) ? proto->getParent() : parent,
|
||||
NULL, clasp == &ArrayClass);
|
||||
clasp == &ArrayClass);
|
||||
|
||||
if (clasp->isNative()
|
||||
? !InitScopeForObject(cx, obj, clasp, type, kind)
|
||||
@ -1608,14 +1629,14 @@ NewFunction(JSContext *cx, js::GlobalObject &global)
|
||||
if (!js_GetClassPrototype(cx, &global, JSProto_Function, &proto))
|
||||
return NULL;
|
||||
return detail::NewObject<WithProto::Given, true>(cx, &FunctionClass, proto, &global,
|
||||
gc::FINALIZE_OBJECT2);
|
||||
gc::FINALIZE_OBJECT4);
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE JSObject *
|
||||
NewFunction(JSContext *cx, JSObject *parent)
|
||||
{
|
||||
return detail::NewObject<WithProto::Class, true>(cx, &FunctionClass, NULL, parent,
|
||||
gc::FINALIZE_OBJECT2);
|
||||
gc::FINALIZE_OBJECT4);
|
||||
}
|
||||
|
||||
template <WithProto::e withProto>
|
||||
@ -1630,7 +1651,7 @@ template <WithProto::e withProto>
|
||||
static JS_ALWAYS_INLINE JSObject *
|
||||
NewNonFunction(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent)
|
||||
{
|
||||
gc::AllocKind kind = gc::GetGCObjectKind(JSCLASS_RESERVED_SLOTS(clasp));
|
||||
gc::AllocKind kind = gc::GetGCObjectKind(clasp);
|
||||
return detail::NewObject<withProto, false>(cx, clasp, proto, parent, kind);
|
||||
}
|
||||
|
||||
@ -1648,7 +1669,7 @@ template <WithProto::e withProto>
|
||||
static JS_ALWAYS_INLINE JSObject *
|
||||
NewObject(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent)
|
||||
{
|
||||
gc::AllocKind kind = gc::GetGCObjectKind(JSCLASS_RESERVED_SLOTS(clasp));
|
||||
gc::AllocKind kind = gc::GetGCObjectKind(clasp);
|
||||
return NewObject<withProto>(cx, clasp, proto, parent, kind);
|
||||
}
|
||||
|
||||
@ -1674,7 +1695,7 @@ NewObjectWithType(JSContext *cx, types::TypeObject *type, JSObject *parent, gc::
|
||||
*/
|
||||
obj->init(cx, type,
|
||||
(!parent && type->proto) ? type->proto->getParent() : parent,
|
||||
NULL, false);
|
||||
false);
|
||||
|
||||
if (!InitScopeForObject(cx, obj, &ObjectClass, type, kind)) {
|
||||
obj = NULL;
|
||||
|
@ -74,8 +74,12 @@ using namespace js;
|
||||
using namespace js::gc;
|
||||
using namespace js::types;
|
||||
|
||||
/* slots can only be upto 255 */
|
||||
static const uint8 ARRAYBUFFER_RESERVED_SLOTS = 16;
|
||||
/*
|
||||
* Allocate array buffers with the maximum number of fixed slots marked as
|
||||
* reserved, so that the fixed slots may be used for the buffer's contents.
|
||||
* The last fixed slot is kept for the object's private data.
|
||||
*/
|
||||
static const uint8 ARRAYBUFFER_RESERVED_SLOTS = JSObject::MAX_FIXED_SLOTS - 1;
|
||||
|
||||
static bool
|
||||
ValueIsLength(JSContext *cx, const Value &v, jsuint *len)
|
||||
@ -765,7 +769,7 @@ TypedArray::lengthOffset()
|
||||
/* static */ int
|
||||
TypedArray::dataOffset()
|
||||
{
|
||||
return offsetof(JSObject, privateData);
|
||||
return JSObject::getPrivateDataOffset(NUM_FIXED_SLOTS);
|
||||
}
|
||||
|
||||
/* Helper clamped uint8 type */
|
||||
@ -1298,6 +1302,8 @@ class TypedArrayTemplate
|
||||
return false;
|
||||
obj->setLastPropertyInfallible(empty);
|
||||
|
||||
JS_ASSERT(obj->numFixedSlots() == NUM_FIXED_SLOTS);
|
||||
|
||||
// FIXME Bug 599008: make it ok to call preventExtensions here.
|
||||
obj->flags |= JSObject::NOT_EXTENSIBLE;
|
||||
|
||||
|
@ -193,7 +193,8 @@ struct JS_FRIEND_API(TypedArray) {
|
||||
FIELD_BYTELENGTH,
|
||||
FIELD_TYPE,
|
||||
FIELD_BUFFER,
|
||||
FIELD_MAX
|
||||
FIELD_MAX,
|
||||
NUM_FIXED_SLOTS = 7
|
||||
};
|
||||
|
||||
// and MUST NOT be used to construct new objects.
|
||||
|
@ -95,7 +95,7 @@ TypedArray::getBuffer(JSObject *obj) {
|
||||
|
||||
inline void *
|
||||
TypedArray::getDataOffset(JSObject *obj) {
|
||||
return (void *)obj->getPrivate();
|
||||
return (void *)obj->getPrivate(NUM_FIXED_SLOTS);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1253,6 +1253,7 @@ static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::SparcRegist
|
||||
JS_ASSERT(cx->typeInferenceEnabled());
|
||||
JS_ASSERT(!templateObject->hasDynamicSlots());
|
||||
JS_ASSERT(!templateObject->hasDynamicElements());
|
||||
JS_ASSERT(!(templateObject->getClass()->flags & JSCLASS_HAS_PRIVATE));
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
if (cx->runtime->needZealousGC())
|
||||
@ -1304,7 +1305,6 @@ static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::SparcRegist
|
||||
store32(Imm32(templateObject->flags), Address(result, offsetof(JSObject, flags)));
|
||||
storePtr(ImmPtr(NULL), Address(result, JSObject::offsetOfSlots()));
|
||||
storePtr(ImmPtr(templateObject->parent), Address(result, offsetof(JSObject, parent)));
|
||||
storePtr(ImmPtr(templateObject->privateData), Address(result, offsetof(JSObject, privateData)));
|
||||
|
||||
if (templateObject->isDenseArray()) {
|
||||
/* Fill in the elements header. */
|
||||
|
@ -3340,7 +3340,7 @@ mjit::Compiler::checkCallApplySpeculation(uint32 callImmArgc, uint32 speculatedA
|
||||
if (origCalleeType.isSet())
|
||||
isObj = masm.testObject(Assembler::NotEqual, origCalleeType.reg());
|
||||
Jump isFun = masm.testFunction(Assembler::NotEqual, origCalleeData, temp);
|
||||
masm.loadObjPrivate(origCalleeData, origCalleeData);
|
||||
masm.loadObjPrivate(origCalleeData, origCalleeData, JSObject::FUN_CLASS_NFIXED_SLOTS);
|
||||
Native native = *PC == JSOP_FUNCALL ? js_fun_call : js_fun_apply;
|
||||
Jump isNative = masm.branchPtr(Assembler::NotEqual,
|
||||
Address(origCalleeData, JSFunction::offsetOfNativeOrScript()),
|
||||
@ -3621,7 +3621,7 @@ mjit::Compiler::inlineCallHelper(uint32 callImmArgc, bool callingNew, FrameSize
|
||||
Jump notFunction = stubcc.masm.testFunction(Assembler::NotEqual, icCalleeData, tmp);
|
||||
|
||||
/* Test if the function is scripted. */
|
||||
stubcc.masm.loadObjPrivate(icCalleeData, funPtrReg);
|
||||
stubcc.masm.loadObjPrivate(icCalleeData, funPtrReg, JSObject::FUN_CLASS_NFIXED_SLOTS);
|
||||
stubcc.masm.load16(Address(funPtrReg, offsetof(JSFunction, flags)), tmp);
|
||||
stubcc.masm.and32(Imm32(JSFUN_KINDMASK), tmp);
|
||||
Jump isNative = stubcc.masm.branch32(Assembler::Below, tmp, Imm32(JSFUN_INTERPRETED));
|
||||
@ -5670,7 +5670,7 @@ mjit::Compiler::iter(uintN flags)
|
||||
stubcc.linkExit(nullIterator, Uses(1));
|
||||
|
||||
/* Get NativeIterator from iter obj. */
|
||||
masm.loadObjPrivate(ioreg, nireg);
|
||||
masm.loadObjPrivate(ioreg, nireg, JSObject::ITER_CLASS_NFIXED_SLOTS);
|
||||
|
||||
/* Test for active iterator. */
|
||||
Address flagsAddr(nireg, offsetof(NativeIterator, flags));
|
||||
@ -5759,7 +5759,7 @@ mjit::Compiler::iterNext(ptrdiff_t offset)
|
||||
stubcc.linkExit(notFast, Uses(1));
|
||||
|
||||
/* Get private from iter obj. */
|
||||
masm.loadObjPrivate(reg, T1);
|
||||
masm.loadObjPrivate(reg, T1, JSObject::ITER_CLASS_NFIXED_SLOTS);
|
||||
|
||||
RegisterID T3 = frame.allocReg();
|
||||
RegisterID T4 = frame.allocReg();
|
||||
@ -5814,7 +5814,7 @@ mjit::Compiler::iterMore(jsbytecode *target)
|
||||
stubcc.linkExitForBranch(notFast);
|
||||
|
||||
/* Get private from iter obj. */
|
||||
masm.loadObjPrivate(reg, reg);
|
||||
masm.loadObjPrivate(reg, reg, JSObject::ITER_CLASS_NFIXED_SLOTS);
|
||||
|
||||
/* Test that the iterator supports fast iteration. */
|
||||
notFast = masm.branchTest32(Assembler::NonZero, Address(reg, offsetof(NativeIterator, flags)),
|
||||
@ -5853,7 +5853,7 @@ mjit::Compiler::iterEnd()
|
||||
stubcc.linkExit(notIterator, Uses(1));
|
||||
|
||||
/* Get private from iter obj. */
|
||||
masm.loadObjPrivate(reg, T1);
|
||||
masm.loadObjPrivate(reg, T1, JSObject::ITER_CLASS_NFIXED_SLOTS);
|
||||
|
||||
RegisterID T2 = frame.allocReg();
|
||||
|
||||
|
@ -747,7 +747,7 @@ class CallCompiler : public BaseCompiler
|
||||
|
||||
/* Guard that it's the same function. */
|
||||
JSFunction *fun = obj->getFunctionPrivate();
|
||||
masm.loadObjPrivate(ic.funObjReg, t0);
|
||||
masm.loadObjPrivate(ic.funObjReg, t0, JSObject::FUN_CLASS_NFIXED_SLOTS);
|
||||
Jump funGuard = masm.branchPtr(Assembler::NotEqual, t0, ImmPtr(fun));
|
||||
Jump done = masm.jump();
|
||||
|
||||
|
@ -345,8 +345,8 @@ class NunboxAssembler : public JSC::MacroAssembler
|
||||
loadPtr(payloadOf(privAddr), to);
|
||||
}
|
||||
|
||||
void loadObjPrivate(RegisterID base, RegisterID to) {
|
||||
Address priv(base, offsetof(JSObject, privateData));
|
||||
void loadObjPrivate(RegisterID base, RegisterID to, uint32 nfixed) {
|
||||
Address priv(base, JSObject::getPrivateDataOffset(nfixed));
|
||||
loadPtr(priv, to);
|
||||
}
|
||||
|
||||
|
@ -357,7 +357,7 @@ class SetPropCompiler : public PICStubCompiler
|
||||
uint16 slot = uint16(shape->shortid());
|
||||
|
||||
/* Guard that the call object has a frame. */
|
||||
masm.loadObjPrivate(pic.objReg, pic.shapeReg);
|
||||
masm.loadObjPrivate(pic.objReg, pic.shapeReg, obj->numFixedSlots());
|
||||
Jump escapedFrame = masm.branchTestPtr(Assembler::Zero, pic.shapeReg, pic.shapeReg);
|
||||
|
||||
{
|
||||
@ -1554,7 +1554,7 @@ class ScopeNameCompiler : public PICStubCompiler
|
||||
}
|
||||
|
||||
/* Get callobj's stack frame. */
|
||||
masm.loadObjPrivate(pic.objReg, pic.shapeReg);
|
||||
masm.loadObjPrivate(pic.objReg, pic.shapeReg, getprop.holder->numFixedSlots());
|
||||
|
||||
JSFunction *fun = getprop.holder->asCall().getCalleeFunction();
|
||||
uint16 slot = uint16(shape->shortid());
|
||||
@ -2556,7 +2556,7 @@ GetElementIC::attachArguments(JSContext *cx, JSObject *obj, const Value &v, jsid
|
||||
}
|
||||
Jump holeCheck = masm.branchPtr(Assembler::Equal, objReg, ImmType(JSVAL_TYPE_MAGIC));
|
||||
|
||||
Address privateData(typeReg, offsetof(JSObject, privateData));
|
||||
Address privateData(typeReg, JSObject::getPrivateDataOffset(ArgumentsObject::NFIXED_SLOTS));
|
||||
Jump liveArguments = masm.branchPtr(Assembler::NotEqual, privateData, ImmPtr(0));
|
||||
|
||||
masm.loadPrivate(Address(typeReg, JSObject::getFixedSlotOffset(ArgumentsObject::DATA_SLOT)), objReg);
|
||||
|
@ -274,8 +274,8 @@ class PunboxAssembler : public JSC::MacroAssembler
|
||||
lshiftPtr(Imm32(1), to);
|
||||
}
|
||||
|
||||
void loadObjPrivate(RegisterID base, RegisterID to) {
|
||||
Address priv(base, offsetof(JSObject, privateData));
|
||||
void loadObjPrivate(RegisterID base, RegisterID to, uint32 nfixed) {
|
||||
Address priv(base, JSObject::getPrivateDataOffset(nfixed));
|
||||
loadPtr(priv, to);
|
||||
}
|
||||
|
||||
|
@ -436,10 +436,13 @@ void ValidateWriter::checkAccSet(LOpcode op, LIns *base, int32_t disp, AccSet ac
|
||||
case ACCSET_OBJ_PRIVATE:
|
||||
// base = <JSObject>
|
||||
// ins = {ld,st}p.objprivate base[offsetof(JSObject, privateData)]
|
||||
ok = false;
|
||||
/*
|
||||
ok = (op == LIR_ldi || op == LIR_ldp ||
|
||||
op == LIR_sti || op == LIR_stp) &&
|
||||
disp == offsetof(JSObject, privateData) &&
|
||||
couldBeObjectOrString(base);
|
||||
*/
|
||||
break;
|
||||
|
||||
case ACCSET_OBJ_CAPACITY:
|
||||
@ -497,9 +500,12 @@ void ValidateWriter::checkAccSet(LOpcode op, LIns *base, int32_t disp, AccSet ac
|
||||
case ACCSET_ITER:
|
||||
// base = ldp.objprivate ...[offsetof(JSObject, privateData)]
|
||||
// ins = {ld,st}p.iter base[<disp within NativeIterator>]
|
||||
ok = false;
|
||||
/*
|
||||
ok = (op == LIR_ldp || op == LIR_stp) &&
|
||||
dispWithin(NativeIterator) &&
|
||||
match(base, LIR_ldp, ACCSET_OBJ_PRIVATE, offsetof(JSObject, privateData));
|
||||
*/
|
||||
break;
|
||||
|
||||
case ACCSET_ITER_PROPS:
|
||||
|
@ -510,19 +510,22 @@ class Writer
|
||||
}
|
||||
|
||||
nj::LIns *ldpObjPrivate(nj::LIns *obj) const {
|
||||
return name(lir->insLoad(nj::LIR_ldp, obj, offsetof(JSObject, privateData),
|
||||
JS_NOT_REACHED("FIXME");
|
||||
return name(lir->insLoad(nj::LIR_ldp, obj, 0,
|
||||
ACCSET_OBJ_PRIVATE),
|
||||
"private");
|
||||
}
|
||||
|
||||
nj::LIns *lduiObjPrivate(nj::LIns *obj) const {
|
||||
return name(lir->insLoad(nj::LIR_ldi, obj, offsetof(JSObject, privateData),
|
||||
JS_NOT_REACHED("FIXME");
|
||||
return name(lir->insLoad(nj::LIR_ldi, obj, 0,
|
||||
ACCSET_OBJ_PRIVATE),
|
||||
"private_uint32");
|
||||
}
|
||||
|
||||
nj::LIns *stuiObjPrivate(nj::LIns *obj, nj::LIns *value) const {
|
||||
return name(lir->insStore(nj::LIR_sti, value, obj, offsetof(JSObject, privateData),
|
||||
JS_NOT_REACHED("FIXME");
|
||||
return name(lir->insStore(nj::LIR_sti, value, obj, 0,
|
||||
ACCSET_OBJ_PRIVATE),
|
||||
"private_uint32");
|
||||
}
|
||||
@ -557,7 +560,8 @@ class Writer
|
||||
}
|
||||
|
||||
nj::LIns *ldpConstTypedArrayData(nj::LIns *obj) const {
|
||||
return name(lir->insLoad(nj::LIR_ldp, obj, offsetof(JSObject, privateData), ACCSET_TARRAY, nj::LOAD_CONST), "typedArrayData");
|
||||
JS_NOT_REACHED("FIXME");
|
||||
return name(lir->insLoad(nj::LIR_ldp, obj, 0, ACCSET_TARRAY, nj::LOAD_CONST), "typedArrayData");
|
||||
}
|
||||
|
||||
nj::LIns *ldc2iTypedArrayElement(nj::LIns *elems, nj::LIns *index) const {
|
||||
|
@ -151,6 +151,7 @@ class ArgumentsObject : public ::JSObject
|
||||
|
||||
public:
|
||||
static const uint32 RESERVED_SLOTS = 2;
|
||||
static const uint32 NFIXED_SLOTS = 3;
|
||||
|
||||
private:
|
||||
/* Lower-order bit stolen from the length slot. */
|
||||
|
@ -56,7 +56,7 @@ CallObject::create(JSContext *cx, JSScript *script, JSObject &scopeChain, JSObje
|
||||
{
|
||||
Bindings &bindings = script->bindings;
|
||||
size_t argsVars = bindings.countArgsAndVars();
|
||||
size_t slots = RESERVED_SLOTS + argsVars;
|
||||
size_t slots = RESERVED_SLOTS + argsVars + 1; /* Add one for privateData. */
|
||||
gc::AllocKind kind = gc::GetGCObjectKind(slots);
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user