Chromium Code Reviews| 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()); |