summaryrefslogtreecommitdiffhomepage
path: root/compiler.c
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 /compiler.c
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 'compiler.c')
-rw-r--r--compiler.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/compiler.c b/compiler.c
index ee6b073..f8d63b6 100644
--- a/compiler.c
+++ b/compiler.c
@@ -2031,8 +2031,8 @@ static void
uc_compiler_compile_while(uc_compiler *compiler)
{
uc_chunk *chunk = uc_compiler_current_chunk(compiler);
+ uc_patchlist p = { .depth = compiler->scope_depth };
size_t cond_off, jmpz_off, end_off;
- uc_patchlist p = { 0 };
p.parent = compiler->patchlist;
compiler->patchlist = &p;
@@ -2079,8 +2079,8 @@ static void
uc_compiler_compile_for_in(uc_compiler *compiler, bool local, uc_token *kvar, uc_token *vvar)
{
uc_chunk *chunk = uc_compiler_current_chunk(compiler);
+ uc_patchlist p = { .depth = compiler->scope_depth + 1 };
size_t skip_jmp, test_jmp, key_slot, val_slot;
- uc_patchlist p = { 0 };
p.parent = compiler->patchlist;
compiler->patchlist = &p;
@@ -2190,7 +2190,7 @@ uc_compiler_compile_for_count(uc_compiler *compiler, bool local, uc_token *var)
{
uc_chunk *chunk = uc_compiler_current_chunk(compiler);
size_t test_off = 0, incr_off, skip_off, cond_off = 0;
- uc_patchlist p = { 0 };
+ uc_patchlist p = { .depth = compiler->scope_depth + 1 };
p.parent = compiler->patchlist;
compiler->patchlist = &p;
@@ -2344,9 +2344,9 @@ uc_compiler_compile_switch(uc_compiler *compiler)
{
size_t i, test_jmp, skip_jmp, next_jmp, value_slot, default_off = 0;
uc_chunk *chunk = uc_compiler_current_chunk(compiler);
+ uc_patchlist p = { .depth = compiler->scope_depth };
uc_locals *locals = &compiler->locals;
uc_jmplist cases = { 0 };
- uc_patchlist p = { 0 };
p.parent = compiler->patchlist;
compiler->patchlist = &p;
@@ -2599,7 +2599,7 @@ uc_compiler_compile_control(uc_compiler *compiler)
}
/* pop locals in scope up to this point */
- for (i = locals->count; i > 0 && (size_t)locals->entries[i - 1].depth == compiler->scope_depth; i--)
+ for (i = locals->count; i > 0 && (size_t)locals->entries[i - 1].depth > p->depth; i--)
uc_compiler_emit_insn(compiler, 0, I_POP);
uc_vector_grow(p);