[njs] Fixed assignment to global property by name only.
Vadim Zhestikov
v.zhestikov at f5.com
Fri Jul 22 01:40:12 UTC 2022
details: https://hg.nginx.org/njs/rev/4b8d8237f598
branches:
changeset: 1916:4b8d8237f598
user: Vadim Zhestikov <v.zhestikov at f5.com>
date: Thu Jul 21 18:33:20 2022 -0700
description:
Fixed assignment to global property by name only.
This closes #145 issue on Github.
diffstat:
src/njs_generator.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++--
src/test/njs_unit_test.c | 22 ++++++++++++++
2 files changed, 91 insertions(+), 3 deletions(-)
diffs (170 lines):
diff -r c597ee3450ab -r 4b8d8237f598 src/njs_generator.c
--- a/src/njs_generator.c Wed Jul 20 17:49:00 2022 -0700
+++ b/src/njs_generator.c Thu Jul 21 18:33:20 2022 -0700
@@ -222,6 +222,9 @@ static njs_int_t njs_generate_comma_expr
njs_generator_t *generator, njs_parser_node_t *node);
static njs_int_t njs_generate_comma_expression_end(njs_vm_t *vm,
njs_generator_t *generator, njs_parser_node_t *node);
+static njs_int_t njs_generate_global_property_set(njs_vm_t *vm,
+ njs_generator_t *generator, njs_parser_node_t *node_dst,
+ njs_parser_node_t *node_src);
static njs_int_t njs_generate_assignment(njs_vm_t *vm,
njs_generator_t *generator, njs_parser_node_t *node);
static njs_int_t njs_generate_assignment_name(njs_vm_t *vm,
@@ -2659,6 +2662,53 @@ njs_generate_comma_expression_end(njs_vm
static njs_int_t
+njs_generate_global_property_set(njs_vm_t *vm, njs_generator_t *generator,
+ njs_parser_node_t *node_dst, njs_parser_node_t *node_src)
+{
+ ssize_t length;
+ njs_int_t ret;
+ njs_value_t property;
+ njs_variable_t *var;
+ njs_vmcode_prop_set_t *prop_set;
+ const njs_lexer_entry_t *lex_entry;
+
+ var = njs_variable_reference(vm, node_dst);
+ if (var == NULL) {
+ njs_generate_code(generator, njs_vmcode_prop_set_t, prop_set,
+ NJS_VMCODE_PROPERTY_SET, 3, node_src);
+
+ prop_set->value = node_dst->index;
+ prop_set->object = njs_scope_global_this_index();
+
+ lex_entry = njs_lexer_entry(node_dst->u.reference.unique_id);
+ if (njs_slow_path(lex_entry == NULL)) {
+ return NJS_ERROR;
+ }
+
+ length = njs_utf8_length(lex_entry->name.start, lex_entry->name.length);
+ if (njs_slow_path(length < 0)) {
+ return NJS_ERROR;
+ }
+
+ ret = njs_string_new(vm, &property, lex_entry->name.start,
+ lex_entry->name.length, length);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return NJS_ERROR;
+ }
+
+ prop_set->property = njs_scope_global_index(vm, &property,
+ generator->runtime);
+ if (njs_slow_path(prop_set->property == NJS_INDEX_ERROR)) {
+ return NJS_ERROR;
+ }
+
+ }
+
+ return NJS_OK;
+}
+
+
+static njs_int_t
njs_generate_assignment(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_node_t *node)
{
@@ -2673,7 +2723,7 @@ njs_generate_assignment(njs_vm_t *vm, nj
if (lvalue->token_type == NJS_TOKEN_NAME) {
- ret = njs_generate_variable(vm, generator, lvalue, NJS_DECLARATION,
+ ret = njs_generate_variable(vm, generator, lvalue, NJS_REFERENCE,
&var);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
@@ -2721,6 +2771,7 @@ static njs_int_t
njs_generate_assignment_name(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_node_t *node)
{
+ njs_int_t ret;
njs_parser_node_t *lvalue, *expr;
njs_vmcode_move_t *move;
@@ -2739,6 +2790,11 @@ njs_generate_assignment_name(njs_vm_t *v
node->index = expr->index;
node->temporary = expr->temporary;
+ ret = njs_generate_global_property_set(vm, generator, node->left, expr);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return ret;
+ }
+
return njs_generator_stack_pop(vm, generator, NULL);
}
@@ -2855,7 +2911,7 @@ njs_generate_operation_assignment(njs_vm
if (lvalue->token_type == NJS_TOKEN_NAME) {
- ret = njs_generate_variable(vm, generator, lvalue, NJS_DECLARATION,
+ ret = njs_generate_variable(vm, generator, lvalue, NJS_REFERENCE,
&var);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
@@ -2938,6 +2994,11 @@ njs_generate_operation_assignment_name(n
node->index = lvalue->index;
+ ret = njs_generate_global_property_set(vm, generator, node->left, expr);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return ret;
+ }
+
if (lvalue->index != index) {
ret = njs_generate_index_release(vm, generator, index);
if (njs_slow_path(ret != NJS_OK)) {
@@ -3553,7 +3614,7 @@ njs_generate_inc_dec_operation(njs_vm_t
if (lvalue->token_type == NJS_TOKEN_NAME) {
- ret = njs_generate_variable(vm, generator, lvalue, NJS_DECLARATION,
+ ret = njs_generate_variable(vm, generator, lvalue, NJS_REFERENCE,
&var);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
@@ -3580,6 +3641,11 @@ njs_generate_inc_dec_operation(njs_vm_t
code->src1 = lvalue->index;
code->src2 = lvalue->index;
+ ret = njs_generate_global_property_set(vm, generator, lvalue, lvalue);
+ if (njs_slow_path(ret) != NJS_OK) {
+ return ret;
+ }
+
return njs_generator_stack_pop(vm, generator, NULL);
}
diff -r c597ee3450ab -r 4b8d8237f598 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c Wed Jul 20 17:49:00 2022 -0700
+++ b/src/test/njs_unit_test.c Thu Jul 21 18:33:20 2022 -0700
@@ -12077,6 +12077,28 @@ static njs_unit_test_t njs_test[] =
{ njs_str("this.a = 1; a"),
njs_str("1") },
+ { njs_str("this.a = 1; a = 3; this.a"),
+ njs_str("3") },
+
+ { njs_str("this.a = 1; ++a; this.a"),
+ njs_str("2") },
+
+ { njs_str("this.a = 1; a += 3; this.a"),
+ njs_str("4") },
+
+ { njs_str("var b=11;"
+ "var t = function () {b += 5; return b};"
+ "t() === 16 && b === 16 && this.b === 16" ),
+ njs_str("true") },
+
+ { njs_str("this.c=15;"
+ "var t = function () {c += 5; return c};"
+ "t() === 20 && c === 20 && this.c === 20" ),
+ njs_str("true") },
+
+ { njs_str("--undefined"),
+ njs_str("TypeError: Cannot assign to read-only property \"undefined\" of object") },
+
{ njs_str("this.a = 2; this.b = 3; a * b - a"),
njs_str("4") },
More information about the nginx-devel
mailing list