| Index: src/arm/codegen-arm.cc
|
| ===================================================================
|
| --- src/arm/codegen-arm.cc (revision 3613)
|
| +++ src/arm/codegen-arm.cc (working copy)
|
| @@ -1091,7 +1091,8 @@
|
|
|
| // Call the function on the stack with the given arguments.
|
| void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args,
|
| - int position) {
|
| + CallFunctionFlags flags,
|
| + int position) {
|
| VirtualFrame::SpilledScope spilled_scope;
|
| // Push the arguments ("left-to-right") on the stack.
|
| int arg_count = args->length();
|
| @@ -1104,7 +1105,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);
|
| frame_->CallStub(&call_function, arg_count + 1);
|
|
|
| // Restore context and pop function from the stack.
|
| @@ -2999,7 +3000,7 @@
|
| 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);
|
| frame_->CallStub(&call_function, arg_count + 1);
|
|
|
| __ ldr(cp, frame_->Context());
|
| @@ -3056,7 +3057,7 @@
|
| frame_->EmitPush(r1); // receiver
|
|
|
| // Call the function.
|
| - CallWithArguments(args, node->position());
|
| + CallWithArguments(args, NO_CALL_FUNCTION_FLAGS, node->position());
|
| frame_->EmitPush(r0);
|
|
|
| } else if (property != NULL) {
|
| @@ -3109,7 +3110,7 @@
|
| }
|
|
|
| // Call the function.
|
| - CallWithArguments(args, node->position());
|
| + CallWithArguments(args, RECEIVER_MIGHT_BE_VALUE, node->position());
|
| frame_->EmitPush(r0);
|
| }
|
|
|
| @@ -3125,7 +3126,7 @@
|
| LoadGlobalReceiver(r0);
|
|
|
| // Call the function.
|
| - CallWithArguments(args, node->position());
|
| + CallWithArguments(args, NO_CALL_FUNCTION_FLAGS, node->position());
|
| frame_->EmitPush(r0);
|
| }
|
| ASSERT(frame_->height() == original_height + 1);
|
| @@ -6601,6 +6602,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.
|
| + // function, receiver [, arguments]
|
| + Label receiver_is_value, receiver_is_js_object;
|
| + __ ldr(r1, MemOperand(sp, argc_ * kPointerSize));
|
| +
|
| + // Check if receiver is a smi (which is a number value).
|
| + __ BranchOnSmi(r1, &receiver_is_value);
|
| +
|
| + // Check if the receiver is a valid JS object.
|
| + __ CompareObjectType(r1, r2, r2, FIRST_JS_OBJECT_TYPE);
|
| + __ b(ge, &receiver_is_js_object);
|
| +
|
| + // Call the runtime to box the value.
|
| + __ bind(&receiver_is_value);
|
| + __ EnterInternalFrame();
|
| + __ push(r1);
|
| + __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS);
|
| + __ LeaveInternalFrame();
|
| + __ str(r0, MemOperand(sp, argc_ * kPointerSize));
|
| +
|
| + __ bind(&receiver_is_js_object);
|
| + }
|
| +
|
| // Get the function to call from the stack.
|
| // function, receiver [, arguments]
|
| __ ldr(r1, MemOperand(sp, (argc_ + 1) * kPointerSize));
|
|
|