Index: src/full-codegen/x64/full-codegen-x64.cc |
diff --git a/src/full-codegen/x64/full-codegen-x64.cc b/src/full-codegen/x64/full-codegen-x64.cc |
index f2850ceebb8b680ad3c4ebedd529c69d28d07b62..bdca0bc022fb928382874049696bfa24f951cd89 100644 |
--- a/src/full-codegen/x64/full-codegen-x64.cc |
+++ b/src/full-codegen/x64/full-codegen-x64.cc |
@@ -1774,14 +1774,17 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { |
void FullCodeGenerator::VisitYield(Yield* expr) { |
- Comment cmnt(masm_, "[ Yield"); |
+ Comment cmnt(masm_, expr->is_async_function_start() ? "[ AsyncFunction start" |
+ : "[ Yield"); |
SetExpressionPosition(expr); |
+ Label eval, suspend, continuation, post_runtime, resume, exception; |
+ |
// Evaluate yielded value first; the initial iterator definition depends on |
// this. It stays on the stack while we update the iterator. |
- VisitForStackValue(expr->expression()); |
- |
- Label suspend, continuation, post_runtime, resume, exception; |
+ if (!expr->is_async_function_start()) { |
+ VisitForStackValue(expr->expression()); |
+ } |
__ jmp(&suspend); |
__ bind(&continuation); |
@@ -1795,14 +1798,21 @@ void FullCodeGenerator::VisitYield(Yield* expr) { |
__ j(less, &resume); |
__ Push(result_register()); |
__ j(greater, &exception); |
- EmitCreateIteratorResult(true); |
- EmitUnwindAndReturn(); |
+ if (!expr->is_async_function_start()) { |
+ EmitCreateIteratorResult(true); |
+ EmitUnwindAndReturn(); |
+ } else { |
+ // AsyncFunction never resumed with `return` mode, should be unreachable. |
+ } |
__ bind(&exception); |
__ CallRuntime(Runtime::kThrow); |
__ bind(&suspend); |
- OperandStackDepthIncrement(1); // Not popped on this path. |
+ |
+ if (!expr->is_async_function_start()) { |
+ OperandStackDepthIncrement(1); // Not popped on this path. |
+ } |
VisitForAccumulatorValue(expr->generator_object()); |
DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); |
__ Move(FieldOperand(rax, JSGeneratorObject::kContinuationOffset), |
@@ -1811,17 +1821,24 @@ void FullCodeGenerator::VisitYield(Yield* expr) { |
__ movp(rcx, rsi); |
__ RecordWriteField(rax, JSGeneratorObject::kContextOffset, rcx, rdx, |
kDontSaveFPRegs); |
- __ leap(rbx, Operand(rbp, StandardFrameConstants::kExpressionsOffset)); |
- __ cmpp(rsp, rbx); |
- __ j(equal, &post_runtime); |
- __ Push(rax); // generator object |
- __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
- __ movp(context_register(), |
- Operand(rbp, StandardFrameConstants::kContextOffset)); |
- __ bind(&post_runtime); |
- |
- PopOperand(result_register()); |
- EmitReturnSequence(); |
+ if (!expr->is_async_function_start()) { |
+ // AsyncFunction start always occurs with an empty operand stack |
+ __ leap(rbx, Operand(rbp, StandardFrameConstants::kExpressionsOffset)); |
+ __ cmpp(rsp, rbx); |
+ __ j(equal, &post_runtime); |
+ __ Push(rax); // generator object |
+ __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
+ __ movp(context_register(), |
+ Operand(rbp, StandardFrameConstants::kContextOffset)); |
+ __ bind(&post_runtime); |
+ |
+ PopOperand(result_register()); |
+ EmitReturnSequence(); |
+ } else { |
+ VisitForAccumulatorValue(expr->expression()); |
+ DCHECK_EQ(result_register().code(), rax.code()); |
caitp (gmail)
2016/04/16 18:33:03
Not sure if this really adds anything, I guess it'
|
+ EmitReturnSequence(); |
+ } |
__ bind(&resume); |
context()->Plug(result_register()); |