OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
8 | 8 |
9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 1260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1271 context()->Plug(eax); | 1271 context()->Plug(eax); |
1272 } | 1272 } |
1273 | 1273 |
1274 | 1274 |
1275 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { | 1275 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { |
1276 Comment cmnt(masm_, "[ VariableProxy"); | 1276 Comment cmnt(masm_, "[ VariableProxy"); |
1277 EmitVariableLoad(expr); | 1277 EmitVariableLoad(expr); |
1278 } | 1278 } |
1279 | 1279 |
1280 | 1280 |
| 1281 void FullCodeGenerator::EmitLoadHomeObject(SuperReference* expr) { |
| 1282 Comment cnmt(masm_, "[ SuperReference "); |
| 1283 |
| 1284 __ mov(LoadDescriptor::ReceiverRegister(), |
| 1285 Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
| 1286 |
| 1287 Handle<Symbol> home_object_symbol(isolate()->heap()->home_object_symbol()); |
| 1288 __ mov(LoadDescriptor::NameRegister(), home_object_symbol); |
| 1289 |
| 1290 CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId()); |
| 1291 |
| 1292 __ cmp(eax, isolate()->factory()->undefined_value()); |
| 1293 Label done; |
| 1294 __ j(not_equal, &done); |
| 1295 __ CallRuntime(Runtime::kThrowNonMethodError, 0); |
| 1296 __ bind(&done); |
| 1297 } |
| 1298 |
| 1299 |
1281 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, | 1300 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, |
1282 TypeofState typeof_state, | 1301 TypeofState typeof_state, |
1283 Label* slow) { | 1302 Label* slow) { |
1284 Register context = esi; | 1303 Register context = esi; |
1285 Register temp = edx; | 1304 Register temp = edx; |
1286 | 1305 |
1287 Scope* s = scope(); | 1306 Scope* s = scope(); |
1288 while (s != NULL) { | 1307 while (s != NULL) { |
1289 if (s->num_heap_slots() > 0) { | 1308 if (s->num_heap_slots() > 0) { |
1290 if (s->calls_sloppy_eval()) { | 1309 if (s->calls_sloppy_eval()) { |
(...skipping 933 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2224 if (FLAG_vector_ics) { | 2243 if (FLAG_vector_ics) { |
2225 __ mov(VectorLoadICDescriptor::SlotRegister(), | 2244 __ mov(VectorLoadICDescriptor::SlotRegister(), |
2226 Immediate(Smi::FromInt(prop->PropertyFeedbackSlot()))); | 2245 Immediate(Smi::FromInt(prop->PropertyFeedbackSlot()))); |
2227 CallLoadIC(NOT_CONTEXTUAL); | 2246 CallLoadIC(NOT_CONTEXTUAL); |
2228 } else { | 2247 } else { |
2229 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); | 2248 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
2230 } | 2249 } |
2231 } | 2250 } |
2232 | 2251 |
2233 | 2252 |
| 2253 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { |
| 2254 SetSourcePosition(prop->position()); |
| 2255 Literal* key = prop->key()->AsLiteral(); |
| 2256 DCHECK(!key->value()->IsSmi()); |
| 2257 DCHECK(prop->IsSuperAccess()); |
| 2258 |
| 2259 SuperReference* super_ref = prop->obj()->AsSuperReference(); |
| 2260 EmitLoadHomeObject(super_ref); |
| 2261 __ push(eax); |
| 2262 VisitForStackValue(super_ref->this_var()); |
| 2263 __ push(Immediate(key->value())); |
| 2264 __ CallRuntime(Runtime::kLoadFromSuper, 3); |
| 2265 } |
| 2266 |
| 2267 |
2234 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2268 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
2235 SetSourcePosition(prop->position()); | 2269 SetSourcePosition(prop->position()); |
2236 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); | 2270 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); |
2237 if (FLAG_vector_ics) { | 2271 if (FLAG_vector_ics) { |
2238 __ mov(VectorLoadICDescriptor::SlotRegister(), | 2272 __ mov(VectorLoadICDescriptor::SlotRegister(), |
2239 Immediate(Smi::FromInt(prop->PropertyFeedbackSlot()))); | 2273 Immediate(Smi::FromInt(prop->PropertyFeedbackSlot()))); |
2240 CallIC(ic); | 2274 CallIC(ic); |
2241 } else { | 2275 } else { |
2242 CallIC(ic, prop->PropertyFeedbackId()); | 2276 CallIC(ic, prop->PropertyFeedbackId()); |
2243 } | 2277 } |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2513 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2547 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2514 context()->Plug(eax); | 2548 context()->Plug(eax); |
2515 } | 2549 } |
2516 | 2550 |
2517 | 2551 |
2518 void FullCodeGenerator::VisitProperty(Property* expr) { | 2552 void FullCodeGenerator::VisitProperty(Property* expr) { |
2519 Comment cmnt(masm_, "[ Property"); | 2553 Comment cmnt(masm_, "[ Property"); |
2520 Expression* key = expr->key(); | 2554 Expression* key = expr->key(); |
2521 | 2555 |
2522 if (key->IsPropertyName()) { | 2556 if (key->IsPropertyName()) { |
2523 VisitForAccumulatorValue(expr->obj()); | 2557 if (!expr->IsSuperAccess()) { |
2524 __ Move(LoadDescriptor::ReceiverRegister(), result_register()); | 2558 VisitForAccumulatorValue(expr->obj()); |
2525 EmitNamedPropertyLoad(expr); | 2559 __ Move(LoadDescriptor::ReceiverRegister(), result_register()); |
| 2560 EmitNamedPropertyLoad(expr); |
| 2561 } else { |
| 2562 EmitNamedSuperPropertyLoad(expr); |
| 2563 } |
2526 PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2564 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
2527 context()->Plug(eax); | 2565 context()->Plug(eax); |
2528 } else { | 2566 } else { |
2529 VisitForStackValue(expr->obj()); | 2567 VisitForStackValue(expr->obj()); |
2530 VisitForAccumulatorValue(expr->key()); | 2568 VisitForAccumulatorValue(expr->key()); |
2531 __ pop(LoadDescriptor::ReceiverRegister()); // Object. | 2569 __ pop(LoadDescriptor::ReceiverRegister()); // Object. |
2532 __ Move(LoadDescriptor::NameRegister(), result_register()); // Key. | 2570 __ Move(LoadDescriptor::NameRegister(), result_register()); // Key. |
2533 EmitKeyedPropertyLoad(expr); | 2571 EmitKeyedPropertyLoad(expr); |
2534 context()->Plug(eax); | 2572 context()->Plug(eax); |
2535 } | 2573 } |
(...skipping 18 matching lines...) Expand all Loading... |
2554 { StackValueContext context(this); | 2592 { StackValueContext context(this); |
2555 EmitVariableLoad(callee->AsVariableProxy()); | 2593 EmitVariableLoad(callee->AsVariableProxy()); |
2556 PrepareForBailout(callee, NO_REGISTERS); | 2594 PrepareForBailout(callee, NO_REGISTERS); |
2557 } | 2595 } |
2558 // Push undefined as receiver. This is patched in the method prologue if it | 2596 // Push undefined as receiver. This is patched in the method prologue if it |
2559 // is a sloppy mode method. | 2597 // is a sloppy mode method. |
2560 __ push(Immediate(isolate()->factory()->undefined_value())); | 2598 __ push(Immediate(isolate()->factory()->undefined_value())); |
2561 } else { | 2599 } else { |
2562 // Load the function from the receiver. | 2600 // Load the function from the receiver. |
2563 DCHECK(callee->IsProperty()); | 2601 DCHECK(callee->IsProperty()); |
| 2602 DCHECK(!callee->AsProperty()->IsSuperAccess()); |
2564 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); | 2603 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); |
2565 EmitNamedPropertyLoad(callee->AsProperty()); | 2604 EmitNamedPropertyLoad(callee->AsProperty()); |
2566 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2605 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2567 // Push the target function under the receiver. | 2606 // Push the target function under the receiver. |
2568 __ push(Operand(esp, 0)); | 2607 __ push(Operand(esp, 0)); |
2569 __ mov(Operand(esp, kPointerSize), eax); | 2608 __ mov(Operand(esp, kPointerSize), eax); |
2570 } | 2609 } |
2571 | 2610 |
2572 EmitCall(expr, call_type); | 2611 EmitCall(expr, call_type); |
2573 } | 2612 } |
2574 | 2613 |
2575 | 2614 |
| 2615 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { |
| 2616 Expression* callee = expr->expression(); |
| 2617 DCHECK(callee->IsProperty()); |
| 2618 Property* prop = callee->AsProperty(); |
| 2619 DCHECK(prop->IsSuperAccess()); |
| 2620 |
| 2621 SetSourcePosition(prop->position()); |
| 2622 Literal* key = prop->key()->AsLiteral(); |
| 2623 DCHECK(!key->value()->IsSmi()); |
| 2624 // Load the function from the receiver. |
| 2625 SuperReference* super_ref = callee->AsProperty()->obj()->AsSuperReference(); |
| 2626 EmitLoadHomeObject(super_ref); |
| 2627 __ push(eax); |
| 2628 VisitForAccumulatorValue(super_ref->this_var()); |
| 2629 __ push(eax); |
| 2630 __ push(Operand(esp, kPointerSize)); |
| 2631 __ push(eax); |
| 2632 __ push(Immediate(key->value())); |
| 2633 // Stack here: |
| 2634 // - home_object |
| 2635 // - this (receiver) |
| 2636 // - home_object <-- LoadFromSuper will pop here and below. |
| 2637 // - this (receiver) |
| 2638 // - key |
| 2639 __ CallRuntime(Runtime::kLoadFromSuper, 3); |
| 2640 |
| 2641 // Replace home_object with target function. |
| 2642 __ mov(Operand(esp, kPointerSize), eax); |
| 2643 |
| 2644 // Stack here: |
| 2645 // - target function |
| 2646 // - this (receiver) |
| 2647 EmitCall(expr, CallICState::METHOD); |
| 2648 } |
| 2649 |
| 2650 |
2576 // Code common for calls using the IC. | 2651 // Code common for calls using the IC. |
2577 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, | 2652 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, |
2578 Expression* key) { | 2653 Expression* key) { |
2579 // Load the key. | 2654 // Load the key. |
2580 VisitForAccumulatorValue(key); | 2655 VisitForAccumulatorValue(key); |
2581 | 2656 |
2582 Expression* callee = expr->expression(); | 2657 Expression* callee = expr->expression(); |
2583 | 2658 |
2584 // Load the function from the receiver. | 2659 // Load the function from the receiver. |
2585 DCHECK(callee->IsProperty()); | 2660 DCHECK(callee->IsProperty()); |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2726 __ push(Immediate(isolate()->factory()->undefined_value())); | 2801 __ push(Immediate(isolate()->factory()->undefined_value())); |
2727 __ bind(&call); | 2802 __ bind(&call); |
2728 } | 2803 } |
2729 | 2804 |
2730 // The receiver is either the global receiver or an object found by | 2805 // The receiver is either the global receiver or an object found by |
2731 // LoadContextSlot. | 2806 // LoadContextSlot. |
2732 EmitCall(expr); | 2807 EmitCall(expr); |
2733 | 2808 |
2734 } else if (call_type == Call::PROPERTY_CALL) { | 2809 } else if (call_type == Call::PROPERTY_CALL) { |
2735 Property* property = callee->AsProperty(); | 2810 Property* property = callee->AsProperty(); |
2736 { PreservePositionScope scope(masm()->positions_recorder()); | 2811 bool is_named_call = property->key()->IsPropertyName(); |
2737 VisitForStackValue(property->obj()); | 2812 // super.x() is handled in EmitCallWithLoadIC. |
| 2813 if (property->IsSuperAccess() && is_named_call) { |
| 2814 EmitSuperCallWithLoadIC(expr); |
| 2815 } else { |
| 2816 { |
| 2817 PreservePositionScope scope(masm()->positions_recorder()); |
| 2818 VisitForStackValue(property->obj()); |
| 2819 } |
| 2820 if (is_named_call) { |
| 2821 EmitCallWithLoadIC(expr); |
| 2822 } else { |
| 2823 EmitKeyedCallWithLoadIC(expr, property->key()); |
| 2824 } |
2738 } | 2825 } |
2739 if (property->key()->IsPropertyName()) { | |
2740 EmitCallWithLoadIC(expr); | |
2741 } else { | |
2742 EmitKeyedCallWithLoadIC(expr, property->key()); | |
2743 } | |
2744 | |
2745 } else { | 2826 } else { |
2746 DCHECK(call_type == Call::OTHER_CALL); | 2827 DCHECK(call_type == Call::OTHER_CALL); |
2747 // Call to an arbitrary expression not handled specially above. | 2828 // Call to an arbitrary expression not handled specially above. |
2748 { PreservePositionScope scope(masm()->positions_recorder()); | 2829 { PreservePositionScope scope(masm()->positions_recorder()); |
2749 VisitForStackValue(callee); | 2830 VisitForStackValue(callee); |
2750 } | 2831 } |
2751 __ push(Immediate(isolate()->factory()->undefined_value())); | 2832 __ push(Immediate(isolate()->factory()->undefined_value())); |
2752 // Emit function call. | 2833 // Emit function call. |
2753 EmitCall(expr); | 2834 EmitCall(expr); |
2754 } | 2835 } |
(...skipping 2068 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4823 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4904 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
4824 Assembler::target_address_at(call_target_address, | 4905 Assembler::target_address_at(call_target_address, |
4825 unoptimized_code)); | 4906 unoptimized_code)); |
4826 return OSR_AFTER_STACK_CHECK; | 4907 return OSR_AFTER_STACK_CHECK; |
4827 } | 4908 } |
4828 | 4909 |
4829 | 4910 |
4830 } } // namespace v8::internal | 4911 } } // namespace v8::internal |
4831 | 4912 |
4832 #endif // V8_TARGET_ARCH_IA32 | 4913 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |