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/v8.h"
9 
10 #include "src/compiler/graph-builder.h"
11 #include "src/compiler/node.h"
12 
13 namespace v8 {
14 namespace internal {
15 namespace compiler {
16 
17 
18 // Base class for all control builders. Also provides a common interface for
19 // control builders to handle 'break' and 'continue' statements when they are
20 // used to model breakable statements.
21 class ControlBuilder {
22  public:
ControlBuilder(StructuredGraphBuilder * builder)23   explicit ControlBuilder(StructuredGraphBuilder* builder)
24       : builder_(builder) {}
~ControlBuilder()25   virtual ~ControlBuilder() {}
26 
27   // Interface for break and continue.
Break()28   virtual void Break() { UNREACHABLE(); }
Continue()29   virtual void Continue() { UNREACHABLE(); }
30 
31  protected:
32   typedef StructuredGraphBuilder Builder;
33   typedef StructuredGraphBuilder::Environment Environment;
34 
zone()35   Zone* zone() const { return builder_->zone(); }
environment()36   Environment* environment() { return builder_->environment(); }
set_environment(Environment * env)37   void set_environment(Environment* env) { builder_->set_environment(env); }
38 
39   Builder* builder_;
40 };
41 
42 
43 // Tracks control flow for a conditional statement.
44 class IfBuilder : public ControlBuilder {
45  public:
IfBuilder(StructuredGraphBuilder * builder)46   explicit IfBuilder(StructuredGraphBuilder* builder)
47       : ControlBuilder(builder),
48         then_environment_(NULL),
49         else_environment_(NULL) {}
50 
51   // Primitive control commands.
52   void If(Node* condition);
53   void Then();
54   void Else();
55   void End();
56 
57  private:
58   Environment* then_environment_;  // Environment after the 'then' body.
59   Environment* else_environment_;  // Environment for the 'else' body.
60 };
61 
62 
63 // Tracks control flow for an iteration statement.
64 class LoopBuilder : public ControlBuilder {
65  public:
LoopBuilder(StructuredGraphBuilder * builder)66   explicit LoopBuilder(StructuredGraphBuilder* builder)
67       : ControlBuilder(builder),
68         loop_environment_(NULL),
69         continue_environment_(NULL),
70         break_environment_(NULL) {}
71 
72   // Primitive control commands.
73   void BeginLoop();
74   void EndBody();
75   void EndLoop();
76 
77   // Primitive support for break and continue.
78   virtual void Continue();
79   virtual void Break();
80 
81   // Compound control command for conditional break.
82   void BreakUnless(Node* condition);
83 
84  private:
85   Environment* loop_environment_;      // Environment of the loop header.
86   Environment* continue_environment_;  // Environment after the loop body.
87   Environment* break_environment_;     // Environment after the loop exits.
88 };
89 
90 
91 // Tracks control flow for a switch statement.
92 class SwitchBuilder : public ControlBuilder {
93  public:
SwitchBuilder(StructuredGraphBuilder * builder,int case_count)94   explicit SwitchBuilder(StructuredGraphBuilder* builder, int case_count)
95       : ControlBuilder(builder),
96         body_environment_(NULL),
97         label_environment_(NULL),
98         break_environment_(NULL),
99         body_environments_(case_count, zone()) {}
100 
101   // Primitive control commands.
102   void BeginSwitch();
103   void BeginLabel(int index, Node* condition);
104   void EndLabel();
105   void DefaultAt(int index);
106   void BeginCase(int index);
107   void EndCase();
108   void EndSwitch();
109 
110   // Primitive support for break.
111   virtual void Break();
112 
113   // The number of cases within a switch is statically known.
case_count()114   int case_count() const { return body_environments_.capacity(); }
115 
116  private:
117   Environment* body_environment_;   // Environment after last case body.
118   Environment* label_environment_;  // Environment for next label condition.
119   Environment* break_environment_;  // Environment after the switch exits.
120   ZoneList<Environment*> body_environments_;
121 };
122 
123 
124 // Tracks control flow for a block statement.
125 class BlockBuilder : public ControlBuilder {
126  public:
BlockBuilder(StructuredGraphBuilder * builder)127   explicit BlockBuilder(StructuredGraphBuilder* builder)
128       : ControlBuilder(builder), break_environment_(NULL) {}
129 
130   // Primitive control commands.
131   void BeginBlock();
132   void EndBlock();
133 
134   // Primitive support for break.
135   virtual void Break();
136 
137  private:
138   Environment* break_environment_;  // Environment after the block exits.
139 };
140 }
141 }
142 }  // namespace v8::internal::compiler
143 
144 #endif  // V8_COMPILER_CONTROL_BUILDERS_H_
145