From a9f49e71239a4070aec560e33c542a8cd277e648 Mon Sep 17 00:00:00 2001 From: hongzhidao Date: Wed, 23 Jan 2019 19:48:19 +0300 Subject: [PATCH] Simplified function parsing. Avoid creating phony parser structures while parsing function bodies. --- 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(-) diff --git a/njs/njs.c b/njs/njs.c index 3c8f48d2..c59aa22b 100644 --- a/njs/njs.c +++ b/njs/njs.c @@ -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 **start, u_char *end) 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 **start, u_char *end) 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 --git a/njs/njs_generator.c b/njs/njs_generator.c index f0219030..ab6317c5 100644 --- a/njs/njs_generator.c +++ b/njs/njs_generator.c @@ -2303,7 +2303,7 @@ njs_generate_function_scope(njs_vm_t *vm, njs_function_lambda_t *lambda, 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, njs_function_lambda_t *lambda, 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_generator_t *generator, 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 --git a/njs/njs_generator.h b/njs/njs_generator.h index f3d211cc..1ffe022e 100644 --- a/njs/njs_generator.h +++ b/njs/njs_generator.h @@ -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 --git a/njs/njs_parser.c b/njs/njs_parser.c index 6d64a7eb..b5038b70 100644 --- a/njs/njs_parser.c +++ b/njs/njs_parser.c @@ -23,8 +23,6 @@ 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, - 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_token(njs_vm_t *vm, 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 *parser, njs_parser_t *prev) 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 *parser, njs_parser_t *prev) 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 *parser, njs_parser_t *prev) 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 *parser, njs_parser_t *prev) 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 *vm, njs_parser_t *parser) 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 *vm, njs_parser_t *parser) 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 *vm, njs_parser_t *parser) 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_parser_t *parser, 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, njs_parser_t *parser, 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, njs_parser_t *parser, 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 --git a/njs/njs_parser.h b/njs/njs_parser.h index 1aed7972..7f4e1c81 100644 --- a/njs/njs_parser.h +++ b/njs/njs_parser.h @@ -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_t *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); -- 2.47.3