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

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

Issue 1618693002: [Interpreter] Ensure context is popped when we break or continue (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Add UNREACHABLE Created 4 years, 11 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
« no previous file with comments | « no previous file | test/cctest/interpreter/test-bytecode-generator.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
OLDNEW
« no previous file with comments | « no previous file | test/cctest/interpreter/test-bytecode-generator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698