From 792e99efa247e0c90298ec9b7d5ea2a1030f5110 Mon Sep 17 00:00:00 2001 From: ctw-ian Date: Wed, 20 Jul 2022 15:00:58 +0800 Subject: [PATCH] Fix hoisting, lexical env and find logic 1. Fix hoisting shadowing parameters 2. Fix loop env creation periteration in for statement 3. Fix finding default value of parameter Signed-off-by: ctw-ian Change-Id: I3d61ce6ab41aa976d11d3b4a32e70f070275b564 --- es2panda/binder/scope.cpp | 17 +++++++++++++++++ es2panda/compiler/base/hoisting.cpp | 14 ++++++++++++++ es2panda/compiler/core/envScope.cpp | 16 +++++++++++++++- es2panda/compiler/core/pandagen.cpp | 9 ++++----- es2panda/compiler/core/pandagen.h | 2 +- 5 files changed, 51 insertions(+), 7 deletions(-) diff --git a/es2panda/binder/scope.cpp b/es2panda/binder/scope.cpp index 402bdd7a0c..dbacd4525f 100644 --- a/es2panda/binder/scope.cpp +++ b/es2panda/binder/scope.cpp @@ -78,6 +78,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/compiler/base/hoisting.cpp b/es2panda/compiler/base/hoisting.cpp index 07621e8d63..9666283a41 100644 --- a/es2panda/compiler/base/hoisting.cpp +++ b/es2panda/compiler/base/hoisting.cpp @@ -31,6 +31,20 @@ static void HoistVar(PandaGen *pg, binder::Variable *var, const binder::VarDecl return; } + auto *iter = scope; + while (iter) { + if (iter->IsFunctionVariableScope()) { + break; + } + iter = iter->Parent(); + } + const auto *funcScope = iter->AsFunctionVariableScope(); + for (auto *param : funcScope->ParamScope()->Params()) { + if (param->Name() == 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..779282ae1b 100644 --- a/es2panda/compiler/core/envScope.cpp +++ b/es2panda/compiler/core/envScope.cpp @@ -77,8 +77,22 @@ void LoopEnvScope::CopyPetIterationCtx() return; } - pg_->CopyLexEnv(scope_->Node()); + auto num = scope_->LexicalSlots(); + RegScope rs(pg_); + std::vector lexicals{}; + 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_->CopyLexEnv(scope_->Node(), num); pg_->StoreAccumulator(scope_->Node(), lexEnv_); + + for (uint32_t i = 0; i < num; i++) { + pg_->LoadAccumulator(scope_->Node(), lexicals[i]); + pg_->StoreLexicalVar(scope_->Node(), 0, i); + } } } // namespace panda::es2panda::compiler diff --git a/es2panda/compiler/core/pandagen.cpp b/es2panda/compiler/core/pandagen.cpp index 7cf1bb96f5..9bfb3f8d82 100644 --- a/es2panda/compiler/core/pandagen.cpp +++ b/es2panda/compiler/core/pandagen.cpp @@ -1479,12 +1479,11 @@ void PandaGen::PopLexEnv(const ir::AstNode *node) sa_.Emit(node); } -void PandaGen::CopyLexEnv(const ir::AstNode *node) +void PandaGen::CopyLexEnv(const ir::AstNode *node, uint32_t num) { - /* - * TODO: copy lexenv - * sa_.Emit(node); - */ + PopLexEnv(node); + NewLexEnv(node, num); + // TODO: optimize this part later } void PandaGen::NewLexEnv(const ir::AstNode *node, uint32_t num) diff --git a/es2panda/compiler/core/pandagen.h b/es2panda/compiler/core/pandagen.h index 77d127c423..09c82a1a82 100644 --- a/es2panda/compiler/core/pandagen.h +++ b/es2panda/compiler/core/pandagen.h @@ -344,7 +344,7 @@ public: void LdLexEnv(const ir::AstNode *node); void PopLexEnv(const ir::AstNode *node); - void CopyLexEnv(const ir::AstNode *node); + void CopyLexEnv(const ir::AstNode *node, uint32_t num); 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); -- Gitee