X87: [builtins] Pass correct number of arguments after adapting arguments.
authorchunyang.dai <chunyang.dai@intel.com>
Mon, 7 Sep 2015 07:42:49 +0000 (00:42 -0700)
committerCommit bot <commit-bot@chromium.org>
Mon, 7 Sep 2015 07:43:00 +0000 (07:43 +0000)
port fbad63669e309e8c5c3f2ecf503df2fefaac79bb (r30467)

original commit message:

    The call protocol requires that the register dedicated to the number of
    actual arguments (i.e. rax on x64) always contains the actual arguments.
    That means after adapting arguments it should match the number of
    expected arguments.  But currently we pass some semi-random value
    (usually some stack address) after adapting arguments.

    It looks like this is currently not observable anywhere, because our
    builtins and functions either don't look at the number of arguments and
    just make hard coded (unchecked) assumptions, or are marked as "don't
    adapt arguments", which bypasses the broken code in the trampoline for
    arguments adaption.  Nevertheless this should be fixed.

BUG=

Review URL: https://codereview.chromium.org/1304893010

Cr-Commit-Position: refs/heads/master@{#30605}

src/x87/builtins-x87.cc

index 77f7938..74d71c0 100644 (file)
@@ -1643,16 +1643,17 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
 
     // Copy receiver and all expected arguments.
     const int offset = StandardFrameConstants::kCallerSPOffset;
-    __ lea(eax, Operand(ebp, eax, times_4, offset));
-    __ mov(edi, -1);  // account for receiver
+    __ lea(edi, Operand(ebp, eax, times_4, offset));
+    __ mov(eax, -1);  // account for receiver
 
     Label copy;
     __ bind(&copy);
-    __ inc(edi);
-    __ push(Operand(eax, 0));
-    __ sub(eax, Immediate(kPointerSize));
-    __ cmp(edi, ebx);
+    __ inc(eax);
+    __ push(Operand(edi, 0));
+    __ sub(edi, Immediate(kPointerSize));
+    __ cmp(eax, ebx);
     __ j(less, &copy);
+    // eax now contains the expected number of arguments.
     __ jmp(&invoke);
   }
 
@@ -1681,6 +1682,9 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
     __ bind(&no_strong_error);
     EnterArgumentsAdaptorFrame(masm);
 
+    // Remember expected arguments in ecx.
+    __ mov(ecx, ebx);
+
     // Copy receiver and all actual arguments.
     const int offset = StandardFrameConstants::kCallerSPOffset;
     __ lea(edi, Operand(ebp, eax, times_4, offset));
@@ -1705,12 +1709,17 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
     __ push(Immediate(masm->isolate()->factory()->undefined_value()));
     __ cmp(eax, ebx);
     __ j(less, &fill);
+
+    // Restore expected arguments.
+    __ mov(eax, ecx);
   }
 
   // Call the entry point.
   __ bind(&invoke);
   // Restore function pointer.
   __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
+  // eax : expected number of arguments
+  // edi : function (passed through to callee)
   __ call(edx);
 
   // Store offset of return address for deoptimizer.