From: Dmitry Volyntsev Date: Thu, 3 Sep 2026 00:39:41 +0000 (-0700) Subject: Parser: store statement labels as atom identifiers X-Git-Tag: 1.0.2~66 X-Git-Url: https://git.kaiwu.me/$%7BGITURL%7D/doc/static/gitweb.js?a=commitdiff_plain;h=51922fe6cfefa7c85a8d8f70ed0e87b441bae6a8;p=njs.git Parser: store statement labels as atom identifiers --- diff --git a/src/njs_generator.c b/src/njs_generator.c index dd6b7111..09cc657d 100644 --- a/src/njs_generator.c +++ b/src/njs_generator.c @@ -643,6 +643,20 @@ static const njs_str_t return_label = njs_str("@return"); static const njs_str_t undef_label = { 0xffffffff, (u_char *) "" }; +njs_inline const njs_str_t * +njs_generate_node_label(njs_vm_t *vm, njs_parser_node_t *node, + njs_str_t *label) +{ + if (node->u.label == NJS_ATOM_STRING_unknown) { + return &no_label; + } + + njs_atom_string_get(vm, node->u.label, label); + + return label; +} + + njs_int_t njs_generator_init(njs_generator_t *generator, njs_str_t *file, njs_int_t depth, njs_bool_t runtime) @@ -1297,9 +1311,10 @@ njs_generate_if_statement(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node) { njs_int_t ret; + njs_str_t label; ret = njs_generate_start_block(vm, generator, NJS_GENERATOR_BLOCK, - &node->name); + njs_generate_node_label(vm, node, &label)); if (njs_slow_path(ret != NJS_OK)) { return ret; } @@ -1545,6 +1560,7 @@ njs_generate_switch_expression(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *swtch) { njs_int_t ret; + njs_str_t label; njs_parser_node_t *expr; njs_vmcode_move_t *move; njs_generator_switch_ctx_t *ctx; @@ -1564,7 +1580,7 @@ njs_generate_switch_expression(njs_vm_t *vm, njs_generator_t *generator, } ret = njs_generate_start_block(vm, generator, NJS_GENERATOR_SWITCH, - &swtch->name); + njs_generate_node_label(vm, swtch, &label)); if (njs_slow_path(ret != NJS_OK)) { return ret; } @@ -1769,6 +1785,7 @@ njs_generate_while_statement(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node) { njs_int_t ret; + njs_str_t label; njs_vmcode_jump_t *jump; njs_generator_loop_ctx_t ctx; @@ -1782,7 +1799,7 @@ njs_generate_while_statement(njs_vm_t *vm, njs_generator_t *generator, ctx.jump_offset = njs_code_offset(generator, jump); ret = njs_generate_start_block(vm, generator, NJS_GENERATOR_LOOP, - &node->name); + njs_generate_node_label(vm, node, &label)); if (njs_slow_path(ret != NJS_OK)) { return ret; } @@ -1851,10 +1868,11 @@ njs_generate_do_while_statement(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node) { njs_int_t ret; + njs_str_t label; njs_generator_loop_ctx_t ctx; ret = njs_generate_start_block(vm, generator, NJS_GENERATOR_LOOP, - &node->name); + njs_generate_node_label(vm, node, &label)); if (njs_slow_path(ret != NJS_OK)) { return ret; } @@ -1918,10 +1936,11 @@ njs_generate_for_statement(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node) { njs_int_t ret; + njs_str_t label; njs_generator_loop_ctx_t ctx; ret = njs_generate_start_block(vm, generator, NJS_GENERATOR_LOOP, - &node->name); + njs_generate_node_label(vm, node, &label)); if (njs_slow_path(ret != NJS_OK)) { return ret; } @@ -2291,11 +2310,12 @@ njs_generate_for_in_statement(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node) { njs_int_t ret; + njs_str_t label; njs_parser_node_t *foreach, *name; njs_generator_loop_ctx_t ctx; ret = njs_generate_start_block(vm, generator, NJS_GENERATOR_LOOP, - &node->name); + njs_generate_node_label(vm, node, &label)); if (njs_slow_path(ret != NJS_OK)) { return ret; } @@ -2851,12 +2871,13 @@ static njs_int_t njs_generate_continue_statement(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node) { + njs_str_t name; const njs_str_t *label, *dest; njs_vmcode_jump_t *jump; njs_generator_patch_t *patch; njs_generator_block_t *block; - label = &node->name; + label = njs_generate_node_label(vm, node, &name); block = njs_generate_find_block(vm, generator->block, NJS_GENERATOR_LOOP, label); @@ -2900,12 +2921,13 @@ static njs_int_t njs_generate_break_statement(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node) { + njs_str_t name; const njs_str_t *label, *dest; njs_vmcode_jump_t *jump; njs_generator_patch_t *patch; njs_generator_block_t *block; - label = &node->name; + label = njs_generate_node_label(vm, node, &name); block = njs_generate_find_block(vm, generator->block, NJS_GENERATOR_ALL, label); @@ -3012,10 +3034,11 @@ njs_generate_block_statement(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node) { njs_int_t ret; + njs_str_t label; njs_queue_link_t *link; ret = njs_generate_start_block(vm, generator, NJS_GENERATOR_BLOCK, - &node->name); + njs_generate_node_label(vm, node, &label)); if (njs_slow_path(ret != NJS_OK)) { return ret; } diff --git a/src/njs_parser.c b/src/njs_parser.c index 0a4419a4..efc1d290 100644 --- a/src/njs_parser.c +++ b/src/njs_parser.c @@ -381,6 +381,8 @@ static njs_int_t njs_parser_labelled_statement(njs_parser_t *parser, njs_lexer_token_t *token, njs_queue_link_t *current); static njs_int_t njs_parser_labelled_statement_after(njs_parser_t *parser, njs_lexer_token_t *token, njs_queue_link_t *current); +static void njs_parser_statement_label(njs_parser_node_t *node, + uintptr_t atom_id); static njs_int_t njs_parser_throw_statement(njs_parser_t *parser, njs_lexer_token_t *token, njs_queue_link_t *current); @@ -6015,8 +6017,6 @@ static njs_int_t njs_parser_break_continue(njs_parser_t *parser, njs_lexer_token_t *token, njs_token_type_t type) { - njs_int_t ret; - parser->node = njs_parser_node_new(parser, type); if (parser->node == NULL) { return NJS_ERROR; @@ -6044,10 +6044,7 @@ njs_parser_break_continue(njs_parser_t *parser, njs_lexer_token_t *token, return NJS_DONE; } - ret = njs_name_copy(parser->vm, &parser->node->name, &token->text); - if (ret != NJS_OK) { - return NJS_ERROR; - } + parser->node->u.label = token->atom_id; break; } @@ -6486,7 +6483,6 @@ njs_parser_labelled_statement_after(njs_parser_t *parser, njs_lexer_token_t *token, njs_queue_link_t *current) { njs_int_t ret; - njs_str_t str; uintptr_t atom_id; njs_parser_node_t *node; @@ -6504,12 +6500,7 @@ njs_parser_labelled_statement_after(njs_parser_t *parser, atom_id = (uint32_t) (uintptr_t) parser->target; - njs_atom_string_get(parser->vm, atom_id, &str); - - ret = njs_name_copy(parser->vm, &parser->node->name, &str); - if (ret != NJS_OK) { - return NJS_ERROR; - } + njs_parser_statement_label(parser->node, atom_id); ret = njs_label_remove(parser, atom_id); if (ret != NJS_OK) { @@ -6520,6 +6511,26 @@ njs_parser_labelled_statement_after(njs_parser_t *parser, } +static void +njs_parser_statement_label(njs_parser_node_t *node, uintptr_t atom_id) +{ + switch (node->token_type) { + case NJS_TOKEN_BLOCK: + case NJS_TOKEN_IF: + case NJS_TOKEN_SWITCH: + case NJS_TOKEN_WHILE: + case NJS_TOKEN_DO: + case NJS_TOKEN_FOR: + case NJS_TOKEN_FOR_IN: + node->u.label = atom_id; + break; + + default: + break; + } +} + + /* * 13.14 throw Statement */ diff --git a/src/njs_parser.h b/src/njs_parser.h index 941a0a10..3498d48e 100644 --- a/src/njs_parser.h +++ b/src/njs_parser.h @@ -58,13 +58,12 @@ struct njs_parser_node_s { } array; njs_variable_reference_t reference; njs_value_t value; + uintptr_t label; njs_vmcode_t operation; njs_parser_node_t *object; njs_mod_t *module; } u; - njs_str_t name; - njs_index_t index; /* diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index fd9dd150..a0b2bd16 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -3973,6 +3973,18 @@ static njs_unit_test_t njs_test[] = { njs_str("a : var n = 0; b :++n"), njs_str("1") }, + { njs_str("var r = 0; outer: for (;;) { inner: break outer; r++ } r"), + njs_str("0") }, + + { njs_str("var r = 0; outer: for (; r < 3; r++) {" + "inner: continue outer } r"), + njs_str("3") }, + + { njs_str("var x = 0, f = () => ++x;" + "a: x = 1; b: x++; c: f(); d: [1,2].length;" + "e: 's'; g: typeof x; x"), + njs_str("3") }, + { njs_str("a:{a:1}"), njs_str("SyntaxError: Label \"a\" has already been declared") },