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 }
     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