зеркало из https://github.com/mozilla/gecko-dev.git
Bug 809021 - Fix FastInvoke arguments length. r=dvander, a=akeybl
This commit is contained in:
Родитель
d2a17065b2
Коммит
b12352fde4
|
@ -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) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче