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 #include "src/objects-inl.h" 8 9 namespace v8 { 10 namespace internal { 11 namespace compiler { 12 13 14 void IfBuilder::If(Node* condition, BranchHint hint) { 15 builder_->NewBranch(condition, hint); 16 else_environment_ = environment()->CopyForConditional(); 17 } 18 19 20 void IfBuilder::Then() { builder_->NewIfTrue(); } 21 22 23 void IfBuilder::Else() { 24 builder_->NewMerge(); 25 then_environment_ = environment(); 26 set_environment(else_environment_); 27 builder_->NewIfFalse(); 28 } 29 30 31 void IfBuilder::End() { 32 then_environment_->Merge(environment()); 33 set_environment(then_environment_); 34 } 35 36 37 void LoopBuilder::BeginLoop(BitVector* assigned, bool is_osr) { 38 loop_environment_ = environment()->CopyForLoop(assigned, is_osr); 39 continue_environment_ = environment()->CopyAsUnreachable(); 40 break_environment_ = environment()->CopyAsUnreachable(); 41 assigned_ = assigned; 42 } 43 44 45 void LoopBuilder::Continue() { 46 continue_environment_->Merge(environment()); 47 environment()->MarkAsUnreachable(); 48 } 49 50 51 void LoopBuilder::Break() { 52 break_environment_->Merge(environment()); 53 environment()->MarkAsUnreachable(); 54 } 55 56 57 void LoopBuilder::EndBody() { 58 continue_environment_->Merge(environment()); 59 set_environment(continue_environment_); 60 } 61 62 63 void LoopBuilder::EndLoop() { 64 loop_environment_->Merge(environment()); 65 set_environment(break_environment_); 66 ExitLoop(); 67 } 68 69 70 void LoopBuilder::BreakUnless(Node* condition) { 71 IfBuilder control_if(builder_); 72 control_if.If(condition); 73 control_if.Then(); 74 control_if.Else(); 75 Break(); 76 control_if.End(); 77 } 78 79 80 void LoopBuilder::BreakWhen(Node* condition) { 81 IfBuilder control_if(builder_); 82 control_if.If(condition); 83 control_if.Then(); 84 Break(); 85 control_if.Else(); 86 control_if.End(); 87 } 88 89 void LoopBuilder::ExitLoop(Node** extra_value_to_rename) { 90 if (extra_value_to_rename) { 91 environment()->Push(*extra_value_to_rename); 92 } 93 environment()->PrepareForLoopExit(loop_environment_->GetControlDependency(), 94 assigned_); 95 if (extra_value_to_rename) { 96 *extra_value_to_rename = environment()->Pop(); 97 } 98 } 99 100 void SwitchBuilder::BeginSwitch() { 101 body_environment_ = environment()->CopyAsUnreachable(); 102 label_environment_ = environment()->CopyAsUnreachable(); 103 break_environment_ = environment()->CopyAsUnreachable(); 104 } 105 106 107 void SwitchBuilder::BeginLabel(int index, Node* condition) { 108 builder_->NewBranch(condition); 109 label_environment_ = environment()->CopyForConditional(); 110 builder_->NewIfTrue(); 111 body_environments_[index] = environment(); 112 } 113 114 115 void SwitchBuilder::EndLabel() { 116 set_environment(label_environment_); 117 builder_->NewIfFalse(); 118 } 119 120 121 void SwitchBuilder::DefaultAt(int index) { 122 label_environment_ = environment()->CopyAsUnreachable(); 123 body_environments_[index] = environment(); 124 } 125 126 127 void SwitchBuilder::BeginCase(int index) { 128 set_environment(body_environments_[index]); 129 environment()->Merge(body_environment_); 130 } 131 132 133 void SwitchBuilder::Break() { 134 break_environment_->Merge(environment()); 135 environment()->MarkAsUnreachable(); 136 } 137 138 139 void SwitchBuilder::EndCase() { body_environment_ = environment(); } 140 141 142 void SwitchBuilder::EndSwitch() { 143 break_environment_->Merge(label_environment_); 144 break_environment_->Merge(environment()); 145 set_environment(break_environment_); 146 } 147 148 149 void BlockBuilder::BeginBlock() { 150 break_environment_ = environment()->CopyAsUnreachable(); 151 } 152 153 154 void BlockBuilder::Break() { 155 break_environment_->Merge(environment()); 156 environment()->MarkAsUnreachable(); 157 } 158 159 160 void BlockBuilder::BreakWhen(Node* condition, BranchHint hint) { 161 IfBuilder control_if(builder_); 162 control_if.If(condition, hint); 163 control_if.Then(); 164 Break(); 165 control_if.Else(); 166 control_if.End(); 167 } 168 169 170 void BlockBuilder::BreakUnless(Node* condition, BranchHint hint) { 171 IfBuilder control_if(builder_); 172 control_if.If(condition, hint); 173 control_if.Then(); 174 control_if.Else(); 175 Break(); 176 control_if.End(); 177 } 178 179 180 void BlockBuilder::EndBlock() { 181 break_environment_->Merge(environment()); 182 set_environment(break_environment_); 183 } 184 185 } // namespace compiler 186 } // namespace internal 187 } // namespace v8 188