mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1133254 - Dehandlify shape-updating object methods, allow setting multiple flags on an object at once, r=terrence.
This commit is contained in:
parent
aa56f5a6fc
commit
02bb5aa67c
@ -1347,10 +1347,10 @@ JSFunction::initBoundFunction(JSContext *cx, HandleObject target, HandleValue th
|
||||
if (!self->toDictionaryMode(cx))
|
||||
return false;
|
||||
|
||||
if (!self->setFlag(cx, BaseShape::BOUND_FUNCTION))
|
||||
if (!self->JSObject::setFlags(cx, BaseShape::BOUND_FUNCTION))
|
||||
return false;
|
||||
|
||||
if (!NativeObject::setSlotSpan(cx, self, BOUND_FUNCTION_RESERVED_SLOTS + argslen))
|
||||
if (!self->setSlotSpan(cx, BOUND_FUNCTION_RESERVED_SLOTS + argslen))
|
||||
return false;
|
||||
|
||||
self->setSlot(JSSLOT_BOUND_FUNCTION_TARGET, ObjectValue(*target));
|
||||
|
@ -1038,7 +1038,7 @@ js::SetIntegrityLevel(JSContext *cx, HandleObject obj, IntegrityLevel level)
|
||||
}
|
||||
|
||||
MOZ_ASSERT(nobj->lastProperty()->slotSpan() == last->slotSpan());
|
||||
JS_ALWAYS_TRUE(NativeObject::setLastProperty(cx, nobj, last));
|
||||
JS_ALWAYS_TRUE(nobj->setLastProperty(cx, last));
|
||||
} else {
|
||||
RootedId id(cx);
|
||||
Rooted<PropertyDescriptor> desc(cx);
|
||||
@ -1845,7 +1845,7 @@ js::DeepCloneObjectLiteral(JSContext *cx, HandleNativeObject obj, NewObjectKind
|
||||
MOZ_ASSERT(!obj->hasPrivate());
|
||||
RootedShape shape(cx, obj->lastProperty());
|
||||
size_t span = shape->slotSpan();
|
||||
clone->setLastProperty(cx, clone, shape);
|
||||
clone->setLastProperty(cx, shape);
|
||||
for (size_t i = 0; i < span; i++) {
|
||||
v = obj->getSlot(i);
|
||||
if (v.isObject()) {
|
||||
@ -2137,7 +2137,7 @@ js::CloneObjectLiteral(JSContext *cx, HandleObject parent, HandleObject srcObj)
|
||||
|
||||
RootedShape newShape(cx, ReshapeForParentAndAllocKind(cx, srcObj->lastProperty(),
|
||||
TaggedProto(proto), parent, kind));
|
||||
if (!newShape || !NativeObject::setLastProperty(cx, res, newShape))
|
||||
if (!newShape || !res->setLastProperty(cx, newShape))
|
||||
return nullptr;
|
||||
|
||||
return res;
|
||||
@ -3139,7 +3139,7 @@ js::PreventExtensions(JSContext *cx, HandleObject obj, bool *succeeded)
|
||||
return false;
|
||||
|
||||
*succeeded = true;
|
||||
return obj->setFlag(cx, BaseShape::NOT_EXTENSIBLE, JSObject::GENERATE_SHAPE);
|
||||
return obj->setFlags(cx, BaseShape::NOT_EXTENSIBLE, JSObject::GENERATE_SHAPE);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -3234,7 +3234,7 @@ js::SetImmutablePrototype(ExclusiveContext *cx, HandleObject obj, bool *succeede
|
||||
return Proxy::setImmutablePrototype(cx->asJSContext(), obj, succeeded);
|
||||
}
|
||||
|
||||
if (!obj->setFlag(cx, BaseShape::IMMUTABLE_PROTOTYPE))
|
||||
if (!obj->setFlags(cx, BaseShape::IMMUTABLE_PROTOTYPE))
|
||||
return false;
|
||||
*succeeded = true;
|
||||
return true;
|
||||
|
@ -189,16 +189,14 @@ class JSObject : public js::gc::Cell
|
||||
inline void setInitialSlotsMaybeNonNative(js::HeapSlot *slots);
|
||||
inline void setInitialElementsMaybeNonNative(js::HeapSlot *elements);
|
||||
|
||||
protected:
|
||||
enum GenerateShape {
|
||||
GENERATE_NONE,
|
||||
GENERATE_SHAPE
|
||||
};
|
||||
|
||||
bool setFlag(js::ExclusiveContext *cx, /*BaseShape::Flag*/ uint32_t flag,
|
||||
GenerateShape generateShape = GENERATE_NONE);
|
||||
bool setFlags(js::ExclusiveContext *cx, /*BaseShape::Flag*/ uint32_t flags,
|
||||
GenerateShape generateShape = GENERATE_NONE);
|
||||
|
||||
public:
|
||||
/*
|
||||
* An object is a delegate if it is on another object's prototype or scope
|
||||
* chain, and therefore the delegate might be asked implicitly to get or
|
||||
@ -213,7 +211,7 @@ class JSObject : public js::gc::Cell
|
||||
}
|
||||
|
||||
bool setDelegate(js::ExclusiveContext *cx) {
|
||||
return setFlag(cx, js::BaseShape::DELEGATE, GENERATE_SHAPE);
|
||||
return setFlags(cx, js::BaseShape::DELEGATE, GENERATE_SHAPE);
|
||||
}
|
||||
|
||||
bool isBoundFunction() const {
|
||||
@ -226,18 +224,18 @@ class JSObject : public js::gc::Cell
|
||||
return lastProperty()->hasObjectFlag(js::BaseShape::WATCHED);
|
||||
}
|
||||
bool setWatched(js::ExclusiveContext *cx) {
|
||||
return setFlag(cx, js::BaseShape::WATCHED, GENERATE_SHAPE);
|
||||
return setFlags(cx, js::BaseShape::WATCHED, GENERATE_SHAPE);
|
||||
}
|
||||
|
||||
/* See InterpreterFrame::varObj. */
|
||||
inline bool isQualifiedVarObj();
|
||||
bool setQualifiedVarObj(js::ExclusiveContext *cx) {
|
||||
return setFlag(cx, js::BaseShape::QUALIFIED_VAROBJ);
|
||||
return setFlags(cx, js::BaseShape::QUALIFIED_VAROBJ);
|
||||
}
|
||||
|
||||
inline bool isUnqualifiedVarObj();
|
||||
bool setUnqualifiedVarObj(js::ExclusiveContext *cx) {
|
||||
return setFlag(cx, js::BaseShape::UNQUALIFIED_VAROBJ);
|
||||
return setFlags(cx, js::BaseShape::UNQUALIFIED_VAROBJ);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -250,7 +248,7 @@ class JSObject : public js::gc::Cell
|
||||
return lastProperty()->hasObjectFlag(js::BaseShape::UNCACHEABLE_PROTO);
|
||||
}
|
||||
bool setUncacheableProto(js::ExclusiveContext *cx) {
|
||||
return setFlag(cx, js::BaseShape::UNCACHEABLE_PROTO, GENERATE_SHAPE);
|
||||
return setFlags(cx, js::BaseShape::UNCACHEABLE_PROTO, GENERATE_SHAPE);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -261,7 +259,7 @@ class JSObject : public js::gc::Cell
|
||||
return lastProperty()->hasObjectFlag(js::BaseShape::HAD_ELEMENTS_ACCESS);
|
||||
}
|
||||
bool setHadElementsAccess(js::ExclusiveContext *cx) {
|
||||
return setFlag(cx, js::BaseShape::HAD_ELEMENTS_ACCESS);
|
||||
return setFlags(cx, js::BaseShape::HAD_ELEMENTS_ACCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -397,7 +395,7 @@ class JSObject : public js::gc::Cell
|
||||
return lastProperty()->hasObjectFlag(js::BaseShape::ITERATED_SINGLETON);
|
||||
}
|
||||
bool setIteratedSingleton(js::ExclusiveContext *cx) {
|
||||
return setFlag(cx, js::BaseShape::ITERATED_SINGLETON);
|
||||
return setFlags(cx, js::BaseShape::ITERATED_SINGLETON);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -414,7 +412,7 @@ class JSObject : public js::gc::Cell
|
||||
return lastProperty()->hasObjectFlag(js::BaseShape::NEW_SCRIPT_CLEARED);
|
||||
}
|
||||
bool setNewScriptCleared(js::ExclusiveContext *cx) {
|
||||
return setFlag(cx, js::BaseShape::NEW_SCRIPT_CLEARED);
|
||||
return setFlags(cx, js::BaseShape::NEW_SCRIPT_CLEARED);
|
||||
}
|
||||
|
||||
/* Set a new prototype for an object with a singleton type. */
|
||||
|
@ -614,11 +614,11 @@ GlobalObject::addIntrinsicValue(JSContext *cx, HandleId id, HandleValue value)
|
||||
Rooted<UnownedBaseShape*> base(cx, last->base()->unowned());
|
||||
|
||||
StackShape child(base, id, slot, 0, 0);
|
||||
RootedShape shape(cx, cx->compartment()->propertyTree.getChild(cx, last, child));
|
||||
Shape *shape = cx->compartment()->propertyTree.getChild(cx, last, child);
|
||||
if (!shape)
|
||||
return false;
|
||||
|
||||
if (!NativeObject::setLastProperty(cx, holder, shape))
|
||||
if (!holder->setLastProperty(cx, shape))
|
||||
return false;
|
||||
|
||||
holder->setSlot(shape->slot(), value);
|
||||
|
@ -39,9 +39,7 @@ inline void
|
||||
NativeObject::removeLastProperty(ExclusiveContext *cx)
|
||||
{
|
||||
MOZ_ASSERT(canRemoveLastProperty());
|
||||
RootedNativeObject self(cx, this);
|
||||
RootedShape prev(cx, lastProperty()->previous());
|
||||
JS_ALWAYS_TRUE(setLastProperty(cx, self, prev));
|
||||
JS_ALWAYS_TRUE(setLastProperty(cx, lastProperty()->previous()));
|
||||
}
|
||||
|
||||
inline bool
|
||||
@ -335,8 +333,7 @@ CopyInitializerObject(JSContext *cx, HandlePlainObject baseobj, NewObjectKind ne
|
||||
return nullptr;
|
||||
|
||||
RootedObject metadata(cx, obj->getMetadata());
|
||||
RootedShape lastProp(cx, baseobj->lastProperty());
|
||||
if (!NativeObject::setLastProperty(cx, obj, lastProp))
|
||||
if (!obj->setLastProperty(cx, baseobj->lastProperty()))
|
||||
return nullptr;
|
||||
if (metadata && !JSObject::setMetadata(cx, obj, metadata))
|
||||
return nullptr;
|
||||
|
@ -296,56 +296,55 @@ PropDesc::trace(JSTracer *trc)
|
||||
gc::MarkValueRoot(trc, &set_, "PropDesc set");
|
||||
}
|
||||
|
||||
/* static */ inline bool
|
||||
NativeObject::updateSlotsForSpan(ExclusiveContext *cx,
|
||||
HandleNativeObject obj, size_t oldSpan, size_t newSpan)
|
||||
inline bool
|
||||
NativeObject::updateSlotsForSpan(ExclusiveContext *cx, size_t oldSpan, size_t newSpan)
|
||||
{
|
||||
MOZ_ASSERT(oldSpan != newSpan);
|
||||
|
||||
size_t oldCount = dynamicSlotsCount(obj->numFixedSlots(), oldSpan, obj->getClass());
|
||||
size_t newCount = dynamicSlotsCount(obj->numFixedSlots(), newSpan, obj->getClass());
|
||||
size_t oldCount = dynamicSlotsCount(numFixedSlots(), oldSpan, getClass());
|
||||
size_t newCount = dynamicSlotsCount(numFixedSlots(), newSpan, getClass());
|
||||
|
||||
if (oldSpan < newSpan) {
|
||||
if (oldCount < newCount && !growSlots(cx, obj, oldCount, newCount))
|
||||
if (oldCount < newCount && !growSlots(cx, oldCount, newCount))
|
||||
return false;
|
||||
|
||||
if (newSpan == oldSpan + 1)
|
||||
obj->initSlotUnchecked(oldSpan, UndefinedValue());
|
||||
initSlotUnchecked(oldSpan, UndefinedValue());
|
||||
else
|
||||
obj->initializeSlotRange(oldSpan, newSpan - oldSpan);
|
||||
initializeSlotRange(oldSpan, newSpan - oldSpan);
|
||||
} else {
|
||||
/* Trigger write barriers on the old slots before reallocating. */
|
||||
obj->prepareSlotRangeForOverwrite(newSpan, oldSpan);
|
||||
obj->invalidateSlotRange(newSpan, oldSpan - newSpan);
|
||||
prepareSlotRangeForOverwrite(newSpan, oldSpan);
|
||||
invalidateSlotRange(newSpan, oldSpan - newSpan);
|
||||
|
||||
if (oldCount > newCount)
|
||||
shrinkSlots(cx, obj, oldCount, newCount);
|
||||
shrinkSlots(cx, oldCount, newCount);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
NativeObject::setLastProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleShape shape)
|
||||
bool
|
||||
NativeObject::setLastProperty(ExclusiveContext *cx, Shape *shape)
|
||||
{
|
||||
MOZ_ASSERT(!obj->inDictionaryMode());
|
||||
MOZ_ASSERT(!inDictionaryMode());
|
||||
MOZ_ASSERT(!shape->inDictionary());
|
||||
MOZ_ASSERT(shape->compartment() == obj->compartment());
|
||||
MOZ_ASSERT(shape->numFixedSlots() == obj->numFixedSlots());
|
||||
MOZ_ASSERT(shape->getObjectClass() == obj->getClass());
|
||||
MOZ_ASSERT(shape->compartment() == compartment());
|
||||
MOZ_ASSERT(shape->numFixedSlots() == numFixedSlots());
|
||||
MOZ_ASSERT(shape->getObjectClass() == getClass());
|
||||
|
||||
size_t oldSpan = obj->lastProperty()->slotSpan();
|
||||
size_t oldSpan = lastProperty()->slotSpan();
|
||||
size_t newSpan = shape->slotSpan();
|
||||
|
||||
if (oldSpan == newSpan) {
|
||||
obj->shape_ = shape;
|
||||
shape_ = shape;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!updateSlotsForSpan(cx, obj, oldSpan, newSpan))
|
||||
if (!updateSlotsForSpan(cx, oldSpan, newSpan))
|
||||
return false;
|
||||
|
||||
obj->shape_ = shape;
|
||||
shape_ = shape;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -383,43 +382,42 @@ NativeObject::setLastPropertyMakeNonNative(Shape *shape)
|
||||
shape_ = shape;
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
NativeObject::setLastPropertyMakeNative(ExclusiveContext *cx, HandleNativeObject obj,
|
||||
HandleShape shape)
|
||||
void
|
||||
NativeObject::setLastPropertyMakeNative(ExclusiveContext *cx, Shape *shape)
|
||||
{
|
||||
MOZ_ASSERT(obj->getClass()->isNative());
|
||||
MOZ_ASSERT(!obj->lastProperty()->isNative());
|
||||
MOZ_ASSERT(getClass()->isNative());
|
||||
MOZ_ASSERT(!lastProperty()->isNative());
|
||||
MOZ_ASSERT(shape->isNative());
|
||||
MOZ_ASSERT(!obj->inDictionaryMode());
|
||||
MOZ_ASSERT(!inDictionaryMode());
|
||||
MOZ_ASSERT(!shape->inDictionary());
|
||||
MOZ_ASSERT(shape->compartment() == obj->compartment());
|
||||
MOZ_ASSERT(shape->compartment() == compartment());
|
||||
|
||||
obj->shape_ = shape;
|
||||
obj->slots_ = nullptr;
|
||||
obj->elements_ = emptyObjectElements;
|
||||
shape_ = shape;
|
||||
slots_ = nullptr;
|
||||
elements_ = emptyObjectElements;
|
||||
|
||||
size_t oldSpan = shape->numFixedSlots();
|
||||
size_t newSpan = shape->slotSpan();
|
||||
|
||||
// A failures at this point will leave the object as a mutant, and we
|
||||
// A failure at this point will leave the object as a mutant, and we
|
||||
// can't recover.
|
||||
if (oldSpan != newSpan && !updateSlotsForSpan(cx, obj, oldSpan, newSpan))
|
||||
if (oldSpan != newSpan && !updateSlotsForSpan(cx, oldSpan, newSpan))
|
||||
CrashAtUnhandlableOOM("NativeObject::setLastPropertyMakeNative");
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
NativeObject::setSlotSpan(ExclusiveContext *cx, HandleNativeObject obj, uint32_t span)
|
||||
bool
|
||||
NativeObject::setSlotSpan(ExclusiveContext *cx, uint32_t span)
|
||||
{
|
||||
MOZ_ASSERT(obj->inDictionaryMode());
|
||||
MOZ_ASSERT(inDictionaryMode());
|
||||
|
||||
size_t oldSpan = obj->lastProperty()->base()->slotSpan();
|
||||
size_t oldSpan = lastProperty()->base()->slotSpan();
|
||||
if (oldSpan == span)
|
||||
return true;
|
||||
|
||||
if (!updateSlotsForSpan(cx, obj, oldSpan, span))
|
||||
if (!updateSlotsForSpan(cx, oldSpan, span))
|
||||
return false;
|
||||
|
||||
obj->lastProperty()->base()->setSlotSpan(span);
|
||||
lastProperty()->base()->setSlotSpan(span);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -448,11 +446,11 @@ ReallocateSlots(ExclusiveContext *cx, JSObject *obj, HeapSlot *oldSlots,
|
||||
return obj->zone()->pod_realloc<HeapSlot>(oldSlots, oldCount, newCount);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
NativeObject::growSlots(ExclusiveContext *cx, HandleNativeObject obj, uint32_t oldCount, uint32_t newCount)
|
||||
bool
|
||||
NativeObject::growSlots(ExclusiveContext *cx, uint32_t oldCount, uint32_t newCount)
|
||||
{
|
||||
MOZ_ASSERT(newCount > oldCount);
|
||||
MOZ_ASSERT_IF(!obj->is<ArrayObject>(), newCount >= SLOT_CAPACITY_MIN);
|
||||
MOZ_ASSERT_IF(!is<ArrayObject>(), newCount >= SLOT_CAPACITY_MIN);
|
||||
|
||||
/*
|
||||
* Slot capacities are determined by the span of allocated objects. Due to
|
||||
@ -463,20 +461,20 @@ NativeObject::growSlots(ExclusiveContext *cx, HandleNativeObject obj, uint32_t o
|
||||
MOZ_ASSERT(newCount < NELEMENTS_LIMIT);
|
||||
|
||||
if (!oldCount) {
|
||||
obj->slots_ = AllocateSlots(cx, obj, newCount);
|
||||
if (!obj->slots_)
|
||||
slots_ = AllocateSlots(cx, this, newCount);
|
||||
if (!slots_)
|
||||
return false;
|
||||
Debug_SetSlotRangeToCrashOnTouch(obj->slots_, newCount);
|
||||
Debug_SetSlotRangeToCrashOnTouch(slots_, newCount);
|
||||
return true;
|
||||
}
|
||||
|
||||
HeapSlot *newslots = ReallocateSlots(cx, obj, obj->slots_, oldCount, newCount);
|
||||
HeapSlot *newslots = ReallocateSlots(cx, this, slots_, oldCount, newCount);
|
||||
if (!newslots)
|
||||
return false; /* Leave slots at its old size. */
|
||||
|
||||
obj->slots_ = newslots;
|
||||
slots_ = newslots;
|
||||
|
||||
Debug_SetSlotRangeToCrashOnTouch(obj->slots_ + oldCount, newCount - oldCount);
|
||||
Debug_SetSlotRangeToCrashOnTouch(slots_ + oldCount, newCount - oldCount);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -490,25 +488,24 @@ FreeSlots(ExclusiveContext *cx, HeapSlot *slots)
|
||||
js_free(slots);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
NativeObject::shrinkSlots(ExclusiveContext *cx, HandleNativeObject obj,
|
||||
uint32_t oldCount, uint32_t newCount)
|
||||
void
|
||||
NativeObject::shrinkSlots(ExclusiveContext *cx, uint32_t oldCount, uint32_t newCount)
|
||||
{
|
||||
MOZ_ASSERT(newCount < oldCount);
|
||||
|
||||
if (newCount == 0) {
|
||||
FreeSlots(cx, obj->slots_);
|
||||
obj->slots_ = nullptr;
|
||||
FreeSlots(cx, slots_);
|
||||
slots_ = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT_IF(!obj->is<ArrayObject>(), newCount >= SLOT_CAPACITY_MIN);
|
||||
MOZ_ASSERT_IF(!is<ArrayObject>(), newCount >= SLOT_CAPACITY_MIN);
|
||||
|
||||
HeapSlot *newslots = ReallocateSlots(cx, obj, obj->slots_, oldCount, newCount);
|
||||
HeapSlot *newslots = ReallocateSlots(cx, this, slots_, oldCount, newCount);
|
||||
if (!newslots)
|
||||
return; /* Leave slots at its old size. */
|
||||
|
||||
obj->slots_ = newslots;
|
||||
slots_ = newslots;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
@ -988,7 +985,7 @@ NativeObject::allocSlot(ExclusiveContext *cx, HandleNativeObject obj, uint32_t *
|
||||
|
||||
*slotp = slot;
|
||||
|
||||
if (obj->inDictionaryMode() && !setSlotSpan(cx, obj, slot + 1))
|
||||
if (obj->inDictionaryMode() && !obj->setSlotSpan(cx, slot + 1))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -399,12 +399,9 @@ class NativeObject : public JSObject
|
||||
return getElementsHeader()->capacity;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the last property, keeping the number of allocated slots in sync
|
||||
* with the object's new slot span.
|
||||
*/
|
||||
static bool setLastProperty(ExclusiveContext *cx,
|
||||
HandleNativeObject obj, HandleShape shape);
|
||||
// Update the last property, keeping the number of allocated slots in sync
|
||||
// with the object's new slot span.
|
||||
bool setLastProperty(ExclusiveContext *cx, Shape *shape);
|
||||
|
||||
// As for setLastProperty(), but allows the number of fixed slots to
|
||||
// change. This can only be used when fixed slots are being erased from the
|
||||
@ -420,8 +417,7 @@ class NativeObject : public JSObject
|
||||
// As for setLastProperty(), but changes the class associated with the
|
||||
// object to a native one. The object's type has already been changed, and
|
||||
// this brings the shape into sync with it.
|
||||
static void setLastPropertyMakeNative(ExclusiveContext *cx, HandleNativeObject obj,
|
||||
HandleShape shape);
|
||||
void setLastPropertyMakeNative(ExclusiveContext *cx, Shape *shape);
|
||||
|
||||
protected:
|
||||
#ifdef DEBUG
|
||||
@ -447,7 +443,7 @@ class NativeObject : public JSObject
|
||||
* Update the slot span directly for a dictionary object, and allocate
|
||||
* slots to cover the new span if necessary.
|
||||
*/
|
||||
static bool setSlotSpan(ExclusiveContext *cx, HandleNativeObject obj, uint32_t span);
|
||||
bool setSlotSpan(ExclusiveContext *cx, uint32_t span);
|
||||
|
||||
bool toDictionaryMode(ExclusiveContext *cx);
|
||||
|
||||
@ -590,10 +586,8 @@ class NativeObject : public JSObject
|
||||
* The number of allocated slots is not stored explicitly, and changes to
|
||||
* the slots must track changes in the slot span.
|
||||
*/
|
||||
static bool growSlots(ExclusiveContext *cx, HandleNativeObject obj, uint32_t oldCount,
|
||||
uint32_t newCount);
|
||||
static void shrinkSlots(ExclusiveContext *cx, HandleNativeObject obj, uint32_t oldCount,
|
||||
uint32_t newCount);
|
||||
bool growSlots(ExclusiveContext *cx, uint32_t oldCount, uint32_t newCount);
|
||||
void shrinkSlots(ExclusiveContext *cx, uint32_t oldCount, uint32_t newCount);
|
||||
|
||||
bool hasDynamicSlots() const { return !!slots_; }
|
||||
|
||||
@ -791,8 +785,7 @@ class NativeObject : public JSObject
|
||||
static const uint32_t MAX_FIXED_SLOTS = 16;
|
||||
|
||||
protected:
|
||||
static inline bool updateSlotsForSpan(ExclusiveContext *cx,
|
||||
HandleNativeObject obj, size_t oldSpan, size_t newSpan);
|
||||
inline bool updateSlotsForSpan(ExclusiveContext *cx, size_t oldSpan, size_t newSpan);
|
||||
|
||||
public:
|
||||
/*
|
||||
|
@ -334,7 +334,7 @@ JSObject::makeLazyGroup(JSContext *cx, HandleObject obj)
|
||||
JSObject::setNewGroupUnknown(JSContext *cx, const js::Class *clasp, JS::HandleObject obj)
|
||||
{
|
||||
ObjectGroup::setDefaultNewGroupUnknown(cx, clasp, obj);
|
||||
return obj->setFlag(cx, BaseShape::NEW_GROUP_UNKNOWN);
|
||||
return obj->setFlags(cx, BaseShape::NEW_GROUP_UNKNOWN);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
@ -1057,8 +1057,7 @@ ObjectGroup::newPlainObject(JSContext *cx, IdValuePair *properties, size_t nprop
|
||||
}
|
||||
MOZ_ASSERT(obj->getProto() == p->value().group->proto().toObject());
|
||||
|
||||
RootedShape shape(cx, p->value().shape);
|
||||
if (!NativeObject::setLastProperty(cx, obj, shape)) {
|
||||
if (!obj->setLastProperty(cx, p->value().shape)) {
|
||||
cx->clearPendingException();
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -387,7 +387,7 @@ NativeObject::getChildPropertyOnDictionary(ExclusiveContext *cx, HandleNativeObj
|
||||
if (!shape)
|
||||
return nullptr;
|
||||
if (childRoot->hasSlot() && childRoot->slot() >= obj->lastProperty()->base()->slotSpan()) {
|
||||
if (!setSlotSpan(cx, obj, childRoot->slot() + 1))
|
||||
if (!obj->setSlotSpan(cx, childRoot->slot() + 1))
|
||||
return nullptr;
|
||||
}
|
||||
shape->initDictionaryShape(*childRoot, obj->numFixedSlots(), &obj->shape_);
|
||||
@ -401,7 +401,7 @@ NativeObject::getChildProperty(ExclusiveContext *cx,
|
||||
HandleNativeObject obj, HandleShape parent, StackShape &unrootedChild)
|
||||
{
|
||||
RootedGeneric<StackShape*> child(cx, &unrootedChild);
|
||||
RootedShape shape(cx, getChildPropertyOnDictionary(cx, obj, parent, *child));
|
||||
Shape *shape = getChildPropertyOnDictionary(cx, obj, parent, *child);
|
||||
|
||||
if (!obj->inDictionaryMode()) {
|
||||
shape = cx->compartment()->propertyTree.getChild(cx, parent, *child);
|
||||
@ -409,7 +409,7 @@ NativeObject::getChildProperty(ExclusiveContext *cx,
|
||||
return nullptr;
|
||||
//MOZ_ASSERT(shape->parent == parent);
|
||||
//MOZ_ASSERT_IF(parent != lastProperty(), parent == lastProperty()->parent);
|
||||
if (!setLastProperty(cx, obj, shape))
|
||||
if (!obj->setLastProperty(cx, shape))
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -1026,7 +1026,7 @@ NativeObject::removeProperty(ExclusiveContext *cx, jsid id_)
|
||||
/* static */ void
|
||||
NativeObject::clear(JSContext *cx, HandleNativeObject obj)
|
||||
{
|
||||
RootedShape shape(cx, obj->lastProperty());
|
||||
Shape *shape = obj->lastProperty();
|
||||
MOZ_ASSERT(obj->inDictionaryMode() == shape->inDictionary());
|
||||
|
||||
while (shape->parent) {
|
||||
@ -1038,7 +1038,7 @@ NativeObject::clear(JSContext *cx, HandleNativeObject obj)
|
||||
if (obj->inDictionaryMode())
|
||||
shape->listp = &obj->shape_;
|
||||
|
||||
JS_ALWAYS_TRUE(setLastProperty(cx, obj, shape));
|
||||
JS_ALWAYS_TRUE(obj->setLastProperty(cx, shape));
|
||||
|
||||
++cx->runtime()->propertyRemovals;
|
||||
obj->checkShapeConsistency();
|
||||
@ -1205,12 +1205,12 @@ Shape::setObjectMetadata(JSContext *cx, JSObject *metadata, TaggedProto proto, S
|
||||
}
|
||||
|
||||
bool
|
||||
JSObject::setFlag(ExclusiveContext *cx, /*BaseShape::Flag*/ uint32_t flag_,
|
||||
GenerateShape generateShape)
|
||||
JSObject::setFlags(ExclusiveContext *cx, /*BaseShape::Flag*/ uint32_t flags_,
|
||||
GenerateShape generateShape)
|
||||
{
|
||||
BaseShape::Flag flag = (BaseShape::Flag) flag_;
|
||||
BaseShape::Flag flags = (BaseShape::Flag) flags_;
|
||||
|
||||
if (lastProperty()->getObjectFlags() & flag)
|
||||
if ((lastProperty()->getObjectFlags() & flags) == flags)
|
||||
return true;
|
||||
|
||||
RootedObject self(cx, this);
|
||||
@ -1219,7 +1219,7 @@ JSObject::setFlag(ExclusiveContext *cx, /*BaseShape::Flag*/ uint32_t flag_,
|
||||
if (generateShape == GENERATE_SHAPE && !as<NativeObject>().generateOwnShape(cx))
|
||||
return false;
|
||||
StackBaseShape base(self->lastProperty());
|
||||
base.flags |= flag;
|
||||
base.flags |= flags;
|
||||
UnownedBaseShape *nbase = BaseShape::getUnowned(cx, base);
|
||||
if (!nbase)
|
||||
return false;
|
||||
@ -1229,7 +1229,7 @@ JSObject::setFlag(ExclusiveContext *cx, /*BaseShape::Flag*/ uint32_t flag_,
|
||||
}
|
||||
|
||||
Shape *newShape =
|
||||
Shape::setObjectFlag(cx, flag, self->getTaggedProto(), self->lastProperty());
|
||||
Shape::setObjectFlags(cx, flags, self->getTaggedProto(), self->lastProperty());
|
||||
if (!newShape)
|
||||
return false;
|
||||
|
||||
@ -1256,13 +1256,13 @@ NativeObject::clearFlag(ExclusiveContext *cx, BaseShape::Flag flag)
|
||||
}
|
||||
|
||||
/* static */ Shape *
|
||||
Shape::setObjectFlag(ExclusiveContext *cx, BaseShape::Flag flag, TaggedProto proto, Shape *last)
|
||||
Shape::setObjectFlags(ExclusiveContext *cx, BaseShape::Flag flags, TaggedProto proto, Shape *last)
|
||||
{
|
||||
if (last->getObjectFlags() & flag)
|
||||
if ((last->getObjectFlags() & flags) == flags)
|
||||
return last;
|
||||
|
||||
StackBaseShape base(last);
|
||||
base.flags |= flag;
|
||||
base.flags |= flags;
|
||||
|
||||
RootedShape lastRoot(cx, last);
|
||||
return replaceLastProperty(cx, base, proto, lastRoot);
|
||||
|
@ -834,8 +834,8 @@ class Shape : public gc::TenuredCell
|
||||
JSObject *obj, TaggedProto proto, Shape *last);
|
||||
static Shape *setObjectMetadata(JSContext *cx,
|
||||
JSObject *metadata, TaggedProto proto, Shape *last);
|
||||
static Shape *setObjectFlag(ExclusiveContext *cx,
|
||||
BaseShape::Flag flag, TaggedProto proto, Shape *last);
|
||||
static Shape *setObjectFlags(ExclusiveContext *cx,
|
||||
BaseShape::Flag flag, TaggedProto proto, Shape *last);
|
||||
|
||||
uint32_t getObjectFlags() const { return base()->getObjectFlags(); }
|
||||
bool hasObjectFlag(BaseShape::Flag flag) const {
|
||||
|
@ -197,7 +197,7 @@ UnboxedPlainObject::convertToNative(JSContext *cx)
|
||||
return false;
|
||||
|
||||
RootedNativeObject nobj(cx, &obj->as<PlainObject>());
|
||||
NativeObject::setLastPropertyMakeNative(cx, nobj, shape);
|
||||
nobj->setLastPropertyMakeNative(cx, shape);
|
||||
|
||||
for (size_t i = 0; i < values.length(); i++)
|
||||
nobj->initSlotUnchecked(i, values[i]);
|
||||
|
Loading…
Reference in New Issue
Block a user