OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/compiler/ast-graph-builder.h" | 5 #include "src/compiler/ast-graph-builder.h" |
6 | 6 |
7 #include "src/compiler.h" | 7 #include "src/compiler.h" |
8 #include "src/compiler/ast-loop-assignment-analyzer.h" | 8 #include "src/compiler/ast-loop-assignment-analyzer.h" |
9 #include "src/compiler/control-builders.h" | 9 #include "src/compiler/control-builders.h" |
10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
(...skipping 2666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2677 case Variable::PARAMETER: | 2677 case Variable::PARAMETER: |
2678 case Variable::LOCAL: | 2678 case Variable::LOCAL: |
2679 // Local var, const, or let variable. | 2679 // Local var, const, or let variable. |
2680 if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) { | 2680 if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) { |
2681 // Perform an initialization check for legacy const variables. | 2681 // Perform an initialization check for legacy const variables. |
2682 Node* current = environment()->Lookup(variable); | 2682 Node* current = environment()->Lookup(variable); |
2683 if (current->op() != the_hole->op()) { | 2683 if (current->op() != the_hole->op()) { |
2684 value = BuildHoleCheckSilent(current, value, current); | 2684 value = BuildHoleCheckSilent(current, value, current); |
2685 } | 2685 } |
2686 } else if (mode == CONST_LEGACY && op != Token::INIT_CONST_LEGACY) { | 2686 } else if (mode == CONST_LEGACY && op != Token::INIT_CONST_LEGACY) { |
2687 // Non-initializing assignments to legacy const is | 2687 // Non-initializing assignment to legacy const is |
2688 // - exception in strict mode. | 2688 // - exception in strict mode. |
2689 // - ignored in sloppy mode. | 2689 // - ignored in sloppy mode. |
2690 if (is_strict(language_mode())) { | 2690 if (is_strict(language_mode())) { |
2691 return BuildThrowConstAssignError(bailout_id); | 2691 return BuildThrowConstAssignError(bailout_id); |
2692 } | 2692 } |
2693 return value; | 2693 return value; |
2694 } else if (mode == LET && op != Token::INIT_LET) { | 2694 } else if (mode == LET && op != Token::INIT_LET) { |
2695 // Perform an initialization check for let declared variables. | 2695 // Perform an initialization check for let declared variables. |
2696 // Also note that the dynamic hole-check is only done to ensure that | 2696 // Also note that the dynamic hole-check is only done to ensure that |
2697 // this does not break in the presence of do-expressions within the | 2697 // this does not break in the presence of do-expressions within the |
2698 // temporal dead zone of a let declared variable. | 2698 // temporal dead zone of a let declared variable. |
2699 Node* current = environment()->Lookup(variable); | 2699 Node* current = environment()->Lookup(variable); |
2700 if (current->op() == the_hole->op()) { | 2700 if (current->op() == the_hole->op()) { |
2701 value = BuildThrowReferenceError(variable, bailout_id); | 2701 value = BuildThrowReferenceError(variable, bailout_id); |
2702 } else if (value->opcode() == IrOpcode::kPhi) { | 2702 } else if (value->opcode() == IrOpcode::kPhi) { |
2703 value = BuildHoleCheckThrow(current, variable, value, bailout_id); | 2703 value = BuildHoleCheckThrow(current, variable, value, bailout_id); |
2704 } | 2704 } |
2705 } else if (mode == CONST && op != Token::INIT_CONST) { | 2705 } else if (mode == CONST && op != Token::INIT_CONST) { |
2706 // Non-initializing assignments to const is exception in all modes. | 2706 // Assignment to const is exception in all modes. |
| 2707 Node* current = environment()->Lookup(variable); |
| 2708 if (current->op() == the_hole->op()) { |
| 2709 return BuildThrowReferenceError(variable, bailout_id); |
| 2710 } else if (value->opcode() == IrOpcode::kPhi) { |
| 2711 BuildHoleCheckThrow(current, variable, value, bailout_id); |
| 2712 } |
2707 return BuildThrowConstAssignError(bailout_id); | 2713 return BuildThrowConstAssignError(bailout_id); |
2708 } | 2714 } |
2709 environment()->Bind(variable, value); | 2715 environment()->Bind(variable, value); |
2710 return value; | 2716 return value; |
2711 case Variable::CONTEXT: { | 2717 case Variable::CONTEXT: { |
2712 // Context variable (potentially up the context chain). | 2718 // Context variable (potentially up the context chain). |
2713 int depth = current_scope()->ContextChainLength(variable->scope()); | 2719 int depth = current_scope()->ContextChainLength(variable->scope()); |
2714 if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) { | 2720 if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) { |
2715 // Perform an initialization check for legacy const variables. | 2721 // Perform an initialization check for legacy const variables. |
2716 const Operator* op = | 2722 const Operator* op = |
2717 javascript()->LoadContext(depth, variable->index(), false); | 2723 javascript()->LoadContext(depth, variable->index(), false); |
2718 Node* current = NewNode(op, current_context()); | 2724 Node* current = NewNode(op, current_context()); |
2719 value = BuildHoleCheckSilent(current, value, current); | 2725 value = BuildHoleCheckSilent(current, value, current); |
2720 } else if (mode == CONST_LEGACY && op != Token::INIT_CONST_LEGACY) { | 2726 } else if (mode == CONST_LEGACY && op != Token::INIT_CONST_LEGACY) { |
2721 // Non-initializing assignments to legacy const is | 2727 // Non-initializing assignment to legacy const is |
2722 // - exception in strict mode. | 2728 // - exception in strict mode. |
2723 // - ignored in sloppy mode. | 2729 // - ignored in sloppy mode. |
2724 if (is_strict(language_mode())) { | 2730 if (is_strict(language_mode())) { |
2725 return BuildThrowConstAssignError(bailout_id); | 2731 return BuildThrowConstAssignError(bailout_id); |
2726 } | 2732 } |
2727 return value; | 2733 return value; |
2728 } else if (mode == LET && op != Token::INIT_LET) { | 2734 } else if (mode == LET && op != Token::INIT_LET) { |
2729 // Perform an initialization check for let declared variables. | 2735 // Perform an initialization check for let declared variables. |
2730 const Operator* op = | 2736 const Operator* op = |
2731 javascript()->LoadContext(depth, variable->index(), false); | 2737 javascript()->LoadContext(depth, variable->index(), false); |
2732 Node* current = NewNode(op, current_context()); | 2738 Node* current = NewNode(op, current_context()); |
2733 value = BuildHoleCheckThrow(current, variable, value, bailout_id); | 2739 value = BuildHoleCheckThrow(current, variable, value, bailout_id); |
2734 } else if (mode == CONST && op != Token::INIT_CONST) { | 2740 } else if (mode == CONST && op != Token::INIT_CONST) { |
2735 // Non-initializing assignments to const is exception in all modes. | 2741 // Assignment to const is exception in all modes. |
| 2742 const Operator* op = |
| 2743 javascript()->LoadContext(depth, variable->index(), false); |
| 2744 Node* current = NewNode(op, current_context()); |
| 2745 BuildHoleCheckThrow(current, variable, value, bailout_id); |
2736 return BuildThrowConstAssignError(bailout_id); | 2746 return BuildThrowConstAssignError(bailout_id); |
2737 } | 2747 } |
2738 const Operator* op = javascript()->StoreContext(depth, variable->index()); | 2748 const Operator* op = javascript()->StoreContext(depth, variable->index()); |
2739 return NewNode(op, current_context(), value); | 2749 return NewNode(op, current_context(), value); |
2740 } | 2750 } |
2741 case Variable::LOOKUP: { | 2751 case Variable::LOOKUP: { |
2742 // Dynamic lookup of context variable (anywhere in the chain). | 2752 // Dynamic lookup of context variable (anywhere in the chain). |
2743 Node* name = jsgraph()->Constant(variable->name()); | 2753 Node* name = jsgraph()->Constant(variable->name()); |
2744 Node* language = jsgraph()->Constant(language_mode()); | 2754 Node* language = jsgraph()->Constant(language_mode()); |
2745 // TODO(mstarzinger): Use Runtime::kInitializeLegacyConstLookupSlot for | 2755 // TODO(mstarzinger): Use Runtime::kInitializeLegacyConstLookupSlot for |
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3233 // Phi does not exist yet, introduce one. | 3243 // Phi does not exist yet, introduce one. |
3234 value = NewPhi(inputs, value, control); | 3244 value = NewPhi(inputs, value, control); |
3235 value->ReplaceInput(inputs - 1, other); | 3245 value->ReplaceInput(inputs - 1, other); |
3236 } | 3246 } |
3237 return value; | 3247 return value; |
3238 } | 3248 } |
3239 | 3249 |
3240 } // namespace compiler | 3250 } // namespace compiler |
3241 } // namespace internal | 3251 } // namespace internal |
3242 } // namespace v8 | 3252 } // namespace v8 |
OLD | NEW |