• 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         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