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. */
|
/* Avoid ensureDenseArrayElements to skip sparse array checks there. */
|
||||||
if (!obj->ensureSlots(cx, length))
|
if (!obj->ensureSlots(cx, length))
|
||||||
return false;
|
return false;
|
||||||
obj->setDenseArrayInitializedLength(length);
|
|
||||||
|
if (cx->typeInferenceEnabled())
|
||||||
|
obj->setDenseArrayInitializedLength(length);
|
||||||
|
else
|
||||||
|
obj->backfillDenseArrayHoles();
|
||||||
|
|
||||||
bool hole = false;
|
bool hole = false;
|
||||||
for (jsuint i = 0; i < length; i++) {
|
for (jsuint i = 0; i < length; i++) {
|
||||||
obj->setDenseArrayElement(i, vector[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))
|
if (hole && !obj->setDenseArrayNotPacked(cx))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
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. */
|
/* Fill out the array's initialized length to its proper length. */
|
||||||
jsuint initlen = obj->getDenseArrayInitializedLength();
|
jsuint initlen = obj->getDenseArrayInitializedLength();
|
||||||
if (len > initlen) {
|
if (len > initlen) {
|
||||||
|
JS_ASSERT(cx->typeInferenceEnabled());
|
||||||
if (!obj->setDenseArrayNotPacked(cx))
|
if (!obj->setDenseArrayNotPacked(cx))
|
||||||
return false;
|
return false;
|
||||||
ClearValueRange(obj->getDenseArrayElements() + initlen, len - initlen, true);
|
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))
|
if (!obj->ensureSlots(cx, length + 1))
|
||||||
return false;
|
return false;
|
||||||
|
if (!cx->typeInferenceEnabled())
|
||||||
|
obj->backfillDenseArrayHoles();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cx->typeInferenceEnabled())
|
||||||
|
obj->setDenseArrayInitializedLength(length + 1);
|
||||||
obj->setDenseArrayLength(length + 1);
|
obj->setDenseArrayLength(length + 1);
|
||||||
obj->setDenseArrayInitializedLength(length + 1);
|
|
||||||
obj->setDenseArrayElement(length, v);
|
obj->setDenseArrayElement(length, v);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -2259,9 +2270,16 @@ array_pop_dense(JSContext *cx, JSObject* obj, Value *vp)
|
|||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
if (!hole && DeleteArrayElement(cx, obj, index, true) < 0)
|
if (!hole && DeleteArrayElement(cx, obj, index, true) < 0)
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
|
|
||||||
obj->setDenseArrayLength(index);
|
obj->setDenseArrayLength(index);
|
||||||
if (index == obj->getDenseArrayInitializedLength() - 1)
|
if (cx->typeInferenceEnabled()) {
|
||||||
obj->setDenseArrayInitializedLength(index);
|
JS_ASSERT(!obj->isPackedDenseArray());
|
||||||
|
if (index == obj->getDenseArrayInitializedLength() - 1)
|
||||||
|
obj->setDenseArrayInitializedLength(index);
|
||||||
|
if (!cx->markTypeArrayShrank(obj->getType()))
|
||||||
|
return JS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2294,23 +2312,24 @@ array_shift(JSContext *cx, uintN argc, Value *vp)
|
|||||||
} else {
|
} else {
|
||||||
length--;
|
length--;
|
||||||
|
|
||||||
if (obj->isDenseArray() && !js_PrototypeHasIndexedProperties(cx, obj)) {
|
if (obj->isDenseArray() && !js_PrototypeHasIndexedProperties(cx, obj) &&
|
||||||
Value *elems = obj->getDenseArrayElements();
|
length < obj->getDenseArrayCapacity() &&
|
||||||
jsuint initlen = obj->getDenseArrayInitializedLength();
|
0 < obj->getDenseArrayInitializedLength()) {
|
||||||
if (initlen > 0) {
|
*vp = obj->getDenseArrayElement(0);
|
||||||
*vp = obj->getDenseArrayElement(0);
|
if (vp->isMagic(JS_ARRAY_HOLE)) {
|
||||||
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();
|
vp->setUndefined();
|
||||||
if (!cx->markTypeCallerUnexpected(TYPE_UNDEFINED))
|
if (!cx->markTypeCallerUnexpected(TYPE_UNDEFINED))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
}
|
}
|
||||||
|
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));
|
JS_ALWAYS_TRUE(obj->setArrayLength(cx, length));
|
||||||
if (!js_SuppressDeletedIndexProperties(cx, obj, length, length + 1))
|
if (!js_SuppressDeletedIndexProperties(cx, obj, length, length + 1))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
|
@ -105,6 +105,7 @@ JSObject::ensureDenseArrayElements(JSContext *cx, uintN index, uintN extra)
|
|||||||
if (index < initLength)
|
if (index < initLength)
|
||||||
return ED_OK;
|
return ED_OK;
|
||||||
if (index < currentCapacity) {
|
if (index < currentCapacity) {
|
||||||
|
JS_ASSERT(cx->typeInferenceEnabled());
|
||||||
if (index > initLength) {
|
if (index > initLength) {
|
||||||
if (!setDenseArrayNotPacked(cx))
|
if (!setDenseArrayNotPacked(cx))
|
||||||
return ED_FAILED;
|
return ED_FAILED;
|
||||||
@ -127,6 +128,7 @@ JSObject::ensureDenseArrayElements(JSContext *cx, uintN index, uintN extra)
|
|||||||
if (requiredCapacity <= initLength)
|
if (requiredCapacity <= initLength)
|
||||||
return ED_OK;
|
return ED_OK;
|
||||||
if (requiredCapacity <= currentCapacity) {
|
if (requiredCapacity <= currentCapacity) {
|
||||||
|
JS_ASSERT(cx->typeInferenceEnabled());
|
||||||
if (index > initLength) {
|
if (index > initLength) {
|
||||||
ClearValueRange(getSlots() + initLength, index - initLength, true);
|
ClearValueRange(getSlots() + initLength, index - initLength, true);
|
||||||
if (!setDenseArrayNotPacked(cx))
|
if (!setDenseArrayNotPacked(cx))
|
||||||
|
@ -4224,8 +4224,10 @@ JSObject::growSlots(JSContext *cx, size_t newcap)
|
|||||||
slots = tmpslots;
|
slots = tmpslots;
|
||||||
capacity = actualCapacity;
|
capacity = actualCapacity;
|
||||||
|
|
||||||
/* Initialize the additional slots we added. */
|
if (!isDenseArray()) {
|
||||||
ClearValueRange(slots + oldcap, actualCapacity - oldcap, isDenseArray());
|
/* Initialize the additional slots we added. This is not required for dense arrays. */
|
||||||
|
ClearValueRange(slots + oldcap, actualCapacity - oldcap, false);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -747,7 +747,7 @@ FrameState::computeAllocation(jsbytecode *target)
|
|||||||
continue;
|
continue;
|
||||||
if (fe >= spBase && !isTemporary(fe))
|
if (fe >= spBase && !isTemporary(fe))
|
||||||
continue;
|
continue;
|
||||||
if (isTemporary(fe) && target - script->code > loop->backedgeOffset())
|
if (isTemporary(fe) && uint32(target - script->code) > loop->backedgeOffset())
|
||||||
continue;
|
continue;
|
||||||
alloc->set(reg, indexOfFe(fe), fe->data.synced());
|
alloc->set(reg, indexOfFe(fe), fe->data.synced());
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user