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 |