summaryrefslogtreecommitdiffhomepage
path: root/tests/custom/03_bugs
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2021-05-05 11:29:20 +0200
committerJo-Philipp Wich <jo@mein.io>2021-05-05 11:31:32 +0200
commit850612f220380ecd8d53c1b7f4132ae468ead2ea (patch)
treef086a5ceea6fa968d28982be1c7b98ba2de368ae /tests/custom/03_bugs
parentf0a987503cb55f438a79c6d14058b23c5b801a0c (diff)
compiler: properly handle break/continue in nested scopes
When emitting byte code for break or continue statements, ensure that local variables in all containing scopes up to the loop body scope are popped, not just those in the same scope the statement is located in. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'tests/custom/03_bugs')
-rw-r--r--tests/custom/03_bugs/22_compile_break_continue_scoping59
1 files changed, 59 insertions, 0 deletions
diff --git a/tests/custom/03_bugs/22_compile_break_continue_scoping b/tests/custom/03_bugs/22_compile_break_continue_scoping
new file mode 100644
index 0000000..461b144
--- /dev/null
+++ b/tests/custom/03_bugs/22_compile_break_continue_scoping
@@ -0,0 +1,59 @@
+When compiling a break or continue statement, the compiler emitted pop
+instructions for local variables within the scope the break or continue
+keyword appeared in, but it must also pop local variables in enclosing
+scopes up until the scope of the containing loop or switch body.
+
+-- Expect stdout --
+1
+2
+3
+-- End --
+
+-- Testcase --
+{%
+ for (let i = 1; i <= 3; i++) {
+ while (true) {
+ let n = i;
+
+ print(n, "\n");
+
+ {
+ // The `let n` stack slot is not popped since it is
+ // outside of break's scope...
+ break;
+ }
+ }
+ }
+%}
+-- End --
+
+-- Expect stdout --
+1
+2
+3
+2
+4
+6
+3
+6
+9
+-- End --
+
+-- Testcase --
+{%
+ for (let i = 1; i <= 3; i++) {
+ for (let j = 1; j <= 3; j++) {
+ let n = i * j;
+
+ print(n, "\n");
+
+ if (j == 1)
+ {
+ // The `let n` stack slot is not popped since it is
+ // outside of continue's scope...
+ continue;
+ }
+ }
+ }
+%}
+-- End --