Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1012)

Side by Side Diff: src/ia32/full-codegen-ia32.cc

Issue 976053002: Fix exception for assignment to uninitialised const (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Comments Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/full-codegen.h ('k') | src/ic/ic.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 2614 matching lines...) Expand 10 before | Expand all | Expand 10 after
2625 2625
2626 2626
2627 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 2627 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
2628 Token::Value op) { 2628 Token::Value op) {
2629 if (var->IsUnallocated()) { 2629 if (var->IsUnallocated()) {
2630 // Global var, const, or let. 2630 // Global var, const, or let.
2631 __ mov(StoreDescriptor::NameRegister(), var->name()); 2631 __ mov(StoreDescriptor::NameRegister(), var->name());
2632 __ mov(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); 2632 __ mov(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand());
2633 CallStoreIC(); 2633 CallStoreIC();
2634 2634
2635 } else if (op == Token::INIT_CONST_LEGACY) {
2636 // Const initializers need a write barrier.
2637 DCHECK(!var->IsParameter()); // No const parameters.
2638 if (var->IsLookupSlot()) {
2639 __ push(eax);
2640 __ push(esi);
2641 __ push(Immediate(var->name()));
2642 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3);
2643 } else {
2644 DCHECK(var->IsStackLocal() || var->IsContextSlot());
2645 Label skip;
2646 MemOperand location = VarOperand(var, ecx);
2647 __ mov(edx, location);
2648 __ cmp(edx, isolate()->factory()->the_hole_value());
2649 __ j(not_equal, &skip, Label::kNear);
2650 EmitStoreToStackLocalOrContextSlot(var, location);
2651 __ bind(&skip);
2652 }
2653
2654 } else if (var->mode() == LET && op != Token::INIT_LET) { 2635 } else if (var->mode() == LET && op != Token::INIT_LET) {
2655 // Non-initializing assignment to let variable needs a write barrier. 2636 // Non-initializing assignment to let variable needs a write barrier.
2656 DCHECK(!var->IsLookupSlot()); 2637 DCHECK(!var->IsLookupSlot());
2657 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2638 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2658 Label assign; 2639 Label assign;
2659 MemOperand location = VarOperand(var, ecx); 2640 MemOperand location = VarOperand(var, ecx);
2660 __ mov(edx, location); 2641 __ mov(edx, location);
2661 __ cmp(edx, isolate()->factory()->the_hole_value()); 2642 __ cmp(edx, isolate()->factory()->the_hole_value());
2662 __ j(not_equal, &assign, Label::kNear); 2643 __ j(not_equal, &assign, Label::kNear);
2663 __ push(Immediate(var->name())); 2644 __ push(Immediate(var->name()));
2664 __ CallRuntime(Runtime::kThrowReferenceError, 1); 2645 __ CallRuntime(Runtime::kThrowReferenceError, 1);
2665 __ bind(&assign); 2646 __ bind(&assign);
2666 EmitStoreToStackLocalOrContextSlot(var, location); 2647 EmitStoreToStackLocalOrContextSlot(var, location);
2648
2649 } else if (var->mode() == CONST && op != Token::INIT_CONST) {
2650 // Assignment to const variable needs a write barrier.
2651 DCHECK(!var->IsLookupSlot());
2652 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2653 Label const_error;
2654 MemOperand location = VarOperand(var, ecx);
2655 __ mov(edx, location);
2656 __ cmp(edx, isolate()->factory()->the_hole_value());
2657 __ j(not_equal, &const_error, Label::kNear);
2658 __ push(Immediate(var->name()));
2659 __ CallRuntime(Runtime::kThrowReferenceError, 1);
2660 __ bind(&const_error);
2661 __ CallRuntime(Runtime::kThrowConstAssignError, 0);
2662
2667 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { 2663 } else if (!var->is_const_mode() || op == Token::INIT_CONST) {
2668 if (var->IsLookupSlot()) { 2664 if (var->IsLookupSlot()) {
2669 // Assignment to var. 2665 // Assignment to var.
2670 __ push(eax); // Value. 2666 __ push(eax); // Value.
2671 __ push(esi); // Context. 2667 __ push(esi); // Context.
2672 __ push(Immediate(var->name())); 2668 __ push(Immediate(var->name()));
2673 __ push(Immediate(Smi::FromInt(language_mode()))); 2669 __ push(Immediate(Smi::FromInt(language_mode())));
2674 __ CallRuntime(Runtime::kStoreLookupSlot, 4); 2670 __ CallRuntime(Runtime::kStoreLookupSlot, 4);
2675 } else { 2671 } else {
2676 // Assignment to var or initializing assignment to let/const in harmony 2672 // Assignment to var or initializing assignment to let/const in harmony
2677 // mode. 2673 // mode.
2678 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2674 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2679 MemOperand location = VarOperand(var, ecx); 2675 MemOperand location = VarOperand(var, ecx);
2680 if (generate_debug_code_ && op == Token::INIT_LET) { 2676 if (generate_debug_code_ && op == Token::INIT_LET) {
2681 // Check for an uninitialized let binding. 2677 // Check for an uninitialized let binding.
2682 __ mov(edx, location); 2678 __ mov(edx, location);
2683 __ cmp(edx, isolate()->factory()->the_hole_value()); 2679 __ cmp(edx, isolate()->factory()->the_hole_value());
2684 __ Check(equal, kLetBindingReInitialization); 2680 __ Check(equal, kLetBindingReInitialization);
2685 } 2681 }
2686 EmitStoreToStackLocalOrContextSlot(var, location); 2682 EmitStoreToStackLocalOrContextSlot(var, location);
2687 } 2683 }
2688 } else if (IsSignallingAssignmentToConst(var, op, language_mode())) { 2684
2689 __ CallRuntime(Runtime::kThrowConstAssignError, 0); 2685 } else if (op == Token::INIT_CONST_LEGACY) {
2686 // Const initializers need a write barrier.
2687 DCHECK(var->mode() == CONST_LEGACY);
2688 DCHECK(!var->IsParameter()); // No const parameters.
2689 if (var->IsLookupSlot()) {
2690 __ push(eax);
2691 __ push(esi);
2692 __ push(Immediate(var->name()));
2693 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3);
2694 } else {
2695 DCHECK(var->IsStackLocal() || var->IsContextSlot());
2696 Label skip;
2697 MemOperand location = VarOperand(var, ecx);
2698 __ mov(edx, location);
2699 __ cmp(edx, isolate()->factory()->the_hole_value());
2700 __ j(not_equal, &skip, Label::kNear);
2701 EmitStoreToStackLocalOrContextSlot(var, location);
2702 __ bind(&skip);
2703 }
2704
2705 } else {
2706 DCHECK(var->mode() == CONST_LEGACY && op != Token::INIT_CONST_LEGACY);
2707 if (is_strict(language_mode())) {
2708 __ CallRuntime(Runtime::kThrowConstAssignError, 0);
2709 }
2710 // Silently ignore store in sloppy mode.
2690 } 2711 }
2691 } 2712 }
2692 2713
2693 2714
2694 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 2715 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2695 // Assignment to a property, using a named store IC. 2716 // Assignment to a property, using a named store IC.
2696 // eax : value 2717 // eax : value
2697 // esp[0] : receiver 2718 // esp[0] : receiver
2698 2719
2699 Property* prop = expr->target()->AsProperty(); 2720 Property* prop = expr->target()->AsProperty();
(...skipping 2664 matching lines...) Expand 10 before | Expand all | Expand 10 after
5364 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), 5385 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(),
5365 Assembler::target_address_at(call_target_address, 5386 Assembler::target_address_at(call_target_address,
5366 unoptimized_code)); 5387 unoptimized_code));
5367 return OSR_AFTER_STACK_CHECK; 5388 return OSR_AFTER_STACK_CHECK;
5368 } 5389 }
5369 5390
5370 5391
5371 } } // namespace v8::internal 5392 } } // namespace v8::internal
5372 5393
5373 #endif // V8_TARGET_ARCH_IA32 5394 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/full-codegen.h ('k') | src/ic/ic.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698