]> git.kaiwu.me - njs.git/commitdiff
Arguments object as a variable.
authorhongzhidao <hongzhidao@gmail.com>
Mon, 25 Mar 2019 16:42:39 +0000 (00:42 +0800)
committerhongzhidao <hongzhidao@gmail.com>
Mon, 25 Mar 2019 16:42:39 +0000 (00:42 +0800)
njs/njs_function.c
njs/njs_function.h
njs/njs_generator.c
njs/njs_parser.h
njs/njs_parser_terminal.c
njs/njs_variable.h
njs/njs_vm.c
njs/njs_vm.h

index d3450ed46fdc353e2de6b857c82b988caa68838b..c0e8b0bc577456169ec37d6767ce89e1bb4829b6 100644 (file)
@@ -495,13 +495,6 @@ njs_function_lambda_call(njs_vm_t *vm, njs_index_t retval,
         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)) {
index b099ec1f8eabfe31f69174380a73956132815027..6d54b83895f60e3de4123da63b15b51d559a3383 100644 (file)
@@ -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. */
index bb0a0cc2afcd1c338eb6607e7795c33b1b182ec6..038e854d4f8c7be6b40e5a9e2b4bbdb5ea5ea7e8 100644 (file)
@@ -61,8 +61,6 @@ static nxt_int_t njs_generate_name(njs_vm_t *vm, njs_generator_t *generator,
     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_declaration(njs_vm_t *vm,
 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_generator_t *generator, njs_parser_node_t *node)
         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_generator_t *generator, njs_parser_node_t *node)
     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);
 
@@ -585,25 +581,6 @@ njs_generate_builtin_object(njs_vm_t *vm, njs_generator_t *generator,
 }
 
 
-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, njs_function_lambda_t *lambda,
         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_generator_t *generator,
     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_generator_t *generator,
 
 
 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;
 }
index 300bb50017fb2036aa311d5da0082e88629bb0d0..62ce9405fe0b25ca4bad8ed6f43f7197e3f75aec 100644 (file)
@@ -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;
 };
 
index a6ca537342f7979c37be4e4283da5e8790412756..813a636d1c84f66655ceb3a2fc18f66cdc5eeb20 100644 (file)
@@ -185,6 +185,7 @@ njs_parser_reference(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token,
 {
     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_parser_t *parser, njs_token_t token,
 
         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_parser_t *parser, njs_token_t token,
 
         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);
 
index 252dc3f3470d9cef416281b743fba2ea268d7153..12d38b92cf86ed706fd11ec57184089aeae23155 100644 (file)
@@ -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;
index aefe678c1ca7e3142c882b171f231ba449f629b0..3ce5109e411f5fdb313b240ecc5da41ae7f66c29 100644 (file)
@@ -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_value_t *invld1, njs_value_t *invld2)
 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_value_t *invld1, njs_value_t *invld2)
         }
     }
 
-    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);
 }
index 2e0ca7d89515847b348ad20ee9f024edd52d0e87..8f3c9975ef7b6a3d91e159c70faa34585da8c0ba 100644 (file)
@@ -639,7 +639,7 @@ typedef struct {
 
 typedef struct {
     njs_vmcode_t               code;
-    njs_index_t                retval;
+    njs_index_t                dst;
 } njs_vmcode_arguments_t;