Fix fixed slots invariant for slow arrays, bug 610592. r=brendan
This commit is contained in:
@@ -1043,12 +1043,10 @@ JSObject::makeDenseArraySlow(JSContext *cx)
|
||||
*/
|
||||
JSObjectMap *oldMap = map;
|
||||
|
||||
/*
|
||||
* Create a native scope. All slow arrays other than Array.prototype get
|
||||
* the same initial shape.
|
||||
*/
|
||||
/* Create a native scope. */
|
||||
JSObject *arrayProto = getProto();
|
||||
if (!InitScopeForObject(cx, this, &js_SlowArrayClass, arrayProto, FINALIZE_OBJECT0))
|
||||
js::gc::FinalizeKind kind = js::gc::FinalizeKind(arena()->header()->thingKind);
|
||||
if (!InitScopeForObject(cx, this, &js_SlowArrayClass, arrayProto, kind))
|
||||
return false;
|
||||
|
||||
uint32 capacity = getDenseArrayCapacity();
|
||||
@@ -1064,7 +1062,11 @@ JSObject::makeDenseArraySlow(JSContext *cx)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Create new properties pointing to existing elements. */
|
||||
/*
|
||||
* Create new properties pointing to existing elements. Pack the array to
|
||||
* remove holes, so that shapes use successive slots (as for other objects).
|
||||
*/
|
||||
uint32 next = 0;
|
||||
for (uint32 i = 0; i < capacity; i++) {
|
||||
jsid id;
|
||||
if (!ValueToId(cx, Int32Value(i), &id)) {
|
||||
@@ -1072,17 +1074,28 @@ JSObject::makeDenseArraySlow(JSContext *cx)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getDenseArrayElement(i).isMagic(JS_ARRAY_HOLE)) {
|
||||
setDenseArrayElement(i, UndefinedValue());
|
||||
if (getDenseArrayElement(i).isMagic(JS_ARRAY_HOLE))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!addDataProperty(cx, id, i, JSPROP_ENUMERATE)) {
|
||||
setDenseArrayElement(next, getDenseArrayElement(i));
|
||||
|
||||
if (!addDataProperty(cx, id, next, JSPROP_ENUMERATE)) {
|
||||
setMap(oldMap);
|
||||
return false;
|
||||
}
|
||||
|
||||
next++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dense arrays with different numbers of slots but the same number of fixed
|
||||
* slots and the same non-hole indexes must use their fixed slots consistently.
|
||||
*/
|
||||
if (hasSlotsArray() && next <= numFixedSlots())
|
||||
revertToFixedSlots(cx);
|
||||
|
||||
ClearValueRange(slots + next, this->capacity - next, false);
|
||||
|
||||
/*
|
||||
* Finally, update class. If |this| is Array.prototype, then js_InitClass
|
||||
* will create an emptyShape whose class is &js_SlowArrayClass, to ensure
|
||||
|
||||
Reference in New Issue
Block a user