details: http://hg.nginx.org/njs/rev/46364c618468 branches: changeset: 648:46364c618468 user: Dmitry Volyntsev <xei...@nginx.com> date: Mon Nov 12 18:27:05 2018 +0300 description: Allowing variables and functions to be redeclared.
diffstat: njs/njs_function.c | 2 +- njs/njs_function.h | 6 ++---- njs/njs_generator.c | 9 +++++++-- njs/njs_parser.c | 6 +++--- njs/njs_variable.c | 17 +++++++---------- njs/test/njs_unit_test.c | 33 ++++++++++++++++++++++++++++----- 6 files changed, 48 insertions(+), 25 deletions(-) diffs (173 lines): diff -r f1da98bdd82f -r 46364c618468 njs/njs_function.c --- a/njs/njs_function.c Mon Nov 12 17:22:14 2018 +0300 +++ b/njs/njs_function.c Mon Nov 12 18:27:05 2018 +0300 @@ -412,7 +412,7 @@ njs_function_call(njs_vm_t *vm, njs_inde frame->return_address = vm->current + advance; lambda = function->u.lambda; - vm->current = lambda->u.start; + vm->current = lambda->start; #if (NXT_DEBUG) vm->scopes[NJS_SCOPE_CALLEE_ARGUMENTS] = NULL; diff -r f1da98bdd82f -r 46364c618468 njs/njs_function.h --- a/njs/njs_function.h Mon Nov 12 17:22:14 2018 +0300 +++ b/njs/njs_function.h Mon Nov 12 18:27:05 2018 +0300 @@ -36,10 +36,8 @@ struct njs_function_lambda_s { njs_value_t *local_scope; njs_value_t *closure_scope; - union { - u_char *start; - njs_parser_t *parser; - } u; + u_char *start; + njs_parser_t *parser; }; diff -r f1da98bdd82f -r 46364c618468 njs/njs_generator.c --- a/njs/njs_generator.c Mon Nov 12 17:22:14 2018 +0300 +++ b/njs/njs_generator.c Mon Nov 12 18:27:05 2018 +0300 @@ -2007,6 +2007,11 @@ njs_generate_function_declaration(njs_vm return NXT_ERROR; } + if (!njs_is_function(&var->value)) { + /* A variable was declared with the same name. */ + return NXT_OK; + } + lambda = var->value.data.u.function->u.lambda; ret = njs_generate_function_scope(vm, lambda, node); @@ -2032,7 +2037,7 @@ njs_generate_function_scope(njs_vm_t *vm nxt_array_t *closure; njs_parser_t *parser; - parser = lambda->u.parser; + parser = lambda->parser; node = node->right; parser->code_size += node->scope->argument_closures @@ -2058,7 +2063,7 @@ njs_generate_function_scope(njs_vm_t *vm lambda->local_size = parser->scope_size; lambda->local_scope = parser->local_scope; - lambda->u.start = parser->code_start; + lambda->start = parser->code_start; } return ret; diff -r f1da98bdd82f -r 46364c618468 njs/njs_parser.c --- a/njs/njs_parser.c Mon Nov 12 17:22:14 2018 +0300 +++ b/njs/njs_parser.c Mon Nov 12 18:27:05 2018 +0300 @@ -496,7 +496,7 @@ njs_parser_function_declaration(njs_vm_t return NJS_TOKEN_ERROR; } - function->u.lambda->u.parser = parser; + function->u.lambda->parser = parser; token = njs_parser_function_lambda(vm, function->u.lambda, token); @@ -578,7 +578,7 @@ njs_parser_function_expression(njs_vm_t } node->u.value.data.u.lambda = lambda; - lambda->u.parser = parser; + lambda->parser = parser; token = njs_parser_function_lambda(vm, lambda, token); @@ -619,7 +619,7 @@ njs_parser_function_lambda(njs_vm_t *vm, njs_variable_t *arg; njs_parser_node_t *node, *body, *last; - parser = lambda->u.parser; + parser = lambda->parser; ret = njs_parser_scope_begin(vm, parser, NJS_SCOPE_FUNCTION); if (nxt_slow_path(ret != NXT_OK)) { diff -r f1da98bdd82f -r 46364c618468 njs/njs_variable.c --- a/njs/njs_variable.c Mon Nov 12 17:22:14 2018 +0300 +++ b/njs/njs_variable.c Mon Nov 12 18:27:05 2018 +0300 @@ -119,12 +119,17 @@ njs_variable_add(njs_vm_t *vm, njs_parse } } + if (nxt_lvlhsh_find(&scope->variables, &lhq) == NXT_OK) { + var = lhq.value; + return var; + } + var = njs_variable_alloc(vm, &lhq.key, type); if (nxt_slow_path(var == NULL)) { return var; } - lhq.replace = vm->options.accumulative; + lhq.replace = 0; lhq.value = var; lhq.pool = vm->mem_cache_pool; @@ -137,15 +142,7 @@ njs_variable_add(njs_vm_t *vm, njs_parse nxt_mem_cache_free(vm->mem_cache_pool, var->name.start); nxt_mem_cache_free(vm->mem_cache_pool, var); - if (ret == NXT_ERROR) { - return NULL; - } - - /* ret == NXT_DECLINED. */ - - njs_parser_syntax_error(vm, parser, "Identifier \"%.*s\" " - "has already been declared", - (int) lhq.key.length, lhq.key.start); + njs_type_error(vm, "lvlhsh insert failed"); return NULL; } diff -r f1da98bdd82f -r 46364c618468 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Mon Nov 12 17:22:14 2018 +0300 +++ b/njs/test/njs_unit_test.c Mon Nov 12 18:27:05 2018 +0300 @@ -75,11 +75,34 @@ static njs_unit_test_t njs_test[] = { nxt_string("if(1)if(0){0?0:0}else\nvar a\nelse\nvar b"), nxt_string("undefined") }, - { nxt_string("function f(){} function f(){}"), - nxt_string("SyntaxError: Identifier \"f\" has already been declared in 1") }, - - { nxt_string("var f = 1; function f() {}"), - nxt_string("SyntaxError: Identifier \"f\" has already been declared in 1") }, + { nxt_string("var a = 1; var a; a"), + nxt_string("1") }, + + { nxt_string("(function (x) {if (x) { var a = 3; return a} else { var a = 4; return a}})(1)"), + nxt_string("3") }, + + { nxt_string("(function (x) {if (x) { var a = 3; return a} else { var a = 4; return a}})(0)"), + nxt_string("4") }, + + { nxt_string("function f(){return 2}; var f; f()"), + nxt_string("2") }, + + { nxt_string("function f(){return 2}; var f = 1; f()"), + nxt_string("TypeError: number is not a function") }, + + { nxt_string("function f(){return 1}; function f(){return 2}; f()"), + nxt_string("2") }, + + { nxt_string("var f = 1; function f() {}; f"), + nxt_string("1") }, + +#if 0 /* TODO */ + { nxt_string("var a; Object.getOwnPropertyDescriptor(this, 'a').value"), + nxt_string("undefined") }, + + { nxt_string("this.a = 1; a"), + nxt_string("1") }, +#endif { nxt_string("f() = 1"), nxt_string("ReferenceError: Invalid left-hand side in assignment in 1") }, _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel