mirror of
https://github.com/bellard/quickjs.git
synced 2025-05-15 02:36:17 +08:00
fixed break statement in the presence of labels (bnoordhuis) (#275)
This commit is contained in:
parent
00e6f29b17
commit
9d3776d0d4
@ -19794,7 +19794,8 @@ typedef struct BlockEnv {
|
|||||||
int drop_count; /* number of stack elements to drop */
|
int drop_count; /* number of stack elements to drop */
|
||||||
int label_finally; /* -1 if none */
|
int label_finally; /* -1 if none */
|
||||||
int scope_level;
|
int scope_level;
|
||||||
int has_iterator;
|
uint8_t has_iterator : 1;
|
||||||
|
uint8_t is_regular_stmt : 1; /* i.e. not a loop statement */
|
||||||
} BlockEnv;
|
} BlockEnv;
|
||||||
|
|
||||||
typedef struct JSGlobalVar {
|
typedef struct JSGlobalVar {
|
||||||
@ -25763,6 +25764,7 @@ static void push_break_entry(JSFunctionDef *fd, BlockEnv *be,
|
|||||||
be->label_finally = -1;
|
be->label_finally = -1;
|
||||||
be->scope_level = fd->scope_level;
|
be->scope_level = fd->scope_level;
|
||||||
be->has_iterator = FALSE;
|
be->has_iterator = FALSE;
|
||||||
|
be->is_regular_stmt = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pop_break_entry(JSFunctionDef *fd)
|
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 &&
|
if (!is_cont &&
|
||||||
top->label_break != -1 &&
|
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);
|
emit_goto(s, OP_goto, top->label_break);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -26355,6 +26358,7 @@ static __exception int js_parse_statement_or_decl(JSParseState *s,
|
|||||||
label_break = new_label(s);
|
label_break = new_label(s);
|
||||||
push_break_entry(s->cur_func, &break_entry,
|
push_break_entry(s->cur_func, &break_entry,
|
||||||
label_name, label_break, -1, 0);
|
label_name, label_break, -1, 0);
|
||||||
|
break_entry.is_regular_stmt = TRUE;
|
||||||
if (!(s->cur_func->js_mode & JS_MODE_STRICT) &&
|
if (!(s->cur_func->js_mode & JS_MODE_STRICT) &&
|
||||||
(decl_mask & DECL_MASK_FUNC_WITH_LABEL)) {
|
(decl_mask & DECL_MASK_FUNC_WITH_LABEL)) {
|
||||||
mask = DECL_MASK_FUNC | DECL_MASK_FUNC_WITH_LABEL;
|
mask = DECL_MASK_FUNC | DECL_MASK_FUNC_WITH_LABEL;
|
||||||
|
@ -398,6 +398,24 @@ function test_labels()
|
|||||||
while (0) x: { break x; };
|
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 test_destructuring()
|
||||||
{
|
{
|
||||||
function * g () { return 0; };
|
function * g () { return 0; };
|
||||||
@ -618,6 +636,7 @@ test_template_skip();
|
|||||||
test_object_literal();
|
test_object_literal();
|
||||||
test_regexp_skip();
|
test_regexp_skip();
|
||||||
test_labels();
|
test_labels();
|
||||||
|
test_labels2();
|
||||||
test_destructuring();
|
test_destructuring();
|
||||||
test_spread();
|
test_spread();
|
||||||
test_function_length();
|
test_function_length();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user