From aa2b152ea8d04896e36702b5065836af39b40bd6 Mon Sep 17 00:00:00 2001 From: Jan Kassens Date: Tue, 29 Nov 2022 18:33:00 -0500 Subject: [PATCH] Fixture tests for 2 cases of expressions that produce incorrect output They're fairly related, but I figured it's worth keeping more examples. - For the `while` example we need to codegen into a single expression. - For the expression with contained assignment we need to either keep the SSA ids around or re-create a similar expression during codegen. --- .../_bug_expression-with-assignment.expect.md | 60 ++++++++++ .../hir/_bug_expression-with-assignment.js | 6 + .../hir/_bug_while-with-assignment.expect.md | 107 ++++++++++++++++++ .../hir/_bug_while-with-assignment.js | 10 ++ 4 files changed, 183 insertions(+) create mode 100644 compiler/forget/src/__tests__/fixtures/hir/_bug_expression-with-assignment.expect.md create mode 100644 compiler/forget/src/__tests__/fixtures/hir/_bug_expression-with-assignment.js create mode 100644 compiler/forget/src/__tests__/fixtures/hir/_bug_while-with-assignment.expect.md create mode 100644 compiler/forget/src/__tests__/fixtures/hir/_bug_while-with-assignment.js diff --git a/compiler/forget/src/__tests__/fixtures/hir/_bug_expression-with-assignment.expect.md b/compiler/forget/src/__tests__/fixtures/hir/_bug_expression-with-assignment.expect.md new file mode 100644 index 0000000000..2e6274626d --- /dev/null +++ b/compiler/forget/src/__tests__/fixtures/hir/_bug_expression-with-assignment.expect.md @@ -0,0 +1,60 @@ + +## Input + +```javascript +function f() { + let x = 1; + // BUG: `x` has different values within this expression. Currently, the + // assignment is evaluated too early. + return x + (x = 2) + x; +} + +``` + +## HIR + +``` +bb0: + [1] Let mutate x$4_@0 = 1 + [2] Reassign mutate x$5_@1 = 2 + [3] Const mutate $6_@2 = Binary read x$5_@1 + read x$5_@1 + [4] Const mutate $7_@3 = Binary read $6_@2 + read x$5_@1 + [5] Return read $7_@3 +scope2 [3:4]: + - read x$5_@1 + - read x$5_@1 +scope3 [4:5]: + - read $6_@2 + - read x$5_@1 +``` + +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Let mutate x$4_@0 = 1 + [2] Reassign mutate x$5_@1 = 2 + [3] Const mutate $6_@2 = Binary read x$5_@1 + read x$5_@1 + [4] Const mutate $7_@3 = Binary read $6_@2 + read x$5_@1 + "] + bb0_instrs --> bb0_terminal(["Return read $7_@3"]) + end + + %% Jumps + %% empty +``` + +## Code + +```javascript +function f$0() { + let x$1 = 1; + x$1 = 2; + return x$1 + x$1 + x$1; +} + +``` + \ No newline at end of file diff --git a/compiler/forget/src/__tests__/fixtures/hir/_bug_expression-with-assignment.js b/compiler/forget/src/__tests__/fixtures/hir/_bug_expression-with-assignment.js new file mode 100644 index 0000000000..49ae886dad --- /dev/null +++ b/compiler/forget/src/__tests__/fixtures/hir/_bug_expression-with-assignment.js @@ -0,0 +1,6 @@ +function f() { + let x = 1; + // BUG: `x` has different values within this expression. Currently, the + // assignment is evaluated too early. + return x + (x = 2) + x; +} diff --git a/compiler/forget/src/__tests__/fixtures/hir/_bug_while-with-assignment.expect.md b/compiler/forget/src/__tests__/fixtures/hir/_bug_while-with-assignment.expect.md new file mode 100644 index 0000000000..d1bdf051a0 --- /dev/null +++ b/compiler/forget/src/__tests__/fixtures/hir/_bug_while-with-assignment.expect.md @@ -0,0 +1,107 @@ + +## Input + +```javascript +function f(reader) { + const queue = [1, 2, 3]; + let value = 0; + let sum = 0; + // BUG: we need to codegen the complex test expression + while ((value = queue.pop()) != null) { + sum += value; + } + return sum; +} + +``` + +## HIR + +``` +bb0: + [1] Const mutate $11_@0 = 1 + [2] Const mutate $12_@1 = 2 + [3] Const mutate $13_@2 = 3 + [4] Const mutate queue$14_@3[0:14] = Array [read $11_@0, read $12_@1, read $13_@2] + [5] Let mutate value$15_@4 = 0 + [6] Let mutate sum$16_@3[0:14] = 0 + [7] While test=bb1 loop=bb3 fallthrough=bb2 +bb1: + predecessor blocks: bb0 bb3 + sum$21_@3[0:14]: phi(bb0: sum$16_@3, bb3: sum$22_@3) + [8] Reassign mutate value$18_@3[0:14] = Call mutate queue$14_@3.pop() + [9] Const mutate $19_@6 = null + [10] Const mutate $20_@7[10:14] = Binary read value$18_@3 != read $19_@6 + [11] If (read $20_@7) then:bb3 else:bb2 +bb3: + predecessor blocks: bb1 + [12] Reassign mutate sum$22_@3[0:14] = Binary read sum$21_@3 + read value$18_@3 + [13] Goto(Continue) bb1 +bb2: + predecessor blocks: bb1 + [14] Return read sum$21_@3 +scope7 [10:14]: + - read $19_@6 +``` + +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate $11_@0 = 1 + [2] Const mutate $12_@1 = 2 + [3] Const mutate $13_@2 = 3 + [4] Const mutate queue$14_@3[0:14] = Array [read $11_@0, read $12_@1, read $13_@2] + [5] Let mutate value$15_@4 = 0 + [6] Let mutate sum$16_@3[0:14] = 0 + "] + bb0_instrs --> bb0_terminal(["While"]) + end + subgraph bb1 + bb1_instrs[" + [8] Reassign mutate value$18_@3[0:14] = Call mutate queue$14_@3.pop() + [9] Const mutate $19_@6 = null + [10] Const mutate $20_@7[10:14] = Binary read value$18_@3 != read $19_@6 + "] + bb1_instrs --> bb1_terminal(["If (read $20_@7)"]) + end + subgraph bb3 + bb3_instrs[" + [12] Reassign mutate sum$22_@3[0:14] = Binary read sum$21_@3 + read value$18_@3 + "] + bb3_instrs --> bb3_terminal(["Goto"]) + end + subgraph bb2 + bb2_terminal(["Return read sum$21_@3"]) + end + + %% Jumps + bb0_terminal -- "test" --> bb1 + bb0_terminal -- "loop" --> bb3 + bb0_terminal -- "fallthrough" --> bb2 + bb1_terminal -- "then" --> bb3 + bb1_terminal -- "else" --> bb2 + bb3_terminal --> bb1 + +``` + +## Code + +```javascript +function f$0(reader$1) { + const queue$2 = [1, 2, 3]; + let value$6 = 0; + let sum$7 = 0; + value$6 = queue$2.pop(); + bb2: while (value$6 != null) { + sum$7 = sum$7 + value$6; + } + + return sum$7; +} + +``` + \ No newline at end of file diff --git a/compiler/forget/src/__tests__/fixtures/hir/_bug_while-with-assignment.js b/compiler/forget/src/__tests__/fixtures/hir/_bug_while-with-assignment.js new file mode 100644 index 0000000000..0ad8369a39 --- /dev/null +++ b/compiler/forget/src/__tests__/fixtures/hir/_bug_while-with-assignment.js @@ -0,0 +1,10 @@ +function f(reader) { + const queue = [1, 2, 3]; + let value = 0; + let sum = 0; + // BUG: we need to codegen the complex test expression + while ((value = queue.pop()) != null) { + sum += value; + } + return sum; +}