]> git.kaiwu.me - quickjs.git/commitdiff
fixed break statement in the presence of labels (bnoordhuis) (#275)
authorFabrice Bellard <fabrice@bellard.org>
Mon, 7 Apr 2025 17:01:30 +0000 (19:01 +0200)
committerFabrice Bellard <fabrice@bellard.org>
Mon, 7 Apr 2025 17:01:30 +0000 (19:01 +0200)
quickjs.c
tests/test_language.js

index 6b731c319e248f3257011d85997a1514a376d99c..db5f04c288fbfb08e63261302d2f8715e66b39df 100644 (file)
--- a/quickjs.c
+++ b/quickjs.c
@@ -19794,7 +19794,8 @@ typedef struct BlockEnv {
     int drop_count; /* number of stack elements to drop */
     int label_finally; /* -1 if none */
     int scope_level;
-    int has_iterator;
+    uint8_t has_iterator : 1;
+    uint8_t is_regular_stmt : 1; /* i.e. not a loop statement */
 } BlockEnv;
 
 typedef struct JSGlobalVar {
@@ -25763,6 +25764,7 @@ static void push_break_entry(JSFunctionDef *fd, BlockEnv *be,
     be->label_finally = -1;
     be->scope_level = fd->scope_level;
     be->has_iterator = FALSE;
+    be->is_regular_stmt = FALSE;
 }
 
 static void pop_break_entry(JSFunctionDef *fd)
@@ -25791,7 +25793,8 @@ static __exception int emit_break(JSParseState *s, JSAtom name, int is_cont)
         }
         if (!is_cont &&
             top->label_break != -1 &&
-            (name == JS_ATOM_NULL || top->label_name == name)) {
+            ((name == JS_ATOM_NULL && !top->is_regular_stmt) ||
+             top->label_name == name)) {
             emit_goto(s, OP_goto, top->label_break);
             return 0;
         }
@@ -26355,6 +26358,7 @@ static __exception int js_parse_statement_or_decl(JSParseState *s,
             label_break = new_label(s);
             push_break_entry(s->cur_func, &break_entry,
                              label_name, label_break, -1, 0);
+            break_entry.is_regular_stmt = TRUE;
             if (!(s->cur_func->js_mode & JS_MODE_STRICT) &&
                 (decl_mask & DECL_MASK_FUNC_WITH_LABEL)) {
                 mask = DECL_MASK_FUNC | DECL_MASK_FUNC_WITH_LABEL;
index 7e98d7a817e71aa3e706733bc5b62d24b3605ff3..11a45de2270ee5191a4cf23b22917e1f5d7d5c0c 100644 (file)
@@ -398,6 +398,24 @@ function test_labels()
     while (0) x: { break x; };
 }
 
+function test_labels2()
+{
+    while (1) label: break
+    var i = 0
+    while (i < 3) label: {
+        if (i > 0)
+            break
+        i++
+    }
+    assert(i, 1)
+    for (;;) label: break
+    for (i = 0; i < 3; i++) label: {
+        if (i > 0)
+            break
+    }
+    assert(i, 1)
+}
+
 function test_destructuring()
 {
     function * g () { return 0; };
@@ -618,6 +636,7 @@ test_template_skip();
 test_object_literal();
 test_regexp_skip();
 test_labels();
+test_labels2();
 test_destructuring();
 test_spread();
 test_function_length();