diff options
author | Jo-Philipp Wich <jo@mein.io> | 2021-05-05 11:29:20 +0200 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2021-05-05 11:31:32 +0200 |
commit | 850612f220380ecd8d53c1b7f4132ae468ead2ea (patch) | |
tree | f086a5ceea6fa968d28982be1c7b98ba2de368ae /tests/custom/03_bugs | |
parent | f0a987503cb55f438a79c6d14058b23c5b801a0c (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_scoping | 59 |
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 -- |