Home | History | Annotate | Download | only in compiler
      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