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 #include "src/compiler/control-builders.h"
6
7 namespace v8 {
8 namespace internal {
9 namespace compiler {
10
11
If(Node * condition,BranchHint hint)12 void IfBuilder::If(Node* condition, BranchHint hint) {
13 builder_->NewBranch(condition, hint);
14 else_environment_ = environment()->CopyForConditional();
15 }
16
17
Then()18 void IfBuilder::Then() { builder_->NewIfTrue(); }
19
20
Else()21 void IfBuilder::Else() {
22 builder_->NewMerge();
23 then_environment_ = environment();
24 set_environment(else_environment_);
25 builder_->NewIfFalse();
26 }
27
28
End()29 void IfBuilder::End() {
30 then_environment_->Merge(environment());
31 set_environment(then_environment_);
32 }
33
34
BeginLoop(BitVector * assigned,bool is_osr)35 void LoopBuilder::BeginLoop(BitVector* assigned, bool is_osr) {
36 loop_environment_ = environment()->CopyForLoop(assigned, is_osr);
37 continue_environment_ = environment()->CopyAsUnreachable();
38 break_environment_ = environment()->CopyAsUnreachable();
39 assigned_ = assigned;
40 }
41
42
Continue()43 void LoopBuilder::Continue() {
44 continue_environment_->Merge(environment());
45 environment()->MarkAsUnreachable();
46 }
47
48
Break()49 void LoopBuilder::Break() {
50 break_environment_->Merge(environment());
51 environment()->MarkAsUnreachable();
52 }
53
54
EndBody()55 void LoopBuilder::EndBody() {
56 continue_environment_->Merge(environment());
57 set_environment(continue_environment_);
58 }
59
60
EndLoop()61 void LoopBuilder::EndLoop() {
62 loop_environment_->Merge(environment());
63 set_environment(break_environment_);
64 ExitLoop();
65 }
66
67
BreakUnless(Node * condition)68 void LoopBuilder::BreakUnless(Node* condition) {
69 IfBuilder control_if(builder_);
70 control_if.If(condition);
71 control_if.Then();
72 control_if.Else();
73 Break();
74 control_if.End();
75 }
76
77
BreakWhen(Node * condition)78 void LoopBuilder::BreakWhen(Node* condition) {
79 IfBuilder control_if(builder_);
80 control_if.If(condition);
81 control_if.Then();
82 Break();
83 control_if.Else();
84 control_if.End();
85 }
86
ExitLoop(Node ** extra_value_to_rename)87 void LoopBuilder::ExitLoop(Node** extra_value_to_rename) {
88 if (extra_value_to_rename) {
89 environment()->Push(*extra_value_to_rename);
90 }
91 environment()->PrepareForLoopExit(loop_environment_->GetControlDependency(),
92 assigned_);
93 if (extra_value_to_rename) {
94 *extra_value_to_rename = environment()->Pop();
95 }
96 }
97
BeginSwitch()98 void SwitchBuilder::BeginSwitch() {
99 body_environment_ = environment()->CopyAsUnreachable();
100 label_environment_ = environment()->CopyAsUnreachable();
101 break_environment_ = environment()->CopyAsUnreachable();
102 }
103
104
BeginLabel(int index,Node * condition)105 void SwitchBuilder::BeginLabel(int index, Node* condition) {
106 builder_->NewBranch(condition);
107 label_environment_ = environment()->CopyForConditional();
108 builder_->NewIfTrue();
109 body_environments_[index] = environment();
110 }
111
112
EndLabel()113 void SwitchBuilder::EndLabel() {
114 set_environment(label_environment_);
115 builder_->NewIfFalse();
116 }
117
118
DefaultAt(int index)119 void SwitchBuilder::DefaultAt(int index) {
120 label_environment_ = environment()->CopyAsUnreachable();
121 body_environments_[index] = environment();
122 }
123
124
BeginCase(int index)125 void SwitchBuilder::BeginCase(int index) {
126 set_environment(body_environments_[index]);
127 environment()->Merge(body_environment_);
128 }
129
130
Break()131 void SwitchBuilder::Break() {
132 break_environment_->Merge(environment());
133 environment()->MarkAsUnreachable();
134 }
135
136
EndCase()137 void SwitchBuilder::EndCase() { body_environment_ = environment(); }
138
139
EndSwitch()140 void SwitchBuilder::EndSwitch() {
141 break_environment_->Merge(label_environment_);
142 break_environment_->Merge(environment());
143 set_environment(break_environment_);
144 }
145
146
BeginBlock()147 void BlockBuilder::BeginBlock() {
148 break_environment_ = environment()->CopyAsUnreachable();
149 }
150
151
Break()152 void BlockBuilder::Break() {
153 break_environment_->Merge(environment());
154 environment()->MarkAsUnreachable();
155 }
156
157
BreakWhen(Node * condition,BranchHint hint)158 void BlockBuilder::BreakWhen(Node* condition, BranchHint hint) {
159 IfBuilder control_if(builder_);
160 control_if.If(condition, hint);
161 control_if.Then();
162 Break();
163 control_if.Else();
164 control_if.End();
165 }
166
167
BreakUnless(Node * condition,BranchHint hint)168 void BlockBuilder::BreakUnless(Node* condition, BranchHint hint) {
169 IfBuilder control_if(builder_);
170 control_if.If(condition, hint);
171 control_if.Then();
172 control_if.Else();
173 Break();
174 control_if.End();
175 }
176
177
EndBlock()178 void BlockBuilder::EndBlock() {
179 break_environment_->Merge(environment());
180 set_environment(break_environment_);
181 }
182
183
BeginTry()184 void TryCatchBuilder::BeginTry() {
185 exit_environment_ = environment()->CopyAsUnreachable();
186 catch_environment_ = environment()->CopyAsUnreachable();
187 catch_environment_->Push(the_hole());
188 }
189
190
Throw(Node * exception)191 void TryCatchBuilder::Throw(Node* exception) {
192 environment()->Push(exception);
193 catch_environment_->Merge(environment());
194 environment()->Pop();
195 environment()->MarkAsUnreachable();
196 }
197
198
EndTry()199 void TryCatchBuilder::EndTry() {
200 exit_environment_->Merge(environment());
201 exception_node_ = catch_environment_->Pop();
202 set_environment(catch_environment_);
203 }
204
205
EndCatch()206 void TryCatchBuilder::EndCatch() {
207 exit_environment_->Merge(environment());
208 set_environment(exit_environment_);
209 }
210
211
BeginTry()212 void TryFinallyBuilder::BeginTry() {
213 finally_environment_ = environment()->CopyAsUnreachable();
214 finally_environment_->Push(the_hole());
215 finally_environment_->Push(the_hole());
216 }
217
218
LeaveTry(Node * token,Node * value)219 void TryFinallyBuilder::LeaveTry(Node* token, Node* value) {
220 environment()->Push(value);
221 environment()->Push(token);
222 finally_environment_->Merge(environment());
223 environment()->Drop(2);
224 }
225
226
EndTry(Node * fallthrough_token,Node * value)227 void TryFinallyBuilder::EndTry(Node* fallthrough_token, Node* value) {
228 environment()->Push(value);
229 environment()->Push(fallthrough_token);
230 finally_environment_->Merge(environment());
231 environment()->Drop(2);
232 token_node_ = finally_environment_->Pop();
233 value_node_ = finally_environment_->Pop();
234 set_environment(finally_environment_);
235 }
236
237
EndFinally()238 void TryFinallyBuilder::EndFinally() {
239 // Nothing to be done here.
240 }
241
242 } // namespace compiler
243 } // namespace internal
244 } // namespace v8
245