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_X87 | 7 #if V8_TARGET_ARCH_X87 |
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 2601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2612 | 2612 |
2613 | 2613 |
2614 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 2614 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
2615 Token::Value op) { | 2615 Token::Value op) { |
2616 if (var->IsUnallocated()) { | 2616 if (var->IsUnallocated()) { |
2617 // Global var, const, or let. | 2617 // Global var, const, or let. |
2618 __ mov(StoreDescriptor::NameRegister(), var->name()); | 2618 __ mov(StoreDescriptor::NameRegister(), var->name()); |
2619 __ mov(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 2619 __ mov(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
2620 CallStoreIC(); | 2620 CallStoreIC(); |
2621 | 2621 |
2622 } else if (op == Token::INIT_CONST_LEGACY) { | |
2623 // Const initializers need a write barrier. | |
2624 DCHECK(!var->IsParameter()); // No const parameters. | |
2625 if (var->IsLookupSlot()) { | |
2626 __ push(eax); | |
2627 __ push(esi); | |
2628 __ push(Immediate(var->name())); | |
2629 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3); | |
2630 } else { | |
2631 DCHECK(var->IsStackLocal() || var->IsContextSlot()); | |
2632 Label skip; | |
2633 MemOperand location = VarOperand(var, ecx); | |
2634 __ mov(edx, location); | |
2635 __ cmp(edx, isolate()->factory()->the_hole_value()); | |
2636 __ j(not_equal, &skip, Label::kNear); | |
2637 EmitStoreToStackLocalOrContextSlot(var, location); | |
2638 __ bind(&skip); | |
2639 } | |
2640 | |
2641 } else if (var->mode() == LET && op != Token::INIT_LET) { | 2622 } else if (var->mode() == LET && op != Token::INIT_LET) { |
2642 // Non-initializing assignment to let variable needs a write barrier. | 2623 // Non-initializing assignment to let variable needs a write barrier. |
2643 DCHECK(!var->IsLookupSlot()); | 2624 DCHECK(!var->IsLookupSlot()); |
2644 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 2625 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
2645 Label assign; | 2626 Label assign; |
2646 MemOperand location = VarOperand(var, ecx); | 2627 MemOperand location = VarOperand(var, ecx); |
2647 __ mov(edx, location); | 2628 __ mov(edx, location); |
2648 __ cmp(edx, isolate()->factory()->the_hole_value()); | 2629 __ cmp(edx, isolate()->factory()->the_hole_value()); |
2649 __ j(not_equal, &assign, Label::kNear); | 2630 __ j(not_equal, &assign, Label::kNear); |
2650 __ push(Immediate(var->name())); | 2631 __ push(Immediate(var->name())); |
2651 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 2632 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
2652 __ bind(&assign); | 2633 __ bind(&assign); |
2653 EmitStoreToStackLocalOrContextSlot(var, location); | 2634 EmitStoreToStackLocalOrContextSlot(var, location); |
| 2635 |
| 2636 } else if (var->mode() == CONST && op != Token::INIT_CONST) { |
| 2637 // Assignment to const variable needs a write barrier. |
| 2638 DCHECK(!var->IsLookupSlot()); |
| 2639 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 2640 Label const_error; |
| 2641 MemOperand location = VarOperand(var, ecx); |
| 2642 __ mov(edx, location); |
| 2643 __ cmp(edx, isolate()->factory()->the_hole_value()); |
| 2644 __ j(not_equal, &const_error, Label::kNear); |
| 2645 __ push(Immediate(var->name())); |
| 2646 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
| 2647 __ bind(&const_error); |
| 2648 __ CallRuntime(Runtime::kThrowConstAssignError, 0); |
| 2649 |
2654 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { | 2650 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { |
2655 if (var->IsLookupSlot()) { | 2651 if (var->IsLookupSlot()) { |
2656 // Assignment to var. | 2652 // Assignment to var. |
2657 __ push(eax); // Value. | 2653 __ push(eax); // Value. |
2658 __ push(esi); // Context. | 2654 __ push(esi); // Context. |
2659 __ push(Immediate(var->name())); | 2655 __ push(Immediate(var->name())); |
2660 __ push(Immediate(Smi::FromInt(language_mode()))); | 2656 __ push(Immediate(Smi::FromInt(language_mode()))); |
2661 __ CallRuntime(Runtime::kStoreLookupSlot, 4); | 2657 __ CallRuntime(Runtime::kStoreLookupSlot, 4); |
2662 } else { | 2658 } else { |
2663 // Assignment to var or initializing assignment to let/const in harmony | 2659 // Assignment to var or initializing assignment to let/const in harmony |
2664 // mode. | 2660 // mode. |
2665 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 2661 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
2666 MemOperand location = VarOperand(var, ecx); | 2662 MemOperand location = VarOperand(var, ecx); |
2667 if (generate_debug_code_ && op == Token::INIT_LET) { | 2663 if (generate_debug_code_ && op == Token::INIT_LET) { |
2668 // Check for an uninitialized let binding. | 2664 // Check for an uninitialized let binding. |
2669 __ mov(edx, location); | 2665 __ mov(edx, location); |
2670 __ cmp(edx, isolate()->factory()->the_hole_value()); | 2666 __ cmp(edx, isolate()->factory()->the_hole_value()); |
2671 __ Check(equal, kLetBindingReInitialization); | 2667 __ Check(equal, kLetBindingReInitialization); |
2672 } | 2668 } |
2673 EmitStoreToStackLocalOrContextSlot(var, location); | 2669 EmitStoreToStackLocalOrContextSlot(var, location); |
2674 } | 2670 } |
2675 } else if (IsSignallingAssignmentToConst(var, op, language_mode())) { | 2671 |
2676 __ CallRuntime(Runtime::kThrowConstAssignError, 0); | 2672 } else if (op == Token::INIT_CONST_LEGACY) { |
| 2673 // Const initializers need a write barrier. |
| 2674 DCHECK(var->mode() == CONST_LEGACY); |
| 2675 DCHECK(!var->IsParameter()); // No const parameters. |
| 2676 if (var->IsLookupSlot()) { |
| 2677 __ push(eax); |
| 2678 __ push(esi); |
| 2679 __ push(Immediate(var->name())); |
| 2680 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3); |
| 2681 } else { |
| 2682 DCHECK(var->IsStackLocal() || var->IsContextSlot()); |
| 2683 Label skip; |
| 2684 MemOperand location = VarOperand(var, ecx); |
| 2685 __ mov(edx, location); |
| 2686 __ cmp(edx, isolate()->factory()->the_hole_value()); |
| 2687 __ j(not_equal, &skip, Label::kNear); |
| 2688 EmitStoreToStackLocalOrContextSlot(var, location); |
| 2689 __ bind(&skip); |
| 2690 } |
| 2691 |
| 2692 } else { |
| 2693 DCHECK(var->mode() == CONST_LEGACY && op != Token::INIT_CONST_LEGACY); |
| 2694 if (is_strict(language_mode())) { |
| 2695 __ CallRuntime(Runtime::kThrowConstAssignError, 0); |
| 2696 } |
| 2697 // Silently ignore store in sloppy mode. |
2677 } | 2698 } |
2678 } | 2699 } |
2679 | 2700 |
2680 | 2701 |
2681 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 2702 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
2682 // Assignment to a property, using a named store IC. | 2703 // Assignment to a property, using a named store IC. |
2683 // eax : value | 2704 // eax : value |
2684 // esp[0] : receiver | 2705 // esp[0] : receiver |
2685 | 2706 |
2686 Property* prop = expr->target()->AsProperty(); | 2707 Property* prop = expr->target()->AsProperty(); |
(...skipping 2666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5353 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 5374 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
5354 Assembler::target_address_at(call_target_address, | 5375 Assembler::target_address_at(call_target_address, |
5355 unoptimized_code)); | 5376 unoptimized_code)); |
5356 return OSR_AFTER_STACK_CHECK; | 5377 return OSR_AFTER_STACK_CHECK; |
5357 } | 5378 } |
5358 | 5379 |
5359 | 5380 |
5360 } } // namespace v8::internal | 5381 } } // namespace v8::internal |
5361 | 5382 |
5362 #endif // V8_TARGET_ARCH_X87 | 5383 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |