[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