| Index: src/interpreter/bytecode-generator.cc
|
| diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc
|
| index cfc45caefe82a366f30f0a3b856ebe44c6bee757..20dd21ffb3d307253da9a12b33eb5300aabb57ad 100644
|
| --- a/src/interpreter/bytecode-generator.cc
|
| +++ b/src/interpreter/bytecode-generator.cc
|
| @@ -106,12 +106,19 @@ class BytecodeGenerator::ControlScope BASE_EMBEDDED {
|
| void Break(Statement* stmt) { PerformCommand(CMD_BREAK, stmt); }
|
| void Continue(Statement* stmt) { PerformCommand(CMD_CONTINUE, stmt); }
|
| void ReturnAccumulator() { PerformCommand(CMD_RETURN, nullptr); }
|
| + void AsyncReturnAccumulator() { PerformCommand(CMD_ASYNC_RETURN, nullptr); }
|
| void ReThrowAccumulator() { PerformCommand(CMD_RETHROW, nullptr); }
|
|
|
| class DeferredCommands;
|
|
|
| protected:
|
| - enum Command { CMD_BREAK, CMD_CONTINUE, CMD_RETURN, CMD_RETHROW };
|
| + enum Command {
|
| + CMD_BREAK,
|
| + CMD_CONTINUE,
|
| + CMD_RETURN,
|
| + CMD_ASYNC_RETURN,
|
| + CMD_RETHROW
|
| + };
|
| void PerformCommand(Command command, Statement* statement);
|
| virtual bool Execute(Command command, Statement* statement) = 0;
|
|
|
| @@ -221,6 +228,9 @@ class BytecodeGenerator::ControlScopeForTopLevel final
|
| case CMD_RETURN:
|
| generator()->BuildReturn();
|
| return true;
|
| + case CMD_ASYNC_RETURN:
|
| + generator()->BuildAsyncReturn();
|
| + return true;
|
| case CMD_RETHROW:
|
| generator()->BuildReThrow();
|
| return true;
|
| @@ -249,6 +259,7 @@ class BytecodeGenerator::ControlScopeForBreakable final
|
| return true;
|
| case CMD_CONTINUE:
|
| case CMD_RETURN:
|
| + case CMD_ASYNC_RETURN:
|
| case CMD_RETHROW:
|
| break;
|
| }
|
| @@ -286,6 +297,7 @@ class BytecodeGenerator::ControlScopeForIteration final
|
| loop_builder_->Continue();
|
| return true;
|
| case CMD_RETURN:
|
| + case CMD_ASYNC_RETURN:
|
| case CMD_RETHROW:
|
| break;
|
| }
|
| @@ -311,6 +323,7 @@ class BytecodeGenerator::ControlScopeForTryCatch final
|
| case CMD_BREAK:
|
| case CMD_CONTINUE:
|
| case CMD_RETURN:
|
| + case CMD_ASYNC_RETURN:
|
| break;
|
| case CMD_RETHROW:
|
| generator()->BuildReThrow();
|
| @@ -337,6 +350,7 @@ class BytecodeGenerator::ControlScopeForTryFinally final
|
| case CMD_BREAK:
|
| case CMD_CONTINUE:
|
| case CMD_RETURN:
|
| + case CMD_ASYNC_RETURN:
|
| case CMD_RETHROW:
|
| commands_->RecordCommand(command, statement);
|
| try_finally_builder_->LeaveTry();
|
| @@ -1058,7 +1072,12 @@ void BytecodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
|
| void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
|
| builder()->SetStatementPosition(stmt);
|
| VisitForAccumulatorValue(stmt->expression());
|
| - execution_control()->ReturnAccumulator();
|
| +
|
| + if (stmt->is_async_return()) {
|
| + execution_control()->AsyncReturnAccumulator();
|
| + } else {
|
| + execution_control()->ReturnAccumulator();
|
| + }
|
| }
|
|
|
| void BytecodeGenerator::VisitWithStatement(WithStatement* stmt) {
|
| @@ -2001,6 +2020,28 @@ void BytecodeGenerator::BuildReturn() {
|
| builder()->Return();
|
| }
|
|
|
| +void BytecodeGenerator::BuildAsyncReturn() {
|
| + DCHECK(IsAsyncFunction(info()->literal()->kind()));
|
| + RegisterAllocationScope register_scope(this);
|
| + RegisterList args = register_allocator()->NewRegisterList(3);
|
| + Register receiver = args[0];
|
| + Register promise = args[1];
|
| + Register return_value = args[2];
|
| + builder()->StoreAccumulatorInRegister(return_value);
|
| +
|
| + Variable* var_promise = scope()->promise_var();
|
| + DCHECK_NOT_NULL(var_promise);
|
| + BuildVariableLoad(var_promise, FeedbackSlot::Invalid(),
|
| + HoleCheckMode::kElided);
|
| + builder()
|
| + ->StoreAccumulatorInRegister(promise)
|
| + .LoadUndefined()
|
| + .StoreAccumulatorInRegister(receiver)
|
| + .CallJSRuntime(Context::PROMISE_RESOLVE_INDEX, args)
|
| + .LoadAccumulatorWithRegister(promise);
|
| + BuildReturn();
|
| +}
|
| +
|
| void BytecodeGenerator::BuildReThrow() { builder()->ReThrow(); }
|
|
|
| void BytecodeGenerator::BuildAbort(BailoutReason bailout_reason) {
|
|
|