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 12 void IfBuilder::If(Node* condition, BranchHint hint) { 13 builder_->NewBranch(condition, hint); 14 else_environment_ = environment()->CopyForConditional(); 15 } 16 17 18 void IfBuilder::Then() { builder_->NewIfTrue(); } 19 20 21 void IfBuilder::Else() { 22 builder_->NewMerge(); 23 then_environment_ = environment(); 24 set_environment(else_environment_); 25 builder_->NewIfFalse(); 26 } 27 28 29 void IfBuilder::End() { 30 then_environment_->Merge(environment()); 31 set_environment(then_environment_); 32 } 33 34 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 43 void LoopBuilder::Continue() { 44 continue_environment_->Merge(environment()); 45 environment()->MarkAsUnreachable(); 46 } 47 48 49 void LoopBuilder::Break() { 50 break_environment_->Merge(environment()); 51 environment()->MarkAsUnreachable(); 52 } 53 54 55 void LoopBuilder::EndBody() { 56 continue_environment_->Merge(environment()); 57 set_environment(continue_environment_); 58 } 59 60 61 void LoopBuilder::EndLoop() { 62 loop_environment_->Merge(environment()); 63 set_environment(break_environment_); 64 ExitLoop(); 65 } 66 67 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 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 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 98 void SwitchBuilder::BeginSwitch() { 99 body_environment_ = environment()->CopyAsUnreachable(); 100 label_environment_ = environment()->CopyAsUnreachable(); 101 break_environment_ = environment()->CopyAsUnreachable(); 102 } 103 104 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 113 void SwitchBuilder::EndLabel() { 114 set_environment(label_environment_); 115 builder_->NewIfFalse(); 116 } 117 118 119 void SwitchBuilder::DefaultAt(int index) { 120 label_environment_ = environment()->CopyAsUnreachable(); 121 body_environments_[index] = environment(); 122 } 123 124 125 void SwitchBuilder::BeginCase(int index) { 126 set_environment(body_environments_[index]); 127 environment()->Merge(body_environment_); 128 } 129 130 131 void SwitchBuilder::Break() { 132 break_environment_->Merge(environment()); 133 environment()->MarkAsUnreachable(); 134 } 135 136 137 void SwitchBuilder::EndCase() { body_environment_ = environment(); } 138 139 140 void SwitchBuilder::EndSwitch() { 141 break_environment_->Merge(label_environment_); 142 break_environment_->Merge(environment()); 143 set_environment(break_environment_); 144 } 145 146 147 void BlockBuilder::BeginBlock() { 148 break_environment_ = environment()->CopyAsUnreachable(); 149 } 150 151 152 void BlockBuilder::Break() { 153 break_environment_->Merge(environment()); 154 environment()->MarkAsUnreachable(); 155 } 156 157 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 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 178 void BlockBuilder::EndBlock() { 179 break_environment_->Merge(environment()); 180 set_environment(break_environment_); 181 } 182 183 184 void TryCatchBuilder::BeginTry() { 185 exit_environment_ = environment()->CopyAsUnreachable(); 186 catch_environment_ = environment()->CopyAsUnreachable(); 187 catch_environment_->Push(the_hole()); 188 } 189 190 191 void TryCatchBuilder::Throw(Node* exception) { 192 environment()->Push(exception); 193 catch_environment_->Merge(environment()); 194 environment()->Pop(); 195 environment()->MarkAsUnreachable(); 196 } 197 198 199 void TryCatchBuilder::EndTry() { 200 exit_environment_->Merge(environment()); 201 exception_node_ = catch_environment_->Pop(); 202 set_environment(catch_environment_); 203 } 204 205 206 void TryCatchBuilder::EndCatch() { 207 exit_environment_->Merge(environment()); 208 set_environment(exit_environment_); 209 } 210 211 212 void TryFinallyBuilder::BeginTry() { 213 finally_environment_ = environment()->CopyAsUnreachable(); 214 finally_environment_->Push(the_hole()); 215 finally_environment_->Push(the_hole()); 216 } 217 218 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 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 238 void TryFinallyBuilder::EndFinally() { 239 // Nothing to be done here. 240 } 241 242 } // namespace compiler 243 } // namespace internal 244 } // namespace v8 245