[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