From: Vadim Zhestikov Date: Fri, 22 Jul 2022 01:33:20 +0000 (-0700) Subject: Fixed assignment to global property by name only. X-Git-Tag: 0.7.7~24 X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=9480746fb1246de9e0dff3529c99704bfa938f24;p=njs.git Fixed assignment to global property by name only. This closes #145 issue on Github. --- diff --git a/src/njs_generator.c b/src/njs_generator.c index 1e13a751..8cc7ee0a 100644 --- a/src/njs_generator.c +++ b/src/njs_generator.c @@ -222,6 +222,9 @@ static njs_int_t njs_generate_comma_expression(njs_vm_t *vm, 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, @@ -2658,6 +2661,53 @@ njs_generate_comma_expression_end(njs_vm_t *vm, njs_generator_t *generator, } +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, njs_generator_t *generator, 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 *vm, njs_generator_t *generator, 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_t *vm, njs_generator_t *generator, 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(njs_vm_t *vm, njs_generator_t *generator, 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 *vm, njs_generator_t *generator, 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 *vm, njs_generator_t *generator, 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 --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index 7935b011..521814a7 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -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") },