| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 // Strict mode functions and builtins need to replace the receiver | 135 // Strict mode functions and builtins need to replace the receiver |
| 136 // with undefined when called as functions (without an explicit | 136 // with undefined when called as functions (without an explicit |
| 137 // receiver object). ecx is zero for method calls and non-zero for | 137 // receiver object). ecx is zero for method calls and non-zero for |
| 138 // function calls. | 138 // function calls. |
| 139 if (info->is_strict_mode() || info->is_native()) { | 139 if (info->is_strict_mode() || info->is_native()) { |
| 140 Label ok; | 140 Label ok; |
| 141 __ test(ecx, ecx); | 141 __ test(ecx, ecx); |
| 142 __ j(zero, &ok, Label::kNear); | 142 __ j(zero, &ok, Label::kNear); |
| 143 // +1 for return address. | 143 // +1 for return address. |
| 144 int receiver_offset = (info->scope()->num_parameters() + 1) * kPointerSize; | 144 int receiver_offset = (info->scope()->num_parameters() + 1) * kPointerSize; |
| 145 __ mov(ecx, Operand(esp, receiver_offset)); |
| 146 __ JumpIfSmi(ecx, &ok); |
| 147 __ CmpObjectType(ecx, JS_GLOBAL_PROXY_TYPE, ecx); |
| 148 __ j(not_equal, &ok, Label::kNear); |
| 145 __ mov(Operand(esp, receiver_offset), | 149 __ mov(Operand(esp, receiver_offset), |
| 146 Immediate(isolate()->factory()->undefined_value())); | 150 Immediate(isolate()->factory()->undefined_value())); |
| 147 __ bind(&ok); | 151 __ bind(&ok); |
| 148 } | 152 } |
| 149 | 153 |
| 150 // Open a frame scope to indicate that there is a frame on the stack. The | 154 // Open a frame scope to indicate that there is a frame on the stack. The |
| 151 // MANUAL indicates that the scope shouldn't actually generate code to set up | 155 // MANUAL indicates that the scope shouldn't actually generate code to set up |
| 152 // the frame (that is done below). | 156 // the frame (that is done below). |
| 153 FrameScope frame_scope(masm_, StackFrame::MANUAL); | 157 FrameScope frame_scope(masm_, StackFrame::MANUAL); |
| 154 | 158 |
| (...skipping 1942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2097 } | 2101 } |
| 2098 // Record source position for debugger. | 2102 // Record source position for debugger. |
| 2099 SetSourcePosition(expr->position()); | 2103 SetSourcePosition(expr->position()); |
| 2100 | 2104 |
| 2101 // Record call targets in unoptimized code, but not in the snapshot. | 2105 // Record call targets in unoptimized code, but not in the snapshot. |
| 2102 bool record_call_target = !Serializer::enabled(); | 2106 bool record_call_target = !Serializer::enabled(); |
| 2103 if (record_call_target) { | 2107 if (record_call_target) { |
| 2104 flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET); | 2108 flags = static_cast<CallFunctionFlags>(flags | RECORD_CALL_TARGET); |
| 2105 } | 2109 } |
| 2106 CallFunctionStub stub(arg_count, flags); | 2110 CallFunctionStub stub(arg_count, flags); |
| 2111 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); |
| 2107 __ CallStub(&stub); | 2112 __ CallStub(&stub); |
| 2108 if (record_call_target) { | 2113 if (record_call_target) { |
| 2109 // There is a one element cache in the instruction stream. | 2114 // There is a one element cache in the instruction stream. |
| 2110 #ifdef DEBUG | 2115 #ifdef DEBUG |
| 2111 int return_site_offset = masm()->pc_offset(); | 2116 int return_site_offset = masm()->pc_offset(); |
| 2112 #endif | 2117 #endif |
| 2113 Handle<Object> uninitialized = | 2118 Handle<Object> uninitialized = |
| 2114 CallFunctionStub::UninitializedSentinel(isolate()); | 2119 CallFunctionStub::UninitializedSentinel(isolate()); |
| 2115 Handle<JSGlobalPropertyCell> cell = | 2120 Handle<JSGlobalPropertyCell> cell = |
| 2116 isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); | 2121 isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2204 __ bind(&done); | 2209 __ bind(&done); |
| 2205 | 2210 |
| 2206 // The runtime call returns a pair of values in eax (function) and | 2211 // The runtime call returns a pair of values in eax (function) and |
| 2207 // edx (receiver). Touch up the stack with the right values. | 2212 // edx (receiver). Touch up the stack with the right values. |
| 2208 __ mov(Operand(esp, (arg_count + 0) * kPointerSize), edx); | 2213 __ mov(Operand(esp, (arg_count + 0) * kPointerSize), edx); |
| 2209 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax); | 2214 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax); |
| 2210 } | 2215 } |
| 2211 // Record source position for debugger. | 2216 // Record source position for debugger. |
| 2212 SetSourcePosition(expr->position()); | 2217 SetSourcePosition(expr->position()); |
| 2213 CallFunctionStub stub(arg_count, RECEIVER_MIGHT_BE_IMPLICIT); | 2218 CallFunctionStub stub(arg_count, RECEIVER_MIGHT_BE_IMPLICIT); |
| 2219 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); |
| 2214 __ CallStub(&stub); | 2220 __ CallStub(&stub); |
| 2215 RecordJSReturnSite(expr); | 2221 RecordJSReturnSite(expr); |
| 2216 // Restore context register. | 2222 // Restore context register. |
| 2217 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2223 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 2218 decrement_stack_height(arg_count + 1); // Function is left on the stack. | 2224 decrement_stack_height(arg_count + 1); // Function is left on the stack. |
| 2219 context()->DropAndPlug(1, eax); | 2225 context()->DropAndPlug(1, eax); |
| 2220 | 2226 |
| 2221 } else if (proxy != NULL && proxy->var()->IsUnallocated()) { | 2227 } else if (proxy != NULL && proxy->var()->IsUnallocated()) { |
| 2222 // Push global object as receiver for the call IC. | 2228 // Push global object as receiver for the call IC. |
| 2223 __ push(GlobalObjectOperand()); | 2229 __ push(GlobalObjectOperand()); |
| (...skipping 884 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3108 | 3114 |
| 3109 void FullCodeGenerator::EmitCallFunction(ZoneList<Expression*>* args) { | 3115 void FullCodeGenerator::EmitCallFunction(ZoneList<Expression*>* args) { |
| 3110 ASSERT(args->length() >= 2); | 3116 ASSERT(args->length() >= 2); |
| 3111 | 3117 |
| 3112 int arg_count = args->length() - 2; // 2 ~ receiver and function. | 3118 int arg_count = args->length() - 2; // 2 ~ receiver and function. |
| 3113 for (int i = 0; i < arg_count + 1; ++i) { | 3119 for (int i = 0; i < arg_count + 1; ++i) { |
| 3114 VisitForStackValue(args->at(i)); | 3120 VisitForStackValue(args->at(i)); |
| 3115 } | 3121 } |
| 3116 VisitForAccumulatorValue(args->last()); // Function. | 3122 VisitForAccumulatorValue(args->last()); // Function. |
| 3117 | 3123 |
| 3124 // Check for proxy. |
| 3125 Label proxy, done; |
| 3126 __ CmpObjectType(eax, JS_FUNCTION_PROXY_TYPE, ebx); |
| 3127 __ j(equal, &proxy); |
| 3128 |
| 3118 // InvokeFunction requires the function in edi. Move it in there. | 3129 // InvokeFunction requires the function in edi. Move it in there. |
| 3119 __ mov(edi, result_register()); | 3130 __ mov(edi, result_register()); |
| 3120 ParameterCount count(arg_count); | 3131 ParameterCount count(arg_count); |
| 3121 __ InvokeFunction(edi, count, CALL_FUNCTION, | 3132 __ InvokeFunction(edi, count, CALL_FUNCTION, |
| 3122 NullCallWrapper(), CALL_AS_METHOD); | 3133 NullCallWrapper(), CALL_AS_METHOD); |
| 3123 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 3134 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 3135 __ jmp(&done); |
| 3136 |
| 3137 __ bind(&proxy); |
| 3138 __ push(eax); |
| 3139 __ CallRuntime(Runtime::kCall, args->length()); |
| 3140 __ bind(&done); |
| 3141 |
| 3124 decrement_stack_height(arg_count + 1); | 3142 decrement_stack_height(arg_count + 1); |
| 3125 context()->Plug(eax); | 3143 context()->Plug(eax); |
| 3126 } | 3144 } |
| 3127 | 3145 |
| 3128 | 3146 |
| 3129 void FullCodeGenerator::EmitRegExpConstructResult(ZoneList<Expression*>* args) { | 3147 void FullCodeGenerator::EmitRegExpConstructResult(ZoneList<Expression*>* args) { |
| 3130 // Load the arguments on the stack and call the stub. | 3148 // Load the arguments on the stack and call the stub. |
| 3131 RegExpConstructResultStub stub; | 3149 RegExpConstructResultStub stub; |
| 3132 ASSERT(args->length() == 3); | 3150 ASSERT(args->length() == 3); |
| 3133 VisitForStackValue(args->at(0)); | 3151 VisitForStackValue(args->at(0)); |
| (...skipping 1201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4335 *context_length = 0; | 4353 *context_length = 0; |
| 4336 return previous_; | 4354 return previous_; |
| 4337 } | 4355 } |
| 4338 | 4356 |
| 4339 | 4357 |
| 4340 #undef __ | 4358 #undef __ |
| 4341 | 4359 |
| 4342 } } // namespace v8::internal | 4360 } } // namespace v8::internal |
| 4343 | 4361 |
| 4344 #endif // V8_TARGET_ARCH_IA32 | 4362 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |