From 3112a975e1a4da0f9252a34eaafd68c0bf1af0cd Mon Sep 17 00:00:00 2001 From: ctw-ian Date: Tue, 19 Jul 2022 20:13:10 +0800 Subject: [PATCH] Fix several functions of es2abc Fix several functions under guidance of test262 and hap compilation Issue:I5IK2O Signed-off-by: ctw-ian Change-Id: I69ff2de52ec2a20eb837f743b400c96f4236d033 --- es2panda/binder/scope.cpp | 31 +++++++++++++++++++++++++++++ es2panda/binder/scope.h | 13 ++++++++++++ es2panda/compiler/base/hoisting.cpp | 5 +++++ es2panda/compiler/core/envScope.cpp | 17 +++++++++++++++- es2panda/compiler/core/pandagen.cpp | 20 ++++++++++++------- es2panda/compiler/core/pandagen.h | 1 + 6 files changed, 79 insertions(+), 8 deletions(-) diff --git a/es2panda/binder/scope.cpp b/es2panda/binder/scope.cpp index e044f66c46..90a0c64ceb 100644 --- a/es2panda/binder/scope.cpp +++ b/es2panda/binder/scope.cpp @@ -49,6 +49,20 @@ VariableScope *Scope::EnclosingVariableScope() return nullptr; } +FunctionScope *Scope::EnclosingFunctionVariableScope() +{ + Scope *iter = this; + while (iter) { + if (iter->IsFunctionVariableScope()) { + return iter->AsFunctionVariableScope(); + } + + iter = iter->Parent(); + } + + return nullptr; +} + Variable *Scope::FindLocal(const util::StringView &name, ResolveBindingOptions options) const { if (options & ResolveBindingOptions::INTERFACES) { @@ -78,6 +92,23 @@ ScopeFindResult Scope::Find(const util::StringView &name, ResolveBindingOptions uint32_t lexLevel = 0; const auto *iter = this; + if (iter->IsFunctionParamScope()) { + Variable *v = iter->FindLocal(name, options); + + if (v != nullptr) { + return {name, const_cast(iter), level, lexLevel, v}; + } + + level++; + auto *funcVariableScope = iter->AsFunctionParamScope()->GetFunctionScope(); + + if (funcVariableScope->NeedLexEnv()) { + lexLevel++; + } + + iter = iter->Parent(); + } + while (iter != nullptr) { Variable *v = iter->FindLocal(name, options); diff --git a/es2panda/binder/scope.h b/es2panda/binder/scope.h index 9621858f36..0dfda446f9 100644 --- a/es2panda/binder/scope.h +++ b/es2panda/binder/scope.h @@ -121,6 +121,8 @@ public: VariableScope *EnclosingVariableScope(); + FunctionScope *EnclosingFunctionVariableScope(); + const ArenaVector &Decls() const { return decls_; @@ -314,6 +316,17 @@ public: return params_; } + bool HasParam(util::StringView name) const + { + for (auto *param : params_) { + if (param->Name() == name) { + return true; + } + } + + return false; + } + std::tuple AddParamDecl(ArenaAllocator *allocator, const ir::AstNode *param); protected: diff --git a/es2panda/compiler/base/hoisting.cpp b/es2panda/compiler/base/hoisting.cpp index 07621e8d63..815bf147a8 100644 --- a/es2panda/compiler/base/hoisting.cpp +++ b/es2panda/compiler/base/hoisting.cpp @@ -31,6 +31,11 @@ static void HoistVar(PandaGen *pg, binder::Variable *var, const binder::VarDecl return; } + auto *funcScope = scope->EnclosingFunctionVariableScope(); + if (funcScope->ParamScope()->HasParam(decl->Name())) { + return; + } + binder::ScopeFindResult result(decl->Name(), scope, 0, var); pg->LoadConst(decl->Node(), Constant::JS_UNDEFINED); diff --git a/es2panda/compiler/core/envScope.cpp b/es2panda/compiler/core/envScope.cpp index 6e2fa13c78..93fa239666 100644 --- a/es2panda/compiler/core/envScope.cpp +++ b/es2panda/compiler/core/envScope.cpp @@ -77,8 +77,23 @@ void LoopEnvScope::CopyPetIterationCtx() return; } - pg_->CopyLexEnv(scope_->Node()); + auto num = scope_->LexicalSlots(); + RegScope rs(pg_); + std::vector lexicals; + lexicals.reserve(num); + for (uint32_t i = 0; i < num; i++) { + VReg lexical = pg_->AllocReg(); + pg_->LoadLexicalVar(scope_->Node(), 0, i); + pg_->StoreAccumulator(scope_->Node(), lexical); + lexicals.push_back(lexical); + } + pg_->PopLexEnv(scope_->Node()); + pg_->NewLexEnv(scope_->Node(), num); pg_->StoreAccumulator(scope_->Node(), lexEnv_); + + for (uint32_t i = 0; i < num; i++) { + pg_->StoreLexicalVar(scope_->Node(), 0, i, lexicals[i]); + } } } // namespace panda::es2panda::compiler diff --git a/es2panda/compiler/core/pandagen.cpp b/es2panda/compiler/core/pandagen.cpp index 17375d9a93..97e7983ee3 100644 --- a/es2panda/compiler/core/pandagen.cpp +++ b/es2panda/compiler/core/pandagen.cpp @@ -164,8 +164,7 @@ void PandaGen::CopyFunctionArguments(const ir::AstNode *node) for (const auto *param : topScope_->ParamScope()->Params()) { if (param->LexicalBound()) { - LoadAccumulator(node, targetReg++); - StoreLexicalVar(node, 0, param->LexIdx()); + StoreLexicalVar(node, 0, param->LexIdx(), targetReg++); } else { ra_.Emit(node, param->Vreg(), targetReg++); } @@ -1353,11 +1352,13 @@ void PandaGen::GetAsyncIterator(const ir::AstNode *node) void PandaGen::CreateObjectWithExcludedKeys(const ir::AstNode *node, VReg obj, VReg argStart, size_t argCount) { ASSERT(argStart == obj + 1); - if (argCount == 0) { // Do not emit undefined register - argStart = obj; + if (argCount == 0) { + 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); } @@ -1482,13 +1483,17 @@ void PandaGen::LoadLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t void PandaGen::StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot) { - // TODO: need to reconsider this part RegScope rs(this); VReg value = AllocReg(); StoreAccumulator(node, value); ra_.Emit(node, level, slot, value); } +void PandaGen::StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot, VReg value) +{ + ra_.Emit(node, level, slot, value); +} + void PandaGen::ThrowIfSuperNotCorrectCall(const ir::AstNode *node, int64_t num) { sa_.Emit(node, num); @@ -1503,6 +1508,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); } @@ -1524,7 +1530,7 @@ void PandaGen::PopLexEnv(const ir::AstNode *node) void PandaGen::CopyLexEnv(const ir::AstNode *node) { /* - * TODO: copy lexenv + * TODO: add copy lexenv to optimize the loop env creation * sa_.Emit(node); */ } diff --git a/es2panda/compiler/core/pandagen.h b/es2panda/compiler/core/pandagen.h index 67582f92e3..2236ffa5ca 100644 --- a/es2panda/compiler/core/pandagen.h +++ b/es2panda/compiler/core/pandagen.h @@ -355,6 +355,7 @@ public: void NewLexEnv(const ir::AstNode *node, uint32_t num); void LoadLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot); void StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot); + void StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot, VReg value); void ThrowIfSuperNotCorrectCall(const ir::AstNode *node, int64_t num); void ThrowUndefinedIfHole(const ir::AstNode *node, const util::StringView &name); -- Gitee