1 // Copyright 2013 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_COMPILER_CONTROL_BUILDERS_H_ 6 #define V8_COMPILER_CONTROL_BUILDERS_H_ 7 8 #include "src/compiler/ast-graph-builder.h" 9 #include "src/compiler/node.h" 10 11 namespace v8 { 12 namespace internal { 13 namespace compiler { 14 15 // Base class for all control builders. Also provides a common interface for 16 // control builders to handle 'break' statements when they are used to model 17 // breakable statements. 18 class ControlBuilder { 19 public: ControlBuilder(AstGraphBuilder * builder)20 explicit ControlBuilder(AstGraphBuilder* builder) : builder_(builder) {} ~ControlBuilder()21 virtual ~ControlBuilder() {} 22 23 // Interface for break. Break()24 virtual void Break() { UNREACHABLE(); } 25 26 protected: 27 typedef AstGraphBuilder Builder; 28 typedef AstGraphBuilder::Environment Environment; 29 zone()30 Zone* zone() const { return builder_->local_zone(); } environment()31 Environment* environment() { return builder_->environment(); } set_environment(Environment * env)32 void set_environment(Environment* env) { builder_->set_environment(env); } the_hole()33 Node* the_hole() const { return builder_->jsgraph()->TheHoleConstant(); } 34 35 Builder* builder_; 36 }; 37 38 39 // Tracks control flow for a conditional statement. 40 class IfBuilder final : public ControlBuilder { 41 public: IfBuilder(AstGraphBuilder * builder)42 explicit IfBuilder(AstGraphBuilder* builder) 43 : ControlBuilder(builder), 44 then_environment_(nullptr), 45 else_environment_(nullptr) {} 46 47 // Primitive control commands. 48 void If(Node* condition, BranchHint hint = BranchHint::kNone); 49 void Then(); 50 void Else(); 51 void End(); 52 53 private: 54 Environment* then_environment_; // Environment after the 'then' body. 55 Environment* else_environment_; // Environment for the 'else' body. 56 }; 57 58 59 // Tracks control flow for an iteration statement. 60 class LoopBuilder final : public ControlBuilder { 61 public: LoopBuilder(AstGraphBuilder * builder)62 explicit LoopBuilder(AstGraphBuilder* builder) 63 : ControlBuilder(builder), 64 loop_environment_(nullptr), 65 continue_environment_(nullptr), 66 break_environment_(nullptr), 67 assigned_(nullptr) {} 68 69 // Primitive control commands. 70 void BeginLoop(BitVector* assigned, bool is_osr = false); 71 void Continue(); 72 void EndBody(); 73 void EndLoop(); 74 75 // Primitive support for break. 76 void Break() final; 77 78 // Loop exit support. Used to introduce explicit loop exit control 79 // node and variable markers. 80 void ExitLoop(Node** extra_value_to_rename = nullptr); 81 82 // Compound control commands for conditional break. 83 void BreakUnless(Node* condition); 84 void BreakWhen(Node* condition); 85 86 private: 87 Environment* loop_environment_; // Environment of the loop header. 88 Environment* continue_environment_; // Environment after the loop body. 89 Environment* break_environment_; // Environment after the loop exits. 90 BitVector* assigned_; // Assigned values in the environment. 91 }; 92 93 94 // Tracks control flow for a switch statement. 95 class SwitchBuilder final : public ControlBuilder { 96 public: SwitchBuilder(AstGraphBuilder * builder,int case_count)97 explicit SwitchBuilder(AstGraphBuilder* builder, int case_count) 98 : ControlBuilder(builder), 99 body_environment_(nullptr), 100 label_environment_(nullptr), 101 break_environment_(nullptr), 102 body_environments_(case_count, zone()) {} 103 104 // Primitive control commands. 105 void BeginSwitch(); 106 void BeginLabel(int index, Node* condition); 107 void EndLabel(); 108 void DefaultAt(int index); 109 void BeginCase(int index); 110 void EndCase(); 111 void EndSwitch(); 112 113 // Primitive support for break. 114 void Break() final; 115 116 // The number of cases within a switch is statically known. case_count()117 size_t case_count() const { return body_environments_.size(); } 118 119 private: 120 Environment* body_environment_; // Environment after last case body. 121 Environment* label_environment_; // Environment for next label condition. 122 Environment* break_environment_; // Environment after the switch exits. 123 ZoneVector<Environment*> body_environments_; 124 }; 125 126 127 // Tracks control flow for a block statement. 128 class BlockBuilder final : public ControlBuilder { 129 public: BlockBuilder(AstGraphBuilder * builder)130 explicit BlockBuilder(AstGraphBuilder* builder) 131 : ControlBuilder(builder), break_environment_(nullptr) {} 132 133 // Primitive control commands. 134 void BeginBlock(); 135 void EndBlock(); 136 137 // Primitive support for break. 138 void Break() final; 139 140 // Compound control commands for conditional break. 141 void BreakWhen(Node* condition, BranchHint = BranchHint::kNone); 142 void BreakUnless(Node* condition, BranchHint hint = BranchHint::kNone); 143 144 private: 145 Environment* break_environment_; // Environment after the block exits. 146 }; 147 148 } // namespace compiler 149 } // namespace internal 150 } // namespace v8 151 152 #endif // V8_COMPILER_CONTROL_BUILDERS_H_ 153