]> git.kaiwu.me - njs.git/commitdiff
The typeof operation did not work in functions.
authorIgor Sysoev <igor@sysoev.ru>
Tue, 3 Apr 2018 14:55:04 +0000 (17:55 +0300)
committerIgor Sysoev <igor@sysoev.ru>
Tue, 3 Apr 2018 14:55:04 +0000 (17:55 +0300)
njs/njs_parser.c
njs/njs_parser.h
njs/njs_parser_expression.c
njs/njs_variable.c
njs/njs_variable.h
njs/test/njs_unit_test.c

index 3b01043072bf97c1d8a3fceb447829e21c64b59e..99d1ccb84f56b06377775536cecf4c7bdb51f6b6 100644 (file)
@@ -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;
     }
index 6d1b261db99ebad4d878a0ab232facd1359b651d..4e531abe31a78328445211c1dc6eadf1c6f9ba13 100644 (file)
@@ -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);
index a37d69f1a013ccdb94a301c95f08efdcbb27f0cb..eb0272cf531f49e9c8ffbe8190817d5b7429d34e 100644 (file)
@@ -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;
index 2e29566995efe7f3b8190af933a7251b0e4919a3..9207c3bd612f0195801316350f89c850f801ff90 100644 (file)
@@ -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;
     }
 
index 412fe541e381322a44a074efb99612c96b6ee179..fbf56d9ffef8ec9202fcb8dc3247155b5e64fd96 100644 (file)
@@ -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;
 
index 88f40e37e7cfeb21958e2f98576c21506e4aa004..75a76fe514e7a362f19c90f559ee7a3bb40a40c6 100644 (file)
@@ -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") },