diff --git a/es2panda/compiler/core/pandagen.cpp b/es2panda/compiler/core/pandagen.cpp index e56e28c72dc42d6fc0fdc2f07c3049f0955913d6..ef06720971367aeeac918908ace76e484125d4d4 100644 --- a/es2panda/compiler/core/pandagen.cpp +++ b/es2panda/compiler/core/pandagen.cpp @@ -1101,7 +1101,7 @@ void PandaGen::DefineFunction(const ir::AstNode *node, const ir::ScriptFunction ra_.Emit(node, name, static_cast(formalParamCnt), LexEnv()); } else if (realNode->IsAsync()) { if (realNode->IsGenerator()) { - // TODO(): async generator + ra_.Emit(node, name, static_cast(formalParamCnt), LexEnv()); } else { ra_.Emit(node, name, static_cast(formalParamCnt), LexEnv()); } @@ -1166,10 +1166,7 @@ void PandaGen::CreateGeneratorObj(const ir::AstNode *node, VReg funcObj) void PandaGen::CreateAsyncGeneratorObj(const ir::AstNode *node, VReg funcObj) { - /* - * TODO: async generator - * ra_.Emit(node, funcObj); - */ + ra_.Emit(node, funcObj); } void PandaGen::CreateIterResultObject(const ir::AstNode *node, VReg value, VReg done) @@ -1236,20 +1233,14 @@ void PandaGen::AsyncFunctionReject(const ir::AstNode *node, VReg asyncFuncObj, V ra_.Emit(node, asyncFuncObj, canSuspend, value); } -void PandaGen::AsyncGeneratorResolve(const ir::AstNode *node, VReg asyncGenObj) +void PandaGen::AsyncGeneratorResolve(const ir::AstNode *node, VReg asyncGenObj, VReg value, VReg canSuspend) { - /* - * TODO: async generator resolve - * ra_.Emit(node, asyncGenObj); - */ + ra_.Emit(node, asyncGenObj, value, canSuspend); } -void PandaGen::AsyncGeneratorReject(const ir::AstNode *node, VReg asyncGenObj) +void PandaGen::AsyncGeneratorReject(const ir::AstNode *node, VReg asyncGenObj, VReg value) { - /* - * TODO: async generator reject - * ra_.Emit(node, asyncGenObj); - */ + ra_.Emit(node, asyncGenObj, value); } void PandaGen::GetTemplateObject(const ir::AstNode *node, VReg value) diff --git a/es2panda/compiler/core/pandagen.h b/es2panda/compiler/core/pandagen.h index 64fe2d6132bd853e72f05f55102588d262f135a5..ffc4ebbcff0250d82f3c5c56922251c09b44bcc9 100644 --- a/es2panda/compiler/core/pandagen.h +++ b/es2panda/compiler/core/pandagen.h @@ -318,8 +318,8 @@ public: void SuspendGenerator(const ir::AstNode *node, VReg genObj, VReg iterResult); void SuspendAsyncGenerator(const ir::AstNode *node, VReg asyncGenObj); - void AsyncGeneratorResolve(const ir::AstNode *node, VReg asyncGenObj); - void AsyncGeneratorReject(const ir::AstNode *node, VReg asyncGenObj); + void AsyncGeneratorResolve(const ir::AstNode *node, VReg asyncGenObj, VReg value, VReg canSuspend); + void AsyncGeneratorReject(const ir::AstNode *node, VReg asyncGenObj, VReg value); void GetTemplateObject(const ir::AstNode *node, VReg value); void CopyRestArgs(const ir::AstNode *node, uint32_t index); diff --git a/es2panda/compiler/function/asyncGeneratorFunctionBuilder.cpp b/es2panda/compiler/function/asyncGeneratorFunctionBuilder.cpp index a74eea46df994ebcf77a2c6e04bdbe664a8b0831..157410a4b715c836e7ca2dd33a23e84f0a610851 100644 --- a/es2panda/compiler/function/asyncGeneratorFunctionBuilder.cpp +++ b/es2panda/compiler/function/asyncGeneratorFunctionBuilder.cpp @@ -22,28 +22,45 @@ namespace panda::es2panda::compiler { void AsyncGeneratorFunctionBuilder::Prepare(const ir::ScriptFunction *node) { + RegScope rs(pg_); VReg callee = FunctionReg(node); + VReg completionType = pg_->AllocReg(); + VReg completionValue = pg_->AllocReg(); pg_->CreateAsyncGeneratorObj(node, callee); pg_->StoreAccumulator(node, funcObj_); - // pg_->SuspendGenerator(node, funcObj_); TODO implement this part correctly while implementing async generator + pg_->SetLabel(node, catchTable_->LabelSet().TryBegin()); + + pg_->LoadConst(node, Constant::JS_UNDEFINED); + SuspendResumeExecution(node, completionType, completionValue); } void AsyncGeneratorFunctionBuilder::CleanUp(const ir::ScriptFunction *node) const { const auto &labelSet = catchTable_->LabelSet(); + RegScope rs(pg_); + VReg value = pg_->AllocReg(); + pg_->SetLabel(node, labelSet.TryEnd()); pg_->SetLabel(node, labelSet.CatchBegin()); - pg_->AsyncGeneratorReject(node, funcObj_); + pg_->StoreAccumulator(node, value); + pg_->AsyncGeneratorReject(node, funcObj_, value); pg_->EmitReturn(node); pg_->SetLabel(node, labelSet.CatchEnd()); } void AsyncGeneratorFunctionBuilder::DirectReturn(const ir::AstNode *node) const { - pg_->AsyncGeneratorResolve(node, funcObj_); + RegScope rs(pg_); + VReg retVal = pg_->AllocReg(); + VReg canSuspend = pg_->AllocReg(); + + pg_->StoreAccumulator(node, retVal); + pg_->StoreConst(node, canSuspend, Constant::JS_TRUE); + + pg_->AsyncGeneratorResolve(node, funcObj_, retVal, canSuspend); pg_->EmitReturn(node); } @@ -55,48 +72,36 @@ void AsyncGeneratorFunctionBuilder::ImplicitReturn(const ir::AstNode *node) cons void AsyncGeneratorFunctionBuilder::Yield(const ir::AstNode *node) { - Await(node); - RegScope rs(pg_); + VReg value = pg_->AllocReg(); + VReg done = pg_->AllocReg(); VReg completionType = pg_->AllocReg(); VReg completionValue = pg_->AllocReg(); - AsyncYield(node, completionType, completionValue); - - auto *notReturnCompletion = pg_->AllocLabel(); - auto *normalCompletion = pg_->AllocLabel(); + auto *notNextCompletion = pg_->AllocLabel(); auto *notThrowCompletion = pg_->AllocLabel(); - // 27.6.3.8.8.a. If resumptionValue.[[Type]] is not return - pg_->LoadAccumulatorInt(node, static_cast(ResumeMode::RETURN)); - pg_->Condition(node, lexer::TokenType::PUNCTUATOR_EQUAL, completionType, notReturnCompletion); - // 27.6.3.8.8.b. Let awaited be Await(resumptionValue.[[Value]]). - pg_->LoadAccumulator(node, completionValue); - pg_->AsyncFunctionAwait(node, funcObj_, completionValue); + pg_->StoreAccumulator(node, value); + pg_->StoreConst(node, done, Constant::JS_FALSE); + pg_->AsyncGeneratorResolve(node, funcObj_, value, done); SuspendResumeExecution(node, completionType, completionValue); - // 27.6.3.8.8.c. If awaited.[[Type]] is throw, return Completion(awaited). - pg_->LoadAccumulatorInt(node, static_cast(ResumeMode::THROW)); - - pg_->Condition(node, lexer::TokenType::PUNCTUATOR_EQUAL, completionType, normalCompletion); + // .next(value) + pg_->LoadAccumulatorInt(node, static_cast(ResumeMode::NEXT)); + pg_->Condition(node, lexer::TokenType::PUNCTUATOR_EQUAL, completionType, notNextCompletion); pg_->LoadAccumulator(node, completionValue); - pg_->EmitThrow(node); - - pg_->SetLabel(node, normalCompletion); - // 27.6.3.8.8.d. Assert: awaited.[[Type]] is normal. - // 27.6.3.8.8.e. Return Completion { [[Type]]: return, [[Value]]: awaited.[[Value]], [[Target]]: empty }. - pg_->ControlFlowChangeBreak(); - pg_->LoadAccumulator(node, completionValue); - pg_->DirectReturn(node); - pg_->SetLabel(node, notReturnCompletion); - // 27.6.3.8.8.a. return Completion(resumptionValue). + // .throw(value) + pg_->SetLabel(node, notNextCompletion); pg_->LoadAccumulatorInt(node, static_cast(ResumeMode::THROW)); pg_->Condition(node, lexer::TokenType::PUNCTUATOR_EQUAL, completionType, notThrowCompletion); pg_->LoadAccumulator(node, completionValue); pg_->EmitThrow(node); + + // .return(value) pg_->SetLabel(node, notThrowCompletion); pg_->LoadAccumulator(node, completionValue); + pg_->EmitReturn(node); } IteratorType AsyncGeneratorFunctionBuilder::GeneratorKind() const