| Index: src/x64/codegen-x64.cc
|
| ===================================================================
|
| --- src/x64/codegen-x64.cc (revision 3613)
|
| +++ src/x64/codegen-x64.cc (working copy)
|
| @@ -815,7 +815,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);
|
|
|
| @@ -2706,7 +2706,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
|
| @@ -2767,7 +2767,7 @@
|
| frame_->EmitPush(rdx);
|
|
|
| // 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.
|
| @@ -2832,7 +2832,7 @@
|
| }
|
|
|
| // Call the function.
|
| - CallWithArguments(args, node->position());
|
| + CallWithArguments(args, RECEIVER_MIGHT_BE_VALUE, node->position());
|
| }
|
|
|
| } else {
|
| @@ -2847,7 +2847,7 @@
|
| LoadGlobalReceiver();
|
|
|
| // Call the function.
|
| - CallWithArguments(args, node->position());
|
| + CallWithArguments(args, NO_CALL_FUNCTION_FLAGS, node->position());
|
| }
|
| }
|
|
|
| @@ -6558,6 +6558,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();
|
| @@ -6570,7 +6571,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.
|
| @@ -6968,6 +6969,32 @@
|
| 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;
|
| + __ movq(rax, Operand(rsp, (argc_ + 1) * kPointerSize));
|
| +
|
| + // Check if receiver is a smi (which is a number value).
|
| + __ JumpIfSmi(rax, &receiver_is_value);
|
| +
|
| + // Check if the receiver is a valid JS object.
|
| + __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rdi);
|
| + __ j(above_equal, &receiver_is_js_object);
|
| +
|
| + // Call the runtime to box the value.
|
| + __ bind(&receiver_is_value);
|
| + __ EnterInternalFrame();
|
| + __ push(rax);
|
| + __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
|
| + __ LeaveInternalFrame();
|
| + __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rax);
|
| +
|
| + __ bind(&receiver_is_js_object);
|
| + }
|
| +
|
| // Get the function to call from the stack.
|
| // +2 ~ receiver, return address
|
| __ movq(rdi, Operand(rsp, (argc_ + 2) * kPointerSize));
|
|
|