From 445a2db67b241886b76cf0efc533c4511074327b Mon Sep 17 00:00:00 2001 From: Dmitry Volyntsev Date: Wed, 16 Jan 2019 18:58:23 +0300 Subject: [PATCH] Making generator block for block statements. --- njs/njs_generator.c | 28 +++++++++++++++++ njs/njs_parser.c | 75 ++++++++++++++++++++++++++++++++++++++------- njs/njs_parser.h | 1 + 3 files changed, 93 insertions(+), 11 deletions(-) diff --git a/njs/njs_generator.c b/njs/njs_generator.c index 575f2aa9..365ab98c 100644 --- a/njs/njs_generator.c +++ b/njs/njs_generator.c @@ -99,6 +99,8 @@ static nxt_int_t njs_generate_break_statement(njs_vm_t *vm, 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_generator_t *generator, njs_parser_node_t *node) 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); @@ -1506,6 +1511,29 @@ njs_generate_statement(njs_vm_t *vm, njs_generator_t *generator, } +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 --git a/njs/njs_parser.c b/njs/njs_parser.c index 8321da9c..6d64a7eb 100644 --- a/njs/njs_parser.c +++ b/njs/njs_parser.c @@ -19,6 +19,8 @@ static njs_token_t njs_parser_statement(njs_vm_t *vm, njs_parser_t *parser, 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_parser_t *parser, 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, njs_parser_t *parser) } } + 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, njs_parser_t *parser) 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, njs_parser_t *parser) 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, njs_parser_t *parser) 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 *vm, njs_parser_t *parser) 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, njs_parser_t *parser) 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 *vm, njs_parser_t *parser, 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, njs_parser_t *parser, nxt_str_t *name, 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, njs_parser_t *parser) 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 --git a/njs/njs_parser.h b/njs/njs_parser.h index d8780e1e..1aed7972 100644 --- a/njs/njs_parser.h +++ b/njs/njs_parser.h @@ -138,6 +138,7 @@ typedef enum { NJS_TOKEN_EXTERNAL, NJS_TOKEN_STATEMENT, + NJS_TOKEN_BLOCK, NJS_TOKEN_VAR, NJS_TOKEN_IF, NJS_TOKEN_ELSE, -- 2.47.3