From: Igor Sysoev Date: Tue, 3 Apr 2018 14:55:04 +0000 (+0300) Subject: The typeof operation did not work in functions. X-Git-Tag: 0.2.1~43 X-Git-Url: http://git.kaiwu.me/postgresql/log/contrib/postgres_fdw/static/gitweb.js?a=commitdiff_plain;h=0aec0a722c9cd53a8b6fe51439d65c0c2c7554f3;p=njs.git The typeof operation did not work in functions. --- diff --git a/njs/njs_parser.c b/njs/njs_parser.c index 3b010430..99d1ccb8 100644 --- a/njs/njs_parser.c +++ b/njs/njs_parser.c @@ -483,7 +483,7 @@ njs_parser_function_declaration(njs_vm_t *vm, njs_parser_t *parser) return NJS_TOKEN_ERROR; } - ret = njs_variable_reference(vm, parser, node, 0); + ret = njs_variable_reference(vm, parser, node, NJS_DECLARATION); if (nxt_slow_path(ret != NXT_OK)) { return NJS_TOKEN_ERROR; } @@ -857,7 +857,7 @@ njs_parser_var_statement(njs_vm_t *vm, njs_parser_t *parser) name->token = NJS_TOKEN_NAME; - ret = njs_variable_reference(vm, parser, name, 0); + ret = njs_variable_reference(vm, parser, name, NJS_DECLARATION); if (nxt_slow_path(ret != NXT_OK)) { return NJS_TOKEN_ERROR; } @@ -1342,7 +1342,7 @@ njs_parser_for_var_statement(njs_vm_t *vm, njs_parser_t *parser) name->token = NJS_TOKEN_NAME; - ret = njs_variable_reference(vm, parser, name, 0); + ret = njs_variable_reference(vm, parser, name, NJS_DECLARATION); if (nxt_slow_path(ret != NXT_OK)) { return NJS_TOKEN_ERROR; } @@ -1634,7 +1634,7 @@ njs_parser_try_statement(njs_vm_t *vm, njs_parser_t *parser) node->token = NJS_TOKEN_NAME; - ret = njs_variable_reference(vm, parser, node, 0); + ret = njs_variable_reference(vm, parser, node, NJS_DECLARATION); if (nxt_slow_path(ret != NXT_OK)) { return NJS_TOKEN_ERROR; } @@ -1852,7 +1852,7 @@ njs_parser_terminal(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token) break; } - ret = njs_variable_reference(vm, parser, node, 1); + ret = njs_variable_reference(vm, parser, node, NJS_REFERENCE); if (nxt_slow_path(ret != NXT_OK)) { return NJS_TOKEN_ERROR; } @@ -2106,7 +2106,7 @@ njs_parser_builtin_object(njs_vm_t *vm, njs_parser_t *parser, var->value.type = NJS_OBJECT; var->value.data.truth = 1; - ret = njs_variable_reference(vm, parser, node, 1); + ret = njs_variable_reference(vm, parser, node, NJS_REFERENCE); if (nxt_slow_path(ret != NXT_OK)) { return NJS_TOKEN_ERROR; } @@ -2139,7 +2139,7 @@ njs_parser_builtin_function(njs_vm_t *vm, njs_parser_t *parser, var->value.type = NJS_FUNCTION; var->value.data.truth = 1; - ret = njs_variable_reference(vm, parser, node, 1); + ret = njs_variable_reference(vm, parser, node, NJS_REFERENCE); if (nxt_slow_path(ret != NXT_OK)) { return NJS_TOKEN_ERROR; } diff --git a/njs/njs_parser.h b/njs/njs_parser.h index 6d1b261d..4e531abe 100644 --- a/njs/njs_parser.h +++ b/njs/njs_parser.h @@ -255,9 +255,9 @@ typedef struct njs_parser_node_s njs_parser_node_t; struct njs_parser_node_s { njs_token_t token:16; - uint8_t ctor:1; /* 1 bit */ - uint8_t temporary; /* 1 bit */ - uint8_t reference; /* 1 bit */ + uint8_t ctor:1; + njs_variable_reference_t reference:2; + uint8_t temporary; /* 1 bit */ uint32_t token_line; uint32_t variable_name_hash; @@ -381,7 +381,7 @@ njs_token_t njs_parser_property_token(njs_parser_t *parser); njs_token_t njs_parser_token(njs_parser_t *parser); nxt_int_t njs_parser_string_create(njs_vm_t *vm, njs_value_t *value); njs_ret_t njs_variable_reference(njs_vm_t *vm, njs_parser_t *parser, - njs_parser_node_t *node, nxt_bool_t reference); + njs_parser_node_t *node, njs_variable_reference_t reference); njs_variable_t *njs_variable_get(njs_vm_t *vm, njs_parser_node_t *node); njs_index_t njs_variable_typeof(njs_vm_t *vm, njs_parser_node_t *node); njs_index_t njs_variable_index(njs_vm_t *vm, njs_parser_node_t *node); diff --git a/njs/njs_parser_expression.c b/njs/njs_parser_expression.c index a37d69f1..eb0272cf 100644 --- a/njs/njs_parser_expression.c +++ b/njs/njs_parser_expression.c @@ -805,6 +805,10 @@ njs_parser_unary_expression(njs_vm_t *vm, njs_parser_t *parser, } } + if (token == NJS_TOKEN_TYPEOF && parser->node->token == NJS_TOKEN_NAME) { + parser->node->reference = NJS_TYPEOF; + } + node = njs_parser_node_alloc(vm); if (nxt_slow_path(node == NULL)) { return NJS_TOKEN_ERROR; diff --git a/njs/njs_variable.c b/njs/njs_variable.c index 2e295669..9207c3bd 100644 --- a/njs/njs_variable.c +++ b/njs/njs_variable.c @@ -193,7 +193,7 @@ const nxt_lvlhsh_proto_t njs_reference_hash_proto njs_ret_t njs_variable_reference(njs_vm_t *vm, njs_parser_t *parser, - njs_parser_node_t *node, nxt_bool_t reference) + njs_parser_node_t *node, njs_variable_reference_t reference) { njs_ret_t ret; nxt_lvlhsh_query_t lhq; @@ -277,8 +277,11 @@ njs_variables_scope_resolve(njs_vm_t *vm, njs_parser_scope_t *scope, } var = njs_variable_get(vm, node); + if (nxt_slow_path(var == NULL)) { - return NXT_ERROR; + if (node->reference != NJS_TYPEOF) { + return NXT_ERROR; + } } } } @@ -397,7 +400,7 @@ njs_variable_get(njs_vm_t *vm, njs_parser_node_t *node) var->argument = index; } - if (node->reference && var->type <= NJS_VARIABLE_LET) { + if (node->reference != NJS_DECLARATION && var->type <= NJS_VARIABLE_LET) { goto not_found; } diff --git a/njs/njs_variable.h b/njs/njs_variable.h index 412fe541..fbf56d9f 100644 --- a/njs/njs_variable.h +++ b/njs/njs_variable.h @@ -18,6 +18,13 @@ typedef enum { } njs_variable_type_t; +typedef enum { + NJS_DECLARATION = 0, + NJS_REFERENCE, + NJS_TYPEOF, +} njs_variable_reference_t; + + typedef struct { nxt_str_t name; diff --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c index 88f40e37..75a76fe5 100644 --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -2318,6 +2318,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("var a = 5; typeof a"), nxt_string("number") }, + { nxt_string("function f() { return typeof a } ; f()"), + nxt_string("undefined") }, + { nxt_string("typeof a; a"), nxt_string("ReferenceError: \"a\" is not defined in 1") },