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(); } |