From 9b35013975d558e35acf03bb9a0d4bd45816627e Mon Sep 17 00:00:00 2001 From: hongzhidao Date: Tue, 26 Mar 2019 00:42:39 +0800 Subject: [PATCH] Arguments object as a variable. --- 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(-) diff --git a/njs/njs_function.c b/njs/njs_function.c index d3450ed4..c0e8b0bc 100644 --- a/njs/njs_function.c +++ b/njs/njs_function.c @@ -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)) { diff --git a/njs/njs_function.h b/njs/njs_function.h index b099ec1f..6d54b838 100644 --- a/njs/njs_function.h +++ b/njs/njs_function.h @@ -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 --git a/njs/njs_generator.c b/njs/njs_generator.c index bb0a0cc2..038e854d 100644 --- a/njs/njs_generator.c +++ b/njs/njs_generator.c @@ -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; } diff --git a/njs/njs_parser.h b/njs/njs_parser.h index 300bb500..62ce9405 100644 --- a/njs/njs_parser.h +++ b/njs/njs_parser.h @@ -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 --git a/njs/njs_parser_terminal.c b/njs/njs_parser_terminal.c index a6ca5373..813a636d 100644 --- a/njs/njs_parser_terminal.c +++ b/njs/njs_parser_terminal.c @@ -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); diff --git a/njs/njs_variable.h b/njs/njs_variable.h index 252dc3f3..12d38b92 100644 --- a/njs/njs_variable.h +++ b/njs/njs_variable.h @@ -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 --git a/njs/njs_vm.c b/njs/njs_vm.c index aefe678c..3ce5109e 100644 --- a/njs/njs_vm.c +++ b/njs/njs_vm.c @@ -9,7 +9,6 @@ #include - 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); } diff --git a/njs/njs_vm.h b/njs/njs_vm.h index 2e0ca7d8..8f3c9975 100644 --- a/njs/njs_vm.h +++ b/njs/njs_vm.h @@ -639,7 +639,7 @@ typedef struct { typedef struct { njs_vmcode_t code; - njs_index_t retval; + njs_index_t dst; } njs_vmcode_arguments_t; -- 2.47.3