• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
68   // Primitive control commands.
69   void BeginLoop(BitVector* assigned, bool is_osr = false);
70   void Continue();
71   void EndBody();
72   void EndLoop();
73 
74   // Primitive support for break.
75   void Break() final;
76 
77   // Compound control commands for conditional break.
78   void BreakUnless(Node* condition);
79   void BreakWhen(Node* condition);
80 
81  private:
82   Environment* loop_environment_;      // Environment of the loop header.
83   Environment* continue_environment_;  // Environment after the loop body.
84   Environment* break_environment_;     // Environment after the loop exits.
85 };
86 
87 
88 // Tracks control flow for a switch statement.
89 class SwitchBuilder final : public ControlBuilder {
90  public:
SwitchBuilder(AstGraphBuilder * builder,int case_count)91   explicit SwitchBuilder(AstGraphBuilder* builder, int case_count)
92       : ControlBuilder(builder),
93         body_environment_(nullptr),
94         label_environment_(nullptr),
95         break_environment_(nullptr),
96         body_environments_(case_count, zone()) {}
97 
98   // Primitive control commands.
99   void BeginSwitch();
100   void BeginLabel(int index, Node* condition);
101   void EndLabel();
102   void DefaultAt(int index);
103   void BeginCase(int index);
104   void EndCase();
105   void EndSwitch();
106 
107   // Primitive support for break.
108   void Break() final;
109 
110   // The number of cases within a switch is statically known.
case_count()111   size_t case_count() const { return body_environments_.size(); }
112 
113  private:
114   Environment* body_environment_;   // Environment after last case body.
115   Environment* label_environment_;  // Environment for next label condition.
116   Environment* break_environment_;  // Environment after the switch exits.
117   ZoneVector<Environment*> body_environments_;
118 };
119 
120 
121 // Tracks control flow for a block statement.
122 class BlockBuilder final : public ControlBuilder {
123  public:
BlockBuilder(AstGraphBuilder * builder)124   explicit BlockBuilder(AstGraphBuilder* builder)
125       : ControlBuilder(builder), break_environment_(nullptr) {}
126 
127   // Primitive control commands.
128   void BeginBlock();
129   void EndBlock();
130 
131   // Primitive support for break.
132   void Break() final;
133 
134   // Compound control commands for conditional break.
135   void BreakWhen(Node* condition, BranchHint = BranchHint::kNone);
136   void BreakUnless(Node* condition, BranchHint hint = BranchHint::kNone);
137 
138  private:
139   Environment* break_environment_;  // Environment after the block exits.
140 };
141 
142 
143 // Tracks control flow for a try-catch statement.
144 class TryCatchBuilder final : public ControlBuilder {
145  public:
TryCatchBuilder(AstGraphBuilder * builder)146   explicit TryCatchBuilder(AstGraphBuilder* builder)
147       : ControlBuilder(builder),
148         catch_environment_(nullptr),
149         exit_environment_(nullptr),
150         exception_node_(nullptr) {}
151 
152   // Primitive control commands.
153   void BeginTry();
154   void Throw(Node* exception);
155   void EndTry();
156   void EndCatch();
157 
158   // Returns the exception value inside the 'catch' body.
GetExceptionNode()159   Node* GetExceptionNode() const { return exception_node_; }
160 
161  private:
162   Environment* catch_environment_;  // Environment for the 'catch' body.
163   Environment* exit_environment_;   // Environment after the statement.
164   Node* exception_node_;            // Node for exception in 'catch' body.
165 };
166 
167 
168 // Tracks control flow for a try-finally statement.
169 class TryFinallyBuilder final : public ControlBuilder {
170  public:
TryFinallyBuilder(AstGraphBuilder * builder)171   explicit TryFinallyBuilder(AstGraphBuilder* builder)
172       : ControlBuilder(builder),
173         finally_environment_(nullptr),
174         token_node_(nullptr),
175         value_node_(nullptr) {}
176 
177   // Primitive control commands.
178   void BeginTry();
179   void LeaveTry(Node* token, Node* value);
180   void EndTry(Node* token, Node* value);
181   void EndFinally();
182 
183   // Returns the dispatch token value inside the 'finally' body.
GetDispatchTokenNode()184   Node* GetDispatchTokenNode() const { return token_node_; }
185 
186   // Returns the saved result value inside the 'finally' body.
GetResultValueNode()187   Node* GetResultValueNode() const { return value_node_; }
188 
189  private:
190   Environment* finally_environment_;  // Environment for the 'finally' body.
191   Node* token_node_;                  // Node for token in 'finally' body.
192   Node* value_node_;                  // Node for value in 'finally' body.
193 };
194 
195 }  // namespace compiler
196 }  // namespace internal
197 }  // namespace v8
198 
199 #endif  // V8_COMPILER_CONTROL_BUILDERS_H_
200