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 |