__ lw(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand());
CallStoreIC();
- } else if (op == Token::INIT_CONST_LEGACY) {
- // Const initializers need a write barrier.
- DCHECK(!var->IsParameter()); // No const parameters.
- if (var->IsLookupSlot()) {
- __ li(a0, Operand(var->name()));
- __ Push(v0, cp, a0); // Context and name.
- __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3);
- } else {
- DCHECK(var->IsStackAllocated() || var->IsContextSlot());
- Label skip;
- MemOperand location = VarOperand(var, a1);
- __ lw(a2, location);
- __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
- __ Branch(&skip, ne, a2, Operand(at));
- EmitStoreToStackLocalOrContextSlot(var, location);
- __ bind(&skip);
- }
-
} else if (var->mode() == LET && op != Token::INIT_LET) {
// Non-initializing assignment to let variable needs a write barrier.
DCHECK(!var->IsLookupSlot());
// Perform the assignment.
__ bind(&assign);
EmitStoreToStackLocalOrContextSlot(var, location);
+
+ } else if (var->mode() == CONST && op != Token::INIT_CONST) {
+ // Assignment to const variable needs a write barrier.
+ DCHECK(!var->IsLookupSlot());
+ DCHECK(var->IsStackAllocated() || var->IsContextSlot());
+ Label const_error;
+ MemOperand location = VarOperand(var, a1);
+ __ lw(a3, location);
+ __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
+ __ Branch(&const_error, ne, a3, Operand(at));
+ __ li(a3, Operand(var->name()));
+ __ push(a3);
+ __ CallRuntime(Runtime::kThrowReferenceError, 1);
+ __ bind(&const_error);
+ __ CallRuntime(Runtime::kThrowConstAssignError, 0);
+
} else if (!var->is_const_mode() || op == Token::INIT_CONST) {
if (var->IsLookupSlot()) {
// Assignment to var.
}
EmitStoreToStackLocalOrContextSlot(var, location);
}
- } else if (IsSignallingAssignmentToConst(var, op, language_mode())) {
- __ CallRuntime(Runtime::kThrowConstAssignError, 0);
+
+ } else if (op == Token::INIT_CONST_LEGACY) {
+ // Const initializers need a write barrier.
+ DCHECK(!var->IsParameter()); // No const parameters.
+ if (var->IsLookupSlot()) {
+ __ li(a0, Operand(var->name()));
+ __ Push(v0, cp, a0); // Context and name.
+ __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3);
+ } else {
+ DCHECK(var->IsStackAllocated() || var->IsContextSlot());
+ Label skip;
+ MemOperand location = VarOperand(var, a1);
+ __ lw(a2, location);
+ __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
+ __ Branch(&skip, ne, a2, Operand(at));
+ EmitStoreToStackLocalOrContextSlot(var, location);
+ __ bind(&skip);
+ }
+
+ } else {
+ DCHECK(var->mode() == CONST_LEGACY && op != Token::INIT_CONST_LEGACY);
+ if (is_strict(language_mode())) {
+ __ CallRuntime(Runtime::kThrowConstAssignError, 0);
+ }
+ // Silently ignore store in sloppy mode.
}
}
__ li(StoreDescriptor::NameRegister(), Operand(var->name()));
__ ld(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand());
CallStoreIC();
- } else if (op == Token::INIT_CONST_LEGACY) {
- // Const initializers need a write barrier.
- DCHECK(!var->IsParameter()); // No const parameters.
- if (var->IsLookupSlot()) {
- __ li(a0, Operand(var->name()));
- __ Push(v0, cp, a0); // Context and name.
- __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3);
- } else {
- DCHECK(var->IsStackAllocated() || var->IsContextSlot());
- Label skip;
- MemOperand location = VarOperand(var, a1);
- __ ld(a2, location);
- __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
- __ Branch(&skip, ne, a2, Operand(at));
- EmitStoreToStackLocalOrContextSlot(var, location);
- __ bind(&skip);
- }
} else if (var->mode() == LET && op != Token::INIT_LET) {
// Non-initializing assignment to let variable needs a write barrier.
// Perform the assignment.
__ bind(&assign);
EmitStoreToStackLocalOrContextSlot(var, location);
+
+ } else if (var->mode() == CONST && op != Token::INIT_CONST) {
+ // Assignment to const variable needs a write barrier.
+ DCHECK(!var->IsLookupSlot());
+ DCHECK(var->IsStackAllocated() || var->IsContextSlot());
+ Label const_error;
+ MemOperand location = VarOperand(var, a1);
+ __ ld(a3, location);
+ __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
+ __ Branch(&const_error, ne, a3, Operand(at));
+ __ li(a3, Operand(var->name()));
+ __ push(a3);
+ __ CallRuntime(Runtime::kThrowReferenceError, 1);
+ __ bind(&const_error);
+ __ CallRuntime(Runtime::kThrowConstAssignError, 0);
+
} else if (!var->is_const_mode() || op == Token::INIT_CONST) {
if (var->IsLookupSlot()) {
// Assignment to var.
}
EmitStoreToStackLocalOrContextSlot(var, location);
}
- } else if (IsSignallingAssignmentToConst(var, op, language_mode())) {
- __ CallRuntime(Runtime::kThrowConstAssignError, 0);
+
+ } else if (op == Token::INIT_CONST_LEGACY) {
+ // Const initializers need a write barrier.
+ DCHECK(!var->IsParameter()); // No const parameters.
+ if (var->IsLookupSlot()) {
+ __ li(a0, Operand(var->name()));
+ __ Push(v0, cp, a0); // Context and name.
+ __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3);
+ } else {
+ DCHECK(var->IsStackAllocated() || var->IsContextSlot());
+ Label skip;
+ MemOperand location = VarOperand(var, a1);
+ __ ld(a2, location);
+ __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
+ __ Branch(&skip, ne, a2, Operand(at));
+ EmitStoreToStackLocalOrContextSlot(var, location);
+ __ bind(&skip);
+ }
+
+ } else {
+ DCHECK(var->mode() == CONST_LEGACY && op != Token::INIT_CONST_LEGACY);
+ if (is_strict(language_mode())) {
+ __ CallRuntime(Runtime::kThrowConstAssignError, 0);
+ }
+ // Silently ignore store in sloppy mode.
}
}