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

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

Issue 2685683002: [async-await] (simpler) fix for Return in try/finally in async functions (Closed)
Patch Set: also shrink the bitfield for ReturnStatement::Type Created 3 years, 10 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 | « src/interpreter/bytecode-generator.h ('k') | src/parsing/parser.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/compile-time-value.h" 7 #include "src/ast/compile-time-value.h"
8 #include "src/ast/scopes.h" 8 #include "src/ast/scopes.h"
9 #include "src/builtins/builtins-constructor.h" 9 #include "src/builtins/builtins-constructor.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 explicit ControlScope(BytecodeGenerator* generator) 99 explicit ControlScope(BytecodeGenerator* generator)
100 : generator_(generator), outer_(generator->execution_control()), 100 : generator_(generator), outer_(generator->execution_control()),
101 context_(generator->execution_context()) { 101 context_(generator->execution_context()) {
102 generator_->set_execution_control(this); 102 generator_->set_execution_control(this);
103 } 103 }
104 virtual ~ControlScope() { generator_->set_execution_control(outer()); } 104 virtual ~ControlScope() { generator_->set_execution_control(outer()); }
105 105
106 void Break(Statement* stmt) { PerformCommand(CMD_BREAK, stmt); } 106 void Break(Statement* stmt) { PerformCommand(CMD_BREAK, stmt); }
107 void Continue(Statement* stmt) { PerformCommand(CMD_CONTINUE, stmt); } 107 void Continue(Statement* stmt) { PerformCommand(CMD_CONTINUE, stmt); }
108 void ReturnAccumulator() { PerformCommand(CMD_RETURN, nullptr); } 108 void ReturnAccumulator() { PerformCommand(CMD_RETURN, nullptr); }
109 void AsyncReturnAccumulator() { PerformCommand(CMD_ASYNC_RETURN, nullptr); }
109 void ReThrowAccumulator() { PerformCommand(CMD_RETHROW, nullptr); } 110 void ReThrowAccumulator() { PerformCommand(CMD_RETHROW, nullptr); }
110 111
111 class DeferredCommands; 112 class DeferredCommands;
112 113
113 protected: 114 protected:
114 enum Command { CMD_BREAK, CMD_CONTINUE, CMD_RETURN, CMD_RETHROW }; 115 enum Command {
116 CMD_BREAK,
117 CMD_CONTINUE,
118 CMD_RETURN,
119 CMD_ASYNC_RETURN,
120 CMD_RETHROW
121 };
115 void PerformCommand(Command command, Statement* statement); 122 void PerformCommand(Command command, Statement* statement);
116 virtual bool Execute(Command command, Statement* statement) = 0; 123 virtual bool Execute(Command command, Statement* statement) = 0;
117 124
118 BytecodeGenerator* generator() const { return generator_; } 125 BytecodeGenerator* generator() const { return generator_; }
119 ControlScope* outer() const { return outer_; } 126 ControlScope* outer() const { return outer_; }
120 ContextScope* context() const { return context_; } 127 ContextScope* context() const { return context_; }
121 128
122 private: 129 private:
123 BytecodeGenerator* generator_; 130 BytecodeGenerator* generator_;
124 ControlScope* outer_; 131 ControlScope* outer_;
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 221
215 protected: 222 protected:
216 bool Execute(Command command, Statement* statement) override { 223 bool Execute(Command command, Statement* statement) override {
217 switch (command) { 224 switch (command) {
218 case CMD_BREAK: // We should never see break/continue in top-level. 225 case CMD_BREAK: // We should never see break/continue in top-level.
219 case CMD_CONTINUE: 226 case CMD_CONTINUE:
220 UNREACHABLE(); 227 UNREACHABLE();
221 case CMD_RETURN: 228 case CMD_RETURN:
222 generator()->BuildReturn(); 229 generator()->BuildReturn();
223 return true; 230 return true;
231 case CMD_ASYNC_RETURN:
232 generator()->BuildAsyncReturn();
233 return true;
224 case CMD_RETHROW: 234 case CMD_RETHROW:
225 generator()->BuildReThrow(); 235 generator()->BuildReThrow();
226 return true; 236 return true;
227 } 237 }
228 return false; 238 return false;
229 } 239 }
230 }; 240 };
231 241
232 // Scoped class for enabling break inside blocks and switch blocks. 242 // Scoped class for enabling break inside blocks and switch blocks.
233 class BytecodeGenerator::ControlScopeForBreakable final 243 class BytecodeGenerator::ControlScopeForBreakable final
234 : public BytecodeGenerator::ControlScope { 244 : public BytecodeGenerator::ControlScope {
235 public: 245 public:
236 ControlScopeForBreakable(BytecodeGenerator* generator, 246 ControlScopeForBreakable(BytecodeGenerator* generator,
237 BreakableStatement* statement, 247 BreakableStatement* statement,
238 BreakableControlFlowBuilder* control_builder) 248 BreakableControlFlowBuilder* control_builder)
239 : ControlScope(generator), 249 : ControlScope(generator),
240 statement_(statement), 250 statement_(statement),
241 control_builder_(control_builder) {} 251 control_builder_(control_builder) {}
242 252
243 protected: 253 protected:
244 bool Execute(Command command, Statement* statement) override { 254 bool Execute(Command command, Statement* statement) override {
245 if (statement != statement_) return false; 255 if (statement != statement_) return false;
246 switch (command) { 256 switch (command) {
247 case CMD_BREAK: 257 case CMD_BREAK:
248 control_builder_->Break(); 258 control_builder_->Break();
249 return true; 259 return true;
250 case CMD_CONTINUE: 260 case CMD_CONTINUE:
251 case CMD_RETURN: 261 case CMD_RETURN:
262 case CMD_ASYNC_RETURN:
252 case CMD_RETHROW: 263 case CMD_RETHROW:
253 break; 264 break;
254 } 265 }
255 return false; 266 return false;
256 } 267 }
257 268
258 private: 269 private:
259 Statement* statement_; 270 Statement* statement_;
260 BreakableControlFlowBuilder* control_builder_; 271 BreakableControlFlowBuilder* control_builder_;
261 }; 272 };
(...skipping 17 matching lines...) Expand all
279 bool Execute(Command command, Statement* statement) override { 290 bool Execute(Command command, Statement* statement) override {
280 if (statement != statement_) return false; 291 if (statement != statement_) return false;
281 switch (command) { 292 switch (command) {
282 case CMD_BREAK: 293 case CMD_BREAK:
283 loop_builder_->Break(); 294 loop_builder_->Break();
284 return true; 295 return true;
285 case CMD_CONTINUE: 296 case CMD_CONTINUE:
286 loop_builder_->Continue(); 297 loop_builder_->Continue();
287 return true; 298 return true;
288 case CMD_RETURN: 299 case CMD_RETURN:
300 case CMD_ASYNC_RETURN:
289 case CMD_RETHROW: 301 case CMD_RETHROW:
290 break; 302 break;
291 } 303 }
292 return false; 304 return false;
293 } 305 }
294 306
295 private: 307 private:
296 Statement* statement_; 308 Statement* statement_;
297 LoopBuilder* loop_builder_; 309 LoopBuilder* loop_builder_;
298 }; 310 };
299 311
300 // Scoped class for enabling 'throw' in try-catch constructs. 312 // Scoped class for enabling 'throw' in try-catch constructs.
301 class BytecodeGenerator::ControlScopeForTryCatch final 313 class BytecodeGenerator::ControlScopeForTryCatch final
302 : public BytecodeGenerator::ControlScope { 314 : public BytecodeGenerator::ControlScope {
303 public: 315 public:
304 ControlScopeForTryCatch(BytecodeGenerator* generator, 316 ControlScopeForTryCatch(BytecodeGenerator* generator,
305 TryCatchBuilder* try_catch_builder) 317 TryCatchBuilder* try_catch_builder)
306 : ControlScope(generator) {} 318 : ControlScope(generator) {}
307 319
308 protected: 320 protected:
309 bool Execute(Command command, Statement* statement) override { 321 bool Execute(Command command, Statement* statement) override {
310 switch (command) { 322 switch (command) {
311 case CMD_BREAK: 323 case CMD_BREAK:
312 case CMD_CONTINUE: 324 case CMD_CONTINUE:
313 case CMD_RETURN: 325 case CMD_RETURN:
326 case CMD_ASYNC_RETURN:
314 break; 327 break;
315 case CMD_RETHROW: 328 case CMD_RETHROW:
316 generator()->BuildReThrow(); 329 generator()->BuildReThrow();
317 return true; 330 return true;
318 } 331 }
319 return false; 332 return false;
320 } 333 }
321 }; 334 };
322 335
323 // Scoped class for enabling control flow through try-finally constructs. 336 // Scoped class for enabling control flow through try-finally constructs.
324 class BytecodeGenerator::ControlScopeForTryFinally final 337 class BytecodeGenerator::ControlScopeForTryFinally final
325 : public BytecodeGenerator::ControlScope { 338 : public BytecodeGenerator::ControlScope {
326 public: 339 public:
327 ControlScopeForTryFinally(BytecodeGenerator* generator, 340 ControlScopeForTryFinally(BytecodeGenerator* generator,
328 TryFinallyBuilder* try_finally_builder, 341 TryFinallyBuilder* try_finally_builder,
329 DeferredCommands* commands) 342 DeferredCommands* commands)
330 : ControlScope(generator), 343 : ControlScope(generator),
331 try_finally_builder_(try_finally_builder), 344 try_finally_builder_(try_finally_builder),
332 commands_(commands) {} 345 commands_(commands) {}
333 346
334 protected: 347 protected:
335 bool Execute(Command command, Statement* statement) override { 348 bool Execute(Command command, Statement* statement) override {
336 switch (command) { 349 switch (command) {
337 case CMD_BREAK: 350 case CMD_BREAK:
338 case CMD_CONTINUE: 351 case CMD_CONTINUE:
339 case CMD_RETURN: 352 case CMD_RETURN:
353 case CMD_ASYNC_RETURN:
340 case CMD_RETHROW: 354 case CMD_RETHROW:
341 commands_->RecordCommand(command, statement); 355 commands_->RecordCommand(command, statement);
342 try_finally_builder_->LeaveTry(); 356 try_finally_builder_->LeaveTry();
343 return true; 357 return true;
344 } 358 }
345 return false; 359 return false;
346 } 360 }
347 361
348 private: 362 private:
349 TryFinallyBuilder* try_finally_builder_; 363 TryFinallyBuilder* try_finally_builder_;
(...skipping 701 matching lines...) Expand 10 before | Expand all | Expand 10 after
1051 } 1065 }
1052 1066
1053 void BytecodeGenerator::VisitBreakStatement(BreakStatement* stmt) { 1067 void BytecodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
1054 builder()->SetStatementPosition(stmt); 1068 builder()->SetStatementPosition(stmt);
1055 execution_control()->Break(stmt->target()); 1069 execution_control()->Break(stmt->target());
1056 } 1070 }
1057 1071
1058 void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { 1072 void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
1059 builder()->SetStatementPosition(stmt); 1073 builder()->SetStatementPosition(stmt);
1060 VisitForAccumulatorValue(stmt->expression()); 1074 VisitForAccumulatorValue(stmt->expression());
1061 execution_control()->ReturnAccumulator(); 1075
1076 if (stmt->is_async_return()) {
1077 execution_control()->AsyncReturnAccumulator();
1078 } else {
1079 execution_control()->ReturnAccumulator();
1080 }
1062 } 1081 }
1063 1082
1064 void BytecodeGenerator::VisitWithStatement(WithStatement* stmt) { 1083 void BytecodeGenerator::VisitWithStatement(WithStatement* stmt) {
1065 builder()->SetStatementPosition(stmt); 1084 builder()->SetStatementPosition(stmt);
1066 VisitForAccumulatorValue(stmt->expression()); 1085 VisitForAccumulatorValue(stmt->expression());
1067 BuildNewLocalWithContext(stmt->scope()); 1086 BuildNewLocalWithContext(stmt->scope());
1068 VisitInScope(stmt->statement(), stmt->scope()); 1087 VisitInScope(stmt->statement(), stmt->scope());
1069 } 1088 }
1070 1089
1071 void BytecodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { 1090 void BytecodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
(...skipping 922 matching lines...) Expand 10 before | Expand all | Expand 10 after
1994 if (FLAG_trace) { 2013 if (FLAG_trace) {
1995 RegisterAllocationScope register_scope(this); 2014 RegisterAllocationScope register_scope(this);
1996 Register result = register_allocator()->NewRegister(); 2015 Register result = register_allocator()->NewRegister();
1997 // Runtime returns {result} value, preserving accumulator. 2016 // Runtime returns {result} value, preserving accumulator.
1998 builder()->StoreAccumulatorInRegister(result).CallRuntime( 2017 builder()->StoreAccumulatorInRegister(result).CallRuntime(
1999 Runtime::kTraceExit, result); 2018 Runtime::kTraceExit, result);
2000 } 2019 }
2001 builder()->Return(); 2020 builder()->Return();
2002 } 2021 }
2003 2022
2023 void BytecodeGenerator::BuildAsyncReturn() {
2024 DCHECK(IsAsyncFunction(info()->literal()->kind()));
2025 RegisterAllocationScope register_scope(this);
2026 RegisterList args = register_allocator()->NewRegisterList(3);
2027 Register receiver = args[0];
2028 Register promise = args[1];
2029 Register return_value = args[2];
2030 builder()->StoreAccumulatorInRegister(return_value);
2031
2032 Variable* var_promise = scope()->promise_var();
2033 DCHECK_NOT_NULL(var_promise);
2034 BuildVariableLoad(var_promise, FeedbackSlot::Invalid(),
2035 HoleCheckMode::kElided);
2036 builder()
2037 ->StoreAccumulatorInRegister(promise)
2038 .LoadUndefined()
2039 .StoreAccumulatorInRegister(receiver)
2040 .CallJSRuntime(Context::PROMISE_RESOLVE_INDEX, args)
2041 .LoadAccumulatorWithRegister(promise);
2042 BuildReturn();
2043 }
2044
2004 void BytecodeGenerator::BuildReThrow() { builder()->ReThrow(); } 2045 void BytecodeGenerator::BuildReThrow() { builder()->ReThrow(); }
2005 2046
2006 void BytecodeGenerator::BuildAbort(BailoutReason bailout_reason) { 2047 void BytecodeGenerator::BuildAbort(BailoutReason bailout_reason) {
2007 RegisterAllocationScope register_scope(this); 2048 RegisterAllocationScope register_scope(this);
2008 Register reason = register_allocator()->NewRegister(); 2049 Register reason = register_allocator()->NewRegister();
2009 builder() 2050 builder()
2010 ->LoadLiteral(Smi::FromInt(static_cast<int>(bailout_reason))) 2051 ->LoadLiteral(Smi::FromInt(static_cast<int>(bailout_reason)))
2011 .StoreAccumulatorInRegister(reason) 2052 .StoreAccumulatorInRegister(reason)
2012 .CallRuntime(Runtime::kAbort, reason); 2053 .CallRuntime(Runtime::kAbort, reason);
2013 } 2054 }
(...skipping 1367 matching lines...) Expand 10 before | Expand all | Expand 10 after
3381 } 3422 }
3382 3423
3383 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { 3424 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() {
3384 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict 3425 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict
3385 : Runtime::kStoreKeyedToSuper_Sloppy; 3426 : Runtime::kStoreKeyedToSuper_Sloppy;
3386 } 3427 }
3387 3428
3388 } // namespace interpreter 3429 } // namespace interpreter
3389 } // namespace internal 3430 } // namespace internal
3390 } // namespace v8 3431 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/bytecode-generator.h ('k') | src/parsing/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698