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