| Index: src/ia32/codegen-ia32.cc
|
| ===================================================================
|
| --- src/ia32/codegen-ia32.cc (revision 3613)
|
| +++ src/ia32/codegen-ia32.cc (working copy)
|
| @@ -2289,6 +2289,7 @@
|
| // Call the function just below TOS on the stack with the given
|
| // arguments. The receiver is the TOS.
|
| void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args,
|
| + CallFunctionFlags flags,
|
| int position) {
|
| // Push the arguments ("left-to-right") on the stack.
|
| int arg_count = args->length();
|
| @@ -2301,7 +2302,7 @@
|
|
|
| // Use the shared code stub to call the function.
|
| InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP;
|
| - CallFunctionStub call_function(arg_count, in_loop);
|
| + CallFunctionStub call_function(arg_count, in_loop, flags);
|
| Result answer = frame_->CallStub(&call_function, arg_count + 1);
|
| // Restore context and replace function on the stack with the
|
| // result of the stub invocation.
|
| @@ -2471,7 +2472,7 @@
|
| frame_->Push(&fn);
|
| frame_->Push(&a1);
|
| frame_->Push(&a2);
|
| - CallFunctionStub call_function(2, NOT_IN_LOOP);
|
| + CallFunctionStub call_function(2, NOT_IN_LOOP, NO_CALL_FUNCTION_FLAGS);
|
| Result res = frame_->CallStub(&call_function, 3);
|
| frame_->Push(&res);
|
|
|
| @@ -4746,7 +4747,7 @@
|
| // Call the function.
|
| CodeForSourcePosition(node->position());
|
| InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP;
|
| - CallFunctionStub call_function(arg_count, in_loop);
|
| + CallFunctionStub call_function(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE);
|
| result = frame_->CallStub(&call_function, arg_count + 1);
|
|
|
| // Restore the context and overwrite the function on the stack with
|
| @@ -4806,7 +4807,7 @@
|
| frame_->EmitPush(edx);
|
|
|
| // Call the function.
|
| - CallWithArguments(args, node->position());
|
| + CallWithArguments(args, NO_CALL_FUNCTION_FLAGS, node->position());
|
|
|
| } else if (property != NULL) {
|
| // Check if the key is a literal string.
|
| @@ -4872,7 +4873,7 @@
|
| }
|
|
|
| // Call the function.
|
| - CallWithArguments(args, node->position());
|
| + CallWithArguments(args, RECEIVER_MIGHT_BE_VALUE, node->position());
|
| }
|
|
|
| } else {
|
| @@ -4887,7 +4888,7 @@
|
| LoadGlobalReceiver();
|
|
|
| // Call the function.
|
| - CallWithArguments(args, node->position());
|
| + CallWithArguments(args, NO_CALL_FUNCTION_FLAGS, node->position());
|
| }
|
| }
|
|
|
| @@ -8681,6 +8682,33 @@
|
| void CallFunctionStub::Generate(MacroAssembler* masm) {
|
| Label slow;
|
|
|
| + // If the receiver might be a value (string, number or boolean) check for this
|
| + // and box it if it is.
|
| + if (ReceiverMightBeValue()) {
|
| + // 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, not_taken);
|
| +
|
| + // 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);
|
| + }
|
| +
|
| // Get the function to call from the stack.
|
| // +2 ~ receiver, return address
|
| __ mov(edi, Operand(esp, (argc_ + 2) * kPointerSize));
|
|
|