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 |