]> git.kaiwu.me - quickjs.git/commitdiff
workaround for #282
authorFabrice Bellard <fabrice@bellard.org>
Thu, 10 Apr 2025 15:38:28 +0000 (17:38 +0200)
committerFabrice Bellard <fabrice@bellard.org>
Thu, 10 Apr 2025 15:38:28 +0000 (17:38 +0200)
quickjs.c
tests/test_loop.js

index fd464c9934e483f62e5e1ce5f685993c60b03ada..028744c6d4712a6120bd2f0ab164299d1bc1d1a4 100644 (file)
--- 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);
index 50e21225753c8117e50e53991ccf1acd4acde916..8f1934d3887a61d8053f1dc34d975f64b2034cdf 100644 (file)
@@ -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();