Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/interpreter/bytecode-generator.h" | 5 #include "src/interpreter/bytecode-generator.h" |
| 6 | 6 |
| 7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
| 8 #include "src/compiler.h" | 8 #include "src/compiler.h" |
| 9 #include "src/interpreter/bytecode-register-allocator.h" | 9 #include "src/interpreter/bytecode-register-allocator.h" |
| 10 #include "src/interpreter/control-flow-builders.h" | 10 #include "src/interpreter/control-flow-builders.h" |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 74 int depth_; | 74 int depth_; |
| 75 bool should_pop_context_; | 75 bool should_pop_context_; |
| 76 }; | 76 }; |
| 77 | 77 |
| 78 | 78 |
| 79 // Scoped class for tracking control statements entered by the | 79 // Scoped class for tracking control statements entered by the |
| 80 // visitor. The pattern derives AstGraphBuilder::ControlScope. | 80 // visitor. The pattern derives AstGraphBuilder::ControlScope. |
| 81 class BytecodeGenerator::ControlScope BASE_EMBEDDED { | 81 class BytecodeGenerator::ControlScope BASE_EMBEDDED { |
| 82 public: | 82 public: |
| 83 explicit ControlScope(BytecodeGenerator* generator) | 83 explicit ControlScope(BytecodeGenerator* generator) |
| 84 : generator_(generator), outer_(generator->execution_control()) { | 84 : generator_(generator), outer_(generator->execution_control()), |
| 85 context_(generator->execution_context()) { | |
| 85 generator_->set_execution_control(this); | 86 generator_->set_execution_control(this); |
| 86 } | 87 } |
| 87 virtual ~ControlScope() { generator_->set_execution_control(outer()); } | 88 virtual ~ControlScope() { generator_->set_execution_control(outer()); } |
| 88 | 89 |
| 89 void Break(Statement* stmt) { PerformCommand(CMD_BREAK, stmt); } | 90 void Break(Statement* stmt) { PerformCommand(CMD_BREAK, stmt); } |
| 90 void Continue(Statement* stmt) { PerformCommand(CMD_CONTINUE, stmt); } | 91 void Continue(Statement* stmt) { PerformCommand(CMD_CONTINUE, stmt); } |
| 91 | 92 |
| 92 protected: | 93 protected: |
| 93 enum Command { CMD_BREAK, CMD_CONTINUE }; | 94 enum Command { CMD_BREAK, CMD_CONTINUE }; |
| 94 void PerformCommand(Command command, Statement* statement); | 95 void PerformCommand(Command command, Statement* statement); |
| 95 virtual bool Execute(Command command, Statement* statement) = 0; | 96 virtual bool ShouldExecute(Command command, Statement* statement) = 0; |
| 97 virtual void Execute(Command command) = 0; | |
| 96 | 98 |
| 97 BytecodeGenerator* generator() const { return generator_; } | 99 BytecodeGenerator* generator() const { return generator_; } |
| 98 ControlScope* outer() const { return outer_; } | 100 ControlScope* outer() const { return outer_; } |
| 101 ContextScope* context() const { return context_; } | |
| 99 | 102 |
| 100 private: | 103 private: |
| 101 BytecodeGenerator* generator_; | 104 BytecodeGenerator* generator_; |
| 102 ControlScope* outer_; | 105 ControlScope* outer_; |
| 106 ContextScope* context_; | |
| 103 | 107 |
| 104 DISALLOW_COPY_AND_ASSIGN(ControlScope); | 108 DISALLOW_COPY_AND_ASSIGN(ControlScope); |
| 105 }; | 109 }; |
| 106 | 110 |
| 107 | 111 |
| 108 // Scoped class for enabling break inside blocks and switch blocks. | 112 // Scoped class for enabling break inside blocks and switch blocks. |
| 109 class BytecodeGenerator::ControlScopeForBreakable final | 113 class BytecodeGenerator::ControlScopeForBreakable final |
| 110 : public BytecodeGenerator::ControlScope { | 114 : public BytecodeGenerator::ControlScope { |
| 111 public: | 115 public: |
| 112 ControlScopeForBreakable(BytecodeGenerator* generator, | 116 ControlScopeForBreakable(BytecodeGenerator* generator, |
| 113 BreakableStatement* statement, | 117 BreakableStatement* statement, |
| 114 BreakableControlFlowBuilder* control_builder) | 118 BreakableControlFlowBuilder* control_builder) |
| 115 : ControlScope(generator), | 119 : ControlScope(generator), |
| 116 statement_(statement), | 120 statement_(statement), |
| 117 control_builder_(control_builder) {} | 121 control_builder_(control_builder) {} |
| 118 | 122 |
| 119 protected: | 123 protected: |
| 120 virtual bool Execute(Command command, Statement* statement) { | 124 bool ShouldExecute(Command command, Statement* statement) override { |
| 121 if (statement != statement_) return false; | 125 if (statement != statement_) return false; |
| 126 return command == CMD_BREAK; | |
| 127 } | |
| 128 | |
| 129 void Execute(Command command) override { | |
| 122 switch (command) { | 130 switch (command) { |
| 123 case CMD_BREAK: | 131 case CMD_BREAK: |
| 124 control_builder_->Break(); | 132 control_builder_->Break(); |
| 125 return true; | 133 break; |
| 126 case CMD_CONTINUE: | 134 case CMD_CONTINUE: |
| 135 UNREACHABLE(); | |
| 127 break; | 136 break; |
| 128 } | 137 } |
| 129 return false; | |
| 130 } | 138 } |
| 131 | 139 |
| 132 private: | 140 private: |
| 133 Statement* statement_; | 141 Statement* statement_; |
| 134 BreakableControlFlowBuilder* control_builder_; | 142 BreakableControlFlowBuilder* control_builder_; |
| 135 }; | 143 }; |
| 136 | 144 |
| 137 | 145 |
| 138 // Scoped class for enabling 'break' and 'continue' in iteration | 146 // Scoped class for enabling 'break' and 'continue' in iteration |
| 139 // constructs, e.g. do...while, while..., for... | 147 // constructs, e.g. do...while, while..., for... |
| 140 class BytecodeGenerator::ControlScopeForIteration final | 148 class BytecodeGenerator::ControlScopeForIteration final |
| 141 : public BytecodeGenerator::ControlScope { | 149 : public BytecodeGenerator::ControlScope { |
| 142 public: | 150 public: |
| 143 ControlScopeForIteration(BytecodeGenerator* generator, | 151 ControlScopeForIteration(BytecodeGenerator* generator, |
| 144 IterationStatement* statement, | 152 IterationStatement* statement, |
| 145 LoopBuilder* loop_builder) | 153 LoopBuilder* loop_builder) |
| 146 : ControlScope(generator), | 154 : ControlScope(generator), |
| 147 statement_(statement), | 155 statement_(statement), |
| 148 loop_builder_(loop_builder) {} | 156 loop_builder_(loop_builder) {} |
| 149 | 157 |
| 150 protected: | 158 protected: |
| 151 virtual bool Execute(Command command, Statement* statement) { | 159 bool ShouldExecute(Command command, Statement* statement) override { |
| 152 if (statement != statement_) return false; | 160 if (statement != statement_) return false; |
| 161 return command == CMD_BREAK || command == CMD_CONTINUE; | |
| 162 } | |
| 163 | |
| 164 void Execute(Command command) override { | |
| 153 switch (command) { | 165 switch (command) { |
| 154 case CMD_BREAK: | 166 case CMD_BREAK: |
| 155 loop_builder_->Break(); | 167 loop_builder_->Break(); |
| 156 return true; | 168 break; |
| 157 case CMD_CONTINUE: | 169 case CMD_CONTINUE: |
| 158 loop_builder_->Continue(); | 170 loop_builder_->Continue(); |
| 159 return true; | 171 break; |
| 160 } | 172 } |
| 161 return false; | |
| 162 } | 173 } |
| 163 | 174 |
| 164 private: | 175 private: |
| 165 Statement* statement_; | 176 Statement* statement_; |
| 166 LoopBuilder* loop_builder_; | 177 LoopBuilder* loop_builder_; |
| 167 }; | 178 }; |
| 168 | 179 |
| 169 | 180 |
| 170 void BytecodeGenerator::ControlScope::PerformCommand(Command command, | 181 void BytecodeGenerator::ControlScope::PerformCommand(Command command, |
| 171 Statement* statement) { | 182 Statement* statement) { |
| 172 ControlScope* current = this; | 183 ControlScope* current = this; |
| 173 do { | 184 do { |
| 174 if (current->Execute(command, statement)) return; | 185 if (current->ShouldExecute(command, statement)) { |
|
Michael Starzinger
2016/01/21 13:25:20
As discussed offline: How would you feel about goi
rmcilroy
2016/01/22 11:46:08
Done.
| |
| 186 if (current->context() != this->context()) { | |
| 187 // Pop context to the expected depth. | |
| 188 generator()->builder()->PopContext(current->context()->reg()); | |
| 189 } | |
| 190 current->Execute(command); | |
| 191 return; | |
| 192 } | |
| 175 current = current->outer(); | 193 current = current->outer(); |
| 176 } while (current != nullptr); | 194 } while (current != nullptr); |
| 177 UNREACHABLE(); | 195 UNREACHABLE(); |
| 178 } | 196 } |
| 179 | 197 |
| 180 | 198 |
| 181 class BytecodeGenerator::RegisterAllocationScope { | 199 class BytecodeGenerator::RegisterAllocationScope { |
| 182 public: | 200 public: |
| 183 explicit RegisterAllocationScope(BytecodeGenerator* generator) | 201 explicit RegisterAllocationScope(BytecodeGenerator* generator) |
| 184 : generator_(generator), | 202 : generator_(generator), |
| (...skipping 2028 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2213 } | 2231 } |
| 2214 | 2232 |
| 2215 | 2233 |
| 2216 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 2234 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
| 2217 return info()->feedback_vector()->GetIndex(slot); | 2235 return info()->feedback_vector()->GetIndex(slot); |
| 2218 } | 2236 } |
| 2219 | 2237 |
| 2220 } // namespace interpreter | 2238 } // namespace interpreter |
| 2221 } // namespace internal | 2239 } // namespace internal |
| 2222 } // namespace v8 | 2240 } // namespace v8 |
| OLD | NEW |