| 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());
|
| + EmitReturnSequence();
|
| + }
|
|
|
| __ bind(&resume);
|
| context()->Plug(result_register());
|
|
|