diff options
author | Jo-Philipp Wich <jo@mein.io> | 2021-03-24 23:32:23 +0100 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2021-03-24 23:32:23 +0100 |
commit | b3d758bcacffa426c2bb2c2384961649b10ec7ca (patch) | |
tree | 8f09b9c8abd3c52c11e6f05b7fa97ddf94f8bf29 /compiler.c | |
parent | 86e3970643e03a5e02f3eac2a52794bd6c040f30 (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.c | 10 |
1 files changed, 5 insertions, 5 deletions
@@ -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 |