diff --git a/es2panda/aot/main.cpp b/es2panda/aot/main.cpp index ad0dde48b47004dd97d13f6bbc7eb2125990f32c..79c5131dec17642a0799feb1dc1c771c6999f135 100644 --- a/es2panda/aot/main.cpp +++ b/es2panda/aot/main.cpp @@ -130,8 +130,8 @@ int Run(int argc, const char **argv) return 0; } - std::cout << err.TypeString() << ": " << err.Message(); - std::cout << " [" << options->SourceFile() << ":" << err.Line() << ":" << err.Col() << "]" << std::endl; + std::cerr << err.TypeString() << ": " << err.Message(); + std::cerr << " [" << options->SourceFile() << ":" << err.Line() << ":" << err.Col() << "]" << std::endl; return err.ErrorCode(); } diff --git a/es2panda/compiler/base/iterators.cpp b/es2panda/compiler/base/iterators.cpp index 8ba4d12a112babd5be5ced988353548bac097703..7078aaf2ab0f4c6fc1769285d4375da8f749d80e 100644 --- a/es2panda/compiler/base/iterators.cpp +++ b/es2panda/compiler/base/iterators.cpp @@ -35,13 +35,11 @@ Iterator::Iterator(PandaGen *pg, const ir::AstNode *node, IteratorType type) pg_->StoreAccumulator(node, iterator_); pg_->LoadObjByName(node_, iterator_, "next"); pg_->StoreAccumulator(node_, method_); - - pg_->ThrowIfNotObject(node_); } void Iterator::GetMethod(util::StringView name) const { - pg_->GetMethod(node_, iterator_, name); + pg_->LoadObjByName(node_, iterator_, name); pg_->StoreAccumulator(node_, method_); } @@ -63,8 +61,8 @@ void Iterator::Next() const pg_->FuncBuilder()->Await(node_); } - pg_->ThrowIfNotObject(node_); pg_->StoreAccumulator(node_, nextResult_); + pg_->ThrowIfNotObject(node_, nextResult_); } void Iterator::Complete() const @@ -77,13 +75,58 @@ void Iterator::Value() const pg_->LoadObjByName(node_, nextResult_, "value"); } +void Iterator::CloseWithException() const +{ + if (type_ == IteratorType::SYNC) { + RegScope rs(pg_); + VReg exception = pg_->AllocReg(); + VReg constReg = pg_->AllocReg(); + Label *noReturn = pg_->AllocLabel(); + pg_->StoreAccumulator(node_, exception); + + pg_->LoadConst(node_, Constant::JS_TRUE); + pg_->StoreAccumulator(node_, constReg); + Complete(); + pg_->Condition(node_, lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL, constReg, noReturn); + + // close iterator + pg_->LoadObjByName(node_, iterator_, "return"); + pg_->StoreAccumulator(node_, method_); + pg_->LoadConst(node_, Constant::JS_UNDEFINED); + pg_->Condition(node_, lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL, method_, noReturn); + CallMethod(); + + pg_->SetLabel(node_, noReturn); + pg_->LoadAccumulator(node_, exception); + pg_->EmitThrow(node_); + return; + } + + // support IteratorType::ASYNC later +} + + void Iterator::Close(bool abruptCompletion) const { if (type_ == IteratorType::SYNC) { - if (!abruptCompletion) { - pg_->LoadConst(node_, Constant::JS_HOLE); - } - pg_->CloseIterator(node_, iterator_); + // if (!abruptCompletion) { + // pg_->LoadConst(node_, Constant::JS_HOLE); + // } + // pg_->CloseIterator(node_, iterator_); + RegScope rs(pg_); + VReg innerResult = pg_->AllocReg(); + Label *noReturn = pg_->AllocLabel(); + + // close iterator + pg_->LoadObjByName(node_, iterator_, "return"); + pg_->StoreAccumulator(node_, method_); + pg_->LoadConst(node_, Constant::JS_UNDEFINED); + pg_->Condition(node_, lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL, method_, noReturn); + CallMethod(); + pg_->StoreAccumulator(node_, innerResult); + pg_->ThrowIfNotObject(node_, innerResult); + + pg_->SetLabel(node_, noReturn); return; } @@ -159,7 +202,7 @@ void Iterator::Close(bool abruptCompletion) const // 8. If Type(innerResult.[[Value]]) is not Object, throw a TypeError exception. pg_->LoadAccumulator(node_, innerResult); - pg_->ThrowIfNotObject(node_); + pg_->ThrowIfNotObject(node_, innerResult); } DestructuringIterator::DestructuringIterator(PandaGen *pg, const ir::AstNode *node) diff --git a/es2panda/compiler/base/iterators.h b/es2panda/compiler/base/iterators.h index 0f23818d9ed2015bc8db01e274ba63b5a064dea1..9768ae53b5456299cb5489b276ba89f5c0b514b4 100644 --- a/es2panda/compiler/base/iterators.h +++ b/es2panda/compiler/base/iterators.h @@ -62,6 +62,7 @@ public: void Next() const; void Complete() const; void Value() const; + void CloseWithException() const; void Close(bool abruptCompletion) const; protected: diff --git a/es2panda/compiler/core/dynamicContext.cpp b/es2panda/compiler/core/dynamicContext.cpp index 73e9e9ddcb08b589c09a48c9d822fe1497086fb4..9c6b9a70470b08522d47c59e529f46ad2722b67f 100644 --- a/es2panda/compiler/core/dynamicContext.cpp +++ b/es2panda/compiler/core/dynamicContext.cpp @@ -118,7 +118,7 @@ IteratorContext::~IteratorContext() pg_->Branch(node, labelSet.CatchEnd()); pg_->SetLabel(node, labelSet.CatchBegin()); - iterator_.Close(true); + iterator_.CloseWithException(); pg_->SetLabel(node, labelSet.CatchEnd()); } diff --git a/es2panda/compiler/core/emitter.cpp b/es2panda/compiler/core/emitter.cpp index ac04127360e7dd7c2b6bba3e29f049b18963d528..1e5d82ba604ee2ff64a3ee42a16cec8600979766 100644 --- a/es2panda/compiler/core/emitter.cpp +++ b/es2panda/compiler/core/emitter.cpp @@ -115,6 +115,11 @@ void FunctionEmitter::GenBufferLiterals(const LiteralBuffer *buff) valueLit.value_ = literal->GetMethod().Mutf8(); break; } + case ir::LiteralTag::METHODAFFILIATE: { + valueLit.tag_ = panda::panda_file::LiteralTag::METHODAFFILIATE; + valueLit.value_ = literal->GetMethodAffiliate(); + break; + } case ir::LiteralTag::GENERATOR_METHOD: { valueLit.tag_ = panda::panda_file::LiteralTag::GENERATORMETHOD; valueLit.value_ = literal->GetMethod().Mutf8(); @@ -136,6 +141,14 @@ void FunctionEmitter::GenBufferLiterals(const LiteralBuffer *buff) array.emplace_back(tagLit); array.emplace_back(valueLit); } + + // std::cout << " --- literal array buffer --- " << std::endl; + // for (auto a : array) { + // std::cout << "tag: " << static_cast::type>(a.tag_) << std::endl; + // std::visit( [](auto&& e) { + // std::cout << "value: " << e << std::endl; + // }, a.value_ ); + // } } util::StringView FunctionEmitter::SourceCode() const diff --git a/es2panda/compiler/core/pandagen.cpp b/es2panda/compiler/core/pandagen.cpp index 7cf1bb96f5a871e58b477d4779e57ce2b7ebc416..1360511a9293837cf761b8a4980ccfee6c1ae6ef 100644 --- a/es2panda/compiler/core/pandagen.cpp +++ b/es2panda/compiler/core/pandagen.cpp @@ -300,10 +300,10 @@ void PandaGen::StoreObjProperty(const ir::AstNode *node, VReg obj, const Operand StoreObjByName(node, obj, std::get(prop)); } -void PandaGen::StoreOwnProperty(const ir::AstNode *node, VReg obj, const Operand &prop) +void PandaGen::StoreOwnProperty(const ir::AstNode *node, VReg obj, const Operand &prop, const bool nameSetting) { if (std::holds_alternative(prop)) { - StOwnByValue(node, obj, std::get(prop)); + StOwnByValue(node, obj, std::get(prop), nameSetting); return; } @@ -313,7 +313,7 @@ void PandaGen::StoreOwnProperty(const ir::AstNode *node, VReg obj, const Operand } ASSERT(std::holds_alternative(prop)); - StOwnByName(node, obj, std::get(prop)); + StOwnByName(node, obj, std::get(prop), nameSetting); } void PandaGen::TryLoadGlobalByName(const ir::AstNode *node, const util::StringView &name) @@ -360,20 +360,22 @@ void PandaGen::StoreObjByIndex(const ir::AstNode *node, VReg obj, int64_t index) ra_.Emit(node, index, obj); } -void PandaGen::StOwnByName(const ir::AstNode *node, VReg obj, const util::StringView &prop) +void PandaGen::StOwnByName(const ir::AstNode *node, VReg obj, const util::StringView &prop, const bool nameSetting) { - ra_.Emit(node, prop, obj); + nameSetting ? ra_.Emit(node, prop, obj) : + ra_.Emit(node, prop, obj); strings_.insert(prop); } -void PandaGen::StOwnByValue(const ir::AstNode *node, VReg obj, VReg prop) +void PandaGen::StOwnByValue(const ir::AstNode *node, VReg obj, VReg prop, const bool nameSetting) { - ra_.Emit(node, obj, prop); + nameSetting ? ra_.Emit(node, obj, prop) : + ra_.Emit(node, obj, prop); } void PandaGen::StOwnByIndex(const ir::AstNode *node, VReg obj, int64_t index) { - ra_.Emit(node, index, obj); + ra_.Emit(node, obj, index); } void PandaGen::DeleteObjProperty(const ir::AstNode *node, VReg obj, const Operand &prop) @@ -802,6 +804,15 @@ void PandaGen::BranchIfNotUndefined(const ir::AstNode *node, Label *target) sa_.Emit(node, target); } +void PandaGen::BranchIfStrictNotUndefined(const ir::AstNode *node, class Label *target) +{ + VReg tmp = AllocReg(); + StoreAccumulator(node, tmp); + LoadConst(node, Constant::JS_UNDEFINED); + ra_.Emit(node, tmp); + sa_.Emit(node, target); +} + void PandaGen::BranchIfTrue(const ir::AstNode *node, Label *target) { sa_.Emit(node, target); @@ -863,7 +874,7 @@ void PandaGen::ValidateClassDirectReturn(const ir::AstNode *node) auto *notUndefined = AllocLabel(); auto *condEnd = AllocLabel(); - BranchIfNotUndefined(node, notUndefined); + BranchIfStrictNotUndefined(node, notUndefined); GetThis(func); ThrowIfSuperNotCorrectCall(func, 0); Branch(node, condEnd); @@ -940,7 +951,7 @@ void PandaGen::LoadHomeObject(const ir::AstNode *node) void PandaGen::DefineFunction(const ir::AstNode *node, const ir::ScriptFunction *realNode, const util::StringView &name) { - auto formalParamCnt = FormalParametersCount(); + auto formalParamCnt = realNode->FormalParamsLength(); if (realNode->IsAsync()) { if (realNode->IsGenerator()) { // TODO(): async generator @@ -998,15 +1009,6 @@ void PandaGen::ToNumber(const ir::AstNode *node, VReg arg) ra_.Emit(node, arg); } -void PandaGen::GetMethod(const ir::AstNode *node, VReg obj, const util::StringView &name) -{ - /** - * TODO - * ra_.Emit(node, name, obj); - * strings_.insert(name); - */ -} - void PandaGen::CreateGeneratorObj(const ir::AstNode *node, VReg funcObj) { ra_.Emit(node, funcObj); @@ -1020,20 +1022,14 @@ void PandaGen::CreateAsyncGeneratorObj(const ir::AstNode *node, VReg funcObj) */ } -void PandaGen::CreateIterResultObject(const ir::AstNode *node, bool done) +void PandaGen::CreateIterResultObject(const ir::AstNode *node, VReg value, VReg done) { - /* - * TODO: create iter result - * ra_.Emit(node, static_cast(done)); - */ + ra_.Emit(node, value, done); } -void PandaGen::SuspendGenerator(const ir::AstNode *node, VReg genObj) +void PandaGen::SuspendGenerator(const ir::AstNode *node, VReg genObj, VReg iterResult) { - /* - * TODO: suspend generator - * ra_.Emit(node, genObj); - */ + ra_.Emit(node, genObj, iterResult); } void PandaGen::SuspendAsyncGenerator(const ir::AstNode *node, VReg asyncGenObj) @@ -1257,7 +1253,7 @@ void PandaGen::CreateArray(const ir::AstNode *node, const ArenaVectorIsOmittedExpression()) { elem->Compile(this); - StOwnByValue(elem, obj, idxReg); + StOwnByValue(elem, obj, idxReg, false); } Unary(elem, lexer::TokenType::PUNCTUATOR_PLUS_PLUS, idxReg); @@ -1271,7 +1267,7 @@ void PandaGen::CreateArray(const ir::AstNode *node, const ArenaVector(node, array, index); } -void PandaGen::ThrowIfNotObject(const ir::AstNode *node) +void PandaGen::ThrowIfNotObject(const ir::AstNode *node, VReg obj) { - // TODO: implement this method correctly - RegScope rs(this); - VReg value = AllocReg(); - ra_.Emit(node, value); + ra_.Emit(node, obj); } void PandaGen::ThrowThrowNotExist(const ir::AstNode *node) @@ -1312,10 +1305,12 @@ void PandaGen::CreateObjectWithExcludedKeys(const ir::AstNode *node, VReg obj, V { ASSERT(argStart == obj + 1); if (argCount == 0) { // Do not emit undefined register - argStart = obj; + LoadConst(node, Constant::JS_UNDEFINED); + StoreAccumulator(node, argStart); } - rra_.Emit(node, argStart, argCount, static_cast(argCount), obj, + size_t argRegCnt = (argCount == 0 ? argCount : argCount - 1); + rra_.Emit(node, argStart, argCount, static_cast(argRegCnt), obj, argStart); } @@ -1339,10 +1334,9 @@ void PandaGen::ImportModule(const ir::AstNode *node, const util::StringView &nam } void PandaGen::DefineClassWithBuffer(const ir::AstNode *node, const util::StringView &ctorId, int32_t litIdx, - VReg lexenv, VReg base) + VReg lexenv, VReg base, int64_t formalParamCnt) { - auto formalParamCnt = FormalParametersCount(); - ra_.Emit(node, ctorId, litIdx, static_cast(formalParamCnt), lexenv, base); + ra_.Emit(node, ctorId, litIdx, formalParamCnt, lexenv, base); strings_.insert(ctorId); } @@ -1461,6 +1455,7 @@ void PandaGen::ThrowUndefinedIfHole(const ir::AstNode *node, const util::StringV VReg nameReg = AllocReg(); StoreAccumulator(node, nameReg); ra_.Emit(node, holeReg, nameReg); + LoadAccumulator(node, holeReg); strings_.insert(name); } @@ -1471,6 +1466,7 @@ void PandaGen::ThrowConstAssignment(const ir::AstNode *node, const util::StringV VReg nameReg = AllocReg(); StoreAccumulator(node, nameReg); ra_.Emit(node, nameReg); + strings_.insert(name); } @@ -1530,11 +1526,15 @@ Operand PandaGen::ToNamedPropertyKey(const ir::Expression *prop, bool isComputed { VReg res {0}; - if (!isComputed) { - if (prop->IsIdentifier()) { - return prop->AsIdentifier()->Name(); - } - } else if (prop->IsStringLiteral()) { + if (isComputed) { + return res; + } + + if (prop->IsIdentifier()) { + return prop->AsIdentifier()->Name(); + } + + if (prop->IsStringLiteral()) { const util::StringView &str = prop->AsStringLiteral()->Str(); /* TODO(dbatyai): remove this when runtime handles __proto__ as property name correctly */ @@ -1548,7 +1548,9 @@ Operand PandaGen::ToNamedPropertyKey(const ir::Expression *prop, bool isComputed } return str; - } else if (prop->IsNumberLiteral()) { + } + + if (prop->IsNumberLiteral()) { auto num = prop->AsNumberLiteral()->Number(); if (util::Helpers::IsIndex(num)) { return static_cast(num); diff --git a/es2panda/compiler/core/pandagen.h b/es2panda/compiler/core/pandagen.h index 77d127c423840d623295924523c4544345361cbb..ac309acc07475c3fa21f50c30536c4bf56e1e197 100644 --- a/es2panda/compiler/core/pandagen.h +++ b/es2panda/compiler/core/pandagen.h @@ -215,7 +215,7 @@ public: void LoadObjByName(const ir::AstNode *node, VReg obj, const util::StringView &prop); void StoreObjProperty(const ir::AstNode *node, VReg obj, const Operand &prop); - void StoreOwnProperty(const ir::AstNode *node, VReg obj, const Operand &prop); + void StoreOwnProperty(const ir::AstNode *node, VReg obj, const Operand &prop, const bool nameSetting = false); void DeleteObjProperty(const ir::AstNode *node, VReg obj, const Operand &prop); void LoadAccumulator(const ir::AstNode *node, VReg reg); void LoadGlobalVar(const ir::AstNode *node, const util::StringView &name); @@ -250,6 +250,7 @@ public: void Binary(const ir::AstNode *node, lexer::TokenType op, VReg lhs); void BranchIfUndefined(const ir::AstNode *node, class Label *target); + void BranchIfStrictNotUndefined(const ir::AstNode *node, class Label *target); void BranchIfNotUndefined(const ir::AstNode *node, class Label *target); void BranchIfHole(const ir::AstNode *node, class Label *target); void BranchIfTrue(const ir::AstNode *node, class Label *target); @@ -291,12 +292,11 @@ public: void AsyncFunctionResolve(const ir::AstNode *node, VReg asyncFuncObj); void AsyncFunctionReject(const ir::AstNode *node, VReg asyncFuncObj); - void GetMethod(const ir::AstNode *node, VReg obj, const util::StringView &name); void GeneratorYield(const ir::AstNode *node, VReg genObj); void GeneratorComplete(const ir::AstNode *node, VReg genObj); void CreateAsyncGeneratorObj(const ir::AstNode *node, VReg funcObj); - void CreateIterResultObject(const ir::AstNode *node, bool done); - void SuspendGenerator(const ir::AstNode *node, VReg genObj); + void CreateIterResultObject(const ir::AstNode *node, VReg value, VReg done); + 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); @@ -319,7 +319,7 @@ public: void CreateArrayWithBuffer(const ir::AstNode *node, uint32_t idx); void StoreArraySpread(const ir::AstNode *node, VReg array, VReg index); - void ThrowIfNotObject(const ir::AstNode *node); + void ThrowIfNotObject(const ir::AstNode *node, VReg obj); void ThrowThrowNotExist(const ir::AstNode *node); void GetIterator(const ir::AstNode *node); void GetAsyncIterator(const ir::AstNode *node); @@ -327,8 +327,8 @@ public: void CreateObjectWithExcludedKeys(const ir::AstNode *node, VReg obj, VReg argStart, size_t argCount); void ThrowObjectNonCoercible(const ir::AstNode *node); void CloseIterator(const ir::AstNode *node, VReg iter); - void DefineClassWithBuffer(const ir::AstNode *node, const util::StringView &ctorId, int32_t litIdx, VReg lexenv, - VReg base); + void DefineClassWithBuffer(const ir::AstNode *node, const util::StringView &ctorId, int32_t litIdx, + VReg lexenv, VReg base, int64_t formalParamCnt); void ImportModule(const ir::AstNode *node, const util::StringView &name); void LoadModuleVariable(const ir::AstNode *node, VReg module, const util::StringView &name); @@ -364,8 +364,8 @@ public: void StoreObjByIndex(const ir::AstNode *node, VReg obj, int64_t index); void StoreObjByValue(const ir::AstNode *node, VReg obj, VReg prop); - void StOwnByName(const ir::AstNode *node, VReg obj, const util::StringView &prop); - void StOwnByValue(const ir::AstNode *node, VReg obj, VReg prop); + void StOwnByName(const ir::AstNode *node, VReg obj, const util::StringView &prop, const bool nameSetting); + void StOwnByValue(const ir::AstNode *node, VReg obj, VReg prop, const bool nameSetting); void StOwnByIndex(const ir::AstNode *node, VReg obj, int64_t index); static Operand ToNamedPropertyKey(const ir::Expression *prop, bool isComputed); diff --git a/es2panda/compiler/core/regAllocator.cpp b/es2panda/compiler/core/regAllocator.cpp index 7ed5763f5499b520da2aff1128a28b73cacc06a7..60412a89c0e0f6752b24d51182c93568ff1a1df6 100644 --- a/es2panda/compiler/core/regAllocator.cpp +++ b/es2panda/compiler/core/regAllocator.cpp @@ -72,7 +72,7 @@ void RegAllocatorBase::Restore(IRNode *ins) VReg spillReg = spillIndex_; VReg origin = regEnd_ + spillIndex_; - Add(ins->Node(), origin, spillReg); + Add(ins->Node(), spillReg, origin); } // RegAllocator @@ -110,7 +110,6 @@ void RegAllocator::Run(IRNode *ins) } // RangeRegAllocator - void RangeRegAllocator::Run(IRNode *ins, VReg rangeStart, size_t argCount) { ASSERT(spillIndex_ == 0); diff --git a/es2panda/compiler/function/asyncFunctionBuilder.cpp b/es2panda/compiler/function/asyncFunctionBuilder.cpp index acbbc790ab449ea78e45f907ad6cc3d527c0c3d5..a2a0c3765ac42f1f53fac06ae0acc15cb4c541a3 100644 --- a/es2panda/compiler/function/asyncFunctionBuilder.cpp +++ b/es2panda/compiler/function/asyncFunctionBuilder.cpp @@ -33,7 +33,7 @@ void AsyncFunctionBuilder::ImplicitReturn(const ir::AstNode *node) const DirectReturn(node); } -void AsyncFunctionBuilder::Prepare(const ir::ScriptFunction *node) const +void AsyncFunctionBuilder::Prepare(const ir::ScriptFunction *node) { pg_->AsyncFunctionEnter(node); pg_->StoreAccumulator(node, funcObj_); diff --git a/es2panda/compiler/function/asyncFunctionBuilder.h b/es2panda/compiler/function/asyncFunctionBuilder.h index bd7f38a81456a69877e83c58318ab9670dec20ba..68bdd99433f8cf94781f210ba5ca6842d8af09cb 100644 --- a/es2panda/compiler/function/asyncFunctionBuilder.h +++ b/es2panda/compiler/function/asyncFunctionBuilder.h @@ -30,7 +30,7 @@ public: NO_COPY_SEMANTIC(AsyncFunctionBuilder); NO_MOVE_SEMANTIC(AsyncFunctionBuilder); - void Prepare(const ir::ScriptFunction *node) const override; + void Prepare(const ir::ScriptFunction *node) override; void CleanUp(const ir::ScriptFunction *node) const override; void DirectReturn(const ir::AstNode *node) const override; diff --git a/es2panda/compiler/function/asyncGeneratorFunctionBuilder.cpp b/es2panda/compiler/function/asyncGeneratorFunctionBuilder.cpp index c4360cd87af39409aa8692c5872f7498320848e7..95effe03c07ff5b840db90b3fdc50003748352c8 100644 --- a/es2panda/compiler/function/asyncGeneratorFunctionBuilder.cpp +++ b/es2panda/compiler/function/asyncGeneratorFunctionBuilder.cpp @@ -20,13 +20,13 @@ #include namespace panda::es2panda::compiler { -void AsyncGeneratorFunctionBuilder::Prepare(const ir::ScriptFunction *node) const +void AsyncGeneratorFunctionBuilder::Prepare(const ir::ScriptFunction *node) { VReg callee = FunctionReg(node); pg_->CreateAsyncGeneratorObj(node, callee); pg_->StoreAccumulator(node, funcObj_); - pg_->SuspendGenerator(node, funcObj_); + // pg_->SuspendGenerator(node, funcObj_); pg_->SetLabel(node, catchTable_->LabelSet().TryBegin()); } diff --git a/es2panda/compiler/function/asyncGeneratorFunctionBuilder.h b/es2panda/compiler/function/asyncGeneratorFunctionBuilder.h index f492da49d1f4428945821d5f1a4fae51c75c7b91..8ae591a79c41b90324fb45d62f41ed5284df1f29 100644 --- a/es2panda/compiler/function/asyncGeneratorFunctionBuilder.h +++ b/es2panda/compiler/function/asyncGeneratorFunctionBuilder.h @@ -30,7 +30,7 @@ public: NO_COPY_SEMANTIC(AsyncGeneratorFunctionBuilder); NO_MOVE_SEMANTIC(AsyncGeneratorFunctionBuilder); - void Prepare(const ir::ScriptFunction *node) const override; + void Prepare(const ir::ScriptFunction *node) override; void CleanUp(const ir::ScriptFunction *node) const override; void DirectReturn(const ir::AstNode *node) const override; diff --git a/es2panda/compiler/function/functionBuilder.cpp b/es2panda/compiler/function/functionBuilder.cpp index eaba22a71aaada4722e54db98adba4d474341bc6..1383835fcf5a6510f6b7855978de60404e47fade 100644 --- a/es2panda/compiler/function/functionBuilder.cpp +++ b/es2panda/compiler/function/functionBuilder.cpp @@ -67,8 +67,10 @@ void FunctionBuilder::SuspendResumeExecution(const ir::AstNode *node, VReg compl { ASSERT(BuilderKind() == BuilderType::ASYNC || BuilderKind() == BuilderType::ASYNC_GENERATOR || BuilderKind() == BuilderType::GENERATOR); - - pg_->SuspendGenerator(node, funcObj_); + RegScope rs(pg_); + VReg iterResult = pg_->AllocReg(); + pg_->StoreAccumulator(node, iterResult); + pg_->SuspendGenerator(node, funcObj_, iterResult); resumeGenerator(node, completionType, completionValue); } @@ -239,7 +241,7 @@ void FunctionBuilder::YieldStar(const ir::AstNode *node) // ii. If Type(innerResult) is not Object, throw a TypeError exception. // 4. If Type(innerResult) is not Object, throw a TypeError exception. // vi. If Type(innerReturnResult) is not Object, throw a TypeError exception. - pg_->ThrowIfNotObject(node); + pg_->ThrowIfNotObject(node, receivedValue); // iv. Let done be ? IteratorComplete(innerResult). // v. Let done be ? IteratorComplete(innerResult). diff --git a/es2panda/compiler/function/functionBuilder.h b/es2panda/compiler/function/functionBuilder.h index 4147c49577a673a71ea7f8ee198bc1e2158443ce..63abf6f78e5cd054a2064fe9340ff85ee66d1f20 100644 --- a/es2panda/compiler/function/functionBuilder.h +++ b/es2panda/compiler/function/functionBuilder.h @@ -49,7 +49,7 @@ public: NO_COPY_SEMANTIC(FunctionBuilder); NO_MOVE_SEMANTIC(FunctionBuilder); - virtual void Prepare([[maybe_unused]] const ir::ScriptFunction *node) const {}; + virtual void Prepare([[maybe_unused]] const ir::ScriptFunction *node) {}; virtual void CleanUp([[maybe_unused]] const ir::ScriptFunction *node) const {}; virtual void DirectReturn(const ir::AstNode *node) const; diff --git a/es2panda/compiler/function/generatorFunctionBuilder.cpp b/es2panda/compiler/function/generatorFunctionBuilder.cpp index a4d71b3fd2dac50aded1c33cabc31d89dac78a15..2ea213b1a6b3e066971363a3b9cdd939e9719de1 100644 --- a/es2panda/compiler/function/generatorFunctionBuilder.cpp +++ b/es2panda/compiler/function/generatorFunctionBuilder.cpp @@ -21,14 +21,16 @@ namespace panda::es2panda::compiler { -void GeneratorFunctionBuilder::Prepare(const ir::ScriptFunction *node) const +void GeneratorFunctionBuilder::Prepare(const ir::ScriptFunction *node) { VReg callee = FunctionReg(node); - + VReg completionType = pg_->AllocReg(); + VReg completionValue = pg_->AllocReg(); pg_->CreateGeneratorObj(node, callee); pg_->StoreAccumulator(node, funcObj_); - pg_->SuspendGenerator(node, funcObj_); - pg_->SetLabel(node, catchTable_->LabelSet().TryBegin()); + pg_->LoadConst(node, Constant::JS_UNDEFINED); + SuspendResumeExecution(node, completionType, completionValue); + HandleCompletion(node, completionType, completionValue); } void GeneratorFunctionBuilder::CleanUp(const ir::ScriptFunction *node) const @@ -44,8 +46,6 @@ void GeneratorFunctionBuilder::CleanUp(const ir::ScriptFunction *node) const void GeneratorFunctionBuilder::DirectReturn(const ir::AstNode *node) const { - pg_->GeneratorComplete(node, funcObj_); - pg_->CreateIterResultObject(node, true); pg_->EmitReturn(node); } @@ -58,13 +58,16 @@ void GeneratorFunctionBuilder::ImplicitReturn(const ir::AstNode *node) const void GeneratorFunctionBuilder::Yield(const ir::AstNode *node) { RegScope rs(pg_); + VReg value = pg_->AllocReg(); + VReg done = pg_->AllocReg(); VReg completionType = pg_->AllocReg(); VReg completionValue = pg_->AllocReg(); - pg_->CreateIterResultObject(node, false); - pg_->GeneratorYield(node, funcObj_); + pg_->StoreAccumulator(node, value); + pg_->LoadConst(node, Constant::JS_FALSE); + pg_->StoreAccumulator(node, done); + pg_->CreateIterResultObject(node, value, done); SuspendResumeExecution(node, completionType, completionValue); - HandleCompletion(node, completionType, completionValue); } diff --git a/es2panda/compiler/function/generatorFunctionBuilder.h b/es2panda/compiler/function/generatorFunctionBuilder.h index a1a12295654cff025fcd0754b8d1cd116074ecff..6b3b96acb38608325ffc00b5426909e807f617db 100644 --- a/es2panda/compiler/function/generatorFunctionBuilder.h +++ b/es2panda/compiler/function/generatorFunctionBuilder.h @@ -44,7 +44,7 @@ public: NO_COPY_SEMANTIC(GeneratorFunctionBuilder); NO_MOVE_SEMANTIC(GeneratorFunctionBuilder); - void Prepare(const ir::ScriptFunction *node) const override; + void Prepare(const ir::ScriptFunction *node) override; void CleanUp(const ir::ScriptFunction *node) const override; void DirectReturn(const ir::AstNode *node) const override; diff --git a/es2panda/ir/base/classDefinition.cpp b/es2panda/ir/base/classDefinition.cpp index bd18a40d3425b32ea918bd40b81e76f83b0d36a3..122ac618ea3c706b023f02165ae43608cc82573f 100644 --- a/es2panda/ir/base/classDefinition.cpp +++ b/es2panda/ir/base/classDefinition.cpp @@ -120,6 +120,7 @@ int32_t ClassDefinition::CreateClassStaticProperties(compiler::PandaGen *pg, uti auto *buf = pg->NewLiteralBuffer(); compiler::LiteralBuffer staticBuf(pg->Allocator()); bool seenComputed = false; + uint32_t unstaticNum = 0; std::unordered_map propNameMap; std::unordered_map staticPropNameMap; @@ -131,12 +132,20 @@ int32_t ClassDefinition::CreateClassStaticProperties(compiler::PandaGen *pg, uti } const ir::MethodDefinition *prop = properties[i]->AsMethodDefinition(); - if (!util::Helpers::IsConstantPropertyKey(prop->Key(), prop->Computed()) || - (prop->Computed() && util::Helpers::IsSpecialPropertyKey(prop->Key()))) { + // if (!util::Helpers::IsConstantPropertyKey(prop->Key(), prop->Computed()) || + // (prop->Computed() && util::Helpers::IsSpecialPropertyKey(prop->Key()))) { + // seenComputed = true; + // continue; + // } + if (prop->Computed()) { seenComputed = true; continue; } + if (prop->IsAccessor()) { + break; + } + util::StringView name = util::Helpers::LiteralToPropName(prop->Key()); compiler::LiteralBuffer *literalBuf = prop->IsStatic() ? &staticBuf : buf; auto &nameMap = prop->IsStatic() ? staticPropNameMap : propNameMap; @@ -149,7 +158,8 @@ int32_t ClassDefinition::CreateClassStaticProperties(compiler::PandaGen *pg, uti } literalBuf->Add(pg->Allocator()->New(name)); - literalBuf->Add(nullptr); + literalBuf->Add(nullptr); // save for method name + literalBuf->Add(nullptr); // save for method affiliate } else { bufferPos = res.first->second; } @@ -163,11 +173,15 @@ int32_t ClassDefinition::CreateClassStaticProperties(compiler::PandaGen *pg, uti value = pg->Allocator()->New(LiteralTag::METHOD, internalName); compiled.Set(i); + literalBuf->ResetLiteral(bufferPos + 1, value); + Literal *methodAffiliate = pg->Allocator()->New(LiteralTag::METHODAFFILIATE, func->Function()->FormalParamsLength()); + literalBuf->ResetLiteral(bufferPos + 2, methodAffiliate); break; } case ir::MethodDefinitionKind::GET: case ir::MethodDefinitionKind::SET: { value = pg->Allocator()->New(); + literalBuf->ResetLiteral(bufferPos + 1, value); break; } default: { @@ -175,17 +189,17 @@ int32_t ClassDefinition::CreateClassStaticProperties(compiler::PandaGen *pg, uti } } - literalBuf->ResetLiteral(bufferPos + 1, value); + if (!prop->IsStatic()) { + unstaticNum++; + } } - uint32_t litPairs = buf->Size() / 2; - /* Static items are stored at the end of the buffer */ buf->Insert(&staticBuf); /* The last literal item represents the offset of the first static property. The regular property literal count * is divided by 2 as key/value pairs count as one. */ - buf->Add(pg->Allocator()->New(litPairs)); + buf->Add(pg->Allocator()->New(unstaticNum)); return pg->AddLiteralBuffer(buf); } @@ -212,12 +226,18 @@ void ClassDefinition::CompileMissingProperties(compiler::PandaGen *pg, const uti switch (prop->Kind()) { case ir::MethodDefinitionKind::METHOD: { compiler::Operand key = pg->ToPropertyKey(prop->Key(), prop->Computed()); - + compiler::VReg keyReg = pg->AllocReg(); + if (prop->Key()->IsIdentifier() && !prop->Computed()) { + pg->LoadAccumulatorString(this, std::get(key)); + } else { + prop->Key()->Compile(pg); + } + pg->StoreAccumulator(this, keyReg); pg->LoadAccumulator(this, dest); const ir::FunctionExpression *func = prop->Value()->AsFunctionExpression(); func->Compile(pg); - pg->StoreOwnProperty(prop->Value()->Parent(), dest, key); + pg->StoreOwnProperty(prop->Value()->Parent(), dest, keyReg, prop->Computed()); break; } case ir::MethodDefinitionKind::GET: @@ -268,8 +288,9 @@ void ClassDefinition::Compile(compiler::PandaGen *pg) const util::BitSet compiled(body_.size()); int32_t bufIdx = CreateClassStaticProperties(pg, compiled); - pg->DefineClassWithBuffer(this, ctorId, bufIdx, lexenv, baseReg); - if (scope_->Parent()->IsGlobalScope() && ident_) { + auto formalParamCnt = Ctor()->Function()->FormalParamsLength(); + pg->DefineClassWithBuffer(this, ctorId, bufIdx, lexenv, baseReg, formalParamCnt); + if (scope_->Parent()->IsGlobalScope() && ident_ && this->Parent()->IsClassDeclaration()) { pg->StoreGlobalLet(this, ident_->Name()); } pg->StoreAccumulator(this, classReg); diff --git a/es2panda/ir/base/methodDefinition.h b/es2panda/ir/base/methodDefinition.h index e304cd084e23e350d8457da1bb9b7e676f6fc26b..1170e01693b500da39d45e68134bcc105aed9a82 100644 --- a/es2panda/ir/base/methodDefinition.h +++ b/es2panda/ir/base/methodDefinition.h @@ -80,6 +80,11 @@ public: return (modifiers_ & ModifierFlags::STATIC) != 0; } + bool IsAccessor() const + { + return (kind_ == MethodDefinitionKind::GET) || (kind_ == MethodDefinitionKind::SET); + } + bool IsOptional() const { return (modifiers_ & ModifierFlags::OPTIONAL) != 0; diff --git a/es2panda/ir/expressions/literal.cpp b/es2panda/ir/expressions/literal.cpp index 48cb9a94d4317a7940cc7c06ae92c416f03258de..4a021f470ff5a8323d89922856ed064cf09c6ec9 100644 --- a/es2panda/ir/expressions/literal.cpp +++ b/es2panda/ir/expressions/literal.cpp @@ -52,4 +52,10 @@ const util::StringView &Literal::GetMethod() const return AsTaggedLiteral()->Method(); } +uint16_t Literal::GetMethodAffiliate() const +{ + ASSERT(IsTaggedLiteral()); + return AsTaggedLiteral()->MethodAffiliate(); +} + } // namespace panda::es2panda::ir diff --git a/es2panda/ir/expressions/literal.h b/es2panda/ir/expressions/literal.h index ee6bc7af23e6d239b26b2b8275c6cb6428c67bb2..60912e74c3e003083eb60f17ccf87011a6f8361e 100644 --- a/es2panda/ir/expressions/literal.h +++ b/es2panda/ir/expressions/literal.h @@ -31,17 +31,18 @@ namespace panda::es2panda::ir { // must be kept in sync with panda::panda_file::LiteralTag enum class LiteralTag { - TAGVALUE, - BOOLEAN, - INTEGER, + TAGVALUE = 0, + BOOLEAN = 1, + INTEGER = 2, FLOAT, - DOUBLE, - STRING, - ACCESSOR, - METHOD, + DOUBLE = 4, + STRING = 5, + METHOD = 6, GENERATOR_METHOD, + ACCESSOR = 8, + METHODAFFILIATE = 9, ASYNC_GENERATOR_METHOD, - NULL_VALUE, + NULL_VALUE = 255, }; class Literal : public Expression { @@ -58,6 +59,7 @@ public: double GetDouble() const; const util::StringView &GetString() const; const util::StringView &GetMethod() const; + uint16_t GetMethodAffiliate() const; protected: explicit Literal(AstNodeType type) : Expression(type) {} diff --git a/es2panda/ir/expressions/literals/taggedLiteral.h b/es2panda/ir/expressions/literals/taggedLiteral.h index 69a4b6486a38bd9e10ad389b8551b24fcf30fcea..c8ecd27e70eb55ca5392b6ff75ddfeb348adee47 100644 --- a/es2panda/ir/expressions/literals/taggedLiteral.h +++ b/es2panda/ir/expressions/literals/taggedLiteral.h @@ -37,6 +37,11 @@ public: { } + explicit TaggedLiteral(LiteralTag tag, uint16_t num) + : Literal(AstNodeType::TAGGED_LITERAL), num_(num), tag_(tag) + { + } + const util::StringView &Str() const { return str_; @@ -59,12 +64,19 @@ public: return str_; } + uint16_t MethodAffiliate() const + { + ASSERT(tag_ == LiteralTag::METHODAFFILIATE); + return num_; + } + void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; void Compile([[maybe_unused]] compiler::PandaGen *pg) const override; checker::Type *Check([[maybe_unused]] checker::Checker *checker) const override; private: + uint16_t num_ {}; util::StringView str_ {}; LiteralTag tag_ {LiteralTag::NULL_VALUE}; }; diff --git a/es2panda/parser/parserImpl.cpp b/es2panda/parser/parserImpl.cpp index 6ecfc77b84dcbe26126be64ed45012ace09a8a34..c297df3fe22cbd3c7d55d472c93ef4f17de50071 100644 --- a/es2panda/parser/parserImpl.cpp +++ b/es2panda/parser/parserImpl.cpp @@ -2399,8 +2399,8 @@ ir::Identifier *ParserImpl::SetIdentNodeInClassDefinition() return identNode; } -ir::ClassDefinition *ParserImpl::ParseClassDefinition(bool isDeclaration, bool idRequired, bool isDeclare, - bool isAbstract) +ir::ClassDefinition *ParserImpl::ParseClassDefinition(bool isDeclaration, bool idRequired, + bool isDeclare, bool isAbstract) { lexer::SourcePosition startLoc = lexer_->GetToken().Start(); lexer_->NextToken(); diff --git a/ts2panda/ts2abc/BUILD.gn b/ts2panda/ts2abc/BUILD.gn index 7e723caf01bfcc095669284ce680668e04f63a47..88d58ab2246a7e422ed576430f8451d72850bebb 100755 --- a/ts2panda/ts2abc/BUILD.gn +++ b/ts2panda/ts2abc/BUILD.gn @@ -73,7 +73,7 @@ if (!defined(ark_independent_build)) { deps = [ ":jsoncpp_set_static" ] use_exceptions = true subsystem_name = "ark" - part_name = "ark_frontend_tool" + part_name = "ark_ts2abc" } ohos_executable("ts2abc") {