| 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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 | 65 |
| 66 ContextScope* previous = this; | 66 ContextScope* previous = this; |
| 67 for (int i = depth; i > 0; --i) { | 67 for (int i = depth; i > 0; --i) { |
| 68 previous = previous->outer_; | 68 previous = previous->outer_; |
| 69 } | 69 } |
| 70 return previous; | 70 return previous; |
| 71 } | 71 } |
| 72 | 72 |
| 73 Scope* scope() const { return scope_; } | 73 Scope* scope() const { return scope_; } |
| 74 Register reg() const { return register_; } | 74 Register reg() const { return register_; } |
| 75 bool ShouldPopContext() { return should_pop_context_; } |
| 75 | 76 |
| 76 private: | 77 private: |
| 77 const BytecodeArrayBuilder* builder() const { return generator_->builder(); } | 78 const BytecodeArrayBuilder* builder() const { return generator_->builder(); } |
| 78 | 79 |
| 79 void set_register(Register reg) { register_ = reg; } | 80 void set_register(Register reg) { register_ = reg; } |
| 80 | 81 |
| 81 BytecodeGenerator* generator_; | 82 BytecodeGenerator* generator_; |
| 82 Scope* scope_; | 83 Scope* scope_; |
| 83 ContextScope* outer_; | 84 ContextScope* outer_; |
| 84 Register register_; | 85 Register register_; |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 // Scoped class for dealing with control flow reaching the function level. | 206 // Scoped class for dealing with control flow reaching the function level. |
| 206 class BytecodeGenerator::ControlScopeForTopLevel final | 207 class BytecodeGenerator::ControlScopeForTopLevel final |
| 207 : public BytecodeGenerator::ControlScope { | 208 : public BytecodeGenerator::ControlScope { |
| 208 public: | 209 public: |
| 209 explicit ControlScopeForTopLevel(BytecodeGenerator* generator) | 210 explicit ControlScopeForTopLevel(BytecodeGenerator* generator) |
| 210 : ControlScope(generator) {} | 211 : ControlScope(generator) {} |
| 211 | 212 |
| 212 protected: | 213 protected: |
| 213 bool Execute(Command command, Statement* statement) override { | 214 bool Execute(Command command, Statement* statement) override { |
| 214 switch (command) { | 215 switch (command) { |
| 215 case CMD_BREAK: | 216 case CMD_BREAK: // We should never see break/continue in top-level. |
| 216 case CMD_CONTINUE: | 217 case CMD_CONTINUE: |
| 217 break; | 218 UNREACHABLE(); |
| 218 case CMD_RETURN: | 219 case CMD_RETURN: |
| 219 generator()->builder()->Return(); | 220 generator()->builder()->Return(); |
| 220 return true; | 221 return true; |
| 221 case CMD_RETHROW: | 222 case CMD_RETHROW: |
| 222 generator()->builder()->ReThrow(); | 223 generator()->builder()->ReThrow(); |
| 223 return true; | 224 return true; |
| 224 } | 225 } |
| 225 return false; | 226 return false; |
| 226 } | 227 } |
| 227 }; | 228 }; |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 356 private: | 357 private: |
| 357 TryFinallyBuilder* try_finally_builder_; | 358 TryFinallyBuilder* try_finally_builder_; |
| 358 DeferredCommands* commands_; | 359 DeferredCommands* commands_; |
| 359 }; | 360 }; |
| 360 | 361 |
| 361 | 362 |
| 362 void BytecodeGenerator::ControlScope::PerformCommand(Command command, | 363 void BytecodeGenerator::ControlScope::PerformCommand(Command command, |
| 363 Statement* statement) { | 364 Statement* statement) { |
| 364 ControlScope* current = this; | 365 ControlScope* current = this; |
| 365 ContextScope* context = generator()->execution_context(); | 366 ContextScope* context = generator()->execution_context(); |
| 367 // Pop context to the expected depth but do not pop the outermost context. |
| 368 if (context != current->context() && context->ShouldPopContext()) { |
| 369 generator()->builder()->PopContext(current->context()->reg()); |
| 370 } |
| 366 do { | 371 do { |
| 367 if (current->context() != context) { | |
| 368 // Pop context to the expected depth for break and continue. For return | |
| 369 // and throw it is not required to pop. Debugger expects that the | |
| 370 // context is not popped on return. So do not pop on return. | |
| 371 // TODO(rmcilroy): Only emit a single context pop. | |
| 372 if (command == CMD_BREAK || command == CMD_CONTINUE) { | |
| 373 generator()->builder()->PopContext(current->context()->reg()); | |
| 374 } | |
| 375 context = current->context(); | |
| 376 } | |
| 377 if (current->Execute(command, statement)) { | 372 if (current->Execute(command, statement)) { |
| 378 return; | 373 return; |
| 379 } | 374 } |
| 380 current = current->outer(); | 375 current = current->outer(); |
| 376 if (current->context() != context) { |
| 377 // Pop context to the expected depth. |
| 378 // TODO(rmcilroy): Only emit a single context pop. |
| 379 generator()->builder()->PopContext(current->context()->reg()); |
| 380 } |
| 381 } while (current != nullptr); | 381 } while (current != nullptr); |
| 382 UNREACHABLE(); | 382 UNREACHABLE(); |
| 383 } | 383 } |
| 384 | 384 |
| 385 | 385 |
| 386 class BytecodeGenerator::RegisterAllocationScope { | 386 class BytecodeGenerator::RegisterAllocationScope { |
| 387 public: | 387 public: |
| 388 explicit RegisterAllocationScope(BytecodeGenerator* generator) | 388 explicit RegisterAllocationScope(BytecodeGenerator* generator) |
| 389 : generator_(generator), | 389 : generator_(generator), |
| 390 outer_(generator->register_allocator()), | 390 outer_(generator->register_allocator()), |
| (...skipping 2764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3155 } | 3155 } |
| 3156 | 3156 |
| 3157 | 3157 |
| 3158 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 3158 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
| 3159 return info()->feedback_vector()->GetIndex(slot); | 3159 return info()->feedback_vector()->GetIndex(slot); |
| 3160 } | 3160 } |
| 3161 | 3161 |
| 3162 } // namespace interpreter | 3162 } // namespace interpreter |
| 3163 } // namespace internal | 3163 } // namespace internal |
| 3164 } // namespace v8 | 3164 } // namespace v8 |
| OLD | NEW |