Welcome! Log In Create A New Profile

Advanced

[njs] This object as a variable.

Dmitry Volyntsev
April 12, 2019 01:00PM
details: https://hg.nginx.org/njs/rev/070b635928a9
branches:
changeset: 887:070b635928a9
user: Dmitry Volyntsev <xeioex@nginx.com>
date: Wed Apr 10 17:46:29 2019 +0300
description:
This object as a variable.

Non-local this is introduced to support arrow functions.
this is non-local when reference scope != first non-arrow
function scope.

diffstat:

njs/njs_disassembler.c | 2 ++
njs/njs_generator.c | 8 ++++++++
njs/njs_lexer.h | 1 +
njs/njs_parser.h | 15 +++++++++++++++
njs/njs_parser_terminal.c | 28 ++++++++++++++++++++++++++--
njs/njs_variable.h | 1 +
njs/njs_vm.c | 17 +++++++++++++++++
njs/njs_vm.h | 8 ++++++++
8 files changed, 78 insertions(+), 2 deletions(-)

diffs (187 lines):

diff -r f582672967ad -r 070b635928a9 njs/njs_disassembler.c
--- a/njs/njs_disassembler.c Wed Apr 10 17:46:29 2019 +0300
+++ b/njs/njs_disassembler.c Wed Apr 10 17:46:29 2019 +0300
@@ -23,6 +23,8 @@ static njs_code_name_t code_names[] = {
nxt_string("OBJECT ") },
{ njs_vmcode_function, sizeof(njs_vmcode_function_t),
nxt_string("FUNCTION ") },
+ { njs_vmcode_this, sizeof(njs_vmcode_this_t),
+ nxt_string("THIS ") },
{ njs_vmcode_arguments, sizeof(njs_vmcode_arguments_t),
nxt_string("ARGUMENTS ") },
{ njs_vmcode_regexp, sizeof(njs_vmcode_regexp_t),
diff -r f582672967ad -r 070b635928a9 njs/njs_generator.c
--- a/njs/njs_generator.c Wed Apr 10 17:46:29 2019 +0300
+++ b/njs/njs_generator.c Wed Apr 10 17:46:29 2019 +0300
@@ -427,6 +427,7 @@ njs_generator(njs_vm_t *vm, njs_generato

case NJS_TOKEN_NAME:
case NJS_TOKEN_ARGUMENTS:
+ case NJS_TOKEN_NON_LOCAL_THIS:
return njs_generate_name(vm, generator, node);

case NJS_TOKEN_GLOBAL_THIS:
@@ -2414,6 +2415,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);
@@ -2431,6 +2433,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 f582672967ad -r 070b635928a9 njs/njs_lexer.h
--- a/njs/njs_lexer.h Wed Apr 10 17:46:29 2019 +0300
+++ b/njs/njs_lexer.h Wed Apr 10 17:46:29 2019 +0300
@@ -159,6 +159,7 @@ typedef enum {
NJS_TOKEN_THROW,

NJS_TOKEN_THIS,
+ NJS_TOKEN_NON_LOCAL_THIS,
NJS_TOKEN_ARGUMENTS,

#define NJS_TOKEN_FIRST_OBJECT NJS_TOKEN_GLOBAL_THIS
diff -r f582672967ad -r 070b635928a9 njs/njs_parser.h
--- a/njs/njs_parser.h Wed Apr 10 17:46:29 2019 +0300
+++ b/njs/njs_parser.h Wed Apr 10 17:46:29 2019 +0300
@@ -225,6 +225,21 @@ njs_parser_global_scope(njs_vm_t *vm)
}


+nxt_inline njs_parser_scope_t *
+njs_function_scope(njs_parser_scope_t *scope)
+{
+ while (scope->type != NJS_SCOPE_GLOBAL) {
+ if (scope->type == NJS_SCOPE_FUNCTION) {
+ return scope;
+ }
+
+ scope = scope->parent;
+ }
+
+ return NULL;
+}
+
+
extern const nxt_lvlhsh_proto_t njs_keyword_hash_proto;


diff -r f582672967ad -r 070b635928a9 njs/njs_parser_terminal.c
--- a/njs/njs_parser_terminal.c Wed Apr 10 17:46:29 2019 +0300
+++ b/njs/njs_parser_terminal.c Wed Apr 10 17:46:29 2019 +0300
@@ -215,14 +215,38 @@ njs_parser_reference(njs_vm_t *vm, njs_p

while (scope->type != NJS_SCOPE_GLOBAL) {
if (scope->type == NJS_SCOPE_FUNCTION) {
- node->index = NJS_INDEX_THIS;
break;
}

scope = scope->parent;
}

- if (node->index == NJS_INDEX_THIS) {
+ if (scope->type != NJS_SCOPE_GLOBAL) {
+ if (njs_function_scope(scope)
+ == njs_function_scope(parser->scope))
+ {
+ node->index = NJS_INDEX_THIS;
+
+ } else {
+ node->token = NJS_TOKEN_NON_LOCAL_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;
+ }
+
+ var = njs_variable_add(vm, parser->scope, name, hash,
+ NJS_VARIABLE_VAR);
+ if (nxt_slow_path(var == NULL)) {
+ return NULL;
+ }
+
+ var->this_object = 1;
+ }
+
break;
}

diff -r f582672967ad -r 070b635928a9 njs/njs_variable.h
--- a/njs/njs_variable.h Wed Apr 10 17:46:29 2019 +0300
+++ b/njs/njs_variable.h Wed Apr 10 17:46:29 2019 +0300
@@ -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 f582672967ad -r 070b635928a9 njs/njs_vm.c
--- a/njs/njs_vm.c Wed Apr 10 17:46:29 2019 +0300
+++ b/njs/njs_vm.c Wed Apr 10 17:46:29 2019 +0300
@@ -391,6 +391,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 f582672967ad -r 070b635928a9 njs/njs_vm.h
--- a/njs/njs_vm.h Wed Apr 10 17:46:29 2019 +0300
+++ b/njs/njs_vm.h Wed Apr 10 17:46:29 2019 +0300
@@ -638,6 +638,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;
@@ -1141,6 +1147,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,
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[njs] This object as a variable.

Dmitry Volyntsev 117 April 12, 2019 01:00PM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 77
Record Number of Users: 6 on February 13, 2018
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready