[njs] This object as a variable.
Dmitry Volyntsev
xeioex at nginx.com
Fri Apr 12 16:58:15 UTC 2019
details: https://hg.nginx.org/njs/rev/070b635928a9
branches:
changeset: 887:070b635928a9
user: Dmitry Volyntsev <xeioex at 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,
More information about the nginx-devel
mailing list