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 } 40 41 42 void LoopBuilder::Continue() { 43 continue_environment_->Merge(environment()); 44 environment()->MarkAsUnreachable(); 45 } 46 47 48 void LoopBuilder::Break() { 49 break_environment_->Merge(environment()); 50 environment()->MarkAsUnreachable(); 51 } 52 53 54 void LoopBuilder::EndBody() { 55 continue_environment_->Merge(environment()); 56 set_environment(continue_environment_); 57 } 58 59 60 void LoopBuilder::EndLoop() { 61 loop_environment_->Merge(environment()); 62 set_environment(break_environment_); 63 } 64 65 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 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 86 void SwitchBuilder::BeginSwitch() { 87 body_environment_ = environment()->CopyAsUnreachable(); 88 label_environment_ = environment()->CopyAsUnreachable(); 89 break_environment_ = environment()->CopyAsUnreachable(); 90 } 91 92 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 101 void SwitchBuilder::EndLabel() { 102 set_environment(label_environment_); 103 builder_->NewIfFalse(); 104 } 105 106 107 void SwitchBuilder::DefaultAt(int index) { 108 label_environment_ = environment()->CopyAsUnreachable(); 109 body_environments_[index] = environment(); 110 } 111 112 113 void SwitchBuilder::BeginCase(int index) { 114 set_environment(body_environments_[index]); 115 environment()->Merge(body_environment_); 116 } 117 118 119 void SwitchBuilder::Break() { 120 break_environment_->Merge(environment()); 121 environment()->MarkAsUnreachable(); 122 } 123 124 125 void SwitchBuilder::EndCase() { body_environment_ = environment(); } 126 127 128 void SwitchBuilder::EndSwitch() { 129 break_environment_->Merge(label_environment_); 130 break_environment_->Merge(environment()); 131 set_environment(break_environment_); 132 } 133 134 135 void BlockBuilder::BeginBlock() { 136 break_environment_ = environment()->CopyAsUnreachable(); 137 } 138 139 140 void BlockBuilder::Break() { 141 break_environment_->Merge(environment()); 142 environment()->MarkAsUnreachable(); 143 } 144 145 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 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 166 void BlockBuilder::EndBlock() { 167 break_environment_->Merge(environment()); 168 set_environment(break_environment_); 169 } 170 171 172 void TryCatchBuilder::BeginTry() { 173 exit_environment_ = environment()->CopyAsUnreachable(); 174 catch_environment_ = environment()->CopyAsUnreachable(); 175 catch_environment_->Push(the_hole()); 176 } 177 178 179 void TryCatchBuilder::Throw(Node* exception) { 180 environment()->Push(exception); 181 catch_environment_->Merge(environment()); 182 environment()->Pop(); 183 environment()->MarkAsUnreachable(); 184 } 185 186 187 void TryCatchBuilder::EndTry() { 188 exit_environment_->Merge(environment()); 189 exception_node_ = catch_environment_->Pop(); 190 set_environment(catch_environment_); 191 } 192 193 194 void TryCatchBuilder::EndCatch() { 195 exit_environment_->Merge(environment()); 196 set_environment(exit_environment_); 197 } 198 199 200 void TryFinallyBuilder::BeginTry() { 201 finally_environment_ = environment()->CopyAsUnreachable(); 202 finally_environment_->Push(the_hole()); 203 finally_environment_->Push(the_hole()); 204 } 205 206 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 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 226 void TryFinallyBuilder::EndFinally() { 227 // Nothing to be done here. 228 } 229 230 } // namespace compiler 231 } // namespace internal 232 } // namespace v8 233