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
7namespace v8 {
8namespace internal {
9namespace compiler {
10
11
12void IfBuilder::If(Node* condition, BranchHint hint) {
13  builder_->NewBranch(condition, hint);
14  else_environment_ = environment()->CopyForConditional();
15}
16
17
18void IfBuilder::Then() { builder_->NewIfTrue(); }
19
20
21void IfBuilder::Else() {
22  builder_->NewMerge();
23  then_environment_ = environment();
24  set_environment(else_environment_);
25  builder_->NewIfFalse();
26}
27
28
29void IfBuilder::End() {
30  then_environment_->Merge(environment());
31  set_environment(then_environment_);
32}
33
34
35void 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
42void LoopBuilder::Continue() {
43  continue_environment_->Merge(environment());
44  environment()->MarkAsUnreachable();
45}
46
47
48void LoopBuilder::Break() {
49  break_environment_->Merge(environment());
50  environment()->MarkAsUnreachable();
51}
52
53
54void LoopBuilder::EndBody() {
55  continue_environment_->Merge(environment());
56  set_environment(continue_environment_);
57}
58
59
60void LoopBuilder::EndLoop() {
61  loop_environment_->Merge(environment());
62  set_environment(break_environment_);
63}
64
65
66void 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
76void 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
86void SwitchBuilder::BeginSwitch() {
87  body_environment_ = environment()->CopyAsUnreachable();
88  label_environment_ = environment()->CopyAsUnreachable();
89  break_environment_ = environment()->CopyAsUnreachable();
90}
91
92
93void 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
101void SwitchBuilder::EndLabel() {
102  set_environment(label_environment_);
103  builder_->NewIfFalse();
104}
105
106
107void SwitchBuilder::DefaultAt(int index) {
108  label_environment_ = environment()->CopyAsUnreachable();
109  body_environments_[index] = environment();
110}
111
112
113void SwitchBuilder::BeginCase(int index) {
114  set_environment(body_environments_[index]);
115  environment()->Merge(body_environment_);
116}
117
118
119void SwitchBuilder::Break() {
120  break_environment_->Merge(environment());
121  environment()->MarkAsUnreachable();
122}
123
124
125void SwitchBuilder::EndCase() { body_environment_ = environment(); }
126
127
128void SwitchBuilder::EndSwitch() {
129  break_environment_->Merge(label_environment_);
130  break_environment_->Merge(environment());
131  set_environment(break_environment_);
132}
133
134
135void BlockBuilder::BeginBlock() {
136  break_environment_ = environment()->CopyAsUnreachable();
137}
138
139
140void BlockBuilder::Break() {
141  break_environment_->Merge(environment());
142  environment()->MarkAsUnreachable();
143}
144
145
146void 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
156void 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
166void BlockBuilder::EndBlock() {
167  break_environment_->Merge(environment());
168  set_environment(break_environment_);
169}
170
171
172void TryCatchBuilder::BeginTry() {
173  exit_environment_ = environment()->CopyAsUnreachable();
174  catch_environment_ = environment()->CopyAsUnreachable();
175  catch_environment_->Push(the_hole());
176}
177
178
179void TryCatchBuilder::Throw(Node* exception) {
180  environment()->Push(exception);
181  catch_environment_->Merge(environment());
182  environment()->Pop();
183  environment()->MarkAsUnreachable();
184}
185
186
187void TryCatchBuilder::EndTry() {
188  exit_environment_->Merge(environment());
189  exception_node_ = catch_environment_->Pop();
190  set_environment(catch_environment_);
191}
192
193
194void TryCatchBuilder::EndCatch() {
195  exit_environment_->Merge(environment());
196  set_environment(exit_environment_);
197}
198
199
200void TryFinallyBuilder::BeginTry() {
201  finally_environment_ = environment()->CopyAsUnreachable();
202  finally_environment_->Push(the_hole());
203  finally_environment_->Push(the_hole());
204}
205
206
207void 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
215void 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
226void TryFinallyBuilder::EndFinally() {
227  // Nothing to be done here.
228}
229
230}  // namespace compiler
231}  // namespace internal
232}  // namespace v8
233