blob: 6ff00be59614378dd8be96943bbe77ba5e35479d [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008#include "src/compiler/ast-graph-builder.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009#include "src/compiler/node.h"
10
11namespace v8 {
12namespace internal {
13namespace compiler {
14
Ben Murdochb8a8cc12014-11-26 15:28:44 +000015// Base class for all control builders. Also provides a common interface for
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000016// control builders to handle 'break' statements when they are used to model
17// breakable statements.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000018class ControlBuilder {
19 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000020 explicit ControlBuilder(AstGraphBuilder* builder) : builder_(builder) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +000021 virtual ~ControlBuilder() {}
22
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000023 // Interface for break.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000024 virtual void Break() { UNREACHABLE(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000025
26 protected:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000027 typedef AstGraphBuilder Builder;
28 typedef AstGraphBuilder::Environment Environment;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000029
Emily Bernierd0a1eb72015-03-24 16:35:39 -040030 Zone* zone() const { return builder_->local_zone(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000031 Environment* environment() { return builder_->environment(); }
32 void set_environment(Environment* env) { builder_->set_environment(env); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000033 Node* the_hole() const { return builder_->jsgraph()->TheHoleConstant(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000034
35 Builder* builder_;
36};
37
38
39// Tracks control flow for a conditional statement.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000040class IfBuilder final : public ControlBuilder {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000041 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000042 explicit IfBuilder(AstGraphBuilder* builder)
Ben Murdochb8a8cc12014-11-26 15:28:44 +000043 : ControlBuilder(builder),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000044 then_environment_(nullptr),
45 else_environment_(nullptr) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +000046
47 // Primitive control commands.
Emily Bernierd0a1eb72015-03-24 16:35:39 -040048 void If(Node* condition, BranchHint hint = BranchHint::kNone);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000049 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.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000060class LoopBuilder final : public ControlBuilder {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000061 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000062 explicit LoopBuilder(AstGraphBuilder* builder)
Ben Murdochb8a8cc12014-11-26 15:28:44 +000063 : ControlBuilder(builder),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000064 loop_environment_(nullptr),
65 continue_environment_(nullptr),
66 break_environment_(nullptr) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +000067
68 // Primitive control commands.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000069 void BeginLoop(BitVector* assigned, bool is_osr = false);
70 void Continue();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000071 void EndBody();
72 void EndLoop();
73
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000074 // Primitive support for break.
75 void Break() final;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000076
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000077 // Compound control commands for conditional break.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000078 void BreakUnless(Node* condition);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000079 void BreakWhen(Node* condition);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000080
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.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000089class SwitchBuilder final : public ControlBuilder {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000090 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000091 explicit SwitchBuilder(AstGraphBuilder* builder, int case_count)
Ben Murdochb8a8cc12014-11-26 15:28:44 +000092 : ControlBuilder(builder),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000093 body_environment_(nullptr),
94 label_environment_(nullptr),
95 break_environment_(nullptr),
Ben Murdochb8a8cc12014-11-26 15:28:44 +000096 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.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000108 void Break() final;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000109
110 // The number of cases within a switch is statically known.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400111 size_t case_count() const { return body_environments_.size(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000112
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.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400117 ZoneVector<Environment*> body_environments_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000118};
119
120
121// Tracks control flow for a block statement.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000122class BlockBuilder final : public ControlBuilder {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000123 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000124 explicit BlockBuilder(AstGraphBuilder* builder)
125 : ControlBuilder(builder), break_environment_(nullptr) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000126
127 // Primitive control commands.
128 void BeginBlock();
129 void EndBlock();
130
131 // Primitive support for break.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000132 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);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000137
138 private:
139 Environment* break_environment_; // Environment after the block exits.
140};
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400141
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000142
143// Tracks control flow for a try-catch statement.
144class TryCatchBuilder final : public ControlBuilder {
145 public:
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.
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.
169class TryFinallyBuilder final : public ControlBuilder {
170 public:
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.
184 Node* GetDispatchTokenNode() const { return token_node_; }
185
186 // Returns the saved result value inside the 'finally' body.
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
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400195} // namespace compiler
196} // namespace internal
197} // namespace v8
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000198
199#endif // V8_COMPILER_CONTROL_BUILDERS_H_