[njs] Variables handling during code generation is improved.
Dmitry Volyntsev
xeioex at nginx.com
Sat Dec 29 07:33:11 UTC 2018
details: https://hg.nginx.org/njs/rev/9fb7bcaf07ba
branches:
changeset: 708:9fb7bcaf07ba
user: hongzhidao <hongzhidao at gmail.com>
date: Sat Dec 29 01:43:44 2018 +0800
description:
Variables handling during code generation is improved.
All the necessary fields related to a variable are moved into
njs_variable_reference_t.
diffstat:
njs/njs_parser.c | 2 +-
njs/njs_parser.h | 4 +-
njs/njs_parser_expression.c | 2 +-
njs/njs_variable.c | 127 +++++++++++++++++++++----------------------
njs/njs_variable.h | 25 +++++--
5 files changed, 83 insertions(+), 77 deletions(-)
diffs (382 lines):
diff -r 792dbba9b902 -r 9fb7bcaf07ba njs/njs_parser.c
--- a/njs/njs_parser.c Sat Dec 29 01:43:44 2018 +0800
+++ b/njs/njs_parser.c Sat Dec 29 01:43:44 2018 +0800
@@ -440,7 +440,7 @@ njs_parser_variable_add(njs_vm_t *vm, nj
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)
+ njs_parser_node_t *node, njs_reference_type_t type)
{
return njs_variable_reference(vm, parser->scope, node, &parser->lexer->text,
parser->lexer->key_hash, type);
diff -r 792dbba9b902 -r 9fb7bcaf07ba njs/njs_parser.h
--- a/njs/njs_parser.h Sat Dec 29 01:43:44 2018 +0800
+++ b/njs/njs_parser.h Sat Dec 29 01:43:44 2018 +0800
@@ -254,14 +254,12 @@ struct njs_parser_scope_s {
struct njs_parser_node_s {
njs_token_t token:16;
uint8_t ctor:1;
- njs_variable_reference_t reference:2;
uint8_t temporary; /* 1 bit */
uint32_t token_line;
- uint32_t variable_name_hash;
union {
uint32_t length;
- nxt_str_t variable_name;
+ njs_variable_reference_t reference;
njs_value_t value;
njs_vmcode_operation_t operation;
njs_parser_node_t *object;
diff -r 792dbba9b902 -r 9fb7bcaf07ba njs/njs_parser_expression.c
--- a/njs/njs_parser_expression.c Sat Dec 29 01:43:44 2018 +0800
+++ b/njs/njs_parser_expression.c Sat Dec 29 01:43:44 2018 +0800
@@ -670,7 +670,7 @@ njs_parser_unary_expression(njs_vm_t *vm
}
if (token == NJS_TOKEN_TYPEOF && node->token == NJS_TOKEN_NAME) {
- node->reference = NJS_TYPEOF;
+ node->u.reference.type = NJS_TYPEOF;
}
node = njs_parser_node_alloc(vm);
diff -r 792dbba9b902 -r 9fb7bcaf07ba njs/njs_variable.c
--- a/njs/njs_variable.c Sat Dec 29 01:43:44 2018 +0800
+++ b/njs/njs_variable.c Sat Dec 29 01:43:44 2018 +0800
@@ -9,15 +9,8 @@
#include <string.h>
-typedef struct {
- nxt_lvlhsh_query_t lhq;
- njs_variable_t *variable;
- njs_parser_scope_t *scope;
-} njs_variable_scope_t;
-
-
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);
+ njs_variable_reference_t *vr);
static njs_variable_t *njs_variable_alloc(njs_vm_t *vm, nxt_str_t *name,
njs_variable_type_t type);
@@ -106,7 +99,7 @@ njs_reference_hash_test(nxt_lvlhsh_query
node = data;
- if (nxt_strstr_eq(&lhq->key, &node->u.variable_name)) {
+ if (nxt_strstr_eq(&lhq->key, &node->u.reference.name)) {
return NXT_OK;
}
@@ -128,20 +121,23 @@ const nxt_lvlhsh_proto_t njs_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_reference_type_t type)
{
- njs_ret_t ret;
- nxt_lvlhsh_query_t lhq;
+ njs_ret_t ret;
+ nxt_lvlhsh_query_t lhq;
+ njs_variable_reference_t *vr;
- ret = njs_name_copy(vm, &node->u.variable_name, name);
+ vr = &node->u.reference;
+
+ ret = njs_name_copy(vm, &vr->name, name);
if (nxt_fast_path(ret == NXT_OK)) {
- node->variable_name_hash = hash;
node->scope = scope;
- node->reference = reference;
+ vr->hash = hash;
+ vr->type = type;
- lhq.key_hash = node->variable_name_hash;
- lhq.key = node->u.variable_name;
+ lhq.key_hash = hash;
+ lhq.key = vr->name;
lhq.proto = &njs_reference_hash_proto;
lhq.replace = 0;
lhq.value = node;
@@ -162,13 +158,13 @@ static njs_ret_t
njs_variables_scope_resolve(njs_vm_t *vm, njs_parser_scope_t *scope,
nxt_bool_t closure)
{
- njs_ret_t ret;
- nxt_queue_t *nested;
- njs_variable_t *var;
- nxt_queue_link_t *lnk;
- njs_parser_node_t *node;
- nxt_lvlhsh_each_t lhe;
- njs_variable_scope_t vs;
+ njs_ret_t ret;
+ nxt_queue_t *nested;
+ njs_variable_t *var;
+ nxt_queue_link_t *lnk;
+ njs_parser_node_t *node;
+ nxt_lvlhsh_each_t lhe;
+ njs_variable_reference_t *vr;
nested = &scope->nested;
@@ -192,19 +188,19 @@ njs_variables_scope_resolve(njs_vm_t *vm
break;
}
+ vr = &node->u.reference;
+
if (closure) {
- ret = njs_variable_find(vm, node->scope, &vs,
- &node->u.variable_name,
- node->variable_name_hash);
+ ret = njs_variable_find(vm, node->scope, vr);
if (nxt_slow_path(ret != NXT_OK)) {
continue;
}
- if (vs.scope->type == NJS_SCOPE_GLOBAL) {
+ if (vr->scope->type == NJS_SCOPE_GLOBAL) {
continue;
}
- if (node->scope->nesting == vs.scope->nesting) {
+ if (node->scope->nesting == vr->scope->nesting) {
/*
* A variable is referenced locally here, but may be
* referenced non-locally in other places, skipping.
@@ -216,7 +212,7 @@ njs_variables_scope_resolve(njs_vm_t *vm
var = njs_variable_get(vm, node);
if (nxt_slow_path(var == NULL)) {
- if (node->reference != NJS_TYPEOF) {
+ if (vr->type != NJS_TYPEOF) {
return NXT_ERROR;
}
}
@@ -255,18 +251,19 @@ njs_variables_scope_reference(njs_vm_t *
njs_index_t
njs_variable_typeof(njs_vm_t *vm, njs_parser_node_t *node)
{
- nxt_int_t ret;
- njs_variable_scope_t vs;
+ nxt_int_t ret;
+ njs_variable_reference_t *vr;
if (node->index != NJS_INDEX_NONE) {
return node->index;
}
- ret = njs_variable_find(vm, node->scope, &vs, &node->u.variable_name,
- node->variable_name_hash);
+ vr = &node->u.reference;
+
+ ret = njs_variable_find(vm, node->scope, vr);
if (nxt_fast_path(ret == NXT_OK)) {
- return vs.variable->index;
+ return vr->variable->index;
}
return NJS_INDEX_NONE;
@@ -295,16 +292,17 @@ njs_variable_index(njs_vm_t *vm, njs_par
njs_variable_t *
njs_variable_get(njs_vm_t *vm, njs_parser_node_t *node)
{
- nxt_int_t ret;
- nxt_uint_t scope_index;
- nxt_array_t *values;
- njs_index_t index;
- njs_value_t *value;
- njs_variable_t *var;
- njs_variable_scope_t vs;
+ nxt_int_t ret;
+ nxt_uint_t scope_index;
+ nxt_array_t *values;
+ njs_index_t index;
+ njs_value_t *value;
+ njs_variable_t *var;
+ njs_variable_reference_t *vr;
- ret = njs_variable_find(vm, node->scope, &vs, &node->u.variable_name,
- node->variable_name_hash);
+ vr = &node->u.reference;
+
+ ret = njs_variable_find(vm, node->scope, vr);
if (nxt_slow_path(ret != NXT_OK)) {
goto not_found;
@@ -312,11 +310,11 @@ njs_variable_get(njs_vm_t *vm, njs_parse
scope_index = 0;
- if (vs.scope->type > NJS_SCOPE_GLOBAL) {
- scope_index = (node->scope->nesting != vs.scope->nesting);
+ if (vr->scope->type > NJS_SCOPE_GLOBAL) {
+ scope_index = (node->scope->nesting != vr->scope->nesting);
}
- var = vs.variable;
+ var = vr->variable;
index = var->index;
if (index != NJS_INDEX_NONE) {
@@ -327,10 +325,10 @@ njs_variable_get(njs_vm_t *vm, njs_parse
return var;
}
- vs.scope->argument_closures++;
+ vr->scope->argument_closures++;
index = (index >> NJS_SCOPE_SHIFT) + 1;
- if (index > 255 || vs.scope->argument_closures == 0) {
+ if (index > 255 || vr->scope->argument_closures == 0) {
njs_internal_error(vm, "too many argument closures");
return NULL;
@@ -339,11 +337,11 @@ njs_variable_get(njs_vm_t *vm, njs_parse
var->argument = index;
}
- if (node->reference != NJS_DECLARATION && var->type <= NJS_VARIABLE_LET) {
+ if (vr->type != NJS_DECLARATION && var->type <= NJS_VARIABLE_LET) {
goto not_found;
}
- if (vm->options.accumulative && vs.scope->type == NJS_SCOPE_GLOBAL) {
+ if (vm->options.accumulative && vr->scope->type == NJS_SCOPE_GLOBAL) {
/*
* When non-clonable VM runs in accumulative mode all
* global variables should be allocated in absolute scope
@@ -359,7 +357,7 @@ njs_variable_get(njs_vm_t *vm, njs_parse
index = (njs_index_t) value;
} else {
- values = vs.scope->values[scope_index];
+ values = vr->scope->values[scope_index];
if (values == NULL) {
values = nxt_array_create(4, sizeof(njs_value_t),
@@ -368,7 +366,7 @@ njs_variable_get(njs_vm_t *vm, njs_parse
return NULL;
}
- vs.scope->values[scope_index] = values;
+ vr->scope->values[scope_index] = values;
}
value = nxt_array_add(values, &njs_array_mem_proto, vm->mem_cache_pool);
@@ -376,8 +374,8 @@ njs_variable_get(njs_vm_t *vm, njs_parse
return NULL;
}
- index = vs.scope->next_index[scope_index];
- vs.scope->next_index[scope_index] += sizeof(njs_value_t);
+ index = vr->scope->next_index[scope_index];
+ vr->scope->next_index[scope_index] += sizeof(njs_value_t);
}
if (njs_is_object(&var->value)) {
@@ -395,7 +393,7 @@ njs_variable_get(njs_vm_t *vm, njs_parse
not_found:
njs_parser_ref_error(vm, vm->parser, "\"%.*s\" is not defined",
- (int) vs.lhq.key.length, vs.lhq.key.start);
+ (int) vr->name.length, vr->name.start);
return NULL;
}
@@ -403,19 +401,20 @@ not_found:
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)
+ njs_variable_reference_t *vr)
{
+ nxt_lvlhsh_query_t lhq;
njs_parser_scope_t *parent, *previous;
- vs->lhq.key_hash = hash;
- vs->lhq.key = *name;
- vs->lhq.proto = &njs_variables_hash_proto;
+ lhq.key_hash = vr->hash;
+ lhq.key = vr->name;
+ lhq.proto = &njs_variables_hash_proto;
previous = NULL;
for ( ;; ) {
- if (nxt_lvlhsh_find(&scope->variables, &vs->lhq) == NXT_OK) {
- vs->variable = vs->lhq.value;
+ if (nxt_lvlhsh_find(&scope->variables, &lhq) == NXT_OK) {
+ vr->variable = lhq.value;
if (scope->type == NJS_SCOPE_SHIM) {
scope = previous;
@@ -430,7 +429,7 @@ njs_variable_find(njs_vm_t *vm, njs_pars
}
}
- vs->scope = scope;
+ vr->scope = scope;
return NXT_OK;
}
@@ -439,7 +438,7 @@ njs_variable_find(njs_vm_t *vm, njs_pars
if (parent == NULL) {
/* A global scope. */
- vs->scope = scope;
+ vr->scope = scope;
return NXT_DECLINED;
}
diff -r 792dbba9b902 -r 9fb7bcaf07ba njs/njs_variable.h
--- a/njs/njs_variable.h Sat Dec 29 01:43:44 2018 +0800
+++ b/njs/njs_variable.h Sat Dec 29 01:43:44 2018 +0800
@@ -18,13 +18,6 @@ typedef enum {
} njs_variable_type_t;
-typedef enum {
- NJS_DECLARATION = 0,
- NJS_REFERENCE,
- NJS_TYPEOF,
-} njs_variable_reference_t;
-
-
typedef struct {
nxt_str_t name;
@@ -42,11 +35,27 @@ typedef struct {
+ njs_scope_offset((var)->index) - NJS_INDEX_GLOBAL_OFFSET)
+typedef enum {
+ NJS_DECLARATION = 0,
+ NJS_REFERENCE,
+ NJS_TYPEOF,
+} njs_reference_type_t;
+
+
+typedef struct {
+ njs_reference_type_t type;
+ uint32_t hash;
+ nxt_str_t name;
+ njs_variable_t *variable;
+ njs_parser_scope_t *scope;
+} njs_variable_reference_t;
+
+
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_reference_type_t type);
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);
More information about the nginx-devel
mailing list