зеркало из https://github.com/mozilla/gecko-dev.git
b=550351; don't abort recording when accessing out of range typed array element (return undefined instead); r=dvander
This commit is contained in:
Родитель
6c9717e4ea
Коммит
73cc73ed0a
|
@ -8638,10 +8638,10 @@ TraceRecorder::equalityHelper(jsval l, jsval r, LIns* l_ins, LIns* r_ins,
|
||||||
op = LIR_feq;
|
op = LIR_feq;
|
||||||
}
|
}
|
||||||
} else if (JSVAL_IS_NULL(l) && JSVAL_IS_SPECIAL(r)) {
|
} else if (JSVAL_IS_NULL(l) && JSVAL_IS_SPECIAL(r)) {
|
||||||
l_ins = lir->insImm(JSVAL_TO_SPECIAL(JSVAL_VOID));
|
l_ins = INS_VOID();
|
||||||
cond = (r == JSVAL_VOID);
|
cond = (r == JSVAL_VOID);
|
||||||
} else if (JSVAL_IS_SPECIAL(l) && JSVAL_IS_NULL(r)) {
|
} else if (JSVAL_IS_SPECIAL(l) && JSVAL_IS_NULL(r)) {
|
||||||
r_ins = lir->insImm(JSVAL_TO_SPECIAL(JSVAL_VOID));
|
r_ins = INS_VOID();
|
||||||
cond = (l == JSVAL_VOID);
|
cond = (l == JSVAL_VOID);
|
||||||
} else if (isNumber(l) && JSVAL_IS_STRING(r)) {
|
} else if (isNumber(l) && JSVAL_IS_STRING(r)) {
|
||||||
args[0] = r_ins, args[1] = cx_ins;
|
args[0] = r_ins, args[1] = cx_ins;
|
||||||
|
@ -12985,7 +12985,7 @@ TraceRecorder::denseArrayElement(jsval& oval, jsval& ival, jsval*& vp, LIns*& v_
|
||||||
CHECK_STATUS(guardPrototypeHasNoIndexedProperties(obj, obj_ins, MISMATCH_EXIT));
|
CHECK_STATUS(guardPrototypeHasNoIndexedProperties(obj, obj_ins, MISMATCH_EXIT));
|
||||||
|
|
||||||
// Return undefined and indicate that we didn't actually read this (addr_ins).
|
// Return undefined and indicate that we didn't actually read this (addr_ins).
|
||||||
v_ins = lir->insImm(JSVAL_TO_SPECIAL(JSVAL_VOID));
|
v_ins = INS_VOID();
|
||||||
addr_ins = NULL;
|
addr_ins = NULL;
|
||||||
return RECORD_CONTINUE;
|
return RECORD_CONTINUE;
|
||||||
}
|
}
|
||||||
|
@ -13057,9 +13057,16 @@ TraceRecorder::typedArrayElement(jsval& oval, jsval& ival, jsval*& vp, LIns*& v_
|
||||||
/* priv_ins will load the TypedArray* */
|
/* priv_ins will load the TypedArray* */
|
||||||
LIns* priv_ins = stobj_get_const_fslot(obj_ins, JSSLOT_PRIVATE);
|
LIns* priv_ins = stobj_get_const_fslot(obj_ins, JSSLOT_PRIVATE);
|
||||||
|
|
||||||
/* for out-of-range, just let the interpreter handle it */
|
/* for out-of-range, do the same thing that the interpreter does, which is return undefined */
|
||||||
if ((jsuint) idx >= tarray->length)
|
if ((jsuint) idx >= tarray->length) {
|
||||||
return ARECORD_STOP;
|
guard(false,
|
||||||
|
lir->ins2(LIR_ult,
|
||||||
|
idx_ins,
|
||||||
|
lir->insLoad(LIR_ldc, priv_ins, js::TypedArray::lengthOffset())),
|
||||||
|
BRANCH_EXIT);
|
||||||
|
v_ins = INS_VOID();
|
||||||
|
return ARECORD_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ensure idx < length
|
* Ensure idx < length
|
||||||
|
@ -13074,7 +13081,7 @@ TraceRecorder::typedArrayElement(jsval& oval, jsval& ival, jsval*& vp, LIns*& v_
|
||||||
lir->ins2(LIR_ult,
|
lir->ins2(LIR_ult,
|
||||||
idx_ins,
|
idx_ins,
|
||||||
lir->insLoad(LIR_ldc, priv_ins, js::TypedArray::lengthOffset())),
|
lir->insLoad(LIR_ldc, priv_ins, js::TypedArray::lengthOffset())),
|
||||||
OVERFLOW_EXIT);
|
BRANCH_EXIT);
|
||||||
|
|
||||||
/* We are now ready to load. Do a different type of load
|
/* We are now ready to load. Do a different type of load
|
||||||
* depending on what type of thing we're loading. */
|
* depending on what type of thing we're loading. */
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
function testTypedArrayTrace()
|
||||||
|
{
|
||||||
|
var ar = new Uint32Array(16);
|
||||||
|
|
||||||
|
for (var i = 0; i < ar.length-1; ++i) {
|
||||||
|
ar[i+1] = i + ar[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < ar.length; ++i) {
|
||||||
|
// deliberate out of bounds access
|
||||||
|
ar[i-2] = ar[i+2];
|
||||||
|
}
|
||||||
|
|
||||||
|
var t = 0;
|
||||||
|
for (var i = 0; i < ar.length; ++i) {
|
||||||
|
t += ar[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
assertEq(testTypedArrayTrace(), 752);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче