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 #ifndef V8_COMPILER_CONTROL_BUILDERS_H_
      6 #define V8_COMPILER_CONTROL_BUILDERS_H_
      7 
      8 #include "src/compiler/ast-graph-builder.h"
      9 #include "src/compiler/node.h"
     10 
     11 namespace v8 {
     12 namespace internal {
     13 namespace compiler {
     14 
     15 // Base class for all control builders. Also provides a common interface for
     16 // control builders to handle 'break' statements when they are used to model
     17 // breakable statements.
     18 class ControlBuilder {
     19  public:
     20   explicit ControlBuilder(AstGraphBuilder* builder) : builder_(builder) {}
     21   virtual ~ControlBuilder() {}
     22 
     23   // Interface for break.
     24   virtual void Break() { UNREACHABLE(); }
     25 
     26  protected:
     27   typedef AstGraphBuilder Builder;
     28   typedef AstGraphBuilder::Environment Environment;
     29 
     30   Zone* zone() const { return builder_->local_zone(); }
     31   Environment* environment() { return builder_->environment(); }
     32   void set_environment(Environment* env) { builder_->set_environment(env); }
     33   Node* the_hole() const { return builder_->jsgraph()->TheHoleConstant(); }
     34 
     35   Builder* builder_;
     36 };
     37 
     38 
     39 // Tracks control flow for a conditional statement.
     40 class IfBuilder final : public ControlBuilder {
     41  public:
     42   explicit IfBuilder(AstGraphBuilder* builder)
     43       : ControlBuilder(builder),
     44         then_environment_(nullptr),
     45         else_environment_(nullptr) {}
     46 
     47   // Primitive control commands.
     48   void If(Node* condition, BranchHint hint = BranchHint::kNone);
     49   void Then();
     50   void Else();
     51   void End();
     52 
     53  private:
     54   Environment* then_environment_;  // Environment after the 'then' body.
     55   Environment* else_environment_;  // Environment for the 'else' body.
     56 };
     57 
     58 
     59 // Tracks control flow for an iteration statement.
     60 class LoopBuilder final : public ControlBuilder {
     61  public:
     62   explicit LoopBuilder(AstGraphBuilder* builder)
     63       : ControlBuilder(builder),
     64         loop_environment_(nullptr),
     65         continue_environment_(nullptr),
     66         break_environment_(nullptr) {}
     67 
     68   // Primitive control commands.
     69   void BeginLoop(BitVector* assigned, bool is_osr = false);
     70   void Continue();
     71   void EndBody();
     72   void EndLoop();
     73 
     74   // Primitive support for break.
     75   void Break() final;
     76 
     77   // Compound control commands for conditional break.
     78   void BreakUnless(Node* condition);
     79   void BreakWhen(Node* condition);
     80 
     81  private:
     82   Environment* loop_environment_;      // Environment of the loop header.
     83   Environment* continue_environment_;  // Environment after the loop body.
     84   Environment* break_environment_;     // Environment after the loop exits.
     85 };
     86 
     87 
     88 // Tracks control flow for a switch statement.
     89 class SwitchBuilder final : public ControlBuilder {
     90  public:
     91   explicit SwitchBuilder(AstGraphBuilder* builder, int case_count)
     92       : ControlBuilder(builder),
     93         body_environment_(nullptr),
     94         label_environment_(nullptr),
     95         break_environment_(nullptr),
     96         body_environments_(case_count, zone()) {}
     97 
     98   // Primitive control commands.
     99   void BeginSwitch();
    100   void BeginLabel(int index, Node* condition);
    101   void EndLabel();
    102   void DefaultAt(int index);
    103   void BeginCase(int index);
    104   void EndCase();
    105   void EndSwitch();
    106 
    107   // Primitive support for break.
    108   void Break() final;
    109 
    110   // The number of cases within a switch is statically known.
    111   size_t case_count() const { return body_environments_.size(); }
    112 
    113  private:
    114   Environment* body_environment_;   // Environment after last case body.
    115   Environment* label_environment_;  // Environment for next label condition.
    116   Environment* break_environment_;  // Environment after the switch exits.
    117   ZoneVector<Environment*> body_environments_;
    118 };
    119 
    120 
    121 // Tracks control flow for a block statement.
    122 class BlockBuilder final : public ControlBuilder {
    123  public:
    124   explicit BlockBuilder(AstGraphBuilder* builder)
    125       : ControlBuilder(builder), break_environment_(nullptr) {}
    126 
    127   // Primitive control commands.
    128   void BeginBlock();
    129   void EndBlock();
    130 
    131   // Primitive support for break.
    132   void Break() final;
    133 
    134   // Compound control commands for conditional break.
    135   void BreakWhen(Node* condition, BranchHint = BranchHint::kNone);
    136   void BreakUnless(Node* condition, BranchHint hint = BranchHint::kNone);
    137 
    138  private:
    139   Environment* break_environment_;  // Environment after the block exits.
    140 };
    141 
    142 
    143 // Tracks control flow for a try-catch statement.
    144 class TryCatchBuilder final : public ControlBuilder {
    145  public:
    146   explicit TryCatchBuilder(AstGraphBuilder* builder)
    147       : ControlBuilder(builder),
    148         catch_environment_(nullptr),
    149         exit_environment_(nullptr),
    150         exception_node_(nullptr) {}
    151 
    152   // Primitive control commands.
    153   void BeginTry();
    154   void Throw(Node* exception);
    155   void EndTry();
    156   void EndCatch();
    157 
    158   // Returns the exception value inside the 'catch' body.
    159   Node* GetExceptionNode() const { return exception_node_; }
    160 
    161  private:
    162   Environment* catch_environment_;  // Environment for the 'catch' body.
    163   Environment* exit_environment_;   // Environment after the statement.
    164   Node* exception_node_;            // Node for exception in 'catch' body.
    165 };
    166 
    167 
    168 // Tracks control flow for a try-finally statement.
    169 class TryFinallyBuilder final : public ControlBuilder {
    170  public:
    171   explicit TryFinallyBuilder(AstGraphBuilder* builder)
    172       : ControlBuilder(builder),
    173         finally_environment_(nullptr),
    174         token_node_(nullptr),
    175         value_node_(nullptr) {}
    176 
    177   // Primitive control commands.
    178   void BeginTry();
    179   void LeaveTry(Node* token, Node* value);
    180   void EndTry(Node* token, Node* value);
    181   void EndFinally();
    182 
    183   // Returns the dispatch token value inside the 'finally' body.
    184   Node* GetDispatchTokenNode() const { return token_node_; }
    185 
    186   // Returns the saved result value inside the 'finally' body.
    187   Node* GetResultValueNode() const { return value_node_; }
    188 
    189  private:
    190   Environment* finally_environment_;  // Environment for the 'finally' body.
    191   Node* token_node_;                  // Node for token in 'finally' body.
    192   Node* value_node_;                  // Node for value in 'finally' body.
    193 };
    194 
    195 }  // namespace compiler
    196 }  // namespace internal
    197 }  // namespace v8
    198 
    199 #endif  // V8_COMPILER_CONTROL_BUILDERS_H_
    200