summaryrefslogtreecommitdiffhomepage
path: root/compiler.c
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2021-03-24 23:32:23 +0100
committerJo-Philipp Wich <jo@mein.io>2021-03-24 23:32:23 +0100
commitb3d758bcacffa426c2bb2c2384961649b10ec7ca (patch)
tree8f09b9c8abd3c52c11e6f05b7fa97ddf94f8bf29 /compiler.c
parent86e3970643e03a5e02f3eac2a52794bd6c040f30 (diff)
compiler: fix for/break miscompilation
When patching jump targets for break statments while compiling for-loop statments, jump beyond the instructions popping intermediate loop variables off the stack to fix a stack position mismatch between compiler and vm. Before that change, local loop body variables got popped twice, breaking the expected stack layout. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'compiler.c')
-rw-r--r--compiler.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/compiler.c b/compiler.c
index 1b0d1c4..ba0b699 100644
--- a/compiler.c
+++ b/compiler.c
@@ -2128,9 +2128,6 @@ uc_compiler_compile_for_in(uc_compiler *compiler, bool local, uc_token *kvar, uc
/* back patch conditional jump */
uc_compiler_set_jmpaddr(compiler, test_jmp, chunk->count);
- /* patch up break/continue */
- uc_compiler_backpatch(compiler, chunk->count, skip_jmp + 5);
-
/* pop loop variables */
uc_compiler_emit_insn(compiler, 0, I_POP);
@@ -2138,6 +2135,9 @@ uc_compiler_compile_for_in(uc_compiler *compiler, bool local, uc_token *kvar, uc
uc_compiler_emit_insn(compiler, 0, I_POP);
uc_compiler_leave_scope(compiler);
+
+ /* patch up break/continue */
+ uc_compiler_backpatch(compiler, chunk->count, skip_jmp + 5);
}
static void
@@ -2232,10 +2232,10 @@ uc_compiler_compile_for_count(uc_compiler *compiler, bool local, uc_token *var)
if (test_off)
uc_compiler_set_jmpaddr(compiler, test_off, chunk->count);
+ uc_compiler_leave_scope(compiler);
+
/* patch up break/continue */
uc_compiler_backpatch(compiler, chunk->count, incr_off);
-
- uc_compiler_leave_scope(compiler);
}
static void