diff --git a/es2panda/binder/binder.cpp b/es2panda/binder/binder.cpp index 1c6f0022a76f4dedfab7b15aeb9d13e7f47fc929..ac8ad439c7d16c36566fe730fd226362486d334f 100644 --- a/es2panda/binder/binder.cpp +++ b/es2panda/binder/binder.cpp @@ -399,7 +399,7 @@ void Binder::BuildForUpdateLoop(ir::ForUpdateStatement *forUpdateStmt) { auto *loopScope = forUpdateStmt->Scope(); - auto declScopeCtx = LexicalScope::Enter(this, loopScope->DeclScope()); + auto loopCtx = LexicalScope::Enter(this, loopScope); if (forUpdateStmt->Init()) { ResolveReference(forUpdateStmt, forUpdateStmt->Init()); @@ -409,29 +409,25 @@ void Binder::BuildForUpdateLoop(ir::ForUpdateStatement *forUpdateStmt) ResolveReference(forUpdateStmt, forUpdateStmt->Update()); } - auto loopCtx = LexicalScope::Enter(this, loopScope); - if (forUpdateStmt->Test()) { ResolveReference(forUpdateStmt, forUpdateStmt->Test()); } ResolveReference(forUpdateStmt, forUpdateStmt->Body()); - loopCtx.GetScope()->ConvertToVariableScope(Allocator()); + loopCtx.GetScope()->InitVariable(); } 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 loopCtx = LexicalScope::Enter(this, loopScope); ResolveReference(parent, right); ResolveReference(parent, left); - auto loopCtx = LexicalScope::Enter(this, loopScope); - ResolveReference(parent, body); - loopCtx.GetScope()->ConvertToVariableScope(Allocator()); + loopCtx.GetScope()->InitVariable(); } void Binder::BuildCatchClause(ir::CatchClause *catchClauseStmt) diff --git a/es2panda/binder/scope.cpp b/es2panda/binder/scope.cpp index 696521f1887da45376ff38bcfe1baf3a1ac91e21..609f762cb8e20fd64f81a1372776bee0c8a8aee0 100644 --- a/es2panda/binder/scope.cpp +++ b/es2panda/binder/scope.cpp @@ -110,6 +110,8 @@ ScopeFindResult Scope::Find(const util::StringView &name, ResolveBindingOptions iter = iter->Parent(); } + bool lexical = false; + while (iter != nullptr) { Variable *v = iter->FindLocal(name, options); @@ -117,8 +119,14 @@ ScopeFindResult Scope::Find(const util::StringView &name, ResolveBindingOptions return {name, const_cast(iter), level, lexLevel, v}; } + if (iter->IsFunctionVariableScope() && !lexical) { + lexical = true; + } + if (iter->IsVariableScope()) { - level++; + if (lexical) { + level++; + } if (iter->AsVariableScope()->NeedLexEnv()) { lexLevel++; @@ -436,53 +444,18 @@ bool LocalScope::AddBinding(ArenaAllocator *allocator, Variable *currentVariable return AddLocal(allocator, currentVariable, newDecl, extension); } -void LoopDeclarationScope::ConvertToVariableScope(ArenaAllocator *allocator) +void LoopScope::InitVariable() { - if (NeedLexEnv()) { - return; - } - - for (auto &[name, var] : bindings_) { - if (!var->LexicalBound() || !var->Declaration()->IsLetOrConstOrClassDecl()) { + for (const auto &[name, var] : bindings_) { + if (!var->Declaration()->IsLetOrConstOrClassDecl()) { continue; } - slotIndex_++; - loopType_ = ScopeType::LOOP_DECL; - auto *copiedVar = var->AsLocalVariable()->Copy(allocator, var->Declaration()); - copiedVar->AddFlag(VariableFlags::INITIALIZED | VariableFlags::PER_ITERATION); - var->AddFlag(VariableFlags::LOOP_DECL); - loopScope_->Bindings().insert({name, copiedVar}); - } - - if (loopType_ == ScopeType::LOOP_DECL) { - slotIndex_ = std::max(slotIndex_, parent_->EnclosingVariableScope()->LexicalSlots()); - initScope_ = allocator->New(allocator, parent_); - initScope_->BindNode(node_); - initScope_->Bindings() = bindings_; - } -} - -void LoopScope::ConvertToVariableScope(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; + var->AddFlag(VariableFlags::INITIALIZED); + if (var->LexicalBound()) { + var->AddFlag(VariableFlags::PER_ITERATION); } } - - 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 70be5ce9a70b62060ee50a843eb4bf1fcdc7fb26..00031885887dd172e1e6282beb7abe0a98db70f9 100644 --- a/es2panda/binder/scope.h +++ b/es2panda/binder/scope.h @@ -635,62 +635,18 @@ public: [[maybe_unused]] ScriptExtension extension) override; }; -class LoopScope; - -class LoopDeclarationScope : public VariableScope { -public: - explicit LoopDeclarationScope(ArenaAllocator *allocator, Scope *parent) : VariableScope(allocator, parent) {} - - ScopeType Type() const override - { - return loopType_; - } - - bool AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, - [[maybe_unused]] ScriptExtension extension) override - { - return AddLocal(allocator, currentVariable, newDecl, extension); - } - - Scope *InitScope() - { - if (NeedLexEnv()) { - return initScope_; - } - - return this; - } - - void ConvertToVariableScope(ArenaAllocator *allocator); - -private: - friend class LoopScope; - LoopScope *loopScope_ {}; - LocalScope *initScope_ {}; - ScopeType loopType_ {ScopeType::LOCAL}; -}; - class LoopScope : public VariableScope { public: explicit LoopScope(ArenaAllocator *allocator, Scope *parent) : VariableScope(allocator, parent) {} - LoopDeclarationScope *DeclScope() - { - return declScope_; - } - - 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); + + void InitVariable(); bool AddBinding(ArenaAllocator *allocator, Variable *currentVariable, Decl *newDecl, [[maybe_unused]] ScriptExtension extension) override @@ -699,8 +655,7 @@ public: } protected: - LoopDeclarationScope *declScope_ {}; - ScopeType loopType_ {ScopeType::LOCAL}; + ScopeType loopType_ {ScopeType::LOOP}; }; class GlobalScope : public FunctionScope { diff --git a/es2panda/compiler/core/envScope.cpp b/es2panda/compiler/core/envScope.cpp index 6cb007c87e5599bda9ef68b52009c49f28edf250..aa3e98344a8b732ed722d99c151615de6372f716 100644 --- a/es2panda/compiler/core/envScope.cpp +++ b/es2panda/compiler/core/envScope.cpp @@ -46,30 +46,18 @@ EnvScope::~EnvScope() pg_->envScope_ = prev_; } -void LoopEnvScope::CopyBindings(PandaGen *pg, binder::VariableScope *scope, binder::VariableFlags flag) +void LoopEnvScope::InitLoopContext(PandaGen *pg, binder::VariableScope *scope) { if (!HasEnv()) { return; } Initialize(pg); - - pg_->NewLexicalEnv(scope_->Node(), scope->LexicalSlots(), scope_); - 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()); - } + pg_->NewLexicalEnv(scope_->Node(), scope->LexicalSlots(), scope_); } -void LoopEnvScope::CopyPetIterationCtx() +void LoopEnvScope::CopyPerIterationCtx() { if (!HasEnv()) { return; diff --git a/es2panda/compiler/core/envScope.h b/es2panda/compiler/core/envScope.h index a21c2a3e52022a8ec6e51467b395d410cda5f5e8..29faecfc9f3bcee5c5298b16bd8cad66ac4d30d8 100644 --- a/es2panda/compiler/core/envScope.h +++ b/es2panda/compiler/core/envScope.h @@ -71,19 +71,13 @@ 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); + InitLoopContext(pg, scope); } 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); + InitLoopContext(pg, scope); } binder::VariableScope *Scope() const @@ -97,7 +91,7 @@ public: return scope_ != nullptr; } - void CopyPetIterationCtx(); + void CopyPerIterationCtx(); private: static bool NeedEnv(binder::VariableScope *scope) @@ -107,6 +101,8 @@ private: void CopyBindings(PandaGen *pg, binder::VariableScope *scope, binder::VariableFlags flag); + void InitLoopContext(PandaGen *pg, binder::VariableScope *scope); + binder::VariableScope *scope_ {}; LocalRegScope regScope_; LexEnvContext lexEnvCtx_; diff --git a/es2panda/ir/statements/forInStatement.cpp b/es2panda/ir/statements/forInStatement.cpp index 2ccad0cb65b5ab4b604d5b7d8bebceaf453e9a21..512f9ca8f2a7e815f7ae2e47db6ee595a13c33e3 100644 --- a/es2panda/ir/statements/forInStatement.cpp +++ b/es2panda/ir/statements/forInStatement.cpp @@ -41,9 +41,11 @@ void ForInStatement::Dump(ir::AstDumper *dumper) const void ForInStatement::Compile(compiler::PandaGen *pg) const { - compiler::LabelTarget labelTarget(pg); + if (scope_->NeedLexEnv()) { + pg->NewLexEnv(this, scope_->LexicalSlots()); + } - compiler::RegScope rs(pg); + compiler::LocalRegScope loopRegScope(pg, scope_); compiler::VReg iter = pg->AllocReg(); compiler::VReg propName = pg->AllocReg(); @@ -52,6 +54,12 @@ void ForInStatement::Compile(compiler::PandaGen *pg) const pg->GetPropIterator(this); pg->StoreAccumulator(this, iter); + if (scope_->NeedLexEnv()) { + pg->PopLexEnv(this); + } + + compiler::LabelTarget labelTarget(pg); + // loop start pg->SetLabel(this, labelTarget.ContinueTarget()); // get next prop of enumerator @@ -59,14 +67,11 @@ void ForInStatement::Compile(compiler::PandaGen *pg) const pg->StoreAccumulator(this, propName); pg->BranchIfUndefined(this, labelTarget.BreakTarget()); - compiler::LocalRegScope declRegScope(pg, scope_->DeclScope()->InitScope()); auto lref = compiler::LReference::CreateLRef(pg, left_, false); - pg->LoadAccumulator(this, propName); - lref.SetValue(); - { - compiler::LoopEnvScope declEnvScope(pg, scope_->DeclScope()); compiler::LoopEnvScope envScope(pg, scope_, labelTarget); + pg->LoadAccumulator(this, propName); + lref.SetValue(); body_->Compile(pg); } @@ -82,11 +87,10 @@ 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 loopCtx = binder::LexicalScope::Enter(binder, loopScope); left_ = std::get(cb(left_)); right_ = std::get(cb(right_))->AsExpression(); - 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..d492fb48cca00dc9662846af65e373c283c16152 100644 --- a/es2panda/ir/statements/forOfStatement.cpp +++ b/es2panda/ir/statements/forOfStatement.cpp @@ -41,9 +41,17 @@ void ForOfStatement::Dump(ir::AstDumper *dumper) const void ForOfStatement::Compile(compiler::PandaGen *pg) const { - compiler::LocalRegScope declRegScope(pg, scope_->DeclScope()->InitScope()); + compiler::LocalRegScope regScope(pg, scope_); - right_->Compile(pg); + if (scope_->NeedLexEnv()) { + pg->NewLexEnv(this, scope_->LexicalSlots()); + } + + right_->Compile(pg); // if poplexenv next, acc will not be affected, no need to store the value to a vreg + + if (scope_->NeedLexEnv()) { + pg->PopLexEnv(this); + } compiler::LabelTarget labelTarget(pg); auto iterator_type = isAwait_ ? compiler::IteratorType::ASYNC : compiler::IteratorType::SYNC; @@ -60,14 +68,12 @@ void ForOfStatement::Compile(compiler::PandaGen *pg) const pg->StoreAccumulator(this, value); auto lref = compiler::LReference::CreateLRef(pg, left_, false); - { compiler::IteratorContext forOfCtx(pg, iterator, labelTarget); + compiler::LoopEnvScope envScope(pg, scope_, {}); pg->LoadAccumulator(this, value); lref.SetValue(); - compiler::LoopEnvScope declEnvScope(pg, scope_->DeclScope()); - compiler::LoopEnvScope envScope(pg, scope_, {}); body_->Compile(pg); } @@ -83,11 +89,10 @@ 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 loopCtx = binder::LexicalScope::Enter(binder, loopScope); left_ = std::get(cb(left_)); right_ = std::get(cb(right_))->AsExpression(); - 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..278cf6a1e258f7aa4391e8ea9f8b5720ff2c116c 100644 --- a/es2panda/ir/statements/forUpdateStatement.cpp +++ b/es2panda/ir/statements/forUpdateStatement.cpp @@ -54,7 +54,9 @@ void ForUpdateStatement::Dump(ir::AstDumper *dumper) const void ForUpdateStatement::Compile(compiler::PandaGen *pg) const { - compiler::LocalRegScope declRegScope(pg, scope_->DeclScope()->InitScope()); + compiler::LocalRegScope loopRegScope(pg, scope_); + compiler::LabelTarget labelTarget(pg); + compiler::LoopEnvScope envScope(pg, labelTarget, scope_); if (init_) { ASSERT(init_->IsVariableDeclaration() || init_->IsExpression()); @@ -62,22 +64,16 @@ void ForUpdateStatement::Compile(compiler::PandaGen *pg) const } auto *startLabel = pg->AllocLabel(); - compiler::LabelTarget labelTarget(pg); - - compiler::LoopEnvScope declEnvScope(pg, scope_->DeclScope()); - compiler::LoopEnvScope envScope(pg, labelTarget, scope_); pg->SetLabel(this, startLabel); { - compiler::LocalRegScope regScope(pg, scope_); - if (test_) { compiler::Condition::Compile(pg, test_, labelTarget.BreakTarget()); } body_->Compile(pg); pg->SetLabel(this, labelTarget.ContinueTarget()); - envScope.CopyPetIterationCtx(); + envScope.CopyPerIterationCtx(); } if (update_) { @@ -113,7 +109,7 @@ 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 loopCtx = binder::LexicalScope::Enter(binder, loopScope); if (init_) { init_ = std::get(cb(init_)); @@ -123,8 +119,6 @@ void ForUpdateStatement::UpdateSelf(const NodeUpdater &cb, binder::Binder *binde test_ = std::get(cb(test_))->AsExpression(); } - 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 d32213d971df572ace95dd4eb2644f92b8feb5cb..04780aa0f4cc772fd305d04a782db56620f8d773 100644 --- a/es2panda/parser/statementParser.cpp +++ b/es2panda/parser/statementParser.cpp @@ -1353,7 +1353,7 @@ ir::Statement *ParserImpl::ParseForStatement() } lexer_->NextToken(); - auto declCtx = binder::LexicalScope(Binder()); + IterationContext iterCtx(&context_, Binder()); switch (lexer_->GetToken().Type()) { case lexer::TokenType::KEYW_VAR: { @@ -1385,9 +1385,6 @@ ir::Statement *ParserImpl::ParseForStatement() } } - IterationContext iterCtx(&context_, Binder()); - iterCtx.LexicalScope().GetScope()->BindDecls(declCtx.GetScope()); - if (initNode != nullptr) { if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) { lexer_->NextToken(); @@ -1429,7 +1426,6 @@ ir::Statement *ParserImpl::ParseForStatement() forStatement->SetRange({startLoc, endLoc}); loopScope->BindNode(forStatement); - loopScope->DeclScope()->BindNode(forStatement); return forStatement; } diff --git a/es2panda/test/compiler/js/lexEnv/forIn-loopEnv-test-1-expected.txt b/es2panda/test/compiler/js/lexEnv/forIn-loopEnv-test-1-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..41fc385ca1f4be981815c6cde40453d094fa158b --- /dev/null +++ b/es2panda/test/compiler/js/lexEnv/forIn-loopEnv-test-1-expected.txt @@ -0,0 +1,3 @@ +0 1,2,3 +1 1,2,3 +2 1,2,3 diff --git a/es2panda/test/compiler/js/lexEnv/forIn-loopEnv-test-1.js b/es2panda/test/compiler/js/lexEnv/forIn-loopEnv-test-1.js new file mode 100644 index 0000000000000000000000000000000000000000..361a247c8039c7117f5ee1db9cfd3cf07affc4c6 --- /dev/null +++ b/es2panda/test/compiler/js/lexEnv/forIn-loopEnv-test-1.js @@ -0,0 +1,12 @@ +{ + let a = [1, 2, 3]; + let b = []; + + for (let i in a) { + b.push(() => { + print(i, a); + }); + } + + b.forEach(f => f()); +} \ No newline at end of file diff --git a/es2panda/test/compiler/js/lexEnv/forIn-loopEnv-test-2-expected.txt b/es2panda/test/compiler/js/lexEnv/forIn-loopEnv-test-2-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..1daca51094e752d46927cd46490e2cc44140c1ad --- /dev/null +++ b/es2panda/test/compiler/js/lexEnv/forIn-loopEnv-test-2-expected.txt @@ -0,0 +1,3 @@ +1 1,2,3 +2 1,2,3 +3 1,2,3 diff --git a/es2panda/test/compiler/js/lexEnv/forIn-loopEnv-test-2.js b/es2panda/test/compiler/js/lexEnv/forIn-loopEnv-test-2.js new file mode 100644 index 0000000000000000000000000000000000000000..d798a1468ed30a30d3692e61befdb9e0680547b1 --- /dev/null +++ b/es2panda/test/compiler/js/lexEnv/forIn-loopEnv-test-2.js @@ -0,0 +1,13 @@ +{ + let a = [1, 2, 3]; + let b = []; + + for (let i in a) { + let j = a[i]; + b.push(() => { + print(j, a); + }); + } + + b.forEach(f => f()); +} \ No newline at end of file diff --git a/es2panda/test/compiler/js/lexEnv/forIn-loopEnv-test-3-expected.txt b/es2panda/test/compiler/js/lexEnv/forIn-loopEnv-test-3-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..fa374f014914d213d79736c71c2ffeb07553a53a --- /dev/null +++ b/es2panda/test/compiler/js/lexEnv/forIn-loopEnv-test-3-expected.txt @@ -0,0 +1,3 @@ +0 1 1,2,3 +1 2 1,2,3 +2 3 1,2,3 diff --git a/es2panda/test/compiler/js/lexEnv/forIn-loopEnv-test-3.js b/es2panda/test/compiler/js/lexEnv/forIn-loopEnv-test-3.js new file mode 100644 index 0000000000000000000000000000000000000000..fe18a4a31f797735401a76a6c5fc6631abffdf55 --- /dev/null +++ b/es2panda/test/compiler/js/lexEnv/forIn-loopEnv-test-3.js @@ -0,0 +1,13 @@ +{ + let a = [1, 2, 3]; + let b = []; + + for (let i in a) { + let j = a[i]; + b.push(() => { + print(i, j, a); + }); + } + + b.forEach(f => f()); +} \ No newline at end of file diff --git a/es2panda/test/compiler/js/lexEnv/forOf-loopEnv-test-1-expected.txt b/es2panda/test/compiler/js/lexEnv/forOf-loopEnv-test-1-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..1daca51094e752d46927cd46490e2cc44140c1ad --- /dev/null +++ b/es2panda/test/compiler/js/lexEnv/forOf-loopEnv-test-1-expected.txt @@ -0,0 +1,3 @@ +1 1,2,3 +2 1,2,3 +3 1,2,3 diff --git a/es2panda/test/compiler/js/lexEnv/forOf-loopEnv-test-1.js b/es2panda/test/compiler/js/lexEnv/forOf-loopEnv-test-1.js new file mode 100644 index 0000000000000000000000000000000000000000..f115fa7c6834379285d45c34d53d138d0531dec1 --- /dev/null +++ b/es2panda/test/compiler/js/lexEnv/forOf-loopEnv-test-1.js @@ -0,0 +1,12 @@ +{ + let a = [1, 2, 3]; + let b = []; + + for (let i of a) { + b.push(() => { + print(i, a); + }); + } + + b.forEach(f => f()); +} \ No newline at end of file diff --git a/es2panda/test/compiler/js/lexEnv/forOf-loopEnv-test-2-expected.txt b/es2panda/test/compiler/js/lexEnv/forOf-loopEnv-test-2-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..1daca51094e752d46927cd46490e2cc44140c1ad --- /dev/null +++ b/es2panda/test/compiler/js/lexEnv/forOf-loopEnv-test-2-expected.txt @@ -0,0 +1,3 @@ +1 1,2,3 +2 1,2,3 +3 1,2,3 diff --git a/es2panda/test/compiler/js/lexEnv/forOf-loopEnv-test-2.js b/es2panda/test/compiler/js/lexEnv/forOf-loopEnv-test-2.js new file mode 100644 index 0000000000000000000000000000000000000000..694cf733a9df13d623d7879c07879c0d4e72a5aa --- /dev/null +++ b/es2panda/test/compiler/js/lexEnv/forOf-loopEnv-test-2.js @@ -0,0 +1,13 @@ +{ + let a = [1, 2, 3]; + let b = []; + + for (let i of a) { + let j = i; + b.push(() => { + print(j, a); + }); + } + + b.forEach(f => f()); +} \ No newline at end of file diff --git a/es2panda/test/compiler/js/lexEnv/forOf-loopEnv-test-3-expected.txt b/es2panda/test/compiler/js/lexEnv/forOf-loopEnv-test-3-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..d6d13b293e9b220ea98c1595c9b0e567a29113da --- /dev/null +++ b/es2panda/test/compiler/js/lexEnv/forOf-loopEnv-test-3-expected.txt @@ -0,0 +1,3 @@ +1 1 1,2,3 +2 2 1,2,3 +3 3 1,2,3 diff --git a/es2panda/test/compiler/js/lexEnv/forOf-loopEnv-test-3.js b/es2panda/test/compiler/js/lexEnv/forOf-loopEnv-test-3.js new file mode 100644 index 0000000000000000000000000000000000000000..880231faf4912683d2c0d06b56e6f85d6b23b579 --- /dev/null +++ b/es2panda/test/compiler/js/lexEnv/forOf-loopEnv-test-3.js @@ -0,0 +1,13 @@ +{ + let a = [1, 2, 3]; + let b = []; + + for (let i of a) { + let j = i; + b.push(() => { + print(i, j, a); + }); + } + + b.forEach(f => f()); +} \ No newline at end of file diff --git a/es2panda/test/compiler/js/lexEnv/forUpdate-loopEnv-test-1-expected.txt b/es2panda/test/compiler/js/lexEnv/forUpdate-loopEnv-test-1-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..8aad39b4fa9987c50b02063c126f518626cb1677 --- /dev/null +++ b/es2panda/test/compiler/js/lexEnv/forUpdate-loopEnv-test-1-expected.txt @@ -0,0 +1,3 @@ +0 3 +1 3 +2 3 diff --git a/es2panda/test/compiler/js/lexEnv/forUpdate-loopEnv-test-1.js b/es2panda/test/compiler/js/lexEnv/forUpdate-loopEnv-test-1.js new file mode 100644 index 0000000000000000000000000000000000000000..1ecaa67f07e118a6cbfcda6133e16d6cdff692b9 --- /dev/null +++ b/es2panda/test/compiler/js/lexEnv/forUpdate-loopEnv-test-1.js @@ -0,0 +1,12 @@ +{ + let a = 3; + let b = []; + + for (let i = 0; i < a; i++) { + b.push(() => { + print(i, a); + }); + } + + b.forEach(f => f()); +} diff --git a/es2panda/test/compiler/js/lexEnv/forUpdate-loopEnv-test-2-expected.txt b/es2panda/test/compiler/js/lexEnv/forUpdate-loopEnv-test-2-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..8aad39b4fa9987c50b02063c126f518626cb1677 --- /dev/null +++ b/es2panda/test/compiler/js/lexEnv/forUpdate-loopEnv-test-2-expected.txt @@ -0,0 +1,3 @@ +0 3 +1 3 +2 3 diff --git a/es2panda/test/compiler/js/lexEnv/forUpdate-loopEnv-test-2.js b/es2panda/test/compiler/js/lexEnv/forUpdate-loopEnv-test-2.js new file mode 100644 index 0000000000000000000000000000000000000000..300d614298cd3c978281a3d82c1cbfeea6bfe1d6 --- /dev/null +++ b/es2panda/test/compiler/js/lexEnv/forUpdate-loopEnv-test-2.js @@ -0,0 +1,13 @@ +{ + let a = 3; + let b = []; + + for (let i = 0; i < a; i++) { + let j = i; + b.push(() => { + print(j, a); + }); + } + + b.forEach(f => f()); +} \ No newline at end of file diff --git a/es2panda/test/compiler/js/lexEnv/forUpdate-loopEnv-test-3-expected.txt b/es2panda/test/compiler/js/lexEnv/forUpdate-loopEnv-test-3-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..50297f767df937a5dd984f3f74acf6d816533d4b --- /dev/null +++ b/es2panda/test/compiler/js/lexEnv/forUpdate-loopEnv-test-3-expected.txt @@ -0,0 +1,3 @@ +0 0 3 +1 1 3 +2 2 3 diff --git a/es2panda/test/compiler/js/lexEnv/forUpdate-loopEnv-test-3.js b/es2panda/test/compiler/js/lexEnv/forUpdate-loopEnv-test-3.js new file mode 100644 index 0000000000000000000000000000000000000000..3900005c58dc1f4afd521c0794fc8c2f2cf1426b --- /dev/null +++ b/es2panda/test/compiler/js/lexEnv/forUpdate-loopEnv-test-3.js @@ -0,0 +1,13 @@ +{ + let a = 3; + let b = []; + + for (let i = 0; i < a; i++) { + let j = i; + b.push(() => { + print(i, j, a); + }); + } + + b.forEach(f => f()); +} \ No newline at end of file