Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # HG changeset patch
- # User hongzhidao <hongzhidao@gmail.com>
- # Date 1553532159 -28800
- # Node ID 89bfc95f182f12238b7884a39326bdae77f6ddc9
- # Parent e3ee3a2d9994f77dc420edf89d6cf2af5b64743e
- Improved lambda arguments object.
- diff -r e3ee3a2d9994 -r 89bfc95f182f njs/njs_function.c
- --- a/njs/njs_function.c Mon Mar 25 17:51:19 2019 +0300
- +++ b/njs/njs_function.c Tue Mar 26 00:42:39 2019 +0800
- @@ -477,13 +477,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 e3ee3a2d9994 -r 89bfc95f182f njs/njs_function.h
- --- a/njs/njs_function.h Mon Mar 25 17:51:19 2019 +0300
- +++ 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 e3ee3a2d9994 -r 89bfc95f182f njs/njs_generator.c
- --- a/njs/njs_generator.c Mon Mar 25 17:51:19 2019 +0300
- +++ 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 e3ee3a2d9994 -r 89bfc95f182f njs/njs_parser.c
- --- a/njs/njs_parser.c Mon Mar 25 17:51:19 2019 +0300
- +++ b/njs/njs_parser.c Tue Mar 26 00:42:39 2019 +0800
- @@ -536,6 +536,7 @@ njs_parser_variable_add(njs_vm_t *vm, nj
- njs_parser_key_hash(parser), type);
- }
- +
- nxt_inline njs_ret_t
- njs_parser_variable_reference(njs_vm_t *vm, njs_parser_t *parser,
- njs_parser_node_t *node, njs_reference_type_t type)
- @@ -546,6 +547,36 @@ njs_parser_variable_reference(njs_vm_t *
- }
- +nxt_inline njs_parser_node_t *
- +njs_parser_variable_node(njs_vm_t *vm, njs_parser_t *parser, nxt_str_t *name,
- + uint32_t hash, njs_variable_type_t type, uint8_t arguments_object)
- +{
- + nxt_int_t ret;
- + njs_variable_t *var;
- + njs_parser_node_t *node;
- +
- + var = njs_variable_add(vm, parser->scope, name, hash, type);
- + if (nxt_slow_path(var == NULL)) {
- + return NULL;
- + }
- +
- + var->arguments_object = arguments_object;
- +
- + node = njs_parser_node_new(vm, parser, NJS_TOKEN_NAME);
- + if (nxt_slow_path(node == NULL)) {
- + return NULL;
- + }
- +
- + ret = njs_variable_reference(vm, parser->scope, node, name, hash,
- + NJS_DECLARATION);
- + if (nxt_slow_path(ret != NXT_OK)) {
- + return NULL;
- + }
- +
- + return node;
- +}
- +
- +
- static njs_token_t
- njs_parser_labelled_statement(njs_vm_t *vm, njs_parser_t *parser)
- {
- @@ -761,8 +792,11 @@ static njs_token_t
- njs_parser_function_lambda(njs_vm_t *vm, njs_parser_t *parser,
- njs_function_lambda_t *lambda, njs_token_t token)
- {
- - njs_ret_t ret;
- - njs_index_t index;
- + njs_ret_t ret;
- + nxt_str_t name;
- + uint32_t hash;
- + njs_index_t index;
- + njs_parser_node_t *node;
- ret = njs_parser_scope_begin(vm, parser, NJS_SCOPE_FUNCTION);
- if (nxt_slow_path(ret != NXT_OK)) {
- @@ -779,6 +813,15 @@ njs_parser_function_lambda(njs_vm_t *vm,
- return token;
- }
- + name = nxt_string_value("arguments");
- + hash = nxt_djb_hash(name.start, name.length);
- +
- + node = njs_parser_variable_node(vm, parser, &name, hash,
- + NJS_VARIABLE_VAR, 1);
- + if (nxt_slow_path(node == NULL)) {
- + return NJS_TOKEN_ERROR;
- + }
- +
- token = njs_parser_lambda_body(vm, parser, token);
- if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- return token;
- @@ -1025,9 +1068,7 @@ njs_parser_return_statement(njs_vm_t *vm
- static njs_token_t
- njs_parser_var_statement(njs_vm_t *vm, njs_parser_t *parser)
- {
- - njs_ret_t ret;
- njs_token_t token;
- - njs_variable_t *var;
- njs_parser_node_t *left, *stmt, *name, *assign, *expr;
- parser->node = NULL;
- @@ -1049,21 +1090,14 @@ njs_parser_var_statement(njs_vm_t *vm, n
- return NJS_TOKEN_ILLEGAL;
- }
- - var = njs_parser_variable_add(vm, parser, NJS_VARIABLE_VAR);
- - if (nxt_slow_path(var == NULL)) {
- - return NJS_TOKEN_ERROR;
- - }
- -
- - name = njs_parser_node_new(vm, parser, NJS_TOKEN_NAME);
- + name = njs_parser_variable_node(vm, parser,
- + njs_parser_text(parser),
- + njs_parser_key_hash(parser),
- + NJS_VARIABLE_VAR, 0);
- if (nxt_slow_path(name == NULL)) {
- return NJS_TOKEN_ERROR;
- }
- - ret = njs_parser_variable_reference(vm, parser, name, NJS_DECLARATION);
- - if (nxt_slow_path(ret != NXT_OK)) {
- - return NJS_TOKEN_ERROR;
- - }
- -
- token = njs_parser_token(vm, parser);
- if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- return token;
- @@ -1477,9 +1511,7 @@ njs_parser_for_statement(njs_vm_t *vm, n
- static njs_token_t
- njs_parser_for_var_statement(njs_vm_t *vm, njs_parser_t *parser)
- {
- - njs_ret_t ret;
- njs_token_t token;
- - njs_variable_t *var;
- njs_parser_node_t *left, *stmt, *name, *assign, *expr;
- parser->node = NULL;
- @@ -1501,21 +1533,14 @@ njs_parser_for_var_statement(njs_vm_t *v
- return NJS_TOKEN_ILLEGAL;
- }
- - var = njs_parser_variable_add(vm, parser, NJS_VARIABLE_VAR);
- - if (nxt_slow_path(var == NULL)) {
- - return NJS_TOKEN_ERROR;
- - }
- -
- - name = njs_parser_node_new(vm, parser, NJS_TOKEN_NAME);
- + name = njs_parser_variable_node(vm, parser,
- + njs_parser_text(parser),
- + njs_parser_key_hash(parser),
- + NJS_VARIABLE_VAR, 0);
- if (nxt_slow_path(name == NULL)) {
- return NJS_TOKEN_ERROR;
- }
- - ret = njs_parser_variable_reference(vm, parser, name, NJS_DECLARATION);
- - if (nxt_slow_path(ret != NXT_OK)) {
- - return NJS_TOKEN_ERROR;
- - }
- -
- token = njs_parser_token(vm, parser);
- if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- return token;
- @@ -1714,7 +1739,6 @@ njs_parser_try_statement(njs_vm_t *vm, n
- {
- njs_ret_t ret;
- njs_token_t token;
- - njs_variable_t *var;
- njs_parser_node_t *node, *try, *catch;
- token = njs_parser_try_block(vm, parser);
- @@ -1760,21 +1784,14 @@ njs_parser_try_statement(njs_vm_t *vm, n
- return NJS_TOKEN_ERROR;
- }
- - var = njs_parser_variable_add(vm, parser, NJS_VARIABLE_CATCH);
- - if (nxt_slow_path(var == NULL)) {
- - return NJS_TOKEN_ERROR;
- - }
- -
- - node = njs_parser_node_new(vm, parser, NJS_TOKEN_NAME);
- + node = njs_parser_variable_node(vm, parser,
- + njs_parser_text(parser),
- + njs_parser_key_hash(parser),
- + NJS_VARIABLE_CATCH, 0);
- if (nxt_slow_path(node == NULL)) {
- return NJS_TOKEN_ERROR;
- }
- - ret = njs_parser_variable_reference(vm, parser, node, NJS_DECLARATION);
- - if (nxt_slow_path(ret != NXT_OK)) {
- - return NJS_TOKEN_ERROR;
- - }
- -
- catch->left = node;
- token = njs_parser_token(vm, parser);
- @@ -1899,7 +1916,6 @@ njs_parser_import_statement(njs_vm_t *vm
- {
- njs_ret_t ret;
- njs_token_t token;
- - njs_variable_t *var;
- njs_parser_node_t *name, *import;
- if (parser->scope->type != NJS_SCOPE_GLOBAL
- @@ -1921,21 +1937,14 @@ njs_parser_import_statement(njs_vm_t *vm
- return NJS_TOKEN_ILLEGAL;
- }
- - var = njs_parser_variable_add(vm, parser, NJS_VARIABLE_VAR);
- - if (nxt_slow_path(var == NULL)) {
- - return NJS_TOKEN_ERROR;
- - }
- -
- - name = njs_parser_node_new(vm, parser, NJS_TOKEN_NAME);
- + name = njs_parser_variable_node(vm, parser,
- + njs_parser_text(parser),
- + njs_parser_key_hash(parser),
- + NJS_VARIABLE_VAR, 0);
- if (nxt_slow_path(name == NULL)) {
- return NJS_TOKEN_ERROR;
- }
- - ret = njs_parser_variable_reference(vm, parser, name, NJS_DECLARATION);
- - if (nxt_slow_path(ret != NXT_OK)) {
- - return NJS_TOKEN_ERROR;
- - }
- -
- token = njs_parser_token(vm, parser);
- if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- return token;
- @@ -2463,20 +2472,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;
- @@ -2566,6 +2561,26 @@ 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;
- + }
- +
- + break;
- +
- case NJS_TOKEN_NAME:
- nxt_thread_log_debug("JS: %V", name);
- diff -r e3ee3a2d9994 -r 89bfc95f182f njs/njs_parser.h
- --- a/njs/njs_parser.h Mon Mar 25 17:51:19 2019 +0300
- +++ 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 e3ee3a2d9994 -r 89bfc95f182f njs/njs_variable.h
- --- a/njs/njs_variable.h Mon Mar 25 17:51:19 2019 +0300
- +++ 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 e3ee3a2d9994 -r 89bfc95f182f njs/njs_vm.c
- --- a/njs/njs_vm.c Mon Mar 25 17:51:19 2019 +0300
- +++ b/njs/njs_vm.c Tue Mar 26 00:42:39 2019 +0800
- @@ -10,7 +10,6 @@
- #include <stdio.h>
- -
- struct njs_property_next_s {
- int32_t index;
- nxt_lvlhsh_each_t lhe;
- @@ -420,8 +419,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;
- @@ -432,9 +433,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 e3ee3a2d9994 -r 89bfc95f182f njs/njs_vm.h
- --- a/njs/njs_vm.h Mon Mar 25 17:51:19 2019 +0300
- +++ 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;
- # HG changeset patch
- # User hongzhidao <hongzhidao@gmail.com>
- # Date 1553533166 -28800
- # Node ID 938cb05807692b9f3d50c210124b48ea832feeed
- # Parent 89bfc95f182f12238b7884a39326bdae77f6ddc9
- Improved lambda this object.
- diff -r 89bfc95f182f -r 938cb0580769 njs/njs_generator.c
- --- a/njs/njs_generator.c Tue Mar 26 00:42:39 2019 +0800
- +++ b/njs/njs_generator.c Tue Mar 26 00:59:26 2019 +0800
- @@ -405,7 +405,6 @@ njs_generator(njs_vm_t *vm, njs_generato
- case NJS_TOKEN_REGEXP:
- return njs_generate_regexp(vm, generator, node);
- - case NJS_TOKEN_THIS:
- case NJS_TOKEN_OBJECT_CONSTRUCTOR:
- case NJS_TOKEN_ARRAY_CONSTRUCTOR:
- case NJS_TOKEN_NUMBER_CONSTRUCTOR:
- @@ -427,6 +426,7 @@ njs_generator(njs_vm_t *vm, njs_generato
- return NXT_OK;
- case NJS_TOKEN_NAME:
- + case NJS_TOKEN_THIS:
- case NJS_TOKEN_ARGUMENTS:
- return njs_generate_name(vm, generator, node);
- @@ -2403,6 +2403,7 @@ njs_generate_lambda_variables(njs_vm_t *
- njs_variable_t *var;
- njs_vmcode_move_t *move;
- nxt_lvlhsh_each_t lhe;
- + njs_vmcode_this_t *this;
- njs_vmcode_arguments_t *arguments;
- nxt_lvlhsh_each_init(&lhe, &njs_variables_hash_proto);
- @@ -2420,6 +2421,12 @@ njs_generate_lambda_variables(njs_vm_t *
- njs_generate_code_move(generator, move, var->index, index);
- }
- + if (var->this_object) {
- + njs_generate_code(generator, njs_vmcode_this_t, this,
- + njs_vmcode_this, 1, 0);
- + this->dst = var->index;
- + }
- +
- if (var->arguments_object) {
- njs_generate_code(generator, njs_vmcode_arguments_t, arguments,
- njs_vmcode_arguments, 1, 0);
- diff -r 89bfc95f182f -r 938cb0580769 njs/njs_parser.c
- --- a/njs/njs_parser.c Tue Mar 26 00:42:39 2019 +0800
- +++ b/njs/njs_parser.c Tue Mar 26 00:59:26 2019 +0800
- @@ -549,7 +549,8 @@ njs_parser_variable_reference(njs_vm_t *
- nxt_inline njs_parser_node_t *
- njs_parser_variable_node(njs_vm_t *vm, njs_parser_t *parser, nxt_str_t *name,
- - uint32_t hash, njs_variable_type_t type, uint8_t arguments_object)
- + uint32_t hash, njs_variable_type_t type, uint8_t arguments_object,
- + uint8_t this_object)
- {
- nxt_int_t ret;
- njs_variable_t *var;
- @@ -560,6 +561,7 @@ njs_parser_variable_node(njs_vm_t *vm, n
- return NULL;
- }
- + var->this_object = this_object;
- var->arguments_object = arguments_object;
- node = njs_parser_node_new(vm, parser, NJS_TOKEN_NAME);
- @@ -813,11 +815,20 @@ njs_parser_function_lambda(njs_vm_t *vm,
- return token;
- }
- + name = nxt_string_value("this");
- + hash = nxt_djb_hash(name.start, name.length);
- +
- + node = njs_parser_variable_node(vm, parser, &name, hash,
- + NJS_VARIABLE_VAR, 0, 1);
- + if (nxt_slow_path(node == NULL)) {
- + return NJS_TOKEN_ERROR;
- + }
- +
- name = nxt_string_value("arguments");
- hash = nxt_djb_hash(name.start, name.length);
- node = njs_parser_variable_node(vm, parser, &name, hash,
- - NJS_VARIABLE_VAR, 1);
- + NJS_VARIABLE_VAR, 1, 0);
- if (nxt_slow_path(node == NULL)) {
- return NJS_TOKEN_ERROR;
- }
- @@ -1093,7 +1104,7 @@ njs_parser_var_statement(njs_vm_t *vm, n
- name = njs_parser_variable_node(vm, parser,
- njs_parser_text(parser),
- njs_parser_key_hash(parser),
- - NJS_VARIABLE_VAR, 0);
- + NJS_VARIABLE_VAR, 0, 0);
- if (nxt_slow_path(name == NULL)) {
- return NJS_TOKEN_ERROR;
- }
- @@ -1536,7 +1547,7 @@ njs_parser_for_var_statement(njs_vm_t *v
- name = njs_parser_variable_node(vm, parser,
- njs_parser_text(parser),
- njs_parser_key_hash(parser),
- - NJS_VARIABLE_VAR, 0);
- + NJS_VARIABLE_VAR, 0, 0);
- if (nxt_slow_path(name == NULL)) {
- return NJS_TOKEN_ERROR;
- }
- @@ -1787,7 +1798,7 @@ njs_parser_try_statement(njs_vm_t *vm, n
- node = njs_parser_variable_node(vm, parser,
- njs_parser_text(parser),
- njs_parser_key_hash(parser),
- - NJS_VARIABLE_CATCH, 0);
- + NJS_VARIABLE_CATCH, 0, 0);
- if (nxt_slow_path(node == NULL)) {
- return NJS_TOKEN_ERROR;
- }
- @@ -1940,7 +1951,7 @@ njs_parser_import_statement(njs_vm_t *vm
- name = njs_parser_variable_node(vm, parser,
- njs_parser_text(parser),
- njs_parser_key_hash(parser),
- - NJS_VARIABLE_VAR, 0);
- + NJS_VARIABLE_VAR, 0, 0);
- if (nxt_slow_path(name == NULL)) {
- return NJS_TOKEN_ERROR;
- }
- @@ -2445,21 +2456,29 @@ njs_parser_reference(njs_vm_t *vm, njs_p
- scope = parser->scope;
- + node->token = NJS_TOKEN_GLOBAL_THIS;
- +
- while (scope->type != NJS_SCOPE_GLOBAL) {
- if (scope->type == NJS_SCOPE_FUNCTION) {
- - node->index = NJS_INDEX_THIS;
- + node->token = NJS_TOKEN_THIS;
- break;
- }
- scope = scope->parent;
- }
- - if (node->index == NJS_INDEX_THIS) {
- + if (node->token == NJS_TOKEN_THIS) {
- + 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;
- + }
- +
- break;
- }
- - node->token = NJS_TOKEN_GLOBAL_THIS;
- -
- /* Fall through. */
- case NJS_TOKEN_NJS:
- diff -r 89bfc95f182f -r 938cb0580769 njs/njs_variable.h
- --- a/njs/njs_variable.h Tue Mar 26 00:42:39 2019 +0800
- +++ b/njs/njs_variable.h Tue Mar 26 00:59:26 2019 +0800
- @@ -23,6 +23,7 @@ typedef struct {
- njs_variable_type_t type:8; /* 3 bits */
- uint8_t argument;
- + uint8_t this_object;
- uint8_t arguments_object;
- njs_index_t index;
- diff -r 89bfc95f182f -r 938cb0580769 njs/njs_vm.c
- --- a/njs/njs_vm.c Tue Mar 26 00:42:39 2019 +0800
- +++ b/njs/njs_vm.c Tue Mar 26 00:59:26 2019 +0800
- @@ -417,6 +417,23 @@ njs_vmcode_function(njs_vm_t *vm, njs_va
- njs_ret_t
- +njs_vmcode_this(njs_vm_t *vm, njs_value_t *invld1, njs_value_t *invld2)
- +{
- + njs_frame_t *frame;
- + njs_value_t *value;
- + njs_vmcode_this_t *code;
- +
- + frame = (njs_frame_t *) vm->active_frame;
- + code = (njs_vmcode_this_t *) vm->current;
- +
- + value = njs_vmcode_operand(vm, code->dst);
- + *value = frame->native.arguments[0];
- +
- + return sizeof(njs_vmcode_this_t);
- +}
- +
- +
- +njs_ret_t
- njs_vmcode_arguments(njs_vm_t *vm, njs_value_t *invld1, njs_value_t *invld2)
- {
- nxt_int_t ret;
- diff -r 89bfc95f182f -r 938cb0580769 njs/njs_vm.h
- --- a/njs/njs_vm.h Tue Mar 26 00:42:39 2019 +0800
- +++ b/njs/njs_vm.h Tue Mar 26 00:59:26 2019 +0800
- @@ -640,6 +640,12 @@ typedef struct {
- typedef struct {
- njs_vmcode_t code;
- njs_index_t dst;
- +} njs_vmcode_this_t;
- +
- +
- +typedef struct {
- + njs_vmcode_t code;
- + njs_index_t dst;
- } njs_vmcode_arguments_t;
- @@ -1136,6 +1142,8 @@ njs_ret_t njs_vmcode_array(njs_vm_t *vm,
- njs_value_t *inlvd2);
- njs_ret_t njs_vmcode_function(njs_vm_t *vm, njs_value_t *inlvd1,
- njs_value_t *invld2);
- +njs_ret_t njs_vmcode_this(njs_vm_t *vm, njs_value_t *inlvd1,
- + njs_value_t *invld2);
- njs_ret_t njs_vmcode_arguments(njs_vm_t *vm, njs_value_t *inlvd1,
- njs_value_t *invld2);
- njs_ret_t njs_vmcode_regexp(njs_vm_t *vm, njs_value_t *inlvd1,
- # HG changeset patch
- # User hongzhidao <hongzhidao@gmail.com>
- # Date 1553534189 -28800
- # Node ID 280cc88eb639fec2c56d0b54af7442529da58b37
- # Parent 938cb05807692b9f3d50c210124b48ea832feeed
- Added arrow function support.
- diff -r 938cb0580769 -r 280cc88eb639 njs/njs_function.h
- --- a/njs/njs_function.h Tue Mar 26 00:59:26 2019 +0800
- +++ b/njs/njs_function.h Tue Mar 26 01:16:29 2019 +0800
- @@ -30,6 +30,7 @@ struct njs_function_lambda_s {
- /* Function internal block closures levels. */
- uint8_t block_closures; /* 4 bits */
- + uint8_t arrow; /* 1 bit */
- uint8_t rest_parameters; /* 1 bit */
- /* Initial values of local scope. */
- diff -r 938cb0580769 -r 280cc88eb639 njs/njs_lexer.c
- --- a/njs/njs_lexer.c Tue Mar 26 00:59:26 2019 +0800
- +++ b/njs/njs_lexer.c Tue Mar 26 01:16:29 2019 +0800
- @@ -278,6 +278,7 @@ static const njs_lexer_multi_t njs_grea
- static const njs_lexer_multi_t njs_assignment_token[] = {
- { '=', NJS_TOKEN_EQUAL, 1, njs_strict_equal_token },
- + { '>', NJS_TOKEN_ARROW, 0, NULL },
- };
- diff -r 938cb0580769 -r 280cc88eb639 njs/njs_lexer.h
- --- a/njs/njs_lexer.h Tue Mar 26 00:59:26 2019 +0800
- +++ b/njs/njs_lexer.h Tue Mar 26 01:16:29 2019 +0800
- @@ -36,6 +36,7 @@ typedef enum {
- NJS_TOKEN_CONDITIONAL,
- NJS_TOKEN_ASSIGNMENT,
- + NJS_TOKEN_ARROW,
- NJS_TOKEN_ADDITION_ASSIGNMENT,
- NJS_TOKEN_SUBSTRACTION_ASSIGNMENT,
- NJS_TOKEN_MULTIPLICATION_ASSIGNMENT,
- diff -r 938cb0580769 -r 280cc88eb639 njs/njs_parser.c
- --- a/njs/njs_parser.c Tue Mar 26 00:59:26 2019 +0800
- +++ b/njs/njs_parser.c Tue Mar 26 01:16:29 2019 +0800
- @@ -2252,6 +2252,166 @@ njs_parser_property_token(njs_vm_t *vm,
- }
- +static nxt_int_t
- +njs_parser_match_arrow_expression(njs_vm_t *vm, njs_parser_t *parser,
- + njs_token_t token)
- +{
- + size_t offset;
- + nxt_bool_t rest_parameters;
- +
- + offset = 0;
- +
- + if (token == NJS_TOKEN_NAME) {
- + goto arrow;
- + }
- +
- + token = njs_parser_peek_token(vm, parser, &offset);
- + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- + return NXT_DECLINED;
- + }
- +
- + rest_parameters = 0;
- +
- + while (token != NJS_TOKEN_CLOSE_PARENTHESIS) {
- +
- + if (rest_parameters) {
- + return NXT_DECLINED;
- + }
- +
- + if (nxt_slow_path(token == NJS_TOKEN_ELLIPSIS)) {
- + rest_parameters = 1;
- +
- + token = njs_parser_peek_token(vm, parser, &offset);
- + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- + return NXT_DECLINED;
- + }
- + }
- +
- + if (nxt_slow_path(token != NJS_TOKEN_NAME)) {
- + return NXT_DECLINED;
- + }
- +
- + token = njs_parser_peek_token(vm, parser, &offset);
- + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- + return token;
- + }
- +
- + if (token == NJS_TOKEN_COMMA) {
- + token = njs_parser_peek_token(vm, parser, &offset);
- + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- + return NXT_DECLINED;
- + }
- + }
- + }
- +
- +arrow:
- +
- + token = njs_parser_peek_token(vm, parser, &offset);
- + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- + return NXT_DECLINED;
- + }
- +
- + if (parser->lexer->prev_token == NJS_TOKEN_LINE_END) {
- + return NXT_DECLINED;
- + }
- +
- + if (nxt_slow_path(token != NJS_TOKEN_ARROW)) {
- + return NXT_DECLINED;
- + }
- +
- + return NXT_OK;
- +}
- +
- +
- +static njs_token_t
- +njs_parser_arrow_expression(njs_vm_t *vm, njs_parser_t *parser,
- + njs_token_t token)
- +{
- + njs_ret_t ret;
- + njs_index_t index;
- + njs_parser_node_t *node, *body, *parent;
- + njs_function_lambda_t *lambda;
- +
- + node = njs_parser_node_new(vm, parser, NJS_TOKEN_FUNCTION_EXPRESSION);
- + if (nxt_slow_path(node == NULL)) {
- + return NJS_TOKEN_ERROR;
- + }
- +
- + node->token_line = njs_parser_token_line(parser);
- + parser->node = node;
- +
- + lambda = nxt_mp_zalloc(vm->mem_pool, sizeof(njs_function_lambda_t));
- + if (nxt_slow_path(lambda == NULL)) {
- + return NJS_TOKEN_ERROR;
- + }
- +
- + lambda->arrow = 1;
- +
- + node->u.value.data.u.lambda = lambda;
- +
- + ret = njs_parser_scope_begin(vm, parser, NJS_SCOPE_FUNCTION);
- + if (nxt_slow_path(ret != NXT_OK)) {
- + return NJS_TOKEN_ERROR;
- + }
- +
- + index = NJS_SCOPE_ARGUMENTS;
- +
- + /* A "this" reservation. */
- + index += sizeof(njs_value_t);
- +
- + if (token == NJS_TOKEN_OPEN_PARENTHESIS) {
- + token = njs_parser_lambda_arguments(vm, parser, lambda, index, token);
- + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- + return token;
- + }
- +
- + } else {
- + token = njs_parser_lambda_argument(vm, parser, index);
- + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- + return token;
- + }
- +
- + lambda->nargs = 1;
- + }
- +
- + if (parser->lexer->prev_token == NJS_TOKEN_LINE_END) {
- + return NJS_TOKEN_ILLEGAL;
- + }
- +
- + token = njs_parser_match(vm, parser, token, NJS_TOKEN_ARROW);
- + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- + return token;
- + }
- +
- + if (token == NJS_TOKEN_OPEN_BRACE) {
- + token = njs_parser_lambda_body(vm, parser, token);
- + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- + return token;
- + }
- +
- + } else {
- + parent = parser->node;
- +
- + token = njs_parser_expression(vm, parser, token);
- + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
- + return token;
- + }
- +
- + body = njs_parser_return_set(vm, parser, parser->node);
- + if (nxt_slow_path(body == NULL)) {
- + return NJS_TOKEN_ERROR;
- + }
- +
- + parent->right = body;
- + parser->node = parent;
- + }
- +
- + njs_parser_scope_end(vm, parser);
- +
- + return token;
- +}
- +
- +
- njs_token_t
- njs_parser_terminal(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token)
- {
- @@ -2259,6 +2419,12 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa
- njs_ret_t ret;
- njs_parser_node_t *node;
- + if (token == NJS_TOKEN_OPEN_PARENTHESIS || token == NJS_TOKEN_NAME) {
- + if (njs_parser_match_arrow_expression(vm, parser, token) == NXT_OK) {
- + return njs_parser_arrow_expression(vm, parser, token);
- + }
- + }
- +
- if (token == NJS_TOKEN_OPEN_PARENTHESIS) {
- token = njs_parser_token(vm, parser);
- diff -r 938cb0580769 -r 280cc88eb639 njs/njs_vm.c
- --- a/njs/njs_vm.c Tue Mar 26 00:59:26 2019 +0800
- +++ b/njs/njs_vm.c Tue Mar 26 01:16:29 2019 +0800
- @@ -394,7 +394,7 @@ njs_vmcode_function(njs_vm_t *vm, njs_va
- function->object.__proto__ = &vm->prototypes[NJS_PROTOTYPE_FUNCTION].object;
- function->object.extensible = 1;
- function->args_offset = 1;
- - function->ctor = 1;
- + function->ctor = lambda->arrow ? 0 : 1;
- if (nesting != 0) {
- function->closure = 1;
- diff -r 938cb0580769 -r 280cc88eb639 njs/test/njs_unit_test.c
- --- a/njs/test/njs_unit_test.c Tue Mar 26 00:59:26 2019 +0800
- +++ b/njs/test/njs_unit_test.c Tue Mar 26 01:16:29 2019 +0800
- @@ -6514,6 +6514,86 @@ static njs_unit_test_t njs_test[] =
- "myFoo(1,2);" ),
- nxt_string("") },
- + /* arrow functions. */
- +
- + { nxt_string("()"),
- + nxt_string("SyntaxError: Unexpected token \")\" in 1") },
- +
- + { nxt_string("() => "),
- + nxt_string("SyntaxError: Unexpected end of input in 1") },
- +
- + { nxt_string("() => {"),
- + nxt_string("SyntaxError: Unexpected end of input in 1") },
- +
- + { nxt_string("a\n => 1"),
- + nxt_string("SyntaxError: Unexpected token \"=>\" in 2") },
- +
- + { nxt_string("new (()=>1)"),
- + nxt_string("TypeError: function is not a constructor")},
- +
- + { nxt_string("(\n) => {}"),
- + nxt_string("[object Function]") },
- +
- + { nxt_string("a => 1"),
- + nxt_string("[object Function]") },
- +
- + { nxt_string("var f = f => {return 1;}; f()"),
- + nxt_string("1") },
- +
- + { nxt_string("var f = (f) => {return 1;}; f()"),
- + nxt_string("1") },
- +
- + { nxt_string("var f = (f, a, b) => {return 1;}; f()"),
- + nxt_string("1") },
- +
- + { nxt_string("var f = () => {return 1;}; f()"),
- + nxt_string("1") },
- +
- + { nxt_string("(f => {return 1;})()"),
- + nxt_string("1") },
- +
- + { nxt_string("((f) => {return 1;})()"),
- + nxt_string("1") },
- +
- + { nxt_string("(((f) => {return 1;}))()"),
- + nxt_string("1") },
- +
- + { nxt_string("var f = f => 1; f()"),
- + nxt_string("1") },
- +
- + { nxt_string("() => 1"),
- + nxt_string("[object Function]") },
- +
- + { nxt_string("var f = ()=>{}; f()"),
- + nxt_string("undefined") },
- +
- + { nxt_string("var f = ()=>({}); f()"),
- + nxt_string("[object Object]") },
- +
- + { nxt_string("var materials = ['Hydrogen', 'Helium', 'Lithium', 'Beryllium'];"
- + "materials.map(material => { return material.length; });"),
- + nxt_string("8,6,7,9") },
- +
- + { nxt_string("var materials = ['Hydrogen', 'Helium', 'Lithium', 'Beryllium'];"
- + "materials.map(material => material.length);"),
- + nxt_string("8,6,7,9") },
- +
- + { nxt_string("var materials = ['Hydrogen', 'Helium', 'Lithium', 'Beryllium'];"
- + "materials.map(material => { material.length });"),
- + nxt_string(",,,") },
- +
- + { nxt_string("function f(a, b, c) {a = 1; return () => { return arguments[1]; };};"
- + "f(1, 2, 3)('a', 'b');"),
- + nxt_string("2") },
- +
- + { nxt_string("var f = (...c) => { return (function() { return arguments.length; }).bind(null, c); };"
- + "var x = f(1,'a',false, {}); x()"),
- + nxt_string("1") },
- +
- + { nxt_string("var f = (...c) => { return (function() { return arguments.length; }).bind(null, c); };"
- + "var x = f(1,'a',false, {}); x(1,2,3)"),
- + nxt_string("4") },
- +
- /* Scopes. */
- { nxt_string("function f(x) { a = x } var a; f(5); a"),
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement