| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 1073 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1084 smi.Bind(); | 1084 smi.Bind(); |
| 1085 __ cmp(r1, Operand(r0)); | 1085 __ cmp(r1, Operand(r0)); |
| 1086 | 1086 |
| 1087 exit.Bind(); | 1087 exit.Bind(); |
| 1088 cc_reg_ = cc; | 1088 cc_reg_ = cc; |
| 1089 } | 1089 } |
| 1090 | 1090 |
| 1091 | 1091 |
| 1092 // Call the function on the stack with the given arguments. | 1092 // Call the function on the stack with the given arguments. |
| 1093 void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args, | 1093 void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args, |
| 1094 int position) { | 1094 CallFunctionFlags flags, |
| 1095 int position) { |
| 1095 VirtualFrame::SpilledScope spilled_scope; | 1096 VirtualFrame::SpilledScope spilled_scope; |
| 1096 // Push the arguments ("left-to-right") on the stack. | 1097 // Push the arguments ("left-to-right") on the stack. |
| 1097 int arg_count = args->length(); | 1098 int arg_count = args->length(); |
| 1098 for (int i = 0; i < arg_count; i++) { | 1099 for (int i = 0; i < arg_count; i++) { |
| 1099 LoadAndSpill(args->at(i)); | 1100 LoadAndSpill(args->at(i)); |
| 1100 } | 1101 } |
| 1101 | 1102 |
| 1102 // Record the position for debugging purposes. | 1103 // Record the position for debugging purposes. |
| 1103 CodeForSourcePosition(position); | 1104 CodeForSourcePosition(position); |
| 1104 | 1105 |
| 1105 // Use the shared code stub to call the function. | 1106 // Use the shared code stub to call the function. |
| 1106 InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP; | 1107 InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP; |
| 1107 CallFunctionStub call_function(arg_count, in_loop); | 1108 CallFunctionStub call_function(arg_count, in_loop, flags); |
| 1108 frame_->CallStub(&call_function, arg_count + 1); | 1109 frame_->CallStub(&call_function, arg_count + 1); |
| 1109 | 1110 |
| 1110 // Restore context and pop function from the stack. | 1111 // Restore context and pop function from the stack. |
| 1111 __ ldr(cp, frame_->Context()); | 1112 __ ldr(cp, frame_->Context()); |
| 1112 frame_->Drop(); // discard the TOS | 1113 frame_->Drop(); // discard the TOS |
| 1113 } | 1114 } |
| 1114 | 1115 |
| 1115 | 1116 |
| 1116 void CodeGenerator::Branch(bool if_true, JumpTarget* target) { | 1117 void CodeGenerator::Branch(bool if_true, JumpTarget* target) { |
| 1117 VirtualFrame::SpilledScope spilled_scope; | 1118 VirtualFrame::SpilledScope spilled_scope; |
| (...skipping 1874 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2992 frame_->CallRuntime(Runtime::kResolvePossiblyDirectEval, 3); | 2993 frame_->CallRuntime(Runtime::kResolvePossiblyDirectEval, 3); |
| 2993 | 2994 |
| 2994 // Touch up stack with the right values for the function and the receiver. | 2995 // Touch up stack with the right values for the function and the receiver. |
| 2995 __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2996 __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 2996 __ str(r1, MemOperand(sp, arg_count * kPointerSize)); | 2997 __ str(r1, MemOperand(sp, arg_count * kPointerSize)); |
| 2997 | 2998 |
| 2998 // Call the function. | 2999 // Call the function. |
| 2999 CodeForSourcePosition(node->position()); | 3000 CodeForSourcePosition(node->position()); |
| 3000 | 3001 |
| 3001 InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP; | 3002 InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP; |
| 3002 CallFunctionStub call_function(arg_count, in_loop); | 3003 CallFunctionStub call_function(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); |
| 3003 frame_->CallStub(&call_function, arg_count + 1); | 3004 frame_->CallStub(&call_function, arg_count + 1); |
| 3004 | 3005 |
| 3005 __ ldr(cp, frame_->Context()); | 3006 __ ldr(cp, frame_->Context()); |
| 3006 // Remove the function from the stack. | 3007 // Remove the function from the stack. |
| 3007 frame_->Drop(); | 3008 frame_->Drop(); |
| 3008 frame_->EmitPush(r0); | 3009 frame_->EmitPush(r0); |
| 3009 | 3010 |
| 3010 } else if (var != NULL && !var->is_this() && var->is_global()) { | 3011 } else if (var != NULL && !var->is_this() && var->is_global()) { |
| 3011 // ---------------------------------- | 3012 // ---------------------------------- |
| 3012 // JavaScript example: 'foo(1, 2, 3)' // foo is global | 3013 // JavaScript example: 'foo(1, 2, 3)' // foo is global |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3049 __ mov(r0, Operand(var->name())); | 3050 __ mov(r0, Operand(var->name())); |
| 3050 frame_->EmitPush(r0); | 3051 frame_->EmitPush(r0); |
| 3051 frame_->CallRuntime(Runtime::kLoadContextSlot, 2); | 3052 frame_->CallRuntime(Runtime::kLoadContextSlot, 2); |
| 3052 // r0: slot value; r1: receiver | 3053 // r0: slot value; r1: receiver |
| 3053 | 3054 |
| 3054 // Load the receiver. | 3055 // Load the receiver. |
| 3055 frame_->EmitPush(r0); // function | 3056 frame_->EmitPush(r0); // function |
| 3056 frame_->EmitPush(r1); // receiver | 3057 frame_->EmitPush(r1); // receiver |
| 3057 | 3058 |
| 3058 // Call the function. | 3059 // Call the function. |
| 3059 CallWithArguments(args, node->position()); | 3060 CallWithArguments(args, NO_CALL_FUNCTION_FLAGS, node->position()); |
| 3060 frame_->EmitPush(r0); | 3061 frame_->EmitPush(r0); |
| 3061 | 3062 |
| 3062 } else if (property != NULL) { | 3063 } else if (property != NULL) { |
| 3063 // Check if the key is a literal string. | 3064 // Check if the key is a literal string. |
| 3064 Literal* literal = property->key()->AsLiteral(); | 3065 Literal* literal = property->key()->AsLiteral(); |
| 3065 | 3066 |
| 3066 if (literal != NULL && literal->handle()->IsSymbol()) { | 3067 if (literal != NULL && literal->handle()->IsSymbol()) { |
| 3067 // ------------------------------------------------------------------ | 3068 // ------------------------------------------------------------------ |
| 3068 // JavaScript example: 'object.foo(1, 2, 3)' or 'map["key"](1, 2, 3)' | 3069 // JavaScript example: 'object.foo(1, 2, 3)' or 'map["key"](1, 2, 3)' |
| 3069 // ------------------------------------------------------------------ | 3070 // ------------------------------------------------------------------ |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3102 | 3103 |
| 3103 // Pass receiver to called function. | 3104 // Pass receiver to called function. |
| 3104 if (property->is_synthetic()) { | 3105 if (property->is_synthetic()) { |
| 3105 LoadGlobalReceiver(r0); | 3106 LoadGlobalReceiver(r0); |
| 3106 } else { | 3107 } else { |
| 3107 __ ldr(r0, frame_->ElementAt(ref.size())); | 3108 __ ldr(r0, frame_->ElementAt(ref.size())); |
| 3108 frame_->EmitPush(r0); | 3109 frame_->EmitPush(r0); |
| 3109 } | 3110 } |
| 3110 | 3111 |
| 3111 // Call the function. | 3112 // Call the function. |
| 3112 CallWithArguments(args, node->position()); | 3113 CallWithArguments(args, RECEIVER_MIGHT_BE_VALUE, node->position()); |
| 3113 frame_->EmitPush(r0); | 3114 frame_->EmitPush(r0); |
| 3114 } | 3115 } |
| 3115 | 3116 |
| 3116 } else { | 3117 } else { |
| 3117 // ---------------------------------- | 3118 // ---------------------------------- |
| 3118 // JavaScript example: 'foo(1, 2, 3)' // foo is not global | 3119 // JavaScript example: 'foo(1, 2, 3)' // foo is not global |
| 3119 // ---------------------------------- | 3120 // ---------------------------------- |
| 3120 | 3121 |
| 3121 // Load the function. | 3122 // Load the function. |
| 3122 LoadAndSpill(function); | 3123 LoadAndSpill(function); |
| 3123 | 3124 |
| 3124 // Pass the global proxy as the receiver. | 3125 // Pass the global proxy as the receiver. |
| 3125 LoadGlobalReceiver(r0); | 3126 LoadGlobalReceiver(r0); |
| 3126 | 3127 |
| 3127 // Call the function. | 3128 // Call the function. |
| 3128 CallWithArguments(args, node->position()); | 3129 CallWithArguments(args, NO_CALL_FUNCTION_FLAGS, node->position()); |
| 3129 frame_->EmitPush(r0); | 3130 frame_->EmitPush(r0); |
| 3130 } | 3131 } |
| 3131 ASSERT(frame_->height() == original_height + 1); | 3132 ASSERT(frame_->height() == original_height + 1); |
| 3132 } | 3133 } |
| 3133 | 3134 |
| 3134 | 3135 |
| 3135 void CodeGenerator::VisitCallNew(CallNew* node) { | 3136 void CodeGenerator::VisitCallNew(CallNew* node) { |
| 3136 #ifdef DEBUG | 3137 #ifdef DEBUG |
| 3137 int original_height = frame_->height(); | 3138 int original_height = frame_->height(); |
| 3138 #endif | 3139 #endif |
| (...skipping 3455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6594 __ str(r3, MemOperand(sp, 1 * kPointerSize)); | 6595 __ str(r3, MemOperand(sp, 1 * kPointerSize)); |
| 6595 | 6596 |
| 6596 // Do the runtime call to allocate the arguments object. | 6597 // Do the runtime call to allocate the arguments object. |
| 6597 __ bind(&runtime); | 6598 __ bind(&runtime); |
| 6598 __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3, 1); | 6599 __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3, 1); |
| 6599 } | 6600 } |
| 6600 | 6601 |
| 6601 | 6602 |
| 6602 void CallFunctionStub::Generate(MacroAssembler* masm) { | 6603 void CallFunctionStub::Generate(MacroAssembler* masm) { |
| 6603 Label slow; | 6604 Label slow; |
| 6605 |
| 6606 // If the receiver might be a value (string, number or boolean) check for this |
| 6607 // and box it if it is. |
| 6608 if (ReceiverMightBeValue()) { |
| 6609 // Get the receiver from the stack. |
| 6610 // function, receiver [, arguments] |
| 6611 Label receiver_is_value, receiver_is_js_object; |
| 6612 __ ldr(r1, MemOperand(sp, argc_ * kPointerSize)); |
| 6613 |
| 6614 // Check if receiver is a smi (which is a number value). |
| 6615 __ BranchOnSmi(r1, &receiver_is_value); |
| 6616 |
| 6617 // Check if the receiver is a valid JS object. |
| 6618 __ CompareObjectType(r1, r2, r2, FIRST_JS_OBJECT_TYPE); |
| 6619 __ b(ge, &receiver_is_js_object); |
| 6620 |
| 6621 // Call the runtime to box the value. |
| 6622 __ bind(&receiver_is_value); |
| 6623 __ EnterInternalFrame(); |
| 6624 __ push(r1); |
| 6625 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS); |
| 6626 __ LeaveInternalFrame(); |
| 6627 __ str(r0, MemOperand(sp, argc_ * kPointerSize)); |
| 6628 |
| 6629 __ bind(&receiver_is_js_object); |
| 6630 } |
| 6631 |
| 6604 // Get the function to call from the stack. | 6632 // Get the function to call from the stack. |
| 6605 // function, receiver [, arguments] | 6633 // function, receiver [, arguments] |
| 6606 __ ldr(r1, MemOperand(sp, (argc_ + 1) * kPointerSize)); | 6634 __ ldr(r1, MemOperand(sp, (argc_ + 1) * kPointerSize)); |
| 6607 | 6635 |
| 6608 // Check that the function is really a JavaScript function. | 6636 // Check that the function is really a JavaScript function. |
| 6609 // r1: pushed function (to be verified) | 6637 // r1: pushed function (to be verified) |
| 6610 __ BranchOnSmi(r1, &slow); | 6638 __ BranchOnSmi(r1, &slow); |
| 6611 // Get the map of the function object. | 6639 // Get the map of the function object. |
| 6612 __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); | 6640 __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); |
| 6613 __ b(ne, &slow); | 6641 __ b(ne, &slow); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6673 ASSERT((static_cast<unsigned>(cc_) >> 26) < (1 << 16)); | 6701 ASSERT((static_cast<unsigned>(cc_) >> 26) < (1 << 16)); |
| 6674 int nnn_value = (never_nan_nan_ ? 2 : 0); | 6702 int nnn_value = (never_nan_nan_ ? 2 : 0); |
| 6675 if (cc_ != eq) nnn_value = 0; // Avoid duplicate stubs. | 6703 if (cc_ != eq) nnn_value = 0; // Avoid duplicate stubs. |
| 6676 return (static_cast<unsigned>(cc_) >> 26) | nnn_value | (strict_ ? 1 : 0); | 6704 return (static_cast<unsigned>(cc_) >> 26) | nnn_value | (strict_ ? 1 : 0); |
| 6677 } | 6705 } |
| 6678 | 6706 |
| 6679 | 6707 |
| 6680 #undef __ | 6708 #undef __ |
| 6681 | 6709 |
| 6682 } } // namespace v8::internal | 6710 } } // namespace v8::internal |
| OLD | NEW |