[njs] The typeof operation did not work in functions.

Igor Sysoev igor at sysoev.ru
Tue Apr 3 14:56:29 UTC 2018


details:   http://hg.nginx.org/njs/rev/671d9dd1ffeb
branches:  
changeset: 487:671d9dd1ffeb
user:      Igor Sysoev <igor at sysoev.ru>
date:      Tue Apr 03 17:55:04 2018 +0300
description:
The typeof operation did not work in functions.

diffstat:

 njs/njs_parser.c            |  14 +++++++-------
 njs/njs_parser.h            |   8 ++++----
 njs/njs_parser_expression.c |   4 ++++
 njs/njs_variable.c          |   9 ++++++---
 njs/njs_variable.h          |   7 +++++++
 njs/test/njs_unit_test.c    |   3 +++
 6 files changed, 31 insertions(+), 14 deletions(-)

diffs (169 lines):

diff -r 08b637d9a099 -r 671d9dd1ffeb njs/njs_parser.c
--- a/njs/njs_parser.c	Tue Apr 03 14:51:22 2018 +0300
+++ b/njs/njs_parser.c	Tue Apr 03 17:55:04 2018 +0300
@@ -483,7 +483,7 @@ njs_parser_function_declaration(njs_vm_t
         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, n
 
         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 *v
 
         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, n
 
         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_pa
             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, 
     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
     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 -r 08b637d9a099 -r 671d9dd1ffeb njs/njs_parser.h
--- a/njs/njs_parser.h	Tue Apr 03 14:51:22 2018 +0300
+++ b/njs/njs_parser.h	Tue Apr 03 17:55:04 2018 +0300
@@ -255,9 +255,9 @@ typedef struct njs_parser_node_s    njs_
 
 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(nj
 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 -r 08b637d9a099 -r 671d9dd1ffeb njs/njs_parser_expression.c
--- a/njs/njs_parser_expression.c	Tue Apr 03 14:51:22 2018 +0300
+++ b/njs/njs_parser_expression.c	Tue Apr 03 17:55:04 2018 +0300
@@ -805,6 +805,10 @@ njs_parser_unary_expression(njs_vm_t *vm
         }
     }
 
+    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 -r 08b637d9a099 -r 671d9dd1ffeb njs/njs_variable.c
--- a/njs/njs_variable.c	Tue Apr 03 14:51:22 2018 +0300
+++ b/njs/njs_variable.c	Tue Apr 03 17:55:04 2018 +0300
@@ -193,7 +193,7 @@ const nxt_lvlhsh_proto_t  njs_reference_
 
 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
             }
 
             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_parse
         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 -r 08b637d9a099 -r 671d9dd1ffeb njs/njs_variable.h
--- a/njs/njs_variable.h	Tue Apr 03 14:51:22 2018 +0300
+++ b/njs/njs_variable.h	Tue Apr 03 17:55:04 2018 +0300
@@ -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 -r 08b637d9a099 -r 671d9dd1ffeb njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c	Tue Apr 03 14:51:22 2018 +0300
+++ b/njs/test/njs_unit_test.c	Tue Apr 03 17:55:04 2018 +0300
@@ -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") },
 


More information about the nginx-devel mailing list