Fix fixed slots invariant for slow arrays, bug 610592. r=brendan

This commit is contained in:
Brian Hackett
2010-11-15 17:21:58 -08:00
parent caa6dc275a
commit 3f4895f3e9
2 changed files with 52 additions and 10 deletions

View File

@@ -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