[njs] Decoupling parser structure from the main VM structure.
Dmitry Volyntsev
xeioex at nginx.com
Wed Feb 24 14:51:02 UTC 2021
details: https://hg.nginx.org/njs/rev/1f22e9008cc3
branches:
changeset: 1610:1f22e9008cc3
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Wed Feb 24 14:48:20 2021 +0000
description:
Decoupling parser structure from the main VM structure.
vm->parser is only needed during parsing phase, so it can be eliminated.
This improves dependencies tracking and readability.
As a side effect it fixes #372 issue on Github: previously, Function
constructor left VM context in inconsistent state if compilation failed.
The direct root cause was that a function object was created, but
because Function constructor ended prematurely the object was not fully
initialized. This is not a problem by itself because usually this
partially created object cannot be referenced. In the accumulative mode,
which is only enabled in CLI, vm->parser was used to store the references
to the variables from the previous iteration.
diffstat:
src/njs_builtin.c | 6 +--
src/njs_function.c | 22 ++++--------
src/njs_module.c | 10 +++--
src/njs_parser.c | 84 +++++++++++++++++------------------------------
src/njs_parser.h | 9 ++--
src/njs_regexp.c | 8 +----
src/njs_shell.c | 10 ++--
src/njs_variable.c | 23 ++++++------
src/njs_variable.h | 4 +-
src/njs_vm.c | 67 ++++++++++++--------------------------
src/njs_vm.h | 1 -
src/test/njs_unit_test.c | 20 ++++++++--
12 files changed, 104 insertions(+), 160 deletions(-)
diffs (695 lines):
diff -r 4197cc28ea9c -r 1f22e9008cc3 src/njs_builtin.c
--- a/src/njs_builtin.c Fri Feb 19 17:27:44 2021 +0000
+++ b/src/njs_builtin.c Wed Feb 24 14:48:20 2021 +0000
@@ -613,10 +613,6 @@ njs_vm_expression_completions(njs_vm_t *
njs_lvlhsh_query_t lhq;
njs_variable_node_t var_node;
- if (njs_slow_path(vm->parser == NULL)) {
- return NULL;
- }
-
p = expression->start;
end = p + expression->length;
@@ -635,7 +631,7 @@ njs_vm_expression_completions(njs_vm_t *
var_node.key = (uintptr_t) lhq.value;
- node = njs_rbtree_find(&vm->parser->scope->variables, &var_node.node);
+ node = njs_rbtree_find(vm->variables_hash, &var_node.node);
if (njs_slow_path(node == NULL)) {
return NULL;
}
diff -r 4197cc28ea9c -r 1f22e9008cc3 src/njs_function.c
--- a/src/njs_function.c Fri Feb 19 17:27:44 2021 +0000
+++ b/src/njs_function.c Wed Feb 24 14:48:20 2021 +0000
@@ -874,7 +874,7 @@ njs_function_constructor(njs_vm_t *vm, n
njs_str_t str, file;
njs_uint_t i;
njs_lexer_t lexer;
- njs_parser_t *parser;
+ njs_parser_t parser;
njs_vm_code_t *code;
njs_function_t *function;
njs_generator_t generator;
@@ -926,15 +926,6 @@ njs_function_constructor(njs_vm_t *vm, n
return NJS_ERROR;
}
- vm->options.accumulative = 1;
-
- parser = njs_mp_zalloc(vm->mem_pool, sizeof(njs_parser_t));
- if (njs_slow_path(parser == NULL)) {
- return NJS_ERROR;
- }
-
- vm->parser = parser;
-
file = njs_str_value("runtime");
ret = njs_lexer_init(vm, &lexer, &file, str.start, str.start + str.length);
@@ -942,10 +933,11 @@ njs_function_constructor(njs_vm_t *vm, n
return ret;
}
- parser->vm = vm;
- parser->lexer = &lexer;
+ njs_memzero(&parser, sizeof(njs_parser_t));
- ret = njs_parser(parser, NULL);
+ parser.lexer = &lexer;
+
+ ret = njs_parser(vm, &parser, NULL);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
}
@@ -957,7 +949,7 @@ njs_function_constructor(njs_vm_t *vm, n
* the global object in a portable way.
*/
- node = parser->node;
+ node = parser.node;
type = &safe_ast[0];
for (; *type != NJS_TOKEN_ILLEGAL; type++, node = node->right) {
@@ -971,7 +963,7 @@ njs_function_constructor(njs_vm_t *vm, n
}
}
- scope = parser->scope;
+ scope = parser.scope;
ret = njs_variables_copy(vm, &scope->variables, vm->variables_hash);
if (njs_slow_path(ret != NJS_OK)) {
diff -r 4197cc28ea9c -r 1f22e9008cc3 src/njs_module.c
--- a/src/njs_module.c Fri Feb 19 17:27:44 2021 +0000
+++ b/src/njs_module.c Wed Feb 24 14:48:20 2021 +0000
@@ -40,7 +40,7 @@ static njs_int_t njs_module_read(njs_vm_
static njs_module_t *njs_module_find(njs_vm_t *vm, njs_str_t *name,
njs_bool_t local);
static njs_module_t *njs_module_add(njs_vm_t *vm, njs_str_t *name);
-static njs_int_t njs_module_insert(njs_vm_t *vm, njs_module_t *module);
+static njs_int_t njs_module_insert(njs_parser_t *parser, njs_module_t *module);
njs_int_t
@@ -273,7 +273,7 @@ njs_parser_module_after(njs_parser_t *pa
module = (njs_module_t *) parser->target;
if (module->index == 0) {
- ret = njs_module_insert(parser->vm, module);
+ ret = njs_module_insert(parser, module);
if (njs_slow_path(ret != NJS_OK)) {
return NJS_ERROR;
}
@@ -564,12 +564,14 @@ njs_module_add(njs_vm_t *vm, njs_str_t *
static njs_int_t
-njs_module_insert(njs_vm_t *vm, njs_module_t *module)
+njs_module_insert(njs_parser_t *parser, njs_module_t *module)
{
+ njs_vm_t *vm;
njs_module_t **value;
njs_parser_scope_t *scope;
- scope = njs_parser_global_scope(vm);
+ scope = njs_parser_global_scope(parser);
+ vm = parser->vm;
module->index = njs_scope_next_index(vm, scope, NJS_SCOPE_INDEX_LOCAL,
&njs_value_undefined);
diff -r 4197cc28ea9c -r 1f22e9008cc3 src/njs_parser.c
--- a/src/njs_parser.c Fri Feb 19 17:27:44 2021 +0000
+++ b/src/njs_parser.c Wed Feb 24 14:48:20 2021 +0000
@@ -503,23 +503,26 @@ njs_parser_reject(njs_parser_t *parser)
njs_int_t
-njs_parser(njs_parser_t *parser, njs_parser_t *prev)
+njs_parser(njs_vm_t *vm, njs_parser_t *parser, njs_rbtree_t *prev_vars)
{
njs_int_t ret;
njs_lexer_token_t *token;
+ parser->vm = vm;
+
+ njs_set_undefined(&vm->retval);
+
ret = njs_parser_scope_begin(parser, NJS_SCOPE_GLOBAL);
if (njs_slow_path(ret != NJS_OK)) {
return NJS_ERROR;
}
- if (prev != NULL) {
+ if (prev_vars != NULL) {
/*
* Copy the global scope variables from the previous
* iteration of the accumulative mode.
*/
- ret = njs_variables_copy(parser->vm, &parser->scope->variables,
- &prev->scope->variables);
+ ret = njs_variables_copy(vm, &parser->scope->variables, prev_vars);
if (ret != NJS_OK) {
return ret;
}
@@ -551,7 +554,7 @@ njs_parser(njs_parser_t *parser, njs_par
return NJS_ERROR;
}
- if (njs_is_error(&parser->vm->retval)) {
+ if (njs_is_error(&vm->retval)) {
return NJS_ERROR;
}
@@ -1196,11 +1199,14 @@ njs_parser_regexp_literal(njs_parser_t *
{
u_char *p;
njs_str_t text;
+ njs_int_t ret;
njs_lexer_t *lexer;
- njs_value_t *value;
+ njs_value_t *value, retval;
njs_regexp_flags_t flags;
njs_regexp_pattern_t *pattern;
+ static const njs_value_t string_message = njs_string("message");
+
value = &parser->node->u.value;
lexer = parser->lexer;
@@ -1269,6 +1275,18 @@ njs_parser_regexp_literal(njs_parser_t *
text.length, flags);
if (njs_slow_path(pattern == NULL)) {
+ ret = njs_value_property(parser->vm, &parser->vm->retval,
+ njs_value_arg(&string_message),
+ &retval);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return NJS_ERROR;
+ }
+
+ njs_string_get(&retval, &text);
+ njs_value_undefined_set(&parser->vm->retval);
+
+ njs_parser_syntax_error(parser, "%V", &text);
+
return NJS_ERROR;
}
@@ -6460,7 +6478,7 @@ njs_parser_function_declaration(njs_pars
njs_lexer_consume_token(parser->lexer, 1);
- var = njs_variable_add(parser->vm, parser->scope, unique_id,
+ var = njs_variable_add(parser, parser->scope, unique_id,
NJS_VARIABLE_FUNCTION);
if (var == NULL) {
return NJS_ERROR;
@@ -6552,7 +6570,7 @@ njs_parser_function_expression(njs_parse
}
if (njs_lexer_token_is_binding_identifier(token)) {
- var = njs_variable_add(parser->vm, parser->scope, token->unique_id,
+ var = njs_variable_add(parser, parser->scope, token->unique_id,
NJS_VARIABLE_SHIM);
if (var == NULL) {
return NJS_ERROR;
@@ -6649,7 +6667,7 @@ njs_parser_formal_parameters(njs_parser_
default:
/* SingleNameBinding */
if (njs_lexer_token_is_binding_identifier(token)) {
- arg = njs_variable_add(parser->vm, parser->scope,
+ arg = njs_variable_add(parser, parser->scope,
token->unique_id, NJS_VARIABLE_VAR);
if (arg == NULL) {
return NJS_ERROR;
@@ -6764,7 +6782,7 @@ njs_parser_arrow_function(njs_parser_t *
njs_parser_arrow_function_args_after);
} else if (njs_lexer_token_is_binding_identifier(token)) {
- arg = njs_variable_add(parser->vm, parser->scope,
+ arg = njs_variable_add(parser, parser->scope,
token->unique_id, NJS_VARIABLE_VAR);
if (arg == NULL) {
return NJS_ERROR;
@@ -7517,7 +7535,7 @@ njs_parser_variable_node(njs_parser_t *p
njs_variable_t *var;
njs_parser_node_t *node;
- var = njs_variable_add(parser->vm, parser->scope, unique_id, type);
+ var = njs_variable_add(parser, parser->scope, unique_id, type);
if (njs_slow_path(var == NULL)) {
return NULL;
}
@@ -7590,7 +7608,7 @@ njs_parser_reference(njs_parser_t *parse
return NULL;
}
- var = njs_variable_add(parser->vm, scope, token->unique_id,
+ var = njs_variable_add(parser, scope, token->unique_id,
NJS_VARIABLE_VAR);
if (njs_slow_path(var == NULL)) {
return NULL;
@@ -7625,7 +7643,7 @@ njs_parser_reference(njs_parser_t *parse
return NULL;
}
- var = njs_variable_add(parser->vm, scope, token->unique_id,
+ var = njs_variable_add(parser, scope, token->unique_id,
NJS_VARIABLE_VAR);
if (njs_slow_path(var == NULL)) {
return NULL;
@@ -8319,46 +8337,6 @@ njs_parser_unexpected_token(njs_vm_t *vm
}
-u_char *
-njs_parser_trace_handler(njs_trace_t *trace, njs_trace_data_t *td,
- u_char *start)
-{
- u_char *p;
- size_t size;
- njs_vm_t *vm;
- njs_lexer_t *lexer;
- njs_parser_t *parser;
-
- size = njs_length("InternalError: ");
- memcpy(start, "InternalError: ", size);
- p = start + size;
-
- vm = trace->data;
-
- trace = trace->next;
- p = trace->handler(trace, td, p);
-
- parser = vm->parser;
-
- if (parser != NULL && parser->lexer != NULL) {
- lexer = parser->lexer;
-
- if (lexer->file.length != 0) {
- njs_internal_error(vm, "%s in %V:%uD", start, &lexer->file,
- parser->lexer->token->line);
- } else {
- njs_internal_error(vm, "%s in %uD", start,
- parser->lexer->token->line);
- }
-
- } else {
- njs_internal_error(vm, "%s", start);
- }
-
- return p;
-}
-
-
static void
njs_parser_scope_error(njs_vm_t *vm, njs_parser_scope_t *scope,
njs_object_type_t type, uint32_t line, const char *fmt, va_list args)
diff -r 4197cc28ea9c -r 1f22e9008cc3 src/njs_parser.h
--- a/src/njs_parser.h Fri Feb 19 17:27:44 2021 +0000
+++ b/src/njs_parser.h Wed Feb 24 14:48:20 2021 +0000
@@ -110,7 +110,8 @@ njs_int_t njs_parser_failed_state(njs_pa
intptr_t njs_parser_scope_rbtree_compare(njs_rbtree_node_t *node1,
njs_rbtree_node_t *node2);
-njs_int_t njs_parser(njs_parser_t *parser, njs_parser_t *prev);
+njs_int_t njs_parser(njs_vm_t *vm, njs_parser_t *parser,
+ njs_rbtree_t *prev_vars);
njs_int_t njs_parser_module_lambda(njs_parser_t *parser,
njs_lexer_token_t *token, njs_queue_link_t *current);
@@ -121,8 +122,6 @@ njs_token_type_t njs_parser_unexpected_t
njs_str_t *name, njs_token_type_t type);
njs_int_t njs_parser_string_create(njs_vm_t *vm, njs_lexer_token_t *token,
njs_value_t *value);
-u_char *njs_parser_trace_handler(njs_trace_t *trace, njs_trace_data_t *td,
- u_char *start);
void njs_parser_lexer_error(njs_parser_t *parser,
njs_object_type_t type, const char *fmt, ...);
void njs_parser_node_error(njs_vm_t *vm, njs_parser_node_t *node,
@@ -201,11 +200,11 @@ njs_parser_node_string(njs_vm_t *vm, njs
njs_inline njs_parser_scope_t *
-njs_parser_global_scope(njs_vm_t *vm)
+njs_parser_global_scope(njs_parser_t *parser)
{
njs_parser_scope_t *scope;
- scope = vm->parser->scope;
+ scope = parser->scope;
while (scope->type != NJS_SCOPE_GLOBAL) {
scope = scope->parent;
diff -r 4197cc28ea9c -r 1f22e9008cc3 src/njs_regexp.c
--- a/src/njs_regexp.c Fri Feb 19 17:27:44 2021 +0000
+++ b/src/njs_regexp.c Wed Feb 24 14:48:20 2021 +0000
@@ -536,13 +536,7 @@ njs_regexp_compile_trace_handler(njs_tra
trace = trace->next;
p = trace->handler(trace, td, start);
- if (vm->parser != NULL && vm->parser->lexer != NULL) {
- njs_syntax_error(vm, "%*s in %uD", p - start, start,
- vm->parser->lexer->line);
-
- } else {
- njs_syntax_error(vm, "%*s", p - start, start);
- }
+ njs_syntax_error(vm, "%*s", p - start, start);
return p;
}
diff -r 4197cc28ea9c -r 1f22e9008cc3 src/njs_shell.c
--- a/src/njs_shell.c Fri Feb 19 17:27:44 2021 +0000
+++ b/src/njs_shell.c Wed Feb 24 14:48:20 2021 +0000
@@ -996,8 +996,8 @@ njs_completion_generator(const char *tex
cmpl->length = njs_strlen(text);
cmpl->suffix_completions = NULL;
- if (vm->parser != NULL) {
- cmpl->node = njs_rbtree_min(&vm->parser->scope->variables);
+ if (vm->variables_hash != NULL) {
+ cmpl->node = njs_rbtree_min(vm->variables_hash);
}
}
@@ -1005,12 +1005,12 @@ next:
switch (cmpl->phase) {
case NJS_COMPLETION_VAR:
- if (vm->parser == NULL) {
+ variables = vm->variables_hash;
+
+ if (variables == NULL) {
njs_next_phase(cmpl);
}
- variables = &vm->parser->scope->variables;
-
while (njs_rbtree_is_there_successor(variables, cmpl->node)) {
var_node = (njs_variable_node_t *) cmpl->node;
diff -r 4197cc28ea9c -r 1f22e9008cc3 src/njs_variable.c
--- a/src/njs_variable.c Fri Feb 19 17:27:44 2021 +0000
+++ b/src/njs_variable.c Wed Feb 24 14:48:20 2021 +0000
@@ -9,7 +9,7 @@
#include <njs_main.h>
-static njs_variable_t *njs_variable_scope_add(njs_vm_t *vm,
+static njs_variable_t *njs_variable_scope_add(njs_parser_t *parser,
njs_parser_scope_t *scope, uintptr_t unique_id, njs_variable_type_t type);
static njs_int_t njs_variable_reference_resolve(njs_vm_t *vm,
njs_variable_reference_t *vr, njs_parser_scope_t *node_scope);
@@ -18,12 +18,12 @@ static njs_variable_t *njs_variable_allo
njs_variable_t *
-njs_variable_add(njs_vm_t *vm, njs_parser_scope_t *scope, uintptr_t unique_id,
- njs_variable_type_t type)
+njs_variable_add(njs_parser_t *parser, njs_parser_scope_t *scope,
+ uintptr_t unique_id, njs_variable_type_t type)
{
njs_variable_t *var;
- var = njs_variable_scope_add(vm, scope, unique_id, type);
+ var = njs_variable_scope_add(parser, scope, unique_id, type);
if (njs_slow_path(var == NULL)) {
return NULL;
}
@@ -33,7 +33,7 @@ njs_variable_add(njs_vm_t *vm, njs_parse
do {
scope = scope->parent;
- var = njs_variable_scope_add(vm, scope, unique_id, type);
+ var = njs_variable_scope_add(parser, scope, unique_id, type);
if (njs_slow_path(var == NULL)) {
return NULL;
}
@@ -78,7 +78,7 @@ njs_variables_copy(njs_vm_t *vm, njs_rbt
static njs_variable_t *
-njs_variable_scope_add(njs_vm_t *vm, njs_parser_scope_t *scope,
+njs_variable_scope_add(njs_parser_t *parser, njs_parser_scope_t *scope,
uintptr_t unique_id, njs_variable_type_t type)
{
njs_variable_t *var;
@@ -104,7 +104,7 @@ njs_variable_scope_add(njs_vm_t *vm, njs
if (scope->type == NJS_SCOPE_GLOBAL) {
- if (vm->options.module) {
+ if (parser->vm->options.module) {
if (type == NJS_VARIABLE_FUNCTION
|| var->type == NJS_VARIABLE_FUNCTION)
{
@@ -116,12 +116,12 @@ njs_variable_scope_add(njs_vm_t *vm, njs
return var;
}
- var = njs_variable_alloc(vm, unique_id, type);
+ var = njs_variable_alloc(parser->vm, unique_id, type);
if (njs_slow_path(var == NULL)) {
goto memory_error;
}
- var_node_new = njs_variable_node_alloc(vm, var, unique_id);
+ var_node_new = njs_variable_node_alloc(parser->vm, var, unique_id);
if (njs_slow_path(var_node_new == NULL)) {
goto memory_error;
}
@@ -132,7 +132,7 @@ njs_variable_scope_add(njs_vm_t *vm, njs
memory_error:
- njs_memory_error(vm);
+ njs_memory_error(parser->vm);
return NULL;
@@ -140,8 +140,7 @@ fail:
entry = njs_lexer_entry(unique_id);
- njs_parser_syntax_error(vm->parser,
- "\"%V\" has already been declared",
+ njs_parser_syntax_error(parser, "\"%V\" has already been declared",
&entry->name);
return NULL;
}
diff -r 4197cc28ea9c -r 1f22e9008cc3 src/njs_variable.h
--- a/src/njs_variable.h Fri Feb 19 17:27:44 2021 +0000
+++ b/src/njs_variable.h Wed Feb 24 14:48:20 2021 +0000
@@ -55,8 +55,8 @@ typedef struct {
} njs_variable_node_t;
-njs_variable_t *njs_variable_add(njs_vm_t *vm, njs_parser_scope_t *scope,
- uintptr_t unique_id, njs_variable_type_t type);
+njs_variable_t *njs_variable_add(njs_parser_t *parser,
+ njs_parser_scope_t *scope, uintptr_t unique_id, njs_variable_type_t type);
njs_int_t njs_variables_copy(njs_vm_t *vm, njs_rbtree_t *variables,
njs_rbtree_t *prev_variables);
njs_variable_t * njs_label_add(njs_vm_t *vm, njs_parser_scope_t *scope,
diff -r 4197cc28ea9c -r 1f22e9008cc3 src/njs_vm.c
--- a/src/njs_vm.c Fri Feb 19 17:27:44 2021 +0000
+++ b/src/njs_vm.c Wed Feb 24 14:48:20 2021 +0000
@@ -68,7 +68,6 @@ njs_vm_create(njs_vm_opt_t *options)
vm->trace.level = NJS_LEVEL_TRACE;
vm->trace.size = 2048;
- vm->trace.handler = njs_parser_trace_handler;
vm->trace.data = vm;
njs_set_undefined(&vm->retval);
@@ -113,66 +112,48 @@ njs_vm_destroy(njs_vm_t *vm)
njs_int_t
njs_vm_compile(njs_vm_t *vm, u_char **start, u_char *end)
{
- njs_int_t ret;
- njs_str_t ast;
- njs_chb_t chain;
- njs_lexer_t lexer;
- njs_parser_t *parser, *prev;
- njs_vm_code_t *code;
- njs_generator_t generator;
- njs_parser_scope_t *scope;
-
- if (vm->parser != NULL && !vm->options.accumulative) {
- return NJS_ERROR;
- }
+ njs_int_t ret;
+ njs_str_t ast;
+ njs_chb_t chain;
+ njs_lexer_t lexer;
+ njs_parser_t parser;
+ njs_vm_code_t *code;
+ njs_generator_t generator;
if (vm->modules != NULL && vm->options.accumulative) {
njs_module_reset(vm);
}
- parser = njs_mp_zalloc(vm->mem_pool, sizeof(njs_parser_t));
- if (njs_slow_path(parser == NULL)) {
- return NJS_ERROR;
- }
-
- prev = vm->parser;
- vm->parser = parser;
-
ret = njs_lexer_init(vm, &lexer, &vm->options.file, *start, end);
if (njs_slow_path(ret != NJS_OK)) {
return NJS_ERROR;
}
- parser->vm = vm;
- parser->lexer = &lexer;
+ njs_memzero(&parser, sizeof(njs_parser_t));
- njs_set_undefined(&vm->retval);
+ parser.lexer = &lexer;
- ret = njs_parser(parser, prev);
+ ret = njs_parser(vm, &parser, vm->variables_hash);
if (njs_slow_path(ret != NJS_OK)) {
- goto fail;
- }
-
- parser->lexer = NULL;
-
- scope = parser->scope;
-
- ret = njs_variables_scope_reference(vm, scope);
- if (njs_slow_path(ret != NJS_OK)) {
- goto fail;
+ return NJS_ERROR;
}
*start = lexer.start;
+ ret = njs_variables_scope_reference(vm, parser.scope);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return NJS_ERROR;
+ }
+
njs_memzero(&generator, sizeof(njs_generator_t));
- code = njs_generate_scope(vm, &generator, scope, &njs_entry_main);
+ code = njs_generate_scope(vm, &generator, parser.scope, &njs_entry_main);
if (njs_slow_path(code == NULL)) {
if (!njs_is_error(&vm->retval)) {
njs_internal_error(vm, "njs_generate_scope() failed");
}
- goto fail;
+ return NJS_ERROR;
}
vm->main_index = code - (njs_vm_code_t *) vm->codes->start;
@@ -180,7 +161,7 @@ njs_vm_compile(njs_vm_t *vm, u_char **st
vm->global_scope = generator.local_scope;
vm->scope_size = generator.scope_size;
- vm->variables_hash = &scope->variables;
+ vm->variables_hash = &parser.scope->variables;
if (vm->options.init && !vm->options.accumulative) {
ret = njs_vm_init(vm);
@@ -195,7 +176,7 @@ njs_vm_compile(njs_vm_t *vm, u_char **st
if (njs_slow_path(vm->options.ast)) {
njs_chb_init(&chain, vm->mem_pool);
- ret = njs_parser_serialize_ast(parser->node, &chain);
+ ret = njs_parser_serialize_ast(parser.node, &chain);
if (njs_slow_path(ret == NJS_ERROR)) {
return ret;
}
@@ -210,13 +191,7 @@ njs_vm_compile(njs_vm_t *vm, u_char **st
njs_mp_free(vm->mem_pool, ast.start);
}
- return ret;
-
-fail:
-
- vm->parser = prev;
-
- return NJS_ERROR;
+ return NJS_OK;
}
diff -r 4197cc28ea9c -r 1f22e9008cc3 src/njs_vm.h
--- a/src/njs_vm.h Fri Feb 19 17:27:44 2021 +0000
+++ b/src/njs_vm.h Wed Feb 24 14:48:20 2021 +0000
@@ -218,7 +218,6 @@ struct njs_vm_s {
size_t stack_size;
njs_vm_shared_t *shared;
- njs_parser_t *parser;
njs_regex_context_t *regex_context;
njs_regex_match_data_t *single_match_data;
diff -r 4197cc28ea9c -r 1f22e9008cc3 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c Fri Feb 19 17:27:44 2021 +0000
+++ b/src/test/njs_unit_test.c Wed Feb 24 14:48:20 2021 +0000
@@ -12696,25 +12696,26 @@ static njs_unit_test_t njs_test[] =
njs_str("1") },
{ njs_str("var sum = new Function('a', 'b', 'return a + b');"
- "sum(2, 4);"),
+ "sum(2, 4);"),
njs_str("6") },
{ njs_str("var sum = new Function('a, b', 'return a + b');"
- "sum(2, 4);"),
+ "sum(2, 4);"),
njs_str("6") },
{ njs_str("var sum = new Function('a, b', 'c', 'return a + b + c');"
- "sum(2, 4, 4);"),
+ "sum(2, 4, 4);"),
njs_str("10") },
{ njs_str("(new Function({ toString() { return '...a'; }}, { toString() { return 'return a;' }}))(1,2,3)"),
njs_str("1,2,3") },
{ njs_str("var x = 10; function foo() { var x = 20; return new Function('return x;'); }"
- "var f = foo(); f()"),
+ "var f = foo(); f()"),
njs_str("10") },
- { njs_str("var fn = (function() { return new Function('return this'); }).call({}), o = {}; fn.call(o) == o && fn.bind(o).call(this) == o"),
+ { njs_str("var fn = (function() { return new Function('return this'); }).call({}), o = {}; "
+ "fn.call(o) == o && fn.bind(o).call(this) == o"),
njs_str("true") },
{ njs_str("(new Function('return this'))() === globalThis"),
@@ -12733,6 +12734,10 @@ static njs_unit_test_t njs_test[] =
{ njs_str("var o = {}; (new Function('return this')).call(o) === o"),
njs_str("true") },
+ { njs_str("(new Function('function foo(){return 1}; return foo()'))();"
+ "foo"),
+ njs_str("ReferenceError: \"foo\" is not defined") },
+
{ njs_str("this.NN = {}; var f = Function('eval = 42;'); f()"),
njs_str("SyntaxError: Identifier \"eval\" is forbidden as left-hand in assignment in runtime:1") },
@@ -20315,6 +20320,11 @@ static njs_unit_test_t njs_shell_test[]
"Number.prototype.test" ENTER),
njs_str("test") },
+ { njs_str("try {(new Function('function foo(){return 1}; ()=>{}breakhere'))} catch (e) {}" ENTER
+ "foo()" ENTER),
+ njs_str("ReferenceError: \"foo\" is not defined\n"
+ " at main (:1)\n") },
+
/* Error handling */
{ njs_str("var a = ;" ENTER
More information about the nginx-devel
mailing list