Bug 809021 - Fix FastInvoke arguments length. r=dvander, a=akeybl

This commit is contained in:
Jan de Mooij 2012-11-14 09:58:23 +01:00
Родитель d2a17065b2
Коммит b12352fde4
4 изменённых файлов: 84 добавлений и 5 удалений

Просмотреть файл

@ -1287,7 +1287,7 @@ ion::CanEnter(JSContext *cx, HandleScript script, StackFrame *fp, bool newType)
}
MethodStatus
ion::CanEnterUsingFastInvoke(JSContext *cx, HandleScript script)
ion::CanEnterUsingFastInvoke(JSContext *cx, HandleScript script, uint32_t numActualArgs)
{
JS_ASSERT(ion::IsEnabled(cx));
@ -1295,6 +1295,11 @@ ion::CanEnterUsingFastInvoke(JSContext *cx, HandleScript script)
if (!script->hasIonScript() || script->ion->bailoutExpected())
return Method_Skipped;
// Don't handle arguments underflow, to make this work we would have to pad
// missing arguments with |undefined|.
if (numActualArgs < script->function()->nargs)
return Method_Skipped;
if (!cx->compartment->ensureIonCompartmentExists(cx))
return Method_Error;
@ -1491,11 +1496,12 @@ ion::FastInvoke(JSContext *cx, HandleFunction fun, CallArgsList &args)
EnterIonCode enter = cx->compartment->ionCompartment()->enterJITInfallible();
void *calleeToken = CalleeToToken(fun);
Value result = Int32Value(fun->nargs);
Value result = Int32Value(args.length());
JS_ASSERT(args.length() >= fun->nargs);
JSAutoResolveFlags rf(cx, RESOLVE_INFER);
args.setActive();
enter(jitcode, args.length() + 1, &args[0] - 1, fp, calleeToken, &result);
enter(jitcode, args.length() + 1, args.array() - 1, fp, calleeToken, &result);
args.setInactive();
if (clearCallingIntoIon)

Просмотреть файл

@ -226,7 +226,7 @@ bool SetIonContext(IonContext *ctx);
MethodStatus CanEnterAtBranch(JSContext *cx, HandleScript script,
StackFrame *fp, jsbytecode *pc);
MethodStatus CanEnter(JSContext *cx, HandleScript script, StackFrame *fp, bool newType);
MethodStatus CanEnterUsingFastInvoke(JSContext *cx, HandleScript script);
MethodStatus CanEnterUsingFastInvoke(JSContext *cx, HandleScript script, uint32_t numActualArgs);
enum IonExecStatus
{

Просмотреть файл

@ -0,0 +1,73 @@
// nactuals > nformals
function testOverflow() {
var called = false;
function f(a) {
assertEq(a, 173);
assertEq(arguments.length, 2);
assertEq(arguments[0], a);
assertEq(arguments[1], a);
called = true;
}
for (var i=0; i<10; i++)
[173, 173, 173].sort(f);
assertEq(called, true);
}
testOverflow();
// nactuals == nformals
function testEqual() {
var called = false;
function f(a, b) {
assertEq(a, 173);
assertEq(arguments.length, 2);
assertEq(arguments[0], a);
assertEq(arguments[1], b);
called = true;
}
for (var i=0; i<10; i++)
[173, 173, 173].sort(f);
assertEq(called, true);
}
testEqual();
// nactuals < nformals
function testUnderflow() {
var called = false;
function f(a, b, c) {
assertEq(a, 173);
assertEq(c, undefined);
assertEq(arguments.length, 2);
assertEq(arguments[0], a);
assertEq(arguments[1], b);
called = true;
}
for (var i=0; i<10; i++)
[173, 173, 173].sort(f);
assertEq(called, true);
}
testUnderflow();
function testUnderflowMany() {
var called = 0;
function f(a, b, c, d, e, f, g, h) {
assertEq(a, 173);
assertEq(arguments.length, 3);
assertEq(arguments[0], a);
assertEq(arguments[1] < 3, true);
assertEq(c.length, 3);
assertEq(d, undefined);
assertEq(e, undefined);
assertEq(f, undefined);
assertEq(g, undefined);
assertEq(h, undefined);
called += 1;
}
for (var i=0; i<10; i++)
[173, 173, 173].map(f);
assertEq(called, 30);
}
testUnderflowMany();

Просмотреть файл

@ -1031,7 +1031,7 @@ class FastInvokeGuard
if (useIon_ && fun_) {
JS_ASSERT(fun_->script() == script_);
ion::MethodStatus status = ion::CanEnterUsingFastInvoke(cx, script_);
ion::MethodStatus status = ion::CanEnterUsingFastInvoke(cx, script_, args_.length());
if (status == ion::Method_Error)
return false;
if (status == ion::Method_Compiled) {