From 4497e6974737b51e7fe40156384e24353a4cfe71 Mon Sep 17 00:00:00 2001 From: Dmitry Volyntsev Date: Wed, 26 Dec 2018 19:57:41 +0300 Subject: [PATCH] Refactored functions related to variables. 1) njs_builtin_add() is refactored out as a minor variant of njs_variable_add(). 2) parser is refactored out from arguments of the functions. --- njs/njs_parser.c | 83 ++++++++++++++++++++++++++++---------- njs/njs_parser.h | 7 ++-- njs/njs_variable.c | 99 +++++++++++++--------------------------------- njs/njs_variable.h | 8 ++-- njs/njs_vm.h | 1 + 5 files changed, 99 insertions(+), 99 deletions(-) diff --git a/njs/njs_parser.c b/njs/njs_parser.c index 68ee8b10..abf7a518 100644 --- a/njs/njs_parser.c +++ b/njs/njs_parser.c @@ -430,6 +430,23 @@ njs_parser_match(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token, } +nxt_inline njs_variable_t * +njs_parser_variable_add(njs_vm_t *vm, njs_parser_t *parser, + njs_variable_type_t type) +{ + return njs_variable_add(vm, parser->scope, &parser->lexer->text, + parser->lexer->key_hash, type); +} + +nxt_inline njs_ret_t +njs_parser_variable_reference(njs_vm_t *vm, njs_parser_t *parser, + njs_parser_node_t *node, njs_variable_reference_t type) +{ + return njs_variable_reference(vm, parser->scope, node, &parser->lexer->text, + parser->lexer->key_hash, type); +} + + static njs_token_t njs_parser_function_declaration(njs_vm_t *vm, njs_parser_t *parser) { @@ -463,12 +480,12 @@ njs_parser_function_declaration(njs_vm_t *vm, njs_parser_t *parser) return NJS_TOKEN_ILLEGAL; } - var = njs_variable_add(vm, parser, NJS_VARIABLE_FUNCTION); + var = njs_parser_variable_add(vm, parser, NJS_VARIABLE_FUNCTION); if (nxt_slow_path(var == NULL)) { return NJS_TOKEN_ERROR; } - ret = njs_variable_reference(vm, parser, node, NJS_DECLARATION); + ret = njs_parser_variable_reference(vm, parser, node, NJS_DECLARATION); if (nxt_slow_path(ret != NXT_OK)) { return NJS_TOKEN_ERROR; } @@ -542,7 +559,7 @@ njs_parser_function_expression(njs_vm_t *vm, njs_parser_t *parser) } if (token == NJS_TOKEN_NAME) { - var = njs_variable_add(vm, parser, NJS_VARIABLE_SHIM); + var = njs_parser_variable_add(vm, parser, NJS_VARIABLE_SHIM); if (nxt_slow_path(var == NULL)) { return NJS_TOKEN_ERROR; } @@ -646,7 +663,7 @@ njs_parser_function_lambda(njs_vm_t *vm, njs_parser_t *parser, return NJS_TOKEN_ILLEGAL; } - arg = njs_variable_add(vm, parser, NJS_VARIABLE_VAR); + arg = njs_parser_variable_add(vm, parser, NJS_VARIABLE_VAR); if (nxt_slow_path(arg == NULL)) { return NJS_TOKEN_ERROR; } @@ -836,7 +853,7 @@ njs_parser_var_statement(njs_vm_t *vm, njs_parser_t *parser) return NJS_TOKEN_ILLEGAL; } - var = njs_variable_add(vm, parser, NJS_VARIABLE_VAR); + var = njs_parser_variable_add(vm, parser, NJS_VARIABLE_VAR); if (nxt_slow_path(var == NULL)) { return NJS_TOKEN_ERROR; } @@ -848,7 +865,7 @@ njs_parser_var_statement(njs_vm_t *vm, njs_parser_t *parser) name->token = NJS_TOKEN_NAME; - ret = njs_variable_reference(vm, parser, name, NJS_DECLARATION); + ret = njs_parser_variable_reference(vm, parser, name, NJS_DECLARATION); if (nxt_slow_path(ret != NXT_OK)) { return NJS_TOKEN_ERROR; } @@ -1299,7 +1316,7 @@ njs_parser_for_var_statement(njs_vm_t *vm, njs_parser_t *parser) return NJS_TOKEN_ILLEGAL; } - var = njs_variable_add(vm, parser, NJS_VARIABLE_VAR); + var = njs_parser_variable_add(vm, parser, NJS_VARIABLE_VAR); if (nxt_slow_path(var == NULL)) { return NJS_TOKEN_ERROR; } @@ -1311,7 +1328,7 @@ njs_parser_for_var_statement(njs_vm_t *vm, njs_parser_t *parser) name->token = NJS_TOKEN_NAME; - ret = njs_variable_reference(vm, parser, name, NJS_DECLARATION); + ret = njs_parser_variable_reference(vm, parser, name, NJS_DECLARATION); if (nxt_slow_path(ret != NXT_OK)) { return NJS_TOKEN_ERROR; } @@ -1584,7 +1601,7 @@ njs_parser_try_statement(njs_vm_t *vm, njs_parser_t *parser) return NJS_TOKEN_ERROR; } - var = njs_variable_add(vm, parser, NJS_VARIABLE_CATCH); + var = njs_parser_variable_add(vm, parser, NJS_VARIABLE_CATCH); if (nxt_slow_path(var == NULL)) { return NJS_TOKEN_ERROR; } @@ -1596,7 +1613,7 @@ njs_parser_try_statement(njs_vm_t *vm, njs_parser_t *parser) node->token = NJS_TOKEN_NAME; - ret = njs_variable_reference(vm, parser, node, NJS_DECLARATION); + ret = njs_parser_variable_reference(vm, parser, node, NJS_DECLARATION); if (nxt_slow_path(ret != NXT_OK)) { return NJS_TOKEN_ERROR; } @@ -1816,7 +1833,7 @@ njs_parser_terminal(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token) break; } - ret = njs_variable_reference(vm, parser, node, NJS_REFERENCE); + ret = njs_parser_variable_reference(vm, parser, node, NJS_REFERENCE); if (nxt_slow_path(ret != NXT_OK)) { return NJS_TOKEN_ERROR; } @@ -2075,11 +2092,23 @@ static njs_token_t njs_parser_builtin_object(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *node) { - njs_ret_t ret; - nxt_uint_t index; - njs_variable_t *var; + uint32_t hash; + nxt_str_t *name; + njs_ret_t ret; + nxt_uint_t index; + njs_variable_t *var; + njs_parser_scope_t *scope; + + scope = parser->scope; - var = njs_builtin_add(vm, parser); + while (scope->type != NJS_SCOPE_GLOBAL) { + scope = scope->parent; + } + + hash = parser->lexer->key_hash; + name = &parser->lexer->text; + + var = njs_variable_add(vm, scope, name, hash, NJS_VARIABLE_VAR); if (nxt_slow_path(var == NULL)) { return NJS_TOKEN_ERROR; } @@ -2090,7 +2119,7 @@ njs_parser_builtin_object(njs_vm_t *vm, njs_parser_t *parser, var->value.type = NJS_OBJECT; var->value.data.truth = 1; - ret = njs_variable_reference(vm, parser, node, NJS_REFERENCE); + ret = njs_variable_reference(vm, scope, node, name, hash, NJS_REFERENCE); if (nxt_slow_path(ret != NXT_OK)) { return NJS_TOKEN_ERROR; } @@ -2107,11 +2136,23 @@ static njs_token_t njs_parser_builtin_function(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *node) { - njs_ret_t ret; - nxt_uint_t index; - njs_variable_t *var; + uint32_t hash; + nxt_str_t *name; + njs_ret_t ret; + nxt_uint_t index; + njs_variable_t *var; + njs_parser_scope_t *scope; + + scope = parser->scope; + + while (scope->type != NJS_SCOPE_GLOBAL) { + scope = scope->parent; + } + + hash = parser->lexer->key_hash; + name = &parser->lexer->text; - var = njs_builtin_add(vm, parser); + var = njs_variable_add(vm, scope, name, hash, NJS_VARIABLE_VAR); if (nxt_slow_path(var == NULL)) { return NJS_TOKEN_ERROR; } @@ -2122,7 +2163,7 @@ njs_parser_builtin_function(njs_vm_t *vm, njs_parser_t *parser, var->value.type = NJS_FUNCTION; var->value.data.truth = 1; - ret = njs_variable_reference(vm, parser, node, NJS_REFERENCE); + ret = njs_variable_reference(vm, scope, node, name, hash, NJS_REFERENCE); if (nxt_slow_path(ret != NXT_OK)) { return NJS_TOKEN_ERROR; } diff --git a/njs/njs_parser.h b/njs/njs_parser.h index 7cda9b21..ab10c0c0 100644 --- a/njs/njs_parser.h +++ b/njs/njs_parser.h @@ -250,8 +250,6 @@ struct njs_parser_scope_s { }; -typedef struct njs_parser_node_s njs_parser_node_t; - struct njs_parser_node_s { njs_token_t token:16; uint8_t ctor:1; @@ -328,8 +326,9 @@ njs_token_t njs_parser_property_name(njs_vm_t *vm, njs_parser_t *parser, njs_token_t njs_parser_property_token(njs_parser_t *parser); njs_token_t njs_parser_token(njs_parser_t *parser); nxt_int_t njs_parser_string_create(njs_vm_t *vm, njs_value_t *value); -njs_ret_t njs_variable_reference(njs_vm_t *vm, njs_parser_t *parser, - njs_parser_node_t *node, njs_variable_reference_t reference); +njs_ret_t njs_variable_reference(njs_vm_t *vm, njs_parser_scope_t *scope, + njs_parser_node_t *node, nxt_str_t *name, uint32_t hash, + njs_variable_reference_t reference); njs_variable_t *njs_variable_get(njs_vm_t *vm, njs_parser_node_t *node); njs_index_t njs_variable_typeof(njs_vm_t *vm, njs_parser_node_t *node); njs_index_t njs_variable_index(njs_vm_t *vm, njs_parser_node_t *node); diff --git a/njs/njs_variable.c b/njs/njs_variable.c index 945c221f..4f2739cb 100644 --- a/njs/njs_variable.c +++ b/njs/njs_variable.c @@ -1,6 +1,7 @@ /* * Copyright (C) Igor Sysoev + * Copyright (C) Dmitry Volyntsev * Copyright (C) NGINX, Inc. */ @@ -15,8 +16,8 @@ typedef struct { } njs_variable_scope_t; -static njs_ret_t njs_variable_find(njs_vm_t *vm, njs_parser_node_t *node, - njs_variable_scope_t *vs); +static njs_ret_t njs_variable_find(njs_vm_t *vm, njs_parser_scope_t *scope, + njs_variable_scope_t *vs, nxt_str_t *name, uint32_t hash); static njs_variable_t *njs_variable_alloc(njs_vm_t *vm, nxt_str_t *name, njs_variable_type_t type); @@ -48,67 +49,17 @@ const nxt_lvlhsh_proto_t njs_variables_hash_proto njs_variable_t * -njs_builtin_add(njs_vm_t *vm, njs_parser_t *parser) +njs_variable_add(njs_vm_t *vm, njs_parser_scope_t *scope, nxt_str_t *name, + uint32_t hash, njs_variable_type_t type) { nxt_int_t ret; njs_variable_t *var; - njs_parser_scope_t *scope; nxt_lvlhsh_query_t lhq; - lhq.key_hash = parser->lexer->key_hash; - lhq.key = parser->lexer->text; - lhq.proto = &njs_variables_hash_proto; - - scope = parser->scope; - - while (scope->type != NJS_SCOPE_GLOBAL) { - scope = scope->parent; - } - - if (nxt_lvlhsh_find(&scope->variables, &lhq) == NXT_OK) { - var = lhq.value; - - return var; - } - - var = njs_variable_alloc(vm, &lhq.key, NJS_VARIABLE_VAR); - if (nxt_slow_path(var == NULL)) { - return var; - } - - lhq.replace = 0; - lhq.value = var; - lhq.pool = vm->mem_cache_pool; - - ret = nxt_lvlhsh_insert(&scope->variables, &lhq); - - if (nxt_fast_path(ret == NXT_OK)) { - return var; - } - - njs_internal_error(vm, "lvlhsh insert failed"); - - nxt_mem_cache_free(vm->mem_cache_pool, var->name.start); - nxt_mem_cache_free(vm->mem_cache_pool, var); - - return NULL; -} - - -njs_variable_t * -njs_variable_add(njs_vm_t *vm, njs_parser_t *parser, njs_variable_type_t type) -{ - nxt_int_t ret; - njs_variable_t *var; - njs_parser_scope_t *scope; - nxt_lvlhsh_query_t lhq; - - lhq.key_hash = parser->lexer->key_hash; - lhq.key = parser->lexer->text; + lhq.key_hash = hash; + lhq.key = *name; lhq.proto = &njs_variables_hash_proto; - scope = parser->scope; - if (type >= NJS_VARIABLE_VAR) { /* * A "var" and "function" declarations are @@ -175,17 +126,18 @@ const nxt_lvlhsh_proto_t njs_reference_hash_proto njs_ret_t -njs_variable_reference(njs_vm_t *vm, njs_parser_t *parser, - njs_parser_node_t *node, njs_variable_reference_t reference) +njs_variable_reference(njs_vm_t *vm, njs_parser_scope_t *scope, + njs_parser_node_t *node, nxt_str_t *name, uint32_t hash, + njs_variable_reference_t reference) { njs_ret_t ret; nxt_lvlhsh_query_t lhq; - ret = njs_name_copy(vm, &node->u.variable_name, &parser->lexer->text); + ret = njs_name_copy(vm, &node->u.variable_name, name); if (nxt_fast_path(ret == NXT_OK)) { - node->variable_name_hash = parser->lexer->key_hash; - node->scope = parser->scope; + node->variable_name_hash = hash; + node->scope = scope; node->reference = reference; lhq.key_hash = node->variable_name_hash; @@ -195,7 +147,7 @@ njs_variable_reference(njs_vm_t *vm, njs_parser_t *parser, lhq.value = node; lhq.pool = vm->mem_cache_pool; - ret = nxt_lvlhsh_insert(&parser->scope->references, &lhq); + ret = nxt_lvlhsh_insert(&scope->references, &lhq); if (nxt_slow_path(ret != NXT_ERROR)) { ret = NXT_OK; @@ -241,7 +193,9 @@ njs_variables_scope_resolve(njs_vm_t *vm, njs_parser_scope_t *scope, } if (!local_scope) { - ret = njs_variable_find(vm, node, &vs); + ret = njs_variable_find(vm, node->scope, &vs, + &node->u.variable_name, + node->variable_name_hash); if (nxt_slow_path(ret != NXT_OK)) { continue; } @@ -308,7 +262,8 @@ njs_variable_typeof(njs_vm_t *vm, njs_parser_node_t *node) return node->index; } - ret = njs_variable_find(vm, node, &vs); + ret = njs_variable_find(vm, node->scope, &vs, &node->u.variable_name, + node->variable_name_hash); if (nxt_fast_path(ret == NXT_OK)) { return vs.variable->index; @@ -348,7 +303,8 @@ njs_variable_get(njs_vm_t *vm, njs_parser_node_t *node) njs_variable_t *var; njs_variable_scope_t vs; - ret = njs_variable_find(vm, node, &vs); + ret = njs_variable_find(vm, node->scope, &vs, &node->u.variable_name, + node->variable_name_hash); if (nxt_slow_path(ret != NXT_OK)) { goto not_found; @@ -446,17 +402,16 @@ not_found: static njs_ret_t -njs_variable_find(njs_vm_t *vm, njs_parser_node_t *node, - njs_variable_scope_t *vs) +njs_variable_find(njs_vm_t *vm, njs_parser_scope_t *scope, + njs_variable_scope_t *vs, nxt_str_t *name, uint32_t hash) { - njs_parser_scope_t *scope, *parent, *previous; + njs_parser_scope_t *parent, *previous; - vs->lhq.key_hash = node->variable_name_hash; - vs->lhq.key = node->u.variable_name; + vs->lhq.key_hash = hash; + vs->lhq.key = *name; vs->lhq.proto = &njs_variables_hash_proto; previous = NULL; - scope = node->scope; for ( ;; ) { if (nxt_lvlhsh_find(&scope->variables, &vs->lhq) == NXT_OK) { @@ -517,6 +472,8 @@ njs_variable_alloc(njs_vm_t *vm, nxt_str_t *name, njs_variable_type_t type) nxt_mem_cache_free(vm->mem_cache_pool, var); + njs_memory_error(vm); + return NULL; } diff --git a/njs/njs_variable.h b/njs/njs_variable.h index fbf56d9f..41e40930 100644 --- a/njs/njs_variable.h +++ b/njs/njs_variable.h @@ -42,9 +42,11 @@ typedef struct { + njs_scope_offset((var)->index) - NJS_INDEX_GLOBAL_OFFSET) -njs_variable_t *njs_builtin_add(njs_vm_t *vm, njs_parser_t *parser); -njs_variable_t *njs_variable_add(njs_vm_t *vm, njs_parser_t *parser, - njs_variable_type_t type); +njs_variable_t *njs_variable_add(njs_vm_t *vm, njs_parser_scope_t *scope, + nxt_str_t *name, uint32_t hash, njs_variable_type_t type); +njs_ret_t njs_variable_reference(njs_vm_t *vm, njs_parser_scope_t *scope, + njs_parser_node_t *node, nxt_str_t *name, uint32_t hash, + njs_variable_reference_t reference); njs_ret_t njs_variables_scope_reference(njs_vm_t *vm, njs_parser_scope_t *scope); njs_ret_t njs_name_copy(njs_vm_t *vm, nxt_str_t *dst, nxt_str_t *src); diff --git a/njs/njs_vm.h b/njs/njs_vm.h index cb353db5..fd7cc240 100644 --- a/njs/njs_vm.h +++ b/njs/njs_vm.h @@ -165,6 +165,7 @@ typedef struct njs_frame_s njs_frame_t; typedef struct njs_native_frame_s njs_native_frame_t; typedef struct njs_property_next_s njs_property_next_t; typedef struct njs_parser_scope_s njs_parser_scope_t; +typedef struct njs_parser_node_s njs_parser_node_t; union njs_value_s { -- 2.47.3