Chromium Code Reviews| Index: src/interpreter/bytecode-generator.cc |
| diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc |
| index cfc45caefe82a366f30f0a3b856ebe44c6bee757..93a77983826800cbad4053d960fe239ec2471cdb 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,6 +1072,11 @@ void BytecodeGenerator::VisitBreakStatement(BreakStatement* stmt) { |
| void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { |
| builder()->SetStatementPosition(stmt); |
| VisitForAccumulatorValue(stmt->expression()); |
| + |
| + if (stmt->is_async_return()) { |
| + return execution_control()->AsyncReturnAccumulator(); |
| + } |
| + |
| execution_control()->ReturnAccumulator(); |
|
rmcilroy
2017/02/09 23:31:45
nit - could you make this:
if (stmt->is_async_ret
caitp
2017/02/10 01:20:01
Done
|
| } |
| @@ -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) { |