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..c1d3292f127730438865ab9ad1e9a071d9d7d991 100644 |
| --- a/src/interpreter/bytecode-generator.cc |
| +++ b/src/interpreter/bytecode-generator.cc |
| @@ -706,8 +706,10 @@ void BytecodeGenerator::GenerateBytecode(uintptr_t stack_limit) { |
| // Emit an implicit return instruction in case control flow can fall off the |
| // end of the function without an explicit return being present on all paths. |
| if (builder()->RequiresImplicitReturn()) { |
| + DCHECK(execution_control() == &control); |
|
rmcilroy
2017/02/08 12:21:56
nit - please add a comment here that we can do a h
caitp
2017/02/08 13:42:58
Done.
|
| builder()->LoadUndefined(); |
| - BuildReturn(); |
| + BuildTraceExit(); |
| + builder()->Return(); |
| } |
| DCHECK(!builder()->RequiresImplicitReturn()); |
| } |
| @@ -1058,6 +1060,15 @@ void BytecodeGenerator::VisitBreakStatement(BreakStatement* stmt) { |
| void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { |
| builder()->SetStatementPosition(stmt); |
| VisitForAccumulatorValue(stmt->expression()); |
| + |
| + if (stmt->is_hard_return()) { |
| + // TODO(caitp): remove hard_return handling and ReturnStatement AST node |
| + // flags once BytecodeGenerator performs all implicit control flow for |
| + // async functions. |
| + builder()->Return(); |
|
rmcilroy
2017/02/08 12:21:56
BuildTraceExit here too? How about Creating a Bui
caitp
2017/02/08 13:42:58
That looks cleaner, nice. Done
|
| + return; |
| + } |
| + |
| execution_control()->ReturnAccumulator(); |
| } |
| @@ -1991,6 +2002,31 @@ void BytecodeGenerator::BuildVariableLoadForAccumulatorValue( |
| } |
| void BytecodeGenerator::BuildReturn() { |
| + if (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); |
| + } |
| + |
| + BuildTraceExit(); |
| + builder()->Return(); |
| +} |
| + |
| +void BytecodeGenerator::BuildTraceExit() { |
| if (FLAG_trace) { |
| RegisterAllocationScope register_scope(this); |
| Register result = register_allocator()->NewRegister(); |
| @@ -1998,7 +2034,6 @@ void BytecodeGenerator::BuildReturn() { |
| builder()->StoreAccumulatorInRegister(result).CallRuntime( |
| Runtime::kTraceExit, result); |
| } |
| - builder()->Return(); |
| } |
| void BytecodeGenerator::BuildReThrow() { builder()->ReThrow(); } |