From 9918c1206e291b0bbd324463b3d1fa347a7222de Mon Sep 17 00:00:00 2001 From: Fabrice Bellard Date: Thu, 10 Apr 2025 17:38:28 +0200 Subject: [PATCH] workaround for #282 --- quickjs.c | 18 ++++++++++++++++-- tests/test_loop.js | 10 ++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/quickjs.c b/quickjs.c index fd464c9..028744c 100644 --- a/quickjs.c +++ b/quickjs.c @@ -31821,10 +31821,11 @@ static BOOL code_has_label(CodeContext *s, int pos, int label) /* return the target label, following the OP_goto jumps the first opcode at destination is stored in *pop */ -static int find_jump_target(JSFunctionDef *s, int label, int *pop, int *pline) +static int find_jump_target(JSFunctionDef *s, int label0, int *pop, int *pline) { - int i, pos, op; + int i, pos, op, label; + label = label0; update_label(s, label, -1); for (i = 0; i < 10; i++) { assert(label >= 0 && label < s->label_count); @@ -31855,6 +31856,19 @@ static int find_jump_target(JSFunctionDef *s, int label, int *pop, int *pline) } } /* cycle detected, could issue a warning */ + /* XXX: the combination of find_jump_target() and skip_dead_code() + seems incorrect with cyclic labels. See for exemple: + + for (;;) { + l:break l; + l:break l; + l:break l; + l:break l; + } + + Avoiding changing the target is just a workaround and might not + suffice to completely fix the problem. */ + label = label0; done: *pop = op; update_label(s, label, +1); diff --git a/tests/test_loop.js b/tests/test_loop.js index 50e2122..8f1934d 100644 --- a/tests/test_loop.js +++ b/tests/test_loop.js @@ -371,6 +371,16 @@ function test_try_catch8() assert(s === "xafyaf"); } +function test_cyclic_labels() +{ + /* just check that it compiles without a crash */ + for (;;) { + l: break l; + l: break l; + l: break l; + } +} + test_while(); test_while_break(); test_do_while();