| Index: src/ia32/builtins-ia32.cc
|
| ===================================================================
|
| --- src/ia32/builtins-ia32.cc (revision 3473)
|
| +++ src/ia32/builtins-ia32.cc (working copy)
|
| @@ -472,35 +472,38 @@
|
| __ bind(&done);
|
| }
|
|
|
| - // 4. Shift stuff one slot down the stack.
|
| + // 4. Check that the function really is a function.
|
| + { Label done;
|
| + __ test(edi, Operand(edi));
|
| + __ j(not_zero, &done, taken);
|
| + __ xor_(ebx, Operand(ebx));
|
| + // CALL_NON_FUNCTION will expect to find the non-function callee on the
|
| + // expression stack of the caller. Transfer it from receiver to the
|
| + // caller's expression stack (and make the first argument the receiver
|
| + // for CALL_NON_FUNCTION) by decrementing the argument count.
|
| + __ dec(eax);
|
| + __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
|
| + __ jmp(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)),
|
| + RelocInfo::CODE_TARGET);
|
| + __ bind(&done);
|
| + }
|
| +
|
| + // 5. Shift arguments and return address one slot down on the stack
|
| + // (overwriting the receiver).
|
| { Label loop;
|
| - __ lea(ecx, Operand(eax, +1)); // +1 ~ copy receiver too
|
| + __ mov(ecx, eax);
|
| __ bind(&loop);
|
| __ mov(ebx, Operand(esp, ecx, times_4, 0));
|
| __ mov(Operand(esp, ecx, times_4, kPointerSize), ebx);
|
| __ dec(ecx);
|
| - __ j(not_zero, &loop);
|
| + __ j(not_sign, &loop);
|
| + __ pop(ebx); // Discard copy of return address.
|
| + __ dec(eax); // One fewer argument (first argument is new receiver).
|
| }
|
|
|
| - // 5. Remove TOS (copy of last arguments), but keep return address.
|
| - __ pop(ebx);
|
| - __ pop(ecx);
|
| - __ push(ebx);
|
| - __ dec(eax);
|
| -
|
| - // 6. Check that function really was a function and get the code to
|
| - // call from the function and check that the number of expected
|
| - // arguments matches what we're providing.
|
| - { Label invoke;
|
| - __ test(edi, Operand(edi));
|
| - __ j(not_zero, &invoke, taken);
|
| - __ xor_(ebx, Operand(ebx));
|
| - __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
|
| - __ jmp(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)),
|
| - RelocInfo::CODE_TARGET);
|
| -
|
| - __ bind(&invoke);
|
| - __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
|
| + // 6. Get the code to call from the function and check that the number of
|
| + // expected arguments matches what we're providing.
|
| + { __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
|
| __ mov(ebx,
|
| FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset));
|
| __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kCodeOffset));
|
|
|