Don't trace apply with overridden argsobj length (bug 541191, r=dmandelin).

This commit is contained in:
David Anderson 2010-10-05 10:25:41 -07:00
parent e911cb2f1c
commit 36107152d8
6 changed files with 124 additions and 1 deletions

View File

@ -13472,6 +13472,9 @@ TraceRecorder::record_JSOP_APPLY()
JSStackFrame *afp = guardArguments(aobj, aobj_ins, &depth);
if (!afp)
RETURN_STOP_A("can't reach arguments object's frame");
if (aobj->isArgsLengthOverridden())
RETURN_STOP_A("can't trace arguments with overridden length");
guardArgsLengthNotAssigned(aobj_ins);
length = afp->numActualArgs();
} else {
RETURN_STOP_A("arguments parameter of apply is not a dense array or argments object");
@ -15233,7 +15236,7 @@ TraceRecorder::guardArgsLengthNotAssigned(LIns* argsobj_ins)
// ARGS_LENGTH_OVERRIDDEN_BIT is set if length was overridden.
LIns *len_ins = stobj_get_fslot_uint32(argsobj_ins, JSObject::JSSLOT_ARGS_LENGTH);
LIns *ovr_ins = lir->ins2(LIR_andi, len_ins, INS_CONST(JSObject::ARGS_LENGTH_OVERRIDDEN_BIT));
guard(true, lir->insEqI_0(ovr_ins), snapshot(BRANCH_EXIT));
guard(true, lir->insEqI_0(ovr_ins), snapshot(MISMATCH_EXIT));
return len_ins;
}

View File

@ -0,0 +1,23 @@
/* vim: set ts=4 sw=4 tw=99 et: */
function g(a, b, c, d) {
return "" + a + b + c + d;
}
var x = 1;
function f(a, b, c) {
arguments[1] = 2;
arguments[2] = 3;
arguments[3] = 4;
if (!x)
arguments.length = 4;
var k;
for (var i = 0; i < 10; i++)
k = g.apply(this, arguments);
return k;
}
assertEq(f(1), "1undefinedundefinedundefined");
x = 0;
assertEq(f(1), "1234");

View File

@ -0,0 +1,23 @@
/* vim: set ts=4 sw=4 tw=99 et: */
function g(a, b, c, d) {
return "" + a + b + c + d;
}
var x = 1;
function f(a, b, c) {
arguments[1] = 2;
arguments[2] = 3;
arguments[3] = 4;
if (x)
arguments.length = 4;
var k;
for (var i = 0; i < RUNLOOP; i++)
k = g.apply(this, arguments);
return k;
}
assertEq(f(1), "1234");
x = 0;
assertEq(f(1), "1undefinedundefinedundefined");

View File

@ -0,0 +1,23 @@
/* vim: set ts=4 sw=4 tw=99 et: */
function g(a, b, c, d) {
return "" + a + b + c + d;
}
var x = 1;
function f(a, b, c) {
arguments[1] = 2;
arguments[2] = 3;
arguments[3] = 4;
if (x)
arguments.length = 1;
var k;
for (var i = 0; i < 10; i++)
k = g.apply(this, arguments);
return k;
}
assertEq(f(1), "1undefinedundefinedundefined");
x = 0;
assertEq(f(1), "1undefinedundefinedundefined");

View File

@ -0,0 +1,27 @@
/* vim: set ts=4 sw=4 tw=99 et: */
function g(a, b, c, d) {
return "" + a + b + c + d;
}
var x = 1;
function f(a, b, c) {
arguments[1] = 2;
arguments[2] = 3;
arguments[3] = 4;
if (x) {
arguments.length = 1;
delete arguments.length;
arguments.__defineGetter__('length', function () { return eval('1'); });
}
var k;
for (var i = 0; i < 10; i++)
k = g.apply(this, arguments);
return k;
}
assertEq(f(1), "1undefinedundefinedundefined");
x = 0;
assertEq(f(1), "1undefinedundefinedundefined");

View File

@ -0,0 +1,24 @@
/* vim: set ts=4 sw=4 tw=99 et: */
function g(a, b, c, d) {
return "" + a + b + c + d;
}
var x = 1;
function f(a, b, c) {
arguments[1] = 2;
arguments[2] = 3;
arguments[3] = 4;
if (x)
arguments.length = 1;
var k;
for (var i = 0; i < 10; i++)
k = g.apply(this, arguments);
return k;
}
assertEq(f(1), "1undefinedundefinedundefined");
x = 0;
assertEq(f(1), "1undefinedundefinedundefined");