From 3f9811d2f7b730f1f1d030872ae1def7e8349be6 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 8 Feb 2024 20:46:02 +0100 Subject: compiler: close upvalues on loop control statements When removing locals from all scopes, upvalues need to be considered like in uc_compiler_leave_scope(). Closing them is required to avoid leaving lingering references to stack values that went out of scope, which would lead to invalid memory accesses in subsequent code when such upvalues are used by closures. Fixes: #187 Signed-off-by: Felix Fietkau [add testcase, reword commit message] Signed-off-by: Jo-Philipp Wich --- .../99_bugs/45_compiler_loop_ctrl_unclosed_upvals | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 tests/custom/99_bugs/45_compiler_loop_ctrl_unclosed_upvals (limited to 'tests') diff --git a/tests/custom/99_bugs/45_compiler_loop_ctrl_unclosed_upvals b/tests/custom/99_bugs/45_compiler_loop_ctrl_unclosed_upvals new file mode 100644 index 0000000..d4b7ed8 --- /dev/null +++ b/tests/custom/99_bugs/45_compiler_loop_ctrl_unclosed_upvals @@ -0,0 +1,22 @@ +When compiling loop control statements, the compiler incorrectly emitted an +I_POP instead of an I_CUPV instruction for open upvalues, causing closures to +reference unclosed upvalues that went out of scope, potentially leading to +invalid stack accesses in subsequent code. + +-- Testcase -- +{% + let dest; + + for (let i in [ 1 ]) { + let foo = i; + dest = () => print(foo, '\n'); + continue; + } + + dest(); +%} +-- End -- + +-- Expect stdout -- +1 +-- End -- -- cgit v1.2.3