mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
[INFER] Fix cases where dense arrays have initialized length < capacity with disabled inference, bug 648357.
This commit is contained in:
parent
52950bca44
commit
814665de9f
3
js/src/jit-test/tests/basic/bug648357.js
Normal file
3
js/src/jit-test/tests/basic/bug648357.js
Normal file
@ -0,0 +1,3 @@
|
||||
var x = [1, 2, 3, 4, 5, 6, 7, 8];
|
||||
x.pop();
|
||||
x.push(9);
|
@ -1509,7 +1509,12 @@ InitArrayObject(JSContext *cx, JSObject *obj, jsuint length, const Value *vector
|
||||
/* Avoid ensureDenseArrayElements to skip sparse array checks there. */
|
||||
if (!obj->ensureSlots(cx, length))
|
||||
return false;
|
||||
|
||||
if (cx->typeInferenceEnabled())
|
||||
obj->setDenseArrayInitializedLength(length);
|
||||
else
|
||||
obj->backfillDenseArrayHoles();
|
||||
|
||||
bool hole = false;
|
||||
for (jsuint i = 0; i < length; i++) {
|
||||
obj->setDenseArrayElement(i, vector[i]);
|
||||
@ -1517,6 +1522,7 @@ InitArrayObject(JSContext *cx, JSObject *obj, jsuint length, const Value *vector
|
||||
}
|
||||
if (hole && !obj->setDenseArrayNotPacked(cx))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1583,6 +1589,7 @@ array_reverse(JSContext *cx, uintN argc, Value *vp)
|
||||
/* Fill out the array's initialized length to its proper length. */
|
||||
jsuint initlen = obj->getDenseArrayInitializedLength();
|
||||
if (len > initlen) {
|
||||
JS_ASSERT(cx->typeInferenceEnabled());
|
||||
if (!obj->setDenseArrayNotPacked(cx))
|
||||
return false;
|
||||
ClearValueRange(obj->getDenseArrayElements() + initlen, len - initlen, true);
|
||||
@ -2169,9 +2176,13 @@ ArrayCompPushImpl(JSContext *cx, JSObject *obj, const Value &v)
|
||||
*/
|
||||
if (!obj->ensureSlots(cx, length + 1))
|
||||
return false;
|
||||
if (!cx->typeInferenceEnabled())
|
||||
obj->backfillDenseArrayHoles();
|
||||
}
|
||||
obj->setDenseArrayLength(length + 1);
|
||||
|
||||
if (cx->typeInferenceEnabled())
|
||||
obj->setDenseArrayInitializedLength(length + 1);
|
||||
obj->setDenseArrayLength(length + 1);
|
||||
obj->setDenseArrayElement(length, v);
|
||||
return true;
|
||||
}
|
||||
@ -2259,9 +2270,16 @@ array_pop_dense(JSContext *cx, JSObject* obj, Value *vp)
|
||||
return JS_FALSE;
|
||||
if (!hole && DeleteArrayElement(cx, obj, index, true) < 0)
|
||||
return JS_FALSE;
|
||||
|
||||
obj->setDenseArrayLength(index);
|
||||
if (cx->typeInferenceEnabled()) {
|
||||
JS_ASSERT(!obj->isPackedDenseArray());
|
||||
if (index == obj->getDenseArrayInitializedLength() - 1)
|
||||
obj->setDenseArrayInitializedLength(index);
|
||||
if (!cx->markTypeArrayShrank(obj->getType()))
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
@ -2294,22 +2312,23 @@ array_shift(JSContext *cx, uintN argc, Value *vp)
|
||||
} else {
|
||||
length--;
|
||||
|
||||
if (obj->isDenseArray() && !js_PrototypeHasIndexedProperties(cx, obj)) {
|
||||
Value *elems = obj->getDenseArrayElements();
|
||||
jsuint initlen = obj->getDenseArrayInitializedLength();
|
||||
if (initlen > 0) {
|
||||
if (obj->isDenseArray() && !js_PrototypeHasIndexedProperties(cx, obj) &&
|
||||
length < obj->getDenseArrayCapacity() &&
|
||||
0 < obj->getDenseArrayInitializedLength()) {
|
||||
*vp = obj->getDenseArrayElement(0);
|
||||
if (vp->isMagic(JS_ARRAY_HOLE)) {
|
||||
vp->setUndefined();
|
||||
if (!cx->markTypeCallerUnexpected(TYPE_UNDEFINED))
|
||||
return JS_FALSE;
|
||||
}
|
||||
memmove(elems, elems + 1, (initlen - 1) * sizeof(jsval));
|
||||
obj->setDenseArrayInitializedLength(initlen - 1);
|
||||
} else {
|
||||
vp->setUndefined();
|
||||
if (!cx->markTypeCallerUnexpected(TYPE_UNDEFINED))
|
||||
Value *elems = obj->getDenseArrayElements();
|
||||
memmove(elems, elems + 1, length * sizeof(jsval));
|
||||
if (cx->typeInferenceEnabled()) {
|
||||
obj->setDenseArrayInitializedLength(obj->getDenseArrayInitializedLength() - 1);
|
||||
if (!cx->markTypeArrayShrank(obj->getType()))
|
||||
return JS_FALSE;
|
||||
} else {
|
||||
obj->setDenseArrayElement(length, MagicValue(JS_ARRAY_HOLE));
|
||||
}
|
||||
JS_ALWAYS_TRUE(obj->setArrayLength(cx, length));
|
||||
if (!js_SuppressDeletedIndexProperties(cx, obj, length, length + 1))
|
||||
|
@ -105,6 +105,7 @@ JSObject::ensureDenseArrayElements(JSContext *cx, uintN index, uintN extra)
|
||||
if (index < initLength)
|
||||
return ED_OK;
|
||||
if (index < currentCapacity) {
|
||||
JS_ASSERT(cx->typeInferenceEnabled());
|
||||
if (index > initLength) {
|
||||
if (!setDenseArrayNotPacked(cx))
|
||||
return ED_FAILED;
|
||||
@ -127,6 +128,7 @@ JSObject::ensureDenseArrayElements(JSContext *cx, uintN index, uintN extra)
|
||||
if (requiredCapacity <= initLength)
|
||||
return ED_OK;
|
||||
if (requiredCapacity <= currentCapacity) {
|
||||
JS_ASSERT(cx->typeInferenceEnabled());
|
||||
if (index > initLength) {
|
||||
ClearValueRange(getSlots() + initLength, index - initLength, true);
|
||||
if (!setDenseArrayNotPacked(cx))
|
||||
|
@ -4224,8 +4224,10 @@ JSObject::growSlots(JSContext *cx, size_t newcap)
|
||||
slots = tmpslots;
|
||||
capacity = actualCapacity;
|
||||
|
||||
/* Initialize the additional slots we added. */
|
||||
ClearValueRange(slots + oldcap, actualCapacity - oldcap, isDenseArray());
|
||||
if (!isDenseArray()) {
|
||||
/* Initialize the additional slots we added. This is not required for dense arrays. */
|
||||
ClearValueRange(slots + oldcap, actualCapacity - oldcap, false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -747,7 +747,7 @@ FrameState::computeAllocation(jsbytecode *target)
|
||||
continue;
|
||||
if (fe >= spBase && !isTemporary(fe))
|
||||
continue;
|
||||
if (isTemporary(fe) && target - script->code > loop->backedgeOffset())
|
||||
if (isTemporary(fe) && uint32(target - script->code) > loop->backedgeOffset())
|
||||
continue;
|
||||
alloc->set(reg, indexOfFe(fe), fe->data.synced());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user