From 1b9a587a022fe0ae24bd22a414271174f9e87324 Mon Sep 17 00:00:00 2001 From: hufeng Date: Thu, 29 Sep 2022 19:12:10 +0800 Subject: [PATCH 1/2] Fix switchStatement's compiling bug caused by it's expression has same name declaration in it's body Signed-off-by: hufeng Change-Id: Ieccf79c24a4ffdeec20b98d4b704db71f564fbb9 --- es2panda/binder/binder.cpp | 9 +++++++-- es2panda/ir/statements/switchStatement.cpp | 3 ++- es2panda/ir/statements/switchStatement.h | 10 ++++++++++ ts2panda/src/statement/switchStatement.ts | 2 +- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/es2panda/binder/binder.cpp b/es2panda/binder/binder.cpp index 1a56f6cdc0..033451bb2e 100644 --- a/es2panda/binder/binder.cpp +++ b/es2panda/binder/binder.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -518,9 +519,13 @@ void Binder::ResolveReference(const ir::AstNode *parent, ir::AstNode *childNode) break; } case ir::AstNodeType::SWITCH_STATEMENT: { - auto scopeCtx = LexicalScope::Enter(this, childNode->AsSwitchStatement()->Scope()); + auto *switchStatement = childNode->AsSwitchStatement(); + ResolveReference(switchStatement, switchStatement->Discriminant()); - ResolveReferences(childNode); + auto scopeCtx = LexicalScope::Enter(this, childNode->AsSwitchStatement()->Scope()); + for (auto *it : switchStatement->Cases()) { + ResolveReference(switchStatement, it); + } break; } case ir::AstNodeType::DO_WHILE_STATEMENT: { diff --git a/es2panda/ir/statements/switchStatement.cpp b/es2panda/ir/statements/switchStatement.cpp index 94b97de649..acf81a4b29 100644 --- a/es2panda/ir/statements/switchStatement.cpp +++ b/es2panda/ir/statements/switchStatement.cpp @@ -43,11 +43,12 @@ void SwitchStatement::Dump(ir::AstDumper *dumper) const void SwitchStatement::Compile(compiler::PandaGen *pg) const { - compiler::LocalRegScope lrs(pg, scope_); compiler::SwitchBuilder builder(pg, this); compiler::VReg tag = pg->AllocReg(); builder.CompileTagOfSwitch(tag); + + compiler::LocalRegScope lrs(pg, scope_); uint32_t defaultIndex = 0; for (size_t i = 0; i < cases_.size(); i++) { diff --git a/es2panda/ir/statements/switchStatement.h b/es2panda/ir/statements/switchStatement.h index 3e2148fd76..748414161f 100644 --- a/es2panda/ir/statements/switchStatement.h +++ b/es2panda/ir/statements/switchStatement.h @@ -49,11 +49,21 @@ public: return discriminant_; } + Expression *Discriminant() + { + return discriminant_; + } + const ArenaVector &Cases() const { return cases_; } + ArenaVector &Cases() + { + return cases_; + } + binder::LocalScope *Scope() const { return scope_; diff --git a/ts2panda/src/statement/switchStatement.ts b/ts2panda/src/statement/switchStatement.ts index f964b12928..180587a66b 100644 --- a/ts2panda/src/statement/switchStatement.ts +++ b/ts2panda/src/statement/switchStatement.ts @@ -92,7 +92,6 @@ export class SwitchBase { } export function compileSwitchStatement(stmt: ts.SwitchStatement, compiler: Compiler) { - compiler.pushScope(stmt); let pandaGen = compiler.getPandaGen(); let caseNums = stmt.caseBlock.clauses.length; let switchEndLabel = new Label(); @@ -100,6 +99,7 @@ export function compileSwitchStatement(stmt: ts.SwitchStatement, compiler: Compi let tagReg = pandaGen.getTemp(); switchBuilder.compileTagOfSwitch(tagReg); + compiler.pushScope(stmt); let caseTargets = stmt.caseBlock.clauses; let defaultIndex = 0; let defaultCnt = 0; -- Gitee From f03312499b0ca0be741084cc4436935a33015ea7 Mon Sep 17 00:00:00 2001 From: hufeng Date: Sat, 8 Oct 2022 09:52:55 +0800 Subject: [PATCH 2/2] Add compiler testcase Signed-off-by: hufeng Change-Id: Ie7101f4977df3cd542e824632e0a1d3b469ba84a --- es2panda/binder/binder.cpp | 2 +- .../switch/discriminant-scope-expected.txt | 1 + .../statements/switch/discriminant-scope.js | 12 +++++ ts2panda/tests/statements/switch.test.ts | 46 ++++++++++++++++++- 4 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 es2panda/test/compiler/js/language/statements/switch/discriminant-scope-expected.txt create mode 100644 es2panda/test/compiler/js/language/statements/switch/discriminant-scope.js diff --git a/es2panda/binder/binder.cpp b/es2panda/binder/binder.cpp index 033451bb2e..418ed1275a 100644 --- a/es2panda/binder/binder.cpp +++ b/es2panda/binder/binder.cpp @@ -38,8 +38,8 @@ #include #include #include -#include #include +#include #include #include #include diff --git a/es2panda/test/compiler/js/language/statements/switch/discriminant-scope-expected.txt b/es2panda/test/compiler/js/language/statements/switch/discriminant-scope-expected.txt new file mode 100644 index 0000000000..a965a70ed4 --- /dev/null +++ b/es2panda/test/compiler/js/language/statements/switch/discriminant-scope-expected.txt @@ -0,0 +1 @@ +Done diff --git a/es2panda/test/compiler/js/language/statements/switch/discriminant-scope.js b/es2panda/test/compiler/js/language/statements/switch/discriminant-scope.js new file mode 100644 index 0000000000..390abba738 --- /dev/null +++ b/es2panda/test/compiler/js/language/statements/switch/discriminant-scope.js @@ -0,0 +1,12 @@ +function test() { + let a = 0; + switch (a) { + case 0: + const a = 0; + break; + } + + print("Done"); +} + +test(); \ No newline at end of file diff --git a/ts2panda/tests/statements/switch.test.ts b/ts2panda/tests/statements/switch.test.ts index f3b908c218..f09bb9bce2 100644 --- a/ts2panda/tests/statements/switch.test.ts +++ b/ts2panda/tests/statements/switch.test.ts @@ -27,12 +27,13 @@ import { Jmp, Jnez, Label, + Lda, Ldai, Sta, VReg, IRNode } from "../../src/irnodes"; -import { checkInstructions, compileMainSnippet } from "../utils/base"; +import { checkInstructions, compileMainSnippet, SnippetCompiler } from "../utils/base"; import { creatAstFromSnippet } from "../utils/asthelper" import { PandaGen } from '../../src/pandagen'; @@ -210,4 +211,47 @@ describe("switchTest", function () { ]; expect(checkInstructions(insns, expected)).to.be.true; }); + + it("discriminant's scope", function () { + let snippetCompiler = new SnippetCompiler(); + snippetCompiler.compile( + `function test() { + let a = 0; + switch (a) { + case 0: + const a = 0; + break; + } + }`); + IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined); + + let a = new VReg(); + let discriminant_a = new VReg(); + let body_a = new VReg(); + let caseLabel_0 = new Label(); + let switchEndLabel = new Label(); + let expected = [ + new Ldai(new Imm(0)), + new Sta(a), + // switch discriminant + new Lda(a), + new Sta(discriminant_a), + // switch body + new Ldai(new Imm(0)), + new Strictnoteq(new Imm(1), discriminant_a), + new Jeqz(caseLabel_0), + new Jmp(switchEndLabel), + // switch cases + caseLabel_0, + new Ldai(new Imm(0)), + new Sta(body_a), + new Jmp(switchEndLabel), + switchEndLabel, + new Returnundefined() + ]; + let functionPg = snippetCompiler.getPandaGenByName("test"); + let insns = functionPg!.getInsns(); + + expect(checkInstructions(insns, expected)).to.be.true; + }); }); -- Gitee