Line data Source code
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:
20 10952 : explicit ControlBuilder(AstGraphBuilder* builder) : builder_(builder) {}
21 0 : virtual ~ControlBuilder() {}
22 :
23 : // Interface for break.
24 0 : virtual void Break() { UNREACHABLE(); }
25 :
26 : protected:
27 : typedef AstGraphBuilder Builder;
28 : typedef AstGraphBuilder::Environment Environment;
29 :
30 76 : Zone* zone() const { return builder_->local_zone(); }
31 25816 : Environment* environment() { return builder_->environment(); }
32 : void set_environment(Environment* env) { builder_->set_environment(env); }
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 0 : class IfBuilder final : public ControlBuilder {
41 : public:
42 : explicit IfBuilder(AstGraphBuilder* builder)
43 : : ControlBuilder(builder),
44 : then_environment_(nullptr),
45 4431 : 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 0 : class LoopBuilder final : public ControlBuilder {
61 : public:
62 : explicit LoopBuilder(AstGraphBuilder* builder)
63 : : ControlBuilder(builder),
64 : loop_environment_(nullptr),
65 : continue_environment_(nullptr),
66 : break_environment_(nullptr),
67 834 : 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 0 : class SwitchBuilder final : public ControlBuilder {
96 : public:
97 76 : explicit SwitchBuilder(AstGraphBuilder* builder, int case_count)
98 : : ControlBuilder(builder),
99 : body_environment_(nullptr),
100 : label_environment_(nullptr),
101 : break_environment_(nullptr),
102 228 : 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.
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 0 : class BlockBuilder final : public ControlBuilder {
129 : public:
130 : explicit BlockBuilder(AstGraphBuilder* builder)
131 5611 : : 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_
|