diff --git a/es2panda/binder/scope.cpp b/es2panda/binder/scope.cpp index 402bdd7a0c77989d8eb0451300936e38afe78d8d..dbacd4525fb13b704aab47411613abc6ab9c6a2a 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 07621e8d630c5793019c81bf2641fc2da9f5b9e2..9666283a418d152002ca2814f253595613ad3a78 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 6e2fa13c78c7038bb1a0d4e2a0eb7405af141868..779282ae1b0a332cda33cd527cc9fc66d2133fcf 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 7cf1bb96f5a871e58b477d4779e57ce2b7ebc416..9bfb3f8d8256f2c05e43930ec8a7d9b10051640e 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 77d127c423840d623295924523c4544345361cbb..09c82a1a8274f703b493bfbd171c7f2c1605ac09 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);