[njs] Simplified function parsing.

Dmitry Volyntsev xeioex at nginx.com
Wed Jan 23 17:39:30 UTC 2019


details:   https://hg.nginx.org/njs/rev/72fce46a7669
branches:  
changeset: 736:72fce46a7669
user:      hongzhidao <hongzhidao at gmail.com>
date:      Wed Jan 23 19:48:19 2019 +0300
description:
Simplified function parsing.

Avoid creating phony parser structures while parsing
function bodies.

diffstat:

 njs/njs.c           |  15 ++++++-------
 njs/njs_generator.c |  25 ++++++++++------------
 njs/njs_generator.h |   2 +-
 njs/njs_parser.c    |  58 +++++++++++++---------------------------------------
 njs/njs_parser.h    |   5 ++-
 5 files changed, 37 insertions(+), 68 deletions(-)

diffs (292 lines):

diff -r 11cfd1d486f7 -r 72fce46a7669 njs/njs.c
--- a/njs/njs.c	Tue Jan 22 18:08:47 2019 +0300
+++ b/njs/njs.c	Wed Jan 23 19:48:19 2019 +0300
@@ -217,11 +217,10 @@ njs_vm_destroy(njs_vm_t *vm)
 nxt_int_t
 njs_vm_compile(njs_vm_t *vm, u_char **start, u_char *end)
 {
-    nxt_int_t          ret;
-    njs_lexer_t        *lexer;
-    njs_parser_t       *parser, *prev;
-    njs_generator_t    *generator;
-    njs_parser_node_t  *node;
+    nxt_int_t         ret;
+    njs_lexer_t      *lexer;
+    njs_parser_t     *parser, *prev;
+    njs_generator_t  *generator;
 
     parser = nxt_mem_cache_zalloc(vm->mem_cache_pool, sizeof(njs_parser_t));
     if (nxt_slow_path(parser == NULL)) {
@@ -252,8 +251,8 @@ njs_vm_compile(njs_vm_t *vm, u_char **st
 
     vm->retval = njs_value_void;
 
-    node = njs_parser(vm, parser, prev);
-    if (nxt_slow_path(node == NULL)) {
+    ret = njs_parser(vm, parser, prev);
+    if (nxt_slow_path(ret != NXT_OK)) {
         goto fail;
     }
 
@@ -279,7 +278,7 @@ njs_vm_compile(njs_vm_t *vm, u_char **st
 
     nxt_memzero(generator, sizeof(njs_generator_t));
 
-    ret = njs_generate_scope(vm, generator, node);
+    ret = njs_generate_scope(vm, generator, parser->scope);
     if (nxt_slow_path(ret != NXT_OK)) {
         goto fail;
     }
diff -r 11cfd1d486f7 -r 72fce46a7669 njs/njs_generator.c
--- a/njs/njs_generator.c	Tue Jan 22 18:08:47 2019 +0300
+++ b/njs/njs_generator.c	Wed Jan 23 19:48:19 2019 +0300
@@ -2303,7 +2303,7 @@ njs_generate_function_scope(njs_vm_t *vm
 
     node = node->right;
 
-    ret = njs_generate_scope(vm, generator, node);
+    ret = njs_generate_scope(vm, generator, node->scope);
 
     if (nxt_fast_path(ret == NXT_OK)) {
         size = 0;
@@ -2334,18 +2334,15 @@ njs_generate_function_scope(njs_vm_t *vm
 
 nxt_int_t
 njs_generate_scope(njs_vm_t *vm, njs_generator_t *generator,
-    njs_parser_node_t *node)
+    njs_parser_scope_t *scope)
 {
-    u_char              *p;
-    size_t              size;
-    uintptr_t           scope_size;
-    nxt_int_t           ret;
-    nxt_uint_t          n;
-    njs_value_t         *value;
-    njs_vm_code_t       *code;
-    njs_parser_scope_t  *scope;
-
-    scope = node->scope;
+    u_char         *p;
+    size_t          size;
+    uintptr_t       scope_size;
+    nxt_int_t       ret;
+    nxt_uint_t      n;
+    njs_value_t    *value;
+    njs_vm_code_t  *code;
 
     generator->code_size = 128;
 
@@ -2357,12 +2354,12 @@ njs_generate_scope(njs_vm_t *vm, njs_gen
     generator->code_start = p;
     generator->code_end = p;
 
-    ret = njs_generate_argument_closures(vm, generator, node);
+    ret = njs_generate_argument_closures(vm, generator, scope->node);
     if (nxt_slow_path(ret != NXT_OK)) {
         return NXT_ERROR;
     }
 
-    if (nxt_slow_path(njs_generator(vm, generator, node) != NXT_OK)) {
+    if (nxt_slow_path(njs_generator(vm, generator, scope->node) != NXT_OK)) {
         return NXT_ERROR;
     }
 
diff -r 11cfd1d486f7 -r 72fce46a7669 njs/njs_generator.h
--- a/njs/njs_generator.h	Tue Jan 22 18:08:47 2019 +0300
+++ b/njs/njs_generator.h	Wed Jan 23 19:48:19 2019 +0300
@@ -29,7 +29,7 @@ struct njs_generator_s {
 
 
 nxt_int_t njs_generate_scope(njs_vm_t *vm, njs_generator_t *generator,
-    njs_parser_node_t *node);
+    njs_parser_scope_t *scope);
 
 
 #endif /* _NJS_GENERATOR_H_INCLUDED_ */
diff -r 11cfd1d486f7 -r 72fce46a7669 njs/njs_parser.c
--- a/njs/njs_parser.c	Tue Jan 22 18:08:47 2019 +0300
+++ b/njs/njs_parser.c	Wed Jan 23 19:48:19 2019 +0300
@@ -23,8 +23,6 @@ static njs_token_t njs_parser_block(njs_
     njs_parser_t *parser, njs_token_t token);
 static njs_token_t njs_parser_function_declaration(njs_vm_t *vm,
     njs_parser_t *parser);
-static njs_parser_t *njs_parser_function_create(njs_vm_t *vm,
-    njs_parser_t *parent);
 static njs_token_t njs_parser_function_lambda(njs_vm_t *vm,
     njs_parser_t *parser, njs_function_lambda_t *lambda, njs_token_t token);
 static njs_token_t njs_parser_return_statement(njs_vm_t *vm,
@@ -68,7 +66,7 @@ static njs_token_t njs_parser_unexpected
     njs_parser_t *parser, njs_token_t token);
 
 
-njs_parser_node_t *
+nxt_int_t
 njs_parser(njs_vm_t *vm, njs_parser_t *parser, njs_parser_t *prev)
 {
     njs_ret_t           ret;
@@ -81,7 +79,7 @@ njs_parser(njs_vm_t *vm, njs_parser_t *p
 
     ret = njs_parser_scope_begin(vm, parser, NJS_SCOPE_GLOBAL);
     if (nxt_slow_path(ret != NXT_OK)) {
-        return NULL;
+        return NXT_ERROR;
     }
 
     if (prev != NULL) {
@@ -111,7 +109,7 @@ njs_parser(njs_vm_t *vm, njs_parser_t *p
 
             ret = nxt_lvlhsh_insert(variables, &lhq);
             if (nxt_slow_path(ret != NXT_OK)) {
-                return NULL;
+                return NXT_ERROR;
             }
         }
     }
@@ -122,7 +120,7 @@ njs_parser(njs_vm_t *vm, njs_parser_t *p
 
         token = njs_parser_statement_chain(vm, parser, token);
         if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
-            return NULL;
+            return NXT_ERROR;
         }
 
         if (token == NJS_TOKEN_CLOSE_BRACE && vm->options.trailer) {
@@ -138,14 +136,16 @@ njs_parser(njs_vm_t *vm, njs_parser_t *p
 
         node = njs_parser_node_alloc(vm);
         if (nxt_slow_path(node == NULL)) {
-            return NULL;
+            return NXT_ERROR;
         }
     }
 
     node->token = NJS_TOKEN_END;
     node->scope = parser->scope;
 
-    return node;
+    parser->scope->node = node;
+
+    return NXT_OK;
 }
 
 
@@ -545,15 +545,8 @@ njs_parser_function_declaration(njs_vm_t
     var->value.type = NJS_FUNCTION;
     var->value.data.truth = 1;
 
-    parser = njs_parser_function_create(vm, parser);
-    if (nxt_slow_path(parser == NULL)) {
-        return NJS_TOKEN_ERROR;
-    }
-
     token = njs_parser_function_lambda(vm, parser, function->u.lambda, token);
 
-    vm->parser = parser->parent;
-
     return token;
 }
 
@@ -578,11 +571,6 @@ njs_parser_function_expression(njs_vm_t 
     node->scope = parser->scope;
     parser->node = node;
 
-    parser = njs_parser_function_create(vm, parser);
-    if (nxt_slow_path(parser == NULL)) {
-        return NJS_TOKEN_ERROR;
-    }
-
     token = njs_parser_token(parser);
     if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
         return token;
@@ -634,31 +622,10 @@ njs_parser_function_expression(njs_vm_t 
 
     njs_parser_scope_end(vm, parser);
 
-    vm->parser = parser->parent;
-
     return token;
 }
 
 
-static njs_parser_t *
-njs_parser_function_create(njs_vm_t *vm, njs_parser_t *parent)
-{
-    njs_parser_t  *parser;
-
-    parser = nxt_mem_cache_zalloc(vm->mem_cache_pool, sizeof(njs_parser_t));
-    if (nxt_slow_path(parser == NULL)) {
-        return NULL;
-    }
-
-    parser->parent = parent;
-    parser->scope = parent->scope;
-    parser->lexer = parent->lexer;
-    vm->parser = parser;
-
-    return parser;
-}
-
-
 static njs_token_t
 njs_parser_function_lambda(njs_vm_t *vm, njs_parser_t *parser,
     njs_function_lambda_t *lambda, njs_token_t token)
@@ -666,7 +633,7 @@ njs_parser_function_lambda(njs_vm_t *vm,
     njs_ret_t          ret;
     njs_index_t        index;
     njs_variable_t     *arg;
-    njs_parser_node_t  *node, *body, *last;
+    njs_parser_node_t  *node, *body, *last, *parent;
 
     ret = njs_parser_scope_begin(vm, parser, NJS_SCOPE_FUNCTION);
     if (nxt_slow_path(ret != NXT_OK)) {
@@ -744,6 +711,7 @@ njs_parser_function_lambda(njs_vm_t *vm,
         return token;
     }
 
+    parent = parser->node;
     parser->node = NULL;
 
     while (token != NJS_TOKEN_CLOSE_BRACE) {
@@ -796,8 +764,12 @@ njs_parser_function_lambda(njs_vm_t *vm,
         node->right->token = NJS_TOKEN_RETURN;
     }
 
-    parser->parent->node->right = parser->node;
+    parent->right = parser->node;
+
     parser->node->scope = parser->scope;
+    parser->scope->node = parser->node;
+
+    parser->node = parent;
 
     njs_parser_scope_end(vm, parser);
 
diff -r 11cfd1d486f7 -r 72fce46a7669 njs/njs_parser.h
--- a/njs/njs_parser.h	Tue Jan 22 18:08:47 2019 +0300
+++ b/njs/njs_parser.h	Wed Jan 23 19:48:19 2019 +0300
@@ -232,6 +232,8 @@ typedef struct {
 
 
 struct njs_parser_scope_s {
+    njs_parser_node_t               *node;
+
     nxt_queue_link_t                link;
     nxt_queue_t                     nested;
 
@@ -289,7 +291,6 @@ struct njs_parser_s {
     njs_lexer_t                     *lexer;
     njs_parser_node_t               *node;
     njs_parser_scope_t              *scope;
-    njs_parser_t                    *parent;
 };
 
 
@@ -308,7 +309,7 @@ njs_token_t njs_lexer_keyword(njs_lexer_
 
 njs_value_t *njs_parser_external(njs_vm_t *vm, njs_parser_t *parser);
 
-njs_parser_node_t *njs_parser(njs_vm_t *vm, njs_parser_t *parser,
+nxt_int_t njs_parser(njs_vm_t *vm, njs_parser_t *parser,
     njs_parser_t *prev);
 njs_token_t njs_parser_arguments(njs_vm_t *vm, njs_parser_t *parser,
     njs_parser_node_t *parent);


More information about the nginx-devel mailing list