diff --git a/es2panda/binder/binder.cpp b/es2panda/binder/binder.cpp index 0d2fd97b87f69bb69448c3bfcb0de0f38c478e55..cb2ea78f19e0d88c2549716d61541af5c431e98e 100644 --- a/es2panda/binder/binder.cpp +++ b/es2panda/binder/binder.cpp @@ -415,7 +415,8 @@ void Binder::BuildForUpdateLoop(ir::ForUpdateStatement *forUpdateStmt) { auto *loopScope = forUpdateStmt->Scope(); - auto declScopeCtx = LexicalScope::Enter(this, loopScope->DeclScope()); + // auto declScopeCtx = LexicalScope::Enter(this, loopScope->DeclScope()); + auto loopCtx = LexicalScope::Enter(this, loopScope); if (forUpdateStmt->Init()) { ResolveReference(forUpdateStmt, forUpdateStmt->Init()); @@ -425,7 +426,7 @@ void Binder::BuildForUpdateLoop(ir::ForUpdateStatement *forUpdateStmt) ResolveReference(forUpdateStmt, forUpdateStmt->Update()); } - auto loopCtx = LexicalScope::Enter(this, loopScope); + // auto loopCtx = LexicalScope::Enter(this, loopScope); if (forUpdateStmt->Test()) { ResolveReference(forUpdateStmt, forUpdateStmt->Test()); @@ -439,12 +440,13 @@ void Binder::BuildForUpdateLoop(ir::ForUpdateStatement *forUpdateStmt) void Binder::BuildForInOfLoop(const ir::Statement *parent, binder::LoopScope *loopScope, ir::AstNode *left, ir::Expression *right, ir::Statement *body) { - auto declScopeCtx = LexicalScope::Enter(this, loopScope->DeclScope()); + // auto declScopeCtx = LexicalScope::Enter(this, loopScope->DeclScope()); + auto loopCtx = LexicalScope::Enter(this, loopScope); ResolveReference(parent, right); ResolveReference(parent, left); - auto loopCtx = LexicalScope::Enter(this, loopScope); + // auto loopCtx = LexicalScope::Enter(this, loopScope); ResolveReference(parent, body); loopCtx.GetScope()->ConvertToVariableScope(Allocator()); diff --git a/es2panda/binder/scope.cpp b/es2panda/binder/scope.cpp index 63e1295967f3da73a975ff76f34261c37b79141f..cf1cedaaf562704e2c802883d7f53310ebb24cb3 100644 --- a/es2panda/binder/scope.cpp +++ b/es2panda/binder/scope.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -454,26 +455,29 @@ void LoopDeclarationScope::ConvertToVariableScope(ArenaAllocator *allocator) } } -void LoopScope::ConvertToVariableScope(ArenaAllocator *allocator) +void LoopScope::ConvertToVariableScope([[maybe_unused]] ArenaAllocator *allocator) { - declScope_->ConvertToVariableScope(allocator); - - if (loopType_ != ScopeType::LOCAL) { - return; - } - - for (const auto &[_, var] : bindings_) { - (void)_; - if (var->LexicalBound() && var->Declaration()->IsLetDecl()) { - ASSERT(declScope_->NeedLexEnv()); - loopType_ = ScopeType::LOOP; - break; - } - } - - if (loopType_ == ScopeType::LOOP) { - slotIndex_ = std::max(slotIndex_, declScope_->LexicalSlots()); + for (auto &[name, var] : bindings_) { + var->AddFlag(VariableFlags::INITIALIZED | VariableFlags::PER_ITERATION); } + // declScope_->ConvertToVariableScope(allocator); + + // if (loopType_ != ScopeType::LOCAL) { + // return; + // } + + // for (const auto &[_, var] : bindings_) { + // (void)_; + // if (var->LexicalBound() && var->Declaration()->IsLetDecl()) { + // ASSERT(declScope_->NeedLexEnv()); + // loopType_ = ScopeType::LOOP; + // break; + // } + // } + + // if (loopType_ == ScopeType::LOOP) { + // slotIndex_ = std::max(slotIndex_, declScope_->LexicalSlots()); + // } } bool CatchParamScope::AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, diff --git a/es2panda/binder/scope.h b/es2panda/binder/scope.h index 29c03a3297ca0c4a9603c581b36bd91ddb7eab68..33b9d0796272c21abe5cfb2a43191e8cc4628120 100644 --- a/es2panda/binder/scope.h +++ b/es2panda/binder/scope.h @@ -679,23 +679,23 @@ class LoopScope : public VariableScope { public: explicit LoopScope(ArenaAllocator *allocator, Scope *parent) : VariableScope(allocator, parent) {} - LoopDeclarationScope *DeclScope() - { - return declScope_; - } + // LoopDeclarationScope *DeclScope() + // { + // return declScope_; + // } - void BindDecls(LoopDeclarationScope *declScope) - { - declScope_ = declScope; - declScope_->loopScope_ = this; - } + // void BindDecls(LoopDeclarationScope *declScope) + // { + // declScope_ = declScope; + // declScope_->loopScope_ = this; + // } ScopeType Type() const override { return loopType_; } - void ConvertToVariableScope(ArenaAllocator *allocator); + void ConvertToVariableScope([[maybe_unused]] ArenaAllocator *allocator); bool AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, [[maybe_unused]] ScriptExtension extension) override @@ -704,8 +704,8 @@ public: } protected: - LoopDeclarationScope *declScope_ {}; - ScopeType loopType_ {ScopeType::LOCAL}; + // LoopDeclarationScope *declScope_ {}; + ScopeType loopType_ {ScopeType::LOOP}; }; class GlobalScope : public FunctionScope { diff --git a/es2panda/binder/variable.cpp b/es2panda/binder/variable.cpp index 0539c9ccc5c0648abfe147207c4e3d992eb9887d..3d90fda7fee0abab72f32e56c5057a0144c44d9d 100644 --- a/es2panda/binder/variable.cpp +++ b/es2panda/binder/variable.cpp @@ -49,7 +49,6 @@ void LocalVariable::SetLexical(Scope *scope, util::Hotfix *hotfixHelper) VariableScope *varScope = scope->EnclosingVariableScope(); uint32_t slot = 0; auto name = Declaration()->Name(); - if (hotfixHelper && hotfixHelper->IsScopeValidToPatchLexical(varScope)) { slot = hotfixHelper->GetSlotIdFromSymbolTable(std::string(name)); if (hotfixHelper->IsPatchVar(slot)) { diff --git a/es2panda/compiler/core/envScope.cpp b/es2panda/compiler/core/envScope.cpp index 6cb007c87e5599bda9ef68b52009c49f28edf250..3f729bf3981deb57a0d097ceaec4371a8806a2f1 100644 --- a/es2panda/compiler/core/envScope.cpp +++ b/es2panda/compiler/core/envScope.cpp @@ -58,15 +58,15 @@ void LoopEnvScope::CopyBindings(PandaGen *pg, binder::VariableScope *scope, bind ASSERT(scope->NeedLexEnv()); - for (const auto &[_, variable] : scope_->Bindings()) { - (void)_; - if (!variable->HasFlag(flag)) { - continue; - } - - pg->LoadLexicalVar(scope_->Node(), 1, variable->AsLocalVariable()->LexIdx()); - pg->StoreLexicalVar(scope_->Parent()->Node(), 0, variable->AsLocalVariable()->LexIdx()); - } + // for (const auto &[_, variable] : scope_->Bindings()) { + // (void)_; + // if (!variable->HasFlag(flag)) { + // continue; + // } + + // pg->LoadLexicalVar(scope_->Node(), 1, variable->AsLocalVariable()->LexIdx()); + // pg->StoreLexicalVar(scope_->Parent()->Node(), 0, variable->AsLocalVariable()->LexIdx()); + // } } void LoopEnvScope::CopyPetIterationCtx() diff --git a/es2panda/compiler/core/envScope.h b/es2panda/compiler/core/envScope.h index a21c2a3e52022a8ec6e51467b395d410cda5f5e8..928357adee4d74550a058412a84af2857e7e88ba 100644 --- a/es2panda/compiler/core/envScope.h +++ b/es2panda/compiler/core/envScope.h @@ -68,20 +68,38 @@ protected: class LoopEnvScope : public EnvScope { public: + // explicit LoopEnvScope(PandaGen *pg, binder::LoopScope *scope, LabelTarget target) + // : scope_(NeedEnv(scope) ? scope : nullptr), regScope_(pg, scope), lexEnvCtx_(this, pg, target) + // { + // CopyBindings(pg, scope, binder::VariableFlags::PER_ITERATION); + // } + + // explicit LoopEnvScope(PandaGen *pg, LabelTarget target, binder::LoopScope *scope) + // : scope_(NeedEnv(scope) ? scope : nullptr), regScope_(pg), lexEnvCtx_(this, pg, target) + // { + // CopyBindings(pg, scope, binder::VariableFlags::PER_ITERATION); + // } + + // explicit LoopEnvScope(PandaGen *pg, binder::LoopDeclarationScope *scope) + // : scope_(NeedEnv(scope) ? scope : nullptr), regScope_(pg), lexEnvCtx_(this, pg, {}) + // { + // CopyBindings(pg, scope, binder::VariableFlags::LOOP_DECL); + // } + explicit LoopEnvScope(PandaGen *pg, binder::LoopScope *scope, LabelTarget target) - : scope_(NeedEnv(scope) ? scope : nullptr), regScope_(pg, scope), lexEnvCtx_(this, pg, target) + : scope_(NeedEnv(scope) ? scope : nullptr), lexEnvCtx_(this, pg, target) { CopyBindings(pg, scope, binder::VariableFlags::PER_ITERATION); } explicit LoopEnvScope(PandaGen *pg, LabelTarget target, binder::LoopScope *scope) - : scope_(NeedEnv(scope) ? scope : nullptr), regScope_(pg), lexEnvCtx_(this, pg, target) + : scope_(NeedEnv(scope) ? scope : nullptr), lexEnvCtx_(this, pg, target) { CopyBindings(pg, scope, binder::VariableFlags::PER_ITERATION); } explicit LoopEnvScope(PandaGen *pg, binder::LoopDeclarationScope *scope) - : scope_(NeedEnv(scope) ? scope : nullptr), regScope_(pg), lexEnvCtx_(this, pg, {}) + : scope_(NeedEnv(scope) ? scope : nullptr), lexEnvCtx_(this, pg, {}) { CopyBindings(pg, scope, binder::VariableFlags::LOOP_DECL); } @@ -108,7 +126,7 @@ private: void CopyBindings(PandaGen *pg, binder::VariableScope *scope, binder::VariableFlags flag); binder::VariableScope *scope_ {}; - LocalRegScope regScope_; + // LocalRegScope regScope_; LexEnvContext lexEnvCtx_; }; diff --git a/es2panda/ir/statements/forInStatement.cpp b/es2panda/ir/statements/forInStatement.cpp index 2ccad0cb65b5ab4b604d5b7d8bebceaf453e9a21..6f948f4eaa7cfe26bb0086b7098735728b3f4685 100644 --- a/es2panda/ir/statements/forInStatement.cpp +++ b/es2panda/ir/statements/forInStatement.cpp @@ -59,13 +59,13 @@ void ForInStatement::Compile(compiler::PandaGen *pg) const pg->StoreAccumulator(this, propName); pg->BranchIfUndefined(this, labelTarget.BreakTarget()); - compiler::LocalRegScope declRegScope(pg, scope_->DeclScope()->InitScope()); + compiler::LocalRegScope declRegScope(pg, scope_); auto lref = compiler::LReference::CreateLRef(pg, left_, false); pg->LoadAccumulator(this, propName); lref.SetValue(); { - compiler::LoopEnvScope declEnvScope(pg, scope_->DeclScope()); + // compiler::LoopEnvScope declEnvScope(pg, scope_->DeclScope()); compiler::LoopEnvScope envScope(pg, scope_, labelTarget); body_->Compile(pg); } @@ -82,11 +82,12 @@ checker::Type *ForInStatement::Check([[maybe_unused]] checker::Checker *checker) void ForInStatement::UpdateSelf(const NodeUpdater &cb, binder::Binder *binder) { auto *loopScope = Scope(); - auto declScopeCtx = binder::LexicalScope::Enter(binder, loopScope->DeclScope()); + // auto declScopeCtx = binder::LexicalScope::Enter(binder, loopScope->DeclScope()); + auto loopCtx = binder::LexicalScope::Enter(binder, loopScope); left_ = std::get(cb(left_)); right_ = std::get(cb(right_))->AsExpression(); - auto loopCtx = binder::LexicalScope::Enter(binder, loopScope); + // auto loopCtx = binder::LexicalScope::Enter(binder, loopScope); body_ = std::get(cb(body_))->AsStatement(); } diff --git a/es2panda/ir/statements/forOfStatement.cpp b/es2panda/ir/statements/forOfStatement.cpp index f653ce3108ac2cc371a09d90282e7fe8e5eadf8b..c606d9889e9e461b21cd0119ae30c3d04e361264 100644 --- a/es2panda/ir/statements/forOfStatement.cpp +++ b/es2panda/ir/statements/forOfStatement.cpp @@ -39,36 +39,72 @@ void ForOfStatement::Dump(ir::AstDumper *dumper) const dumper->Add({{"type", "ForOfStatement"}, {"await", isAwait_}, {"left", left_}, {"right", right_}, {"body", body_}}); } -void ForOfStatement::Compile(compiler::PandaGen *pg) const -{ - compiler::LocalRegScope declRegScope(pg, scope_->DeclScope()->InitScope()); +// void ForOfStatement::Compile(compiler::PandaGen *pg) const +// { +// compiler::LocalRegScope regScope(pg, scope_); - right_->Compile(pg); +// right_->Compile(pg); - compiler::LabelTarget labelTarget(pg); - auto iterator_type = isAwait_ ? compiler::IteratorType::ASYNC : compiler::IteratorType::SYNC; - compiler::Iterator iterator(pg, this, iterator_type); +// compiler::LabelTarget labelTarget(pg); +// auto iterator_type = isAwait_ ? compiler::IteratorType::ASYNC : compiler::IteratorType::SYNC; +// compiler::Iterator iterator(pg, this, iterator_type); - pg->SetLabel(this, labelTarget.ContinueTarget()); +// pg->SetLabel(this, labelTarget.ContinueTarget()); - iterator.Next(); - iterator.Complete(); - pg->BranchIfTrue(this, labelTarget.BreakTarget()); +// iterator.Next(); +// iterator.Complete(); +// pg->BranchIfTrue(this, labelTarget.BreakTarget()); - compiler::VReg value = pg->AllocReg(); - iterator.Value(); - pg->StoreAccumulator(this, value); +// compiler::VReg value = pg->AllocReg(); +// iterator.Value(); +// pg->StoreAccumulator(this, value); - auto lref = compiler::LReference::CreateLRef(pg, left_, false); +// auto lref = compiler::LReference::CreateLRef(pg, left_, false); - { - compiler::IteratorContext forOfCtx(pg, iterator, labelTarget); - pg->LoadAccumulator(this, value); - lref.SetValue(); +// { +// compiler::IteratorContext forOfCtx(pg, iterator, labelTarget); +// pg->LoadAccumulator(this, value); +// lref.SetValue(); + +// // compiler::LoopEnvScope declEnvScope(pg, scope_->DeclScope()); +// compiler::LoopEnvScope envScope(pg, scope_, {}); +// body_->Compile(pg); +// } - compiler::LoopEnvScope declEnvScope(pg, scope_->DeclScope()); +// pg->Branch(this, labelTarget.ContinueTarget()); +// pg->SetLabel(this, labelTarget.BreakTarget()); +// } + +void ForOfStatement::Compile(compiler::PandaGen *pg) const +{ + compiler::LocalRegScope regScope(pg, scope_); + compiler::LabelTarget labelTarget(pg); + { compiler::LoopEnvScope envScope(pg, scope_, {}); - body_->Compile(pg); + + right_->Compile(pg); + + auto iterator_type = isAwait_ ? compiler::IteratorType::ASYNC : compiler::IteratorType::SYNC; + compiler::Iterator iterator(pg, this, iterator_type); + + pg->SetLabel(this, labelTarget.ContinueTarget()); + + iterator.Next(); + iterator.Complete(); + pg->BranchIfTrue(this, labelTarget.BreakTarget()); + + compiler::VReg value = pg->AllocReg(); + iterator.Value(); + pg->StoreAccumulator(this, value); + + auto lref = compiler::LReference::CreateLRef(pg, left_, false); + { + compiler::IteratorContext forOfCtx(pg, iterator, labelTarget); + pg->LoadAccumulator(this, value); + lref.SetValue(); + + body_->Compile(pg); + } } pg->Branch(this, labelTarget.ContinueTarget()); @@ -83,11 +119,12 @@ checker::Type *ForOfStatement::Check([[maybe_unused]] checker::Checker *checker) void ForOfStatement::UpdateSelf(const NodeUpdater &cb, binder::Binder *binder) { auto *loopScope = Scope(); - auto declScopeCtx = binder::LexicalScope::Enter(binder, loopScope->DeclScope()); + // auto declScopeCtx = binder::LexicalScope::Enter(binder, loopScope->DeclScope()); + auto loopCtx = binder::LexicalScope::Enter(binder, loopScope); left_ = std::get(cb(left_)); right_ = std::get(cb(right_))->AsExpression(); - auto loopCtx = binder::LexicalScope::Enter(binder, loopScope); + // auto loopCtx = binder::LexicalScope::Enter(binder, loopScope); body_ = std::get(cb(body_))->AsStatement(); } diff --git a/es2panda/ir/statements/forUpdateStatement.cpp b/es2panda/ir/statements/forUpdateStatement.cpp index d6275d9817170a63e6a7ffccbea43dc86a7f47e5..9931e536ef0b5e3d612f6808528e2d685cc66986 100644 --- a/es2panda/ir/statements/forUpdateStatement.cpp +++ b/es2panda/ir/statements/forUpdateStatement.cpp @@ -54,7 +54,8 @@ void ForUpdateStatement::Dump(ir::AstDumper *dumper) const void ForUpdateStatement::Compile(compiler::PandaGen *pg) const { - compiler::LocalRegScope declRegScope(pg, scope_->DeclScope()->InitScope()); + // compiler::LocalRegScope declRegScope(pg, scope_->DeclScope()->InitScope()); + compiler::LocalRegScope regScope(pg, scope_); if (init_) { ASSERT(init_->IsVariableDeclaration() || init_->IsExpression()); @@ -64,12 +65,12 @@ void ForUpdateStatement::Compile(compiler::PandaGen *pg) const auto *startLabel = pg->AllocLabel(); compiler::LabelTarget labelTarget(pg); - compiler::LoopEnvScope declEnvScope(pg, scope_->DeclScope()); + // compiler::LoopEnvScope declEnvScope(pg, scope_->DeclScope()); compiler::LoopEnvScope envScope(pg, labelTarget, scope_); pg->SetLabel(this, startLabel); { - compiler::LocalRegScope regScope(pg, scope_); + // compiler::LocalRegScope regScope(pg, scope_); if (test_) { compiler::Condition::Compile(pg, test_, labelTarget.BreakTarget()); @@ -113,7 +114,8 @@ checker::Type *ForUpdateStatement::Check(checker::Checker *checker) const void ForUpdateStatement::UpdateSelf(const NodeUpdater &cb, binder::Binder *binder) { auto *loopScope = Scope(); - auto declScopeCtx = binder::LexicalScope::Enter(binder, loopScope->DeclScope()); + // auto declScopeCtx = binder::LexicalScope::Enter(binder, loopScope->DeclScope()); + auto loopCtx = binder::LexicalScope::Enter(binder, loopScope); if (init_) { init_ = std::get(cb(init_)); @@ -123,7 +125,7 @@ void ForUpdateStatement::UpdateSelf(const NodeUpdater &cb, binder::Binder *binde test_ = std::get(cb(test_))->AsExpression(); } - auto loopCtx = binder::LexicalScope::Enter(binder, loopScope); + // auto loopCtx = binder::LexicalScope::Enter(binder, loopScope); if (update_) { update_ = std::get(cb(update_))->AsExpression(); diff --git a/es2panda/parser/statementParser.cpp b/es2panda/parser/statementParser.cpp index b9c73c0ad85f75fccc6d04d60996a78efc32f5c3..6e996362c66c507e14ca74811764097524b24e07 100644 --- a/es2panda/parser/statementParser.cpp +++ b/es2panda/parser/statementParser.cpp @@ -1453,7 +1453,8 @@ ir::Statement *ParserImpl::ParseForStatement() } lexer_->NextToken(); - auto declCtx = binder::LexicalScope(Binder()); + // auto declCtx = binder::LexicalScope(Binder()); + IterationContext iterCtx(&context_, Binder()); switch (lexer_->GetToken().Type()) { case lexer::TokenType::KEYW_VAR: { @@ -1485,8 +1486,8 @@ ir::Statement *ParserImpl::ParseForStatement() } } - IterationContext iterCtx(&context_, Binder()); - iterCtx.LexicalScope().GetScope()->BindDecls(declCtx.GetScope()); + // IterationContext iterCtx(&context_, Binder()); + // iterCtx.LexicalScope().GetScope()->BindDecls(declCtx.GetScope()); if (initNode != nullptr) { if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) { @@ -1529,7 +1530,7 @@ ir::Statement *ParserImpl::ParseForStatement() forStatement->SetRange({startLoc, endLoc}); loopScope->BindNode(forStatement); - loopScope->DeclScope()->BindNode(forStatement); + // loopScope->DeclScope()->BindNode(forStatement); return forStatement; }