Index: src/builtins/mips64/builtins-mips64.cc |
diff --git a/src/builtins/mips64/builtins-mips64.cc b/src/builtins/mips64/builtins-mips64.cc |
index cb469c5b4e8e2e2c1e5b0d0d2c68314cacb25c84..46ffdd49480ea76731afa1e58d2efcfb1707bcab 100644 |
--- a/src/builtins/mips64/builtins-mips64.cc |
+++ b/src/builtins/mips64/builtins-mips64.cc |
@@ -2301,6 +2301,72 @@ void Builtins::Generate_Apply(MacroAssembler* masm) { |
} |
} |
+// static |
+void Builtins::Generate_CallForwardVarargs(MacroAssembler* masm, |
+ Handle<Code> code) { |
+ // ----------- S t a t e ------------- |
+ // -- a1 : the target to call (can be any Object) |
+ // -- a2 : start index (to support rest parameters) |
+ // -- ra : return address. |
+ // -- sp[0] : thisArgument |
+ // ----------------------------------- |
+ |
+ // Check if we have an arguments adaptor frame below the function frame. |
+ Label arguments_adaptor, arguments_done; |
+ __ ld(a3, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
+ __ ld(a0, MemOperand(a3, CommonFrameConstants::kContextOrFrameTypeOffset)); |
+ __ Branch(&arguments_adaptor, eq, a0, |
+ Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
+ { |
+ __ ld(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
+ __ ld(a0, FieldMemOperand(a0, JSFunction::kSharedFunctionInfoOffset)); |
+ __ lw(a0, |
+ FieldMemOperand(a0, SharedFunctionInfo::kFormalParameterCountOffset)); |
+ __ mov(a3, fp); |
+ } |
+ __ Branch(&arguments_done); |
+ __ bind(&arguments_adaptor); |
+ { |
+ // Just get the length from the ArgumentsAdaptorFrame. |
+ __ lw(a0, UntagSmiMemOperand( |
+ a3, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
+ } |
+ __ bind(&arguments_done); |
+ |
+ Label stack_empty, stack_done, stack_overflow; |
+ __ Subu(a0, a0, a2); |
+ __ Branch(&stack_empty, le, a0, Operand(zero_reg)); |
+ { |
+ // Check for stack overflow. |
+ Generate_StackOverflowCheck(masm, a0, a4, a5, &stack_overflow); |
+ |
+ // Forward the arguments from the caller frame. |
+ { |
+ Label loop; |
+ __ mov(a2, a0); |
+ __ bind(&loop); |
+ { |
+ __ Dlsa(at, a3, a2, kPointerSizeLog2); |
+ __ ld(at, MemOperand(at, 1 * kPointerSize)); |
+ __ push(at); |
+ __ Subu(a2, a2, Operand(1)); |
+ __ Branch(&loop, ne, a2, Operand(zero_reg)); |
+ } |
+ } |
+ } |
+ __ Branch(&stack_done); |
+ __ bind(&stack_overflow); |
+ __ TailCallRuntime(Runtime::kThrowStackOverflow); |
+ __ bind(&stack_empty); |
+ { |
+ // We just pass the receiver, which is already on the stack. |
+ __ mov(a0, zero_reg); |
+ } |
+ __ bind(&stack_done); |
+ |
+ __ Jump(code, RelocInfo::CODE_TARGET); |
+} |
+ |
namespace { |
// Drops top JavaScript frame and an arguments adaptor frame below it (if |