From: Dmitry Volyntsev Date: Thu, 3 Sep 2026 00:39:41 +0000 (-0700) Subject: Parser: use compact active labels X-Git-Tag: 1.0.2~67 X-Git-Url: https://git.kaiwu.me/%7B@url%7D?a=commitdiff_plain;h=b68a3978309c9a22f3053bd091f02d2df88291a0;p=njs.git Parser: use compact active labels --- diff --git a/src/njs_parser.c b/src/njs_parser.c index a278824b..0a4419a4 100644 --- a/src/njs_parser.c +++ b/src/njs_parser.c @@ -549,6 +549,8 @@ njs_parser_init(njs_vm_t *vm, njs_parser_t *parser, njs_parser_scope_t *scope, lexer = &parser->lexer0; parser->lexer = lexer; + njs_rbtree_init(&parser->labels, njs_parser_scope_rbtree_compare); + return njs_lexer_init(vm, lexer, file, start, end); } @@ -672,7 +674,6 @@ njs_parser_scope_begin(njs_parser_t *parser, njs_scope_t type, scope->type = type; njs_rbtree_init(&scope->variables, njs_parser_scope_rbtree_compare); - njs_rbtree_init(&scope->labels, njs_parser_scope_rbtree_compare); njs_rbtree_init(&scope->references, njs_parser_scope_rbtree_compare); parent = parser->scope; @@ -6036,8 +6037,7 @@ njs_parser_break_continue(njs_parser_t *parser, njs_lexer_token_t *token, return njs_parser_stack_pop(parser); } - if (njs_label_find(parser->vm, parser->scope, token->atom_id) - == NULL) + if (!njs_label_find(parser, token->atom_id)) { njs_parser_syntax_error(parser, "Undefined label \"%V\"", &token->text); @@ -6445,19 +6445,16 @@ njs_parser_labelled_statement(njs_parser_t *parser, njs_lexer_token_t *token, njs_queue_link_t *current) { uintptr_t atom_id; - njs_variable_t *label; atom_id = token->atom_id; - label = njs_label_find(parser->vm, parser->scope, atom_id); - if (label != NULL) { + if (njs_label_find(parser, atom_id)) { njs_parser_syntax_error(parser, "Label \"%V\" " "has already been declared", &token->text); return NJS_DONE; } - label = njs_label_add(parser->vm, parser->scope, atom_id); - if (label == NULL) { + if (njs_label_add(parser, atom_id) != NJS_OK) { return NJS_ERROR; } @@ -6514,7 +6511,7 @@ njs_parser_labelled_statement_after(njs_parser_t *parser, return NJS_ERROR; } - ret = njs_label_remove(parser->vm, parser->scope, atom_id); + ret = njs_label_remove(parser, atom_id); if (ret != NJS_OK) { return NJS_ERROR; } @@ -6917,7 +6914,7 @@ njs_parser_function_declaration_after(njs_parser_t *parser, njs_value_null_set(&parser->node->u.value); ret = njs_parser_variable_reference(parser, parser->scope, parser->node, - atom_id, NJS_DECLARATION); + atom_id); if (ret != NJS_OK) { return NJS_ERROR; } @@ -6994,8 +6991,7 @@ njs_parser_function_expression(njs_parser_t *parser, njs_lexer_token_t *token, var->self = 1; ret = njs_parser_variable_reference(parser, parser->scope, - parser->node->left, atom_id, - NJS_DECLARATION); + parser->node->left, atom_id); if (ret != NJS_OK) { return NJS_ERROR; } @@ -7224,7 +7220,7 @@ njs_parser_arrow_function(njs_parser_t *parser, njs_lexer_token_t *token, } ret = njs_parser_variable_reference(parser, parser->scope, node->left, - NJS_ATOM_STRING_empty, NJS_DECLARATION); + NJS_ATOM_STRING_empty); if (ret != NJS_OK) { return NJS_ERROR; } @@ -8113,8 +8109,7 @@ njs_parser_variable_node(njs_parser_t *parser, uintptr_t atom_id, return NULL; } - ret = njs_parser_variable_reference(parser, parser->scope, node, atom_id, - NJS_DECLARATION); + ret = njs_parser_variable_reference(parser, parser->scope, node, atom_id); if (njs_slow_path(ret != NJS_OK)) { return NULL; } @@ -8171,7 +8166,7 @@ njs_parser_reference(njs_parser_t *parser, njs_lexer_token_t *token) node->token_line = token->line; ret = njs_parser_variable_reference(parser, parser->scope, node, - token->atom_id, NJS_REFERENCE); + token->atom_id); if (njs_slow_path(ret != NJS_OK)) { return NULL; } @@ -8196,7 +8191,7 @@ njs_parser_reference(njs_parser_t *parser, njs_lexer_token_t *token) node->token_line = token->line; ret = njs_parser_variable_reference(parser, parser->scope, node, - token->atom_id, NJS_REFERENCE); + token->atom_id); if (njs_slow_path(ret != NJS_OK)) { return NULL; } @@ -8224,7 +8219,7 @@ njs_parser_reference(njs_parser_t *parser, njs_lexer_token_t *token) node->token_line = token->line; ret = njs_parser_variable_reference(parser, parser->scope, node, - token->atom_id, NJS_REFERENCE); + token->atom_id); if (njs_slow_path(ret != NJS_OK)) { return NULL; } @@ -8973,7 +8968,7 @@ njs_parser_has_side_effect(njs_parser_node_t *node) njs_int_t njs_parser_variable_reference(njs_parser_t *parser, njs_parser_scope_t *scope, - njs_parser_node_t *node, uintptr_t atom_id, njs_reference_type_t type) + njs_parser_node_t *node, uintptr_t atom_id) { njs_rbtree_node_t *rb_node; njs_variable_reference_t *vr; diff --git a/src/njs_parser.h b/src/njs_parser.h index da52dfb2..941a0a10 100644 --- a/src/njs_parser.h +++ b/src/njs_parser.h @@ -14,7 +14,6 @@ struct njs_parser_scope_s { njs_parser_scope_t *parent; njs_rbtree_t variables; - njs_rbtree_t labels; njs_rbtree_t references; njs_arr_t *closures; @@ -35,6 +34,14 @@ typedef struct { } njs_parser_array_item_t; +typedef struct njs_parser_label_s njs_parser_label_t; + +struct njs_parser_label_s { + NJS_RBTREE_NODE (node); + uintptr_t key; +}; + + struct njs_parser_node_s { njs_token_type_t token_type:16; uint8_t ctor:1; @@ -87,6 +94,7 @@ struct njs_parser_s { njs_parser_node_t *node; njs_parser_node_t *target; njs_parser_scope_t *scope; + njs_rbtree_t labels; njs_variable_type_t var_type; njs_int_t ret; @@ -145,8 +153,7 @@ njs_variable_t *njs_variable_resolve(njs_vm_t *vm, njs_parser_node_t *node); njs_index_t njs_variable_index(njs_vm_t *vm, njs_parser_node_t *node); njs_bool_t njs_parser_has_side_effect(njs_parser_node_t *node); njs_int_t njs_parser_variable_reference(njs_parser_t *parser, - njs_parser_scope_t *scope, njs_parser_node_t *node, uintptr_t atom_id, - njs_reference_type_t type); + njs_parser_scope_t *scope, njs_parser_node_t *node, uintptr_t atom_id); njs_token_type_t njs_parser_unexpected_token(njs_vm_t *vm, njs_parser_t *parser, njs_str_t *name, njs_token_type_t type); njs_int_t njs_parser_string_create(njs_vm_t *vm, njs_lexer_token_t *token, diff --git a/src/njs_variable.c b/src/njs_variable.c index 50b13950..47ee5009 100644 --- a/src/njs_variable.c +++ b/src/njs_variable.c @@ -301,59 +301,41 @@ memory_error: } -njs_variable_t * -njs_label_add(njs_vm_t *vm, njs_parser_scope_t *scope, uintptr_t atom_id) +njs_int_t +njs_label_add(njs_parser_t *parser, uintptr_t atom_id) { - njs_variable_t *label; - njs_rbtree_node_t *node; - njs_variable_node_t var_node, *var_node_new; - - var_node.key = atom_id; - - node = njs_rbtree_find(&scope->labels, &var_node.node); - - if (node != NULL) { - return ((njs_variable_node_t *) node)->variable; - } + njs_parser_label_t *label; - label = njs_variable_alloc(vm, atom_id, NJS_VARIABLE_CONST); + label = njs_mp_alloc(parser->vm->mem_pool, sizeof(njs_parser_label_t)); if (njs_slow_path(label == NULL)) { - goto memory_error; - } - - var_node_new = njs_variable_node_alloc(vm, label, atom_id); - if (njs_slow_path(var_node_new == NULL)) { - goto memory_error; + njs_memory_error(parser->vm); + return NJS_ERROR; } - njs_rbtree_insert(&scope->labels, &var_node_new->node); - - return label; + label->key = atom_id; -memory_error: - - njs_memory_error(vm); + njs_rbtree_insert(&parser->labels, &label->node); - return NULL; + return NJS_OK; } njs_int_t -njs_label_remove(njs_vm_t *vm, njs_parser_scope_t *scope, uintptr_t atom_id) +njs_label_remove(njs_parser_t *parser, uintptr_t atom_id) { - njs_rbtree_node_t *node; - njs_variable_node_t var_node; + njs_rbtree_node_t *node; + njs_parser_label_t label; - var_node.key = atom_id; + label.key = atom_id; - node = njs_rbtree_find(&scope->labels, &var_node.node); + node = njs_rbtree_find(&parser->labels, &label.node); if (njs_slow_path(node == NULL)) { - njs_internal_error(vm, "failed to find label while removing"); + njs_internal_error(parser->vm, "failed to find label while removing"); return NJS_ERROR; } - njs_rbtree_delete(&scope->labels, (njs_rbtree_part_t *) node); - njs_variable_node_free(vm, (njs_variable_node_t *) node); + njs_rbtree_delete(&parser->labels, (njs_rbtree_part_t *) node); + njs_mp_free(parser->vm->mem_pool, node); return NJS_OK; } @@ -554,26 +536,14 @@ njs_variable_reference(njs_vm_t *vm, njs_parser_node_t *node) } -njs_variable_t * -njs_label_find(njs_vm_t *vm, njs_parser_scope_t *scope, uintptr_t atom_id) +njs_bool_t +njs_label_find(njs_parser_t *parser, uintptr_t atom_id) { - njs_rbtree_node_t *node; - njs_variable_node_t var_node; - - var_node.key = atom_id; - - do { - node = njs_rbtree_find(&scope->labels, &var_node.node); - - if (node != NULL) { - return ((njs_variable_node_t *) node)->variable; - } + njs_parser_label_t label; - scope = scope->parent; + label.key = atom_id; - } while (scope != NULL); - - return NULL; + return njs_rbtree_find(&parser->labels, &label.node) != NULL; } diff --git a/src/njs_variable.h b/src/njs_variable.h index be1eec68..980782ba 100644 --- a/src/njs_variable.h +++ b/src/njs_variable.h @@ -59,12 +59,9 @@ njs_variable_t *njs_variable_add(njs_parser_t *parser, njs_parser_scope_t *scope, uintptr_t atom_id, njs_variable_type_t type); njs_variable_t *njs_variable_function_add(njs_parser_t *parser, njs_parser_scope_t *scope, uintptr_t atom_id); -njs_variable_t * njs_label_add(njs_vm_t *vm, njs_parser_scope_t *scope, - uintptr_t atom_id); -njs_variable_t *njs_label_find(njs_vm_t *vm, njs_parser_scope_t *scope, - uintptr_t atom_id); -njs_int_t njs_label_remove(njs_vm_t *vm, njs_parser_scope_t *scope, - uintptr_t atom_id); +njs_int_t njs_label_add(njs_parser_t *parser, uintptr_t atom_id); +njs_bool_t njs_label_find(njs_parser_t *parser, uintptr_t atom_id); +njs_int_t njs_label_remove(njs_parser_t *parser, uintptr_t atom_id); njs_variable_t *njs_variable_reference(njs_vm_t *vm, njs_parser_node_t *node); njs_variable_t *njs_variable_scope_add(njs_parser_t *parser, njs_parser_scope_t *scope, njs_parser_scope_t *original,