Index: src/builtins/s390/builtins-s390.cc |
diff --git a/src/builtins/s390/builtins-s390.cc b/src/builtins/s390/builtins-s390.cc |
index d6feab89dde33dad7d0fa4721999bd2184438c94..38dc3feb29cda3d6bdfea23eb02fc2fffc80af99 100644 |
--- a/src/builtins/s390/builtins-s390.cc |
+++ b/src/builtins/s390/builtins-s390.cc |
@@ -2315,6 +2315,75 @@ void Builtins::Generate_Apply(MacroAssembler* masm) { |
} |
} |
+// static |
+void Builtins::Generate_CallForwardVarargs(MacroAssembler* masm, |
+ Handle<Code> code) { |
+ // ----------- S t a t e ------------- |
+ // -- r3 : the target to call (can be any Object) |
+ // -- r4 : start index (to support rest parameters) |
+ // -- lr : return address. |
+ // -- sp[0] : thisArgument |
+ // ----------------------------------- |
+ |
+ // Check if we have an arguments adaptor frame below the function frame. |
+ Label arguments_adaptor, arguments_done; |
+ __ LoadP(r5, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
+ __ LoadP(ip, MemOperand(r5, CommonFrameConstants::kContextOrFrameTypeOffset)); |
+ __ CmpSmiLiteral(ip, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0); |
john.yan
2017/04/26 16:48:19
ip was pointer size (LoadP) here. Maybe try to use
|
+ __ beq(&arguments_adaptor); |
+ { |
+ __ LoadP(r2, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
+ __ LoadP(r2, FieldMemOperand(r2, JSFunction::kSharedFunctionInfoOffset)); |
+ __ LoadW(r2, FieldMemOperand( |
+ r2, SharedFunctionInfo::kFormalParameterCountOffset)); |
+ __ LoadRR(r5, fp); |
+ } |
+ __ b(&arguments_done); |
+ __ bind(&arguments_adaptor); |
+ { |
+ // Load the length from the ArgumentsAdaptorFrame. |
+ __ LoadP(r2, MemOperand(r5, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
+ } |
+ __ bind(&arguments_done); |
+ |
+ Label stack_empty, stack_done, stack_overflow; |
+ __ SmiUntag(r2); |
+ __ SubP(r2, r2, r4); |
+ __ CmpP(r2, Operand::Zero()); |
john.yan
2017/04/26 16:48:19
CmpP isn't necessary here since SubP sets CC impli
|
+ __ ble(&stack_empty); |
+ { |
+ // Check for stack overflow. |
+ Generate_StackOverflowCheck(masm, r2, r4, &stack_overflow); |
+ |
+ // Forward the arguments from the caller frame. |
+ { |
+ Label loop; |
+ __ AddP(r5, r5, Operand(kPointerSize)); |
+ __ LoadRR(r4, r2); |
+ __ bind(&loop); |
+ { |
+ __ ShiftLeftP(ip, r4, Operand(kPointerSizeLog2)); |
+ __ LoadP(ip, MemOperand(r5, ip)); |
+ __ push(ip); |
+ __ SubP(r4, r4, Operand(1)); |
+ __ CmpP(r4, Operand::Zero()); |
john.yan
2017/04/26 16:48:19
Same as above.
|
+ __ bne(&loop); |
+ } |
+ } |
+ } |
+ __ b(&stack_done); |
+ __ bind(&stack_overflow); |
+ __ TailCallRuntime(Runtime::kThrowStackOverflow); |
+ __ bind(&stack_empty); |
+ { |
+ // We just pass the receiver, which is already on the stack. |
+ __ mov(r2, Operand::Zero()); |
+ } |
+ __ bind(&stack_done); |
+ |
+ __ Jump(code, RelocInfo::CODE_TARGET); |
+} |
+ |
namespace { |
// Drops top JavaScript frame and an arguments adaptor frame below it (if |