[builtins] Make sure argument count is always valid for C++ builtins.
When calling into C++ builtins, we need to make sure that the argument count register contains the correct number of arguments, otherwise the CEntryStub will not be able to leave the stack in the correct state. R=ishell@chromium.org BUG=v8:4413 LOG=n Review URL: https://codereview.chromium.org/1391543002 Cr-Commit-Position: refs/heads/master@{#31120}
This commit is contained in:
parent
299c72bc88
commit
9c8262f11e
@ -22,11 +22,12 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm,
|
||||
BuiltinExtraArguments extra_args) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- r0 : number of arguments excluding receiver
|
||||
// -- r1 : called function (only guaranteed when
|
||||
// extra_args requires it)
|
||||
// (only guaranteed when the called function
|
||||
// is not marked as DontAdaptArguments)
|
||||
// -- r1 : called function
|
||||
// -- sp[0] : last argument
|
||||
// -- ...
|
||||
// -- sp[4 * (argc - 1)] : first argument (argc == r0)
|
||||
// -- sp[4 * (argc - 1)] : first argument
|
||||
// -- sp[4 * argc] : receiver
|
||||
// -----------------------------------
|
||||
__ AssertFunction(r1);
|
||||
@ -48,8 +49,17 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm,
|
||||
}
|
||||
|
||||
// JumpToExternalReference expects r0 to contain the number of arguments
|
||||
// including the receiver and the extra arguments.
|
||||
// including the receiver and the extra arguments. But r0 is only valid
|
||||
// if the called function is marked as DontAdaptArguments, otherwise we
|
||||
// need to load the argument count from the SharedFunctionInfo.
|
||||
__ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ ldr(r2,
|
||||
FieldMemOperand(r2, SharedFunctionInfo::kFormalParameterCountOffset));
|
||||
__ SmiUntag(r2);
|
||||
__ cmp(r2, Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel));
|
||||
__ mov(r0, r2, LeaveCC, ne);
|
||||
__ add(r0, r0, Operand(num_extra_args + 1));
|
||||
|
||||
__ JumpToExternalReference(ExternalReference(id, masm->isolate()));
|
||||
}
|
||||
|
||||
|
@ -49,11 +49,12 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm,
|
||||
BuiltinExtraArguments extra_args) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- x0 : number of arguments excluding receiver
|
||||
// -- x1 : called function (only guaranteed when
|
||||
// extra_args requires it)
|
||||
// (only guaranteed when the called function
|
||||
// is not marked as DontAdaptArguments)
|
||||
// -- x1 : called function
|
||||
// -- sp[0] : last argument
|
||||
// -- ...
|
||||
// -- sp[4 * (argc - 1)] : first argument (argc == x0)
|
||||
// -- sp[4 * (argc - 1)] : first argument
|
||||
// -- sp[4 * argc] : receiver
|
||||
// -----------------------------------
|
||||
__ AssertFunction(x1);
|
||||
@ -75,8 +76,16 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm,
|
||||
}
|
||||
|
||||
// JumpToExternalReference expects x0 to contain the number of arguments
|
||||
// including the receiver and the extra arguments.
|
||||
// including the receiver and the extra arguments. But x0 is only valid
|
||||
// if the called function is marked as DontAdaptArguments, otherwise we
|
||||
// need to load the argument count from the SharedFunctionInfo.
|
||||
__ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ Ldrsw(
|
||||
x2, FieldMemOperand(x2, SharedFunctionInfo::kFormalParameterCountOffset));
|
||||
__ Cmp(x2, SharedFunctionInfo::kDontAdaptArgumentsSentinel);
|
||||
__ Csel(x0, x0, x2, eq);
|
||||
__ Add(x0, x0, num_extra_args + 1);
|
||||
|
||||
__ JumpToExternalReference(ExternalReference(id, masm->isolate()));
|
||||
}
|
||||
|
||||
|
@ -22,12 +22,13 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm,
|
||||
BuiltinExtraArguments extra_args) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- eax : number of arguments excluding receiver
|
||||
// -- edi : called function (only guaranteed when
|
||||
// extra_args requires it)
|
||||
// (only guaranteed when the called function
|
||||
// is not marked as DontAdaptArguments)
|
||||
// -- edi : called function
|
||||
// -- esp[0] : return address
|
||||
// -- esp[4] : last argument
|
||||
// -- ...
|
||||
// -- esp[4 * argc] : first argument (argc == eax)
|
||||
// -- esp[4 * argc] : first argument
|
||||
// -- esp[4 * (argc +1)] : receiver
|
||||
// -----------------------------------
|
||||
__ AssertFunction(edi);
|
||||
@ -52,8 +53,22 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm,
|
||||
}
|
||||
|
||||
// JumpToExternalReference expects eax to contain the number of arguments
|
||||
// including the receiver and the extra arguments.
|
||||
// including the receiver and the extra arguments. But eax is only valid
|
||||
// if the called function is marked as DontAdaptArguments, otherwise we
|
||||
// need to load the argument count from the SharedFunctionInfo.
|
||||
Label argc, done_argc;
|
||||
__ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ mov(ebx,
|
||||
FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset));
|
||||
__ SmiUntag(ebx);
|
||||
__ cmp(ebx, SharedFunctionInfo::kDontAdaptArgumentsSentinel);
|
||||
__ j(equal, &argc, Label::kNear);
|
||||
__ lea(eax, Operand(ebx, num_extra_args + 1));
|
||||
__ jmp(&done_argc, Label::kNear);
|
||||
__ bind(&argc);
|
||||
__ add(eax, Immediate(num_extra_args + 1));
|
||||
__ bind(&done_argc);
|
||||
|
||||
__ JumpToExternalReference(ExternalReference(id, masm->isolate()));
|
||||
}
|
||||
|
||||
|
@ -23,8 +23,9 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm,
|
||||
BuiltinExtraArguments extra_args) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- a0 : number of arguments excluding receiver
|
||||
// -- a1 : called function (only guaranteed when
|
||||
// -- extra_args requires it)
|
||||
// (only guaranteed when the called function
|
||||
// is not marked as DontAdaptArguments)
|
||||
// -- a1 : called function
|
||||
// -- sp[0] : last argument
|
||||
// -- ...
|
||||
// -- sp[4 * (argc - 1)] : first argument
|
||||
@ -49,8 +50,22 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm,
|
||||
}
|
||||
|
||||
// JumpToExternalReference expects a0 to contain the number of arguments
|
||||
// including the receiver and the extra arguments.
|
||||
// including the receiver and the extra arguments. But a0 is only valid
|
||||
// if the called function is marked as DontAdaptArguments, otherwise we
|
||||
// need to load the argument count from the SharedFunctionInfo.
|
||||
Label argc, done_argc;
|
||||
__ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ lw(a2,
|
||||
FieldMemOperand(a2, SharedFunctionInfo::kFormalParameterCountOffset));
|
||||
__ SmiUntag(a2);
|
||||
__ Branch(&argc, ne, a2,
|
||||
Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel));
|
||||
__ Addu(a0, a2, num_extra_args + 1);
|
||||
__ jmp(&done_argc);
|
||||
__ bind(&argc);
|
||||
__ Addu(a0, a0, num_extra_args + 1);
|
||||
__ bind(&done_argc);
|
||||
|
||||
__ JumpToExternalReference(ExternalReference(id, masm->isolate()));
|
||||
}
|
||||
|
||||
|
@ -22,8 +22,9 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm,
|
||||
BuiltinExtraArguments extra_args) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- a0 : number of arguments excluding receiver
|
||||
// -- a1 : called function (only guaranteed when
|
||||
// -- extra_args requires it)
|
||||
// (only guaranteed when the called function
|
||||
// is not marked as DontAdaptArguments)
|
||||
// -- a1 : called function
|
||||
// -- sp[0] : last argument
|
||||
// -- ...
|
||||
// -- sp[8 * (argc - 1)] : first argument
|
||||
@ -48,8 +49,21 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm,
|
||||
}
|
||||
|
||||
// JumpToExternalReference expects a0 to contain the number of arguments
|
||||
// including the receiver and the extra arguments.
|
||||
// including the receiver and the extra arguments. But a0 is only valid
|
||||
// if the called function is marked as DontAdaptArguments, otherwise we
|
||||
// need to load the argument count from the SharedFunctionInfo.
|
||||
Label argc, done_argc;
|
||||
__ ld(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ lw(a2,
|
||||
FieldMemOperand(a2, SharedFunctionInfo::kFormalParameterCountOffset));
|
||||
__ Branch(&argc, ne, a2,
|
||||
Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel));
|
||||
__ Daddu(a0, a2, num_extra_args + 1);
|
||||
__ jmp(&done_argc);
|
||||
__ bind(&argc);
|
||||
__ Daddu(a0, a0, num_extra_args + 1);
|
||||
__ bind(&done_argc);
|
||||
|
||||
__ JumpToExternalReference(ExternalReference(id, masm->isolate()));
|
||||
}
|
||||
|
||||
|
@ -21,12 +21,13 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm,
|
||||
BuiltinExtraArguments extra_args) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- rax : number of arguments excluding receiver
|
||||
// -- rdi : called function (only guaranteed when
|
||||
// extra_args requires it)
|
||||
// (only guaranteed when the called function
|
||||
// is not marked as DontAdaptArguments)
|
||||
// -- rdi : called function
|
||||
// -- rsp[0] : return address
|
||||
// -- rsp[8] : last argument
|
||||
// -- ...
|
||||
// -- rsp[8 * argc] : first argument (argc == rax)
|
||||
// -- rsp[8 * argc] : first argument
|
||||
// -- rsp[8 * (argc + 1)] : receiver
|
||||
// -----------------------------------
|
||||
__ AssertFunction(rdi);
|
||||
@ -50,8 +51,21 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm,
|
||||
}
|
||||
|
||||
// JumpToExternalReference expects rax to contain the number of arguments
|
||||
// including the receiver and the extra arguments.
|
||||
// including the receiver and the extra arguments. But rax is only valid
|
||||
// if the called function is marked as DontAdaptArguments, otherwise we
|
||||
// need to load the argument count from the SharedFunctionInfo.
|
||||
Label argc, done_argc;
|
||||
__ movp(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ LoadSharedFunctionInfoSpecialField(
|
||||
rbx, rdx, SharedFunctionInfo::kFormalParameterCountOffset);
|
||||
__ cmpp(rbx, Immediate(SharedFunctionInfo::kDontAdaptArgumentsSentinel));
|
||||
__ j(equal, &argc, Label::kNear);
|
||||
__ leap(rax, Operand(rbx, num_extra_args + 1));
|
||||
__ jmp(&done_argc, Label::kNear);
|
||||
__ bind(&argc);
|
||||
__ addp(rax, Immediate(num_extra_args + 1));
|
||||
__ bind(&done_argc);
|
||||
|
||||
__ JumpToExternalReference(ExternalReference(id, masm->isolate()), 1);
|
||||
}
|
||||
|
||||
|
15
test/mjsunit/compiler/regress-4413-1.js
Normal file
15
test/mjsunit/compiler/regress-4413-1.js
Normal file
@ -0,0 +1,15 @@
|
||||
// Copyright 2015 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --allow-natives-syntax --turbo-asm
|
||||
|
||||
var foo = (function(stdlib) {
|
||||
"use asm";
|
||||
var bar = stdlib.Symbol;
|
||||
function foo() { return bar("lala"); }
|
||||
return foo;
|
||||
})(this);
|
||||
|
||||
%OptimizeFunctionOnNextCall(foo);
|
||||
foo();
|
Loading…
Reference in New Issue
Block a user