| Index: src/interpreter/bytecode-generator.cc
|
| diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc
|
| index 9148b2d294cc475f96b31372cb7725405d705125..444316c8502c4de1c1a4bc1e89cbb8a4192782b4 100644
|
| --- a/src/interpreter/bytecode-generator.cc
|
| +++ b/src/interpreter/bytecode-generator.cc
|
| @@ -703,7 +703,7 @@ void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) {
|
| VariableMode mode = decl->mode();
|
| // Const and let variables are initialized with the hole so that we can
|
| // check that they are only assigned once.
|
| - bool hole_init = mode == CONST || mode == CONST_LEGACY || mode == LET;
|
| + bool hole_init = mode == CONST || mode == LET;
|
| switch (variable->location()) {
|
| case VariableLocation::GLOBAL:
|
| case VariableLocation::UNALLOCATED: {
|
| @@ -1793,10 +1793,7 @@ void BytecodeGenerator::VisitVariableProxy(VariableProxy* proxy) {
|
|
|
| void BytecodeGenerator::BuildHoleCheckForVariableLoad(VariableMode mode,
|
| Handle<String> name) {
|
| - if (mode == CONST_LEGACY) {
|
| - BytecodeLabel end_label;
|
| - builder()->JumpIfNotHole(&end_label).LoadUndefined().Bind(&end_label);
|
| - } else if (mode == LET || mode == CONST) {
|
| + if (mode == LET || mode == CONST) {
|
| BuildThrowIfHole(name);
|
| }
|
| }
|
| @@ -1980,7 +1977,7 @@ void BytecodeGenerator::VisitVariableAssignment(Variable* variable,
|
| RegisterAllocationScope assignment_register_scope(this);
|
| BytecodeLabel end_label;
|
| bool hole_check_required =
|
| - (mode == CONST_LEGACY) || (mode == LET && op != Token::INIT) ||
|
| + (mode == LET && op != Token::INIT) ||
|
| (mode == CONST && op != Token::INIT) ||
|
| (mode == CONST && op == Token::INIT && variable->is_this());
|
| switch (variable->location()) {
|
| @@ -1993,6 +1990,16 @@ void BytecodeGenerator::VisitVariableAssignment(Variable* variable,
|
| destination = Register(variable->index());
|
| }
|
|
|
| + if (mode == CONST_LEGACY && op != Token::INIT) {
|
| + if (is_strict(language_mode())) {
|
| + builder()->CallRuntime(Runtime::kThrowConstAssignError, Register(),
|
| + 0);
|
| + }
|
| + // Non-initializing assignments to legacy constants are ignored
|
| + // in sloppy mode. Break here to avoid storing into variable.
|
| + break;
|
| + }
|
| +
|
| if (hole_check_required) {
|
| // Load destination to check for hole.
|
| Register value_temp = register_allocator()->NewRegister();
|
| @@ -2000,32 +2007,9 @@ void BytecodeGenerator::VisitVariableAssignment(Variable* variable,
|
| ->StoreAccumulatorInRegister(value_temp)
|
| .LoadAccumulatorWithRegister(destination);
|
|
|
| - if (mode == CONST_LEGACY && op == Token::INIT) {
|
| - // Perform an intialization check for legacy constants.
|
| - builder()
|
| - ->JumpIfNotHole(&end_label)
|
| - .MoveRegister(value_temp, destination)
|
| - .Bind(&end_label)
|
| - .LoadAccumulatorWithRegister(value_temp);
|
| - // Break here because the value should not be stored unconditionally.
|
| - break;
|
| - } else if (mode == CONST_LEGACY && op != Token::INIT) {
|
| - if (is_strict(language_mode())) {
|
| - builder()->CallRuntime(Runtime::kThrowConstAssignError, Register(),
|
| - 0);
|
| - } else {
|
| - // Ensure accumulator is in the correct state.
|
| - builder()->LoadAccumulatorWithRegister(value_temp);
|
| - }
|
| - // Non-initializing assignments to legacy constants are ignored
|
| - // in sloppy mode. Break here to avoid storing into variable.
|
| - break;
|
| - } else {
|
| - BuildHoleCheckForVariableAssignment(variable, op);
|
| - builder()->LoadAccumulatorWithRegister(value_temp);
|
| - }
|
| + BuildHoleCheckForVariableAssignment(variable, op);
|
| + builder()->LoadAccumulatorWithRegister(value_temp);
|
| }
|
| -
|
| builder()->StoreAccumulatorInRegister(destination);
|
| break;
|
| }
|
| @@ -2062,6 +2046,16 @@ void BytecodeGenerator::VisitVariableAssignment(Variable* variable,
|
| builder()->LoadAccumulatorWithRegister(value_temp);
|
| }
|
|
|
| + if (mode == CONST_LEGACY && op != Token::INIT) {
|
| + if (is_strict(language_mode())) {
|
| + builder()->CallRuntime(Runtime::kThrowConstAssignError, Register(),
|
| + 0);
|
| + }
|
| + // Non-initializing assignments to legacy constants are ignored
|
| + // in sloppy mode. Break here to avoid storing into variable.
|
| + break;
|
| + }
|
| +
|
| if (hole_check_required) {
|
| // Load destination to check for hole.
|
| Register value_temp = register_allocator()->NewRegister();
|
| @@ -2069,56 +2063,16 @@ void BytecodeGenerator::VisitVariableAssignment(Variable* variable,
|
| ->StoreAccumulatorInRegister(value_temp)
|
| .LoadContextSlot(context_reg, variable->index());
|
|
|
| - if (mode == CONST_LEGACY && op == Token::INIT) {
|
| - // Perform an intialization check for legacy constants.
|
| - builder()
|
| - ->JumpIfNotHole(&end_label)
|
| - .LoadAccumulatorWithRegister(value_temp)
|
| - .StoreContextSlot(context_reg, variable->index())
|
| - .Bind(&end_label);
|
| - builder()->LoadAccumulatorWithRegister(value_temp);
|
| - // Break here because the value should not be stored unconditionally.
|
| - // The above code performs the store conditionally.
|
| - break;
|
| - } else if (mode == CONST_LEGACY && op != Token::INIT) {
|
| - if (is_strict(language_mode())) {
|
| - builder()->CallRuntime(Runtime::kThrowConstAssignError, Register(),
|
| - 0);
|
| - } else {
|
| - // Ensure accumulator is in the correct state.
|
| - builder()->LoadAccumulatorWithRegister(value_temp);
|
| - }
|
| - // Non-initializing assignments to legacy constants are ignored
|
| - // in sloppy mode. Break here to avoid storing into variable.
|
| - break;
|
| - } else {
|
| - BuildHoleCheckForVariableAssignment(variable, op);
|
| - builder()->LoadAccumulatorWithRegister(value_temp);
|
| - }
|
| + BuildHoleCheckForVariableAssignment(variable, op);
|
| + builder()->LoadAccumulatorWithRegister(value_temp);
|
| }
|
|
|
| builder()->StoreContextSlot(context_reg, variable->index());
|
| break;
|
| }
|
| case VariableLocation::LOOKUP: {
|
| - if (mode == CONST_LEGACY && op == Token::INIT) {
|
| - register_allocator()->PrepareForConsecutiveAllocations(3);
|
| - Register value = register_allocator()->NextConsecutiveRegister();
|
| - Register context = register_allocator()->NextConsecutiveRegister();
|
| - Register name = register_allocator()->NextConsecutiveRegister();
|
| -
|
| - // InitializeLegacyConstLookupSlot runtime call returns the 'value'
|
| - // passed to it. So, accumulator will have its original contents when
|
| - // runtime call returns.
|
| - builder()
|
| - ->StoreAccumulatorInRegister(value)
|
| - .MoveRegister(execution_context()->reg(), context)
|
| - .LoadLiteral(variable->name())
|
| - .StoreAccumulatorInRegister(name)
|
| - .CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, value, 3);
|
| - } else {
|
| - builder()->StoreLookupSlot(variable->name(), language_mode());
|
| - }
|
| + DCHECK_NE(CONST_LEGACY, variable->mode());
|
| + builder()->StoreLookupSlot(variable->name(), language_mode());
|
| break;
|
| }
|
| }
|
|
|