Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(249)

Side by Side Diff: src/interpreter/bytecode-generator.cc

Issue 1796893002: [Interpreter] Pops the context to the correct level on return. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebased the patch. Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698