[njs] Making generator block for block statements.

Dmitry Volyntsev xeioex at nginx.com
Thu Jan 17 14:03:22 UTC 2019


details:   https://hg.nginx.org/njs/rev/0f919fb820e8
branches:  
changeset: 729:0f919fb820e8
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Wed Jan 16 18:58:23 2019 +0300
description:
Making generator block for block statements.

diffstat:

 njs/njs_generator.c |  28 +++++++++++++++++++
 njs/njs_parser.c    |  75 +++++++++++++++++++++++++++++++++++++++++++++-------
 njs/njs_parser.h    |   1 +
 3 files changed, 93 insertions(+), 11 deletions(-)

diffs (230 lines):

diff -r 4c0de77ef946 -r 0f919fb820e8 njs/njs_generator.c
--- a/njs/njs_generator.c	Wed Jan 16 18:55:16 2019 +0300
+++ b/njs/njs_generator.c	Wed Jan 16 18:58:23 2019 +0300
@@ -99,6 +99,8 @@ static nxt_int_t njs_generate_break_stat
     njs_generator_t *generator, njs_parser_node_t *node);
 static nxt_int_t njs_generate_statement(njs_vm_t *vm,
     njs_generator_t *generator, njs_parser_node_t *node);
+static nxt_int_t njs_generate_block_statement(njs_vm_t *vm,
+    njs_generator_t *generator, njs_parser_node_t *node);
 static nxt_int_t njs_generate_children(njs_vm_t *vm, njs_generator_t *generator,
     njs_parser_node_t *node);
 static nxt_int_t njs_generate_stop_statement(njs_vm_t *vm,
@@ -257,6 +259,9 @@ njs_generator(njs_vm_t *vm, njs_generato
     case NJS_TOKEN_STATEMENT:
         return njs_generate_statement(vm, generator, node);
 
+    case NJS_TOKEN_BLOCK:
+        return njs_generate_block_statement(vm, generator, node);
+
     case NJS_TOKEN_END:
         return njs_generate_stop_statement(vm, generator, node);
 
@@ -1507,6 +1512,29 @@ njs_generate_statement(njs_vm_t *vm, njs
 
 
 static nxt_int_t
+njs_generate_block_statement(njs_vm_t *vm, njs_generator_t *generator,
+    njs_parser_node_t *node)
+{
+    nxt_int_t  ret;
+
+    ret = njs_generate_start_block(vm, generator, NJS_GENERATOR_BLOCK,
+                                   &no_label);
+    if (nxt_slow_path(ret != NXT_OK)) {
+        return ret;
+    }
+
+    ret = njs_generate_statement(vm, generator, node->left);
+    if (nxt_slow_path(ret != NXT_OK)) {
+        return ret;
+    }
+
+    njs_generate_patch_block_exit(vm, generator);
+
+    return ret;
+}
+
+
+static nxt_int_t
 njs_generate_children(njs_vm_t *vm, njs_generator_t *generator,
     njs_parser_node_t *node)
 {
diff -r 4c0de77ef946 -r 0f919fb820e8 njs/njs_parser.c
--- a/njs/njs_parser.c	Wed Jan 16 18:55:16 2019 +0300
+++ b/njs/njs_parser.c	Wed Jan 16 18:58:23 2019 +0300
@@ -19,6 +19,8 @@ static njs_token_t njs_parser_statement(
     njs_token_t token);
 static njs_token_t njs_parser_block_statement(njs_vm_t *vm,
     njs_parser_t *parser);
+static njs_token_t njs_parser_block(njs_vm_t *vm,
+    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,
@@ -390,8 +392,9 @@ njs_parser_statement(njs_vm_t *vm, njs_p
 static njs_token_t
 njs_parser_block_statement(njs_vm_t *vm, njs_parser_t *parser)
 {
-    njs_ret_t    ret;
-    njs_token_t  token;
+    njs_ret_t          ret;
+    njs_token_t        token;
+    njs_parser_node_t  *node;
 
     token = njs_parser_token(parser);
     if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
@@ -412,12 +415,48 @@ njs_parser_block_statement(njs_vm_t *vm,
         }
     }
 
+    if (parser->node != NULL) {
+        /* The statement is not empty block or just semicolon. */
+
+        node = njs_parser_node_alloc(vm);
+        if (nxt_slow_path(node == NULL)) {
+            return NJS_TOKEN_ERROR;
+        }
+
+        node->token = NJS_TOKEN_BLOCK;
+        node->left = parser->node;
+        node->right = NULL;
+        parser->node = node;
+    }
+
     njs_parser_scope_end(vm, parser);
 
     return njs_parser_token(parser);
 }
 
 
+static njs_token_t
+njs_parser_block(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token)
+{
+    njs_parser_node_t  *node;
+
+    token = njs_parser_statement(vm, parser, token);
+    if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
+        return token;
+    }
+
+    node = parser->node;
+
+    if (node != NULL && node->token == NJS_TOKEN_BLOCK) {
+        parser->node = node->left;
+
+        nxt_mem_cache_free(vm->mem_cache_pool, node);
+    }
+
+    return token;
+}
+
+
 nxt_inline njs_token_t
 njs_parser_match(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token,
     njs_token_t match)
@@ -933,7 +972,7 @@ njs_parser_if_statement(njs_vm_t *vm, nj
 
     cond = parser->node;
 
-    token = njs_parser_statement(vm, parser, token);
+    token = njs_parser_block(vm, parser, token);
     if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
         return token;
     }
@@ -947,7 +986,7 @@ njs_parser_if_statement(njs_vm_t *vm, nj
             return token;
         }
 
-        token = njs_parser_statement(vm, parser, token);
+        token = njs_parser_block(vm, parser, token);
         if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
             return token;
         }
@@ -1104,7 +1143,7 @@ njs_parser_while_statement(njs_vm_t *vm,
 
     cond = parser->node;
 
-    token = njs_parser_statement(vm, parser, token);
+    token = njs_parser_block(vm, parser, token);
     if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
         return token;
     }
@@ -1134,7 +1173,7 @@ njs_parser_do_while_statement(njs_vm_t *
         return token;
     }
 
-    token = njs_parser_statement(vm, parser, token);
+    token = njs_parser_block(vm, parser, token);
     if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
         return token;
     }
@@ -1252,7 +1291,7 @@ njs_parser_for_statement(njs_vm_t *vm, n
         return token;
     }
 
-    token = njs_parser_statement(vm, parser, token);
+    token = njs_parser_block(vm, parser, token);
     if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
         return token;
     }
@@ -1418,7 +1457,7 @@ njs_parser_for_var_in_statement(njs_vm_t
         return token;
     }
 
-    token = njs_parser_statement(vm, parser, token);
+    token = njs_parser_block(vm, parser, token);
     if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
         return token;
     }
@@ -1467,7 +1506,7 @@ njs_parser_for_in_statement(njs_vm_t *vm
         return token;
     }
 
-    token = njs_parser_statement(vm, parser, token);
+    token = njs_parser_block(vm, parser, token);
     if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
         return token;
     }
@@ -1677,14 +1716,28 @@ njs_parser_try_statement(njs_vm_t *vm, n
 static njs_token_t
 njs_parser_try_block(njs_vm_t *vm, njs_parser_t *parser)
 {
-    njs_token_t  token;
+    njs_token_t        token;
+    njs_parser_node_t  *node;
 
     token = njs_parser_token(parser);
     if (nxt_slow_path(token != NJS_TOKEN_OPEN_BRACE)) {
         return NJS_TOKEN_ILLEGAL;
     }
 
-    return njs_parser_block_statement(vm, parser);
+    token = njs_parser_block_statement(vm, parser);
+    if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
+        return token;
+    }
+
+    node = parser->node;
+
+    if (node != NULL && node->token == NJS_TOKEN_BLOCK) {
+        parser->node = node->left;
+
+        nxt_mem_cache_free(vm->mem_cache_pool, node);
+    }
+
+    return token;
 }
 
 
diff -r 4c0de77ef946 -r 0f919fb820e8 njs/njs_parser.h
--- a/njs/njs_parser.h	Wed Jan 16 18:55:16 2019 +0300
+++ b/njs/njs_parser.h	Wed Jan 16 18:58:23 2019 +0300
@@ -138,6 +138,7 @@ typedef enum {
     NJS_TOKEN_EXTERNAL,
 
     NJS_TOKEN_STATEMENT,
+    NJS_TOKEN_BLOCK,
     NJS_TOKEN_VAR,
     NJS_TOKEN_IF,
     NJS_TOKEN_ELSE,


More information about the nginx-devel mailing list