[njs] Arguments object as a variable.

Dmitry Volyntsev xeioex at nginx.com
Thu Apr 4 13:59:24 UTC 2019


details:   https://hg.nginx.org/njs/rev/b137489312e1
branches:  
changeset: 868:b137489312e1
user:      hongzhidao <hongzhidao at gmail.com>
date:      Tue Mar 26 00:42:39 2019 +0800
description:
Arguments object as a variable.

diffstat:

 njs/njs_function.c        |   7 -----
 njs/njs_function.h        |   1 -
 njs/njs_generator.c       |  63 ++++++++++++++--------------------------------
 njs/njs_parser.h          |   1 -
 njs/njs_parser_terminal.c |  42 ++++++++++++++++++++----------
 njs/njs_variable.h        |   1 +
 njs/njs_vm.c              |  16 +++++++----
 njs/njs_vm.h              |   2 +-
 8 files changed, 60 insertions(+), 73 deletions(-)

diffs (303 lines):

diff -r d1cedbc86bc2 -r b137489312e1 njs/njs_function.c
--- a/njs/njs_function.c	Wed Apr 03 11:27:05 2019 +0800
+++ b/njs/njs_function.c	Tue Mar 26 00:42:39 2019 +0800
@@ -495,13 +495,6 @@ njs_function_lambda_call(njs_vm_t *vm, n
         vm->scopes[NJS_SCOPE_CLOSURE + n] = &closure->u.values;
     }
 
-    if (lambda->arguments_object) {
-        ret = njs_function_arguments_object_init(vm, &frame->native);
-        if (nxt_slow_path(ret != NXT_OK)) {
-            return NXT_ERROR;
-        }
-    }
-
     if (lambda->rest_parameters) {
         ret = njs_function_rest_parameters_init(vm, &frame->native);
         if (nxt_slow_path(ret != NXT_OK)) {
diff -r d1cedbc86bc2 -r b137489312e1 njs/njs_function.h
--- a/njs/njs_function.h	Wed Apr 03 11:27:05 2019 +0800
+++ b/njs/njs_function.h	Tue Mar 26 00:42:39 2019 +0800
@@ -30,7 +30,6 @@ struct njs_function_lambda_s {
     /* Function internal block closures levels. */
     uint8_t                        block_closures;    /* 4 bits */
 
-    uint8_t                        arguments_object;  /* 1 bit */
     uint8_t                        rest_parameters;   /* 1 bit */
 
     /* Initial values of local scope. */
diff -r d1cedbc86bc2 -r b137489312e1 njs/njs_generator.c
--- a/njs/njs_generator.c	Wed Apr 03 11:27:05 2019 +0800
+++ b/njs/njs_generator.c	Tue Mar 26 00:42:39 2019 +0800
@@ -61,8 +61,6 @@ static nxt_int_t njs_generate_name(njs_v
     njs_parser_node_t *node);
 static nxt_int_t njs_generate_builtin_object(njs_vm_t *vm,
     njs_generator_t *generator, njs_parser_node_t *node);
-static nxt_int_t njs_generate_arguments_object(njs_vm_t *vm,
-    njs_generator_t *generator, njs_parser_node_t *node);
 static nxt_int_t njs_generate_variable(njs_vm_t *vm, njs_generator_t *generator,
     njs_parser_node_t *node);
 static nxt_int_t njs_generate_var_statement(njs_vm_t *vm,
@@ -140,7 +138,7 @@ static nxt_int_t njs_generate_function_d
 static nxt_int_t njs_generate_function_scope(njs_vm_t *vm,
     njs_function_lambda_t *lambda, njs_parser_node_t *node,
     const nxt_str_t *name);
-static nxt_int_t njs_generate_argument_closures(njs_vm_t *vm,
+static nxt_int_t njs_generate_lambda_variables(njs_vm_t *vm,
     njs_generator_t *generator, njs_parser_node_t *node);
 static nxt_int_t njs_generate_return_statement(njs_vm_t *vm,
     njs_generator_t *generator, njs_parser_node_t *node);
@@ -429,6 +427,7 @@ njs_generator(njs_vm_t *vm, njs_generato
         return NXT_OK;
 
     case NJS_TOKEN_NAME:
+    case NJS_TOKEN_ARGUMENTS:
         return njs_generate_name(vm, generator, node);
 
     case NJS_TOKEN_GLOBAL_THIS:
@@ -451,9 +450,6 @@ njs_generator(njs_vm_t *vm, njs_generato
     case NJS_TOKEN_CLEAR_TIMEOUT:
         return njs_generate_builtin_object(vm, generator, node);
 
-    case NJS_TOKEN_ARGUMENTS:
-        return njs_generate_arguments_object(vm, generator, node);
-
     case NJS_TOKEN_FUNCTION:
         return njs_generate_function_declaration(vm, generator, node);
 
@@ -586,25 +582,6 @@ njs_generate_builtin_object(njs_vm_t *vm
 
 
 static nxt_int_t
-njs_generate_arguments_object(njs_vm_t *vm, njs_generator_t *generator,
-    njs_parser_node_t *node)
-{
-    njs_vmcode_arguments_t  *gen;
-
-    node->index = njs_generate_object_dest_index(vm, generator, node);
-    if (nxt_slow_path(node->index == NJS_INDEX_ERROR)) {
-        return NXT_ERROR;
-    }
-
-    njs_generate_code(generator, njs_vmcode_arguments_t, gen,
-                      njs_vmcode_arguments, 1, 1);
-    gen->retval = node->index;
-
-    return NXT_OK;
-}
-
-
-static nxt_int_t
 njs_generate_variable(njs_vm_t *vm, njs_generator_t *generator,
     njs_parser_node_t *node)
 {
@@ -2329,7 +2306,6 @@ njs_generate_function_scope(njs_vm_t *vm
         lambda->closure_size = size;
 
         lambda->nesting = node->scope->nesting;
-        lambda->arguments_object = node->scope->arguments_object;
 
         lambda->start = generator.code_start;
         lambda->local_size = generator.scope_size;
@@ -2362,7 +2338,7 @@ njs_generate_scope(njs_vm_t *vm, njs_gen
     generator->code_start = p;
     generator->code_end = p;
 
-    ret = njs_generate_argument_closures(vm, generator, scope->top);
+    ret = njs_generate_lambda_variables(vm, generator, scope->top);
     if (nxt_slow_path(ret != NXT_OK)) {
         return NXT_ERROR;
     }
@@ -2420,35 +2396,36 @@ njs_generate_scope(njs_vm_t *vm, njs_gen
 
 
 static nxt_int_t
-njs_generate_argument_closures(njs_vm_t *vm, njs_generator_t *generator,
+njs_generate_lambda_variables(njs_vm_t *vm, njs_generator_t *generator,
     njs_parser_node_t *node)
 {
-    nxt_uint_t         n;
-    njs_index_t        index;
-    njs_variable_t     *var;
-    njs_vmcode_move_t  *move;
-    nxt_lvlhsh_each_t  lhe;
-
-    n = node->scope->argument_closures;
-
-    if (n == 0) {
-        return NXT_OK;
-    }
+    njs_index_t             index;
+    njs_variable_t          *var;
+    njs_vmcode_move_t       *move;
+    nxt_lvlhsh_each_t       lhe;
+    njs_vmcode_arguments_t  *arguments;
 
     nxt_lvlhsh_each_init(&lhe, &njs_variables_hash_proto);
 
-    do {
+    for ( ;; ) {
         var = nxt_lvlhsh_each(&node->scope->variables, &lhe);
 
+        if (var == NULL) {
+            break;
+        }
+
         if (var->argument != 0) {
             index = njs_scope_index((var->argument - 1), NJS_SCOPE_ARGUMENTS);
 
             njs_generate_code_move(generator, move, var->index, index);
-
-            n--;
         }
 
-    } while (n != 0);
+        if (var->arguments_object) {
+            njs_generate_code(generator, njs_vmcode_arguments_t, arguments,
+                              njs_vmcode_arguments, 1, 0);
+            arguments->dst = var->index;
+        }
+    }
 
     return NXT_OK;
 }
diff -r d1cedbc86bc2 -r b137489312e1 njs/njs_parser.h
--- a/njs/njs_parser.h	Wed Apr 03 11:27:05 2019 +0800
+++ b/njs/njs_parser.h	Tue Mar 26 00:42:39 2019 +0800
@@ -31,7 +31,6 @@ struct njs_parser_scope_s {
     njs_scope_t                     type:8;
     uint8_t                         nesting;     /* 4 bits */
     uint8_t                         argument_closures;
-    uint8_t                         arguments_object;
     uint8_t                         module;
 };
 
diff -r d1cedbc86bc2 -r b137489312e1 njs/njs_parser_terminal.c
--- a/njs/njs_parser_terminal.c	Wed Apr 03 11:27:05 2019 +0800
+++ b/njs/njs_parser_terminal.c	Tue Mar 26 00:42:39 2019 +0800
@@ -185,6 +185,7 @@ njs_parser_reference(njs_vm_t *vm, njs_p
 {
     njs_ret_t           ret;
     njs_value_t         *ext;
+    njs_variable_t      *var;
     njs_parser_node_t   *node;
     njs_parser_scope_t  *scope;
 
@@ -239,20 +240,6 @@ njs_parser_reference(njs_vm_t *vm, njs_p
 
         break;
 
-    case NJS_TOKEN_ARGUMENTS:
-        nxt_thread_log_debug("JS: arguments");
-
-        if (parser->scope->type <= NJS_SCOPE_GLOBAL) {
-            njs_parser_syntax_error(vm, parser, "\"%V\" object "
-                                    "in global scope", name);
-
-            return NULL;
-        }
-
-        parser->scope->arguments_object = 1;
-
-        break;
-
     case NJS_TOKEN_OBJECT_CONSTRUCTOR:
         node->index = NJS_INDEX_OBJECT;
         break;
@@ -342,6 +329,33 @@ njs_parser_reference(njs_vm_t *vm, njs_p
 
         break;
 
+    case NJS_TOKEN_ARGUMENTS:
+        nxt_thread_log_debug("JS: arguments");
+
+        if (parser->scope->type <= NJS_SCOPE_GLOBAL) {
+            njs_parser_syntax_error(vm, parser, "\"%V\" object "
+                                    "in global scope", name);
+
+            return NULL;
+        }
+
+        node->token_line = token_line;
+
+        ret = njs_variable_reference(vm, parser->scope, node, name, hash,
+                                     NJS_REFERENCE);
+        if (nxt_slow_path(ret != NXT_OK)) {
+            return NULL;
+        }
+
+        var = njs_variable_add(vm, parser->scope, name, hash, NJS_VARIABLE_VAR);
+        if (nxt_slow_path(var == NULL)) {
+            return NULL;
+        }
+
+        var->arguments_object = 1;
+
+        break;
+
     case NJS_TOKEN_NAME:
         nxt_thread_log_debug("JS: %V", name);
 
diff -r d1cedbc86bc2 -r b137489312e1 njs/njs_variable.h
--- a/njs/njs_variable.h	Wed Apr 03 11:27:05 2019 +0800
+++ b/njs/njs_variable.h	Tue Mar 26 00:42:39 2019 +0800
@@ -23,6 +23,7 @@ typedef struct {
 
     njs_variable_type_t   type:8;    /* 3 bits */
     uint8_t               argument;
+    uint8_t               arguments_object;
 
     njs_index_t           index;
     njs_value_t           value;
diff -r d1cedbc86bc2 -r b137489312e1 njs/njs_vm.c
--- a/njs/njs_vm.c	Wed Apr 03 11:27:05 2019 +0800
+++ b/njs/njs_vm.c	Tue Mar 26 00:42:39 2019 +0800
@@ -9,7 +9,6 @@
 #include <string.h>
 
 
-
 struct njs_property_next_s {
     int32_t                        index;
     nxt_lvlhsh_each_t              lhe;
@@ -394,8 +393,10 @@ njs_vmcode_function(njs_vm_t *vm, njs_va
 njs_ret_t
 njs_vmcode_arguments(njs_vm_t *vm, njs_value_t *invld1, njs_value_t *invld2)
 {
-    njs_ret_t    ret;
-    njs_frame_t  *frame;
+    nxt_int_t               ret;
+    njs_frame_t             *frame;
+    njs_value_t             *value;
+    njs_vmcode_arguments_t  *code;
 
     frame = (njs_frame_t *) vm->active_frame;
 
@@ -406,9 +407,12 @@ njs_vmcode_arguments(njs_vm_t *vm, njs_v
         }
     }
 
-    vm->retval.data.u.object = frame->native.arguments_object;
-    vm->retval.type = NJS_OBJECT;
-    vm->retval.data.truth = 1;
+    code = (njs_vmcode_arguments_t *) vm->current;
+
+    value = njs_vmcode_operand(vm, code->dst);
+    value->data.u.object = frame->native.arguments_object;
+    value->type = NJS_OBJECT;
+    value->data.truth = 1;
 
     return sizeof(njs_vmcode_arguments_t);
 }
diff -r d1cedbc86bc2 -r b137489312e1 njs/njs_vm.h
--- a/njs/njs_vm.h	Wed Apr 03 11:27:05 2019 +0800
+++ b/njs/njs_vm.h	Tue Mar 26 00:42:39 2019 +0800
@@ -639,7 +639,7 @@ typedef struct {
 
 typedef struct {
     njs_vmcode_t               code;
-    njs_index_t                retval;
+    njs_index_t                dst;
 } njs_vmcode_arguments_t;
 
 


More information about the nginx-devel mailing list