Index: src/ia32/code-stubs-ia32.cc |
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc |
index ac0b64525ac1a7cac410ada0bb2415eeed05f8ca..797915f3140f523e2ff28758f2f8c590ce95997e 100644 |
--- a/src/ia32/code-stubs-ia32.cc |
+++ b/src/ia32/code-stubs-ia32.cc |
@@ -3952,29 +3952,19 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { |
// If the receiver might be a value (string, number or boolean) check for this |
Mads Ager (chromium)
2011/05/24 07:14:14
I will update this comment.
|
// and box it if it is. |
- if (ReceiverMightBeValue()) { |
+ if (ReceiverMightBeImplicit()) { |
+ Label call; |
// Get the receiver from the stack. |
// +1 ~ return address |
- Label receiver_is_value, receiver_is_js_object; |
__ mov(eax, Operand(esp, (argc_ + 1) * kPointerSize)); |
- |
- // Check if receiver is a smi (which is a number value). |
- __ test(eax, Immediate(kSmiTagMask)); |
- __ j(zero, &receiver_is_value); |
- |
- // Check if the receiver is a valid JS object. |
- __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, edi); |
- __ j(above_equal, &receiver_is_js_object); |
- |
- // Call the runtime to box the value. |
- __ bind(&receiver_is_value); |
- __ EnterInternalFrame(); |
- __ push(eax); |
- __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); |
- __ LeaveInternalFrame(); |
- __ mov(Operand(esp, (argc_ + 1) * kPointerSize), eax); |
- |
- __ bind(&receiver_is_js_object); |
+ // Call as function is indicated with the hole. |
+ __ cmp(eax, masm->isolate()->factory()->the_hole_value()); |
+ __ j(not_equal, &call, Label::kNear); |
+ // Patch the receiver on the stack with the global receiver object. |
+ __ mov(ebx, GlobalObjectOperand()); |
+ __ mov(ebx, FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset)); |
+ __ mov(Operand(esp, (argc_ + 1) * kPointerSize), ebx); |
+ __ bind(&call); |
} |
// Get the function to call from the stack. |
@@ -3985,12 +3975,24 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { |
__ test(edi, Immediate(kSmiTagMask)); |
__ j(zero, &slow); |
// Goto slow case if we do not have a function. |
- __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); |
+ __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx); |
__ j(not_equal, &slow); |
// Fast-case: Just invoke the function. |
ParameterCount actual(argc_); |
- __ InvokeFunction(edi, actual, JUMP_FUNCTION); |
+ |
+ if (ReceiverMightBeImplicit()) { |
+ Label call_as_function; |
+ __ cmp(eax, masm->isolate()->factory()->the_hole_value()); |
+ __ j(equal, &call_as_function); |
+ __ InvokeFunction(edi, actual, JUMP_FUNCTION); |
+ __ bind(&call_as_function); |
+ } |
+ __ InvokeFunction(edi, |
+ actual, |
+ JUMP_FUNCTION, |
+ NullCallWrapper(), |
+ CALL_AS_FUNCTION); |
// Slow-case: Non-function called. |
__ bind(&slow); |
@@ -4284,6 +4286,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { |
} |
__ mov(edx, Operand(edx, 0)); // deref address |
__ lea(edx, FieldOperand(edx, Code::kHeaderSize)); |
+ __ SetCallKind(ecx, CALL_AS_METHOD); |
__ call(Operand(edx)); |
// Unlink this frame from the handler chain. |