Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 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/v8.h" |
| 9 | |
| 10 | #include "src/compiler/graph-builder.h" |
| 11 | #include "src/compiler/node.h" |
| 12 | |
| 13 | namespace v8 { |
| 14 | namespace internal { |
| 15 | namespace compiler { |
| 16 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 17 | // Base class for all control builders. Also provides a common interface for |
| 18 | // control builders to handle 'break' and 'continue' statements when they are |
| 19 | // used to model breakable statements. |
| 20 | class ControlBuilder { |
| 21 | public: |
| 22 | explicit ControlBuilder(StructuredGraphBuilder* builder) |
| 23 | : builder_(builder) {} |
| 24 | virtual ~ControlBuilder() {} |
| 25 | |
| 26 | // Interface for break and continue. |
| 27 | virtual void Break() { UNREACHABLE(); } |
| 28 | virtual void Continue() { UNREACHABLE(); } |
| 29 | |
| 30 | protected: |
| 31 | typedef StructuredGraphBuilder Builder; |
| 32 | typedef StructuredGraphBuilder::Environment Environment; |
| 33 | |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame^] | 34 | Zone* zone() const { return builder_->local_zone(); } |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 35 | Environment* environment() { return builder_->environment(); } |
| 36 | void set_environment(Environment* env) { builder_->set_environment(env); } |
| 37 | |
| 38 | Builder* builder_; |
| 39 | }; |
| 40 | |
| 41 | |
| 42 | // Tracks control flow for a conditional statement. |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame^] | 43 | class IfBuilder FINAL : public ControlBuilder { |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 44 | public: |
| 45 | explicit IfBuilder(StructuredGraphBuilder* builder) |
| 46 | : ControlBuilder(builder), |
| 47 | then_environment_(NULL), |
| 48 | else_environment_(NULL) {} |
| 49 | |
| 50 | // Primitive control commands. |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame^] | 51 | void If(Node* condition, BranchHint hint = BranchHint::kNone); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 52 | void Then(); |
| 53 | void Else(); |
| 54 | void End(); |
| 55 | |
| 56 | private: |
| 57 | Environment* then_environment_; // Environment after the 'then' body. |
| 58 | Environment* else_environment_; // Environment for the 'else' body. |
| 59 | }; |
| 60 | |
| 61 | |
| 62 | // Tracks control flow for an iteration statement. |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame^] | 63 | class LoopBuilder FINAL : public ControlBuilder { |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 64 | public: |
| 65 | explicit LoopBuilder(StructuredGraphBuilder* builder) |
| 66 | : ControlBuilder(builder), |
| 67 | loop_environment_(NULL), |
| 68 | continue_environment_(NULL), |
| 69 | break_environment_(NULL) {} |
| 70 | |
| 71 | // Primitive control commands. |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame^] | 72 | void BeginLoop(BitVector* assigned); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 73 | void EndBody(); |
| 74 | void EndLoop(); |
| 75 | |
| 76 | // Primitive support for break and continue. |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame^] | 77 | void Continue() FINAL; |
| 78 | void Break() FINAL; |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 79 | |
| 80 | // Compound control command for conditional break. |
| 81 | void BreakUnless(Node* condition); |
| 82 | |
| 83 | private: |
| 84 | Environment* loop_environment_; // Environment of the loop header. |
| 85 | Environment* continue_environment_; // Environment after the loop body. |
| 86 | Environment* break_environment_; // Environment after the loop exits. |
| 87 | }; |
| 88 | |
| 89 | |
| 90 | // Tracks control flow for a switch statement. |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame^] | 91 | class SwitchBuilder FINAL : public ControlBuilder { |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 92 | public: |
| 93 | explicit SwitchBuilder(StructuredGraphBuilder* builder, int case_count) |
| 94 | : ControlBuilder(builder), |
| 95 | body_environment_(NULL), |
| 96 | label_environment_(NULL), |
| 97 | break_environment_(NULL), |
| 98 | body_environments_(case_count, zone()) {} |
| 99 | |
| 100 | // Primitive control commands. |
| 101 | void BeginSwitch(); |
| 102 | void BeginLabel(int index, Node* condition); |
| 103 | void EndLabel(); |
| 104 | void DefaultAt(int index); |
| 105 | void BeginCase(int index); |
| 106 | void EndCase(); |
| 107 | void EndSwitch(); |
| 108 | |
| 109 | // Primitive support for break. |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame^] | 110 | void Break() FINAL; |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 111 | |
| 112 | // The number of cases within a switch is statically known. |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame^] | 113 | size_t case_count() const { return body_environments_.size(); } |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 114 | |
| 115 | private: |
| 116 | Environment* body_environment_; // Environment after last case body. |
| 117 | Environment* label_environment_; // Environment for next label condition. |
| 118 | Environment* break_environment_; // Environment after the switch exits. |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame^] | 119 | ZoneVector<Environment*> body_environments_; |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 120 | }; |
| 121 | |
| 122 | |
| 123 | // Tracks control flow for a block statement. |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame^] | 124 | class BlockBuilder FINAL : public ControlBuilder { |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 125 | public: |
| 126 | explicit BlockBuilder(StructuredGraphBuilder* builder) |
| 127 | : ControlBuilder(builder), break_environment_(NULL) {} |
| 128 | |
| 129 | // Primitive control commands. |
| 130 | void BeginBlock(); |
| 131 | void EndBlock(); |
| 132 | |
| 133 | // Primitive support for break. |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame^] | 134 | void Break() FINAL; |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 135 | |
| 136 | private: |
| 137 | Environment* break_environment_; // Environment after the block exits. |
| 138 | }; |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame^] | 139 | |
| 140 | } // namespace compiler |
| 141 | } // namespace internal |
| 142 | } // namespace v8 |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 143 | |
| 144 | #endif // V8_COMPILER_CONTROL_BUILDERS_H_ |