From e88613e84a75624ffa8810c2c920e1ea30d8eacd Mon Sep 17 00:00:00 2001 From: Dmitry Volyntsev Date: Mon, 19 Sep 2022 17:36:02 -0700 Subject: [PATCH] Improved complex assignments when key is a primitive object. When key is a primitive object NJS_VMCODE_TO_PROPERTY_KEY is not necessary. --- src/njs_generator.c | 44 ++++++++++++++++++++++++---------------- src/njs_parser.h | 5 +++++ src/test/njs_unit_test.c | 30 +++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 18 deletions(-) diff --git a/src/njs_generator.c b/src/njs_generator.c index 74c4635d..76a57e83 100644 --- a/src/njs_generator.c +++ b/src/njs_generator.c @@ -3054,17 +3054,21 @@ njs_generate_operation_assignment_prop(njs_vm_t *vm, njs_generator_t *generator, } } - prop_index = njs_generate_node_temp_index_get(vm, generator, node); - if (njs_slow_path(prop_index == NJS_INDEX_ERROR)) { - return NJS_ERROR; - } + prop_index = property->index; + + if (!njs_parser_is_primitive(property)) { + prop_index = njs_generate_node_temp_index_get(vm, generator, node); + if (njs_slow_path(prop_index == NJS_INDEX_ERROR)) { + return NJS_ERROR; + } - njs_generate_code(generator, njs_vmcode_3addr_t, to_property_key, - NJS_VMCODE_TO_PROPERTY_KEY, 2, property); + njs_generate_code(generator, njs_vmcode_3addr_t, to_property_key, + NJS_VMCODE_TO_PROPERTY_KEY, 2, property); - to_property_key->src2 = object->index; - to_property_key->src1 = property->index; - to_property_key->dst = prop_index; + to_property_key->src2 = object->index; + to_property_key->src1 = property->index; + to_property_key->dst = prop_index; + } index = njs_generate_node_temp_index_get(vm, generator, node); if (njs_slow_path(index == NJS_INDEX_ERROR)) { @@ -3718,17 +3722,21 @@ njs_generate_inc_dec_operation_prop(njs_vm_t *vm, njs_generator_t *generator, found: - prop_index = njs_generate_temp_index_get(vm, generator, node); - if (njs_slow_path(prop_index == NJS_INDEX_ERROR)) { - return NJS_ERROR; - } + prop_index = lvalue->right->index; + + if (!njs_parser_is_primitive(lvalue->right)) { + prop_index = njs_generate_temp_index_get(vm, generator, node); + if (njs_slow_path(prop_index == NJS_INDEX_ERROR)) { + return NJS_ERROR; + } - njs_generate_code(generator, njs_vmcode_3addr_t, to_property_key, - NJS_VMCODE_TO_PROPERTY_KEY, 2, node); + njs_generate_code(generator, njs_vmcode_3addr_t, to_property_key, + NJS_VMCODE_TO_PROPERTY_KEY, 2, node); - to_property_key->src2 = lvalue->left->index; - to_property_key->src1 = lvalue->right->index; - to_property_key->dst = prop_index; + to_property_key->src2 = lvalue->left->index; + to_property_key->src1 = lvalue->right->index; + to_property_key->dst = prop_index; + } post = *((njs_bool_t *) generator->context); diff --git a/src/njs_parser.h b/src/njs_parser.h index 2d343260..9a8e9521 100644 --- a/src/njs_parser.h +++ b/src/njs_parser.h @@ -157,6 +157,11 @@ njs_int_t njs_parser_serialize_ast(njs_parser_node_t *node, njs_chb_t *chain); || (node)->token_type == NJS_TOKEN_PROPERTY) +#define njs_parser_is_primitive(node) \ + ((node)->token_type >= NJS_TOKEN_NULL \ + && (node)->token_type <= NJS_TOKEN_STRING) + + #define njs_parser_syntax_error(parser, fmt, ...) \ njs_parser_lexer_error(parser, NJS_OBJ_TYPE_SYNTAX_ERROR, fmt, \ ##__VA_ARGS__) diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index 1306f3d1..c67b509c 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -3647,6 +3647,36 @@ static njs_unit_test_t njs_test[] = { njs_str("var a = 1; var b = { x:2 }; a = b.x += (a = 1)"), njs_str("3") }, + { njs_str("var o = {true:1}; o[true] += 1; o.true"), + njs_str("2") }, + + { njs_str("var o = {false:1}; o[false] += 1; o.false"), + njs_str("2") }, + + { njs_str("var o = {undefined:1}; o[undefined] += 1; o.undefined"), + njs_str("2") }, + + { njs_str("var o = {'5':1}; o[5] += 1; o[5]"), + njs_str("2") }, + + { njs_str("var o = {a:1}; o[{toString:()=>'a'}] += 1; o.a"), + njs_str("2") }, + + { njs_str("var o = {true:1}; o[true]++; o.true"), + njs_str("2") }, + + { njs_str("var o = {false:1}; o[false]++; o.false"), + njs_str("2") }, + + { njs_str("var o = {undefined:1}; o[undefined]++; o.undefined"), + njs_str("2") }, + + { njs_str("var o = {'5':1}; o[5]++; o[5]"), + njs_str("2") }, + + { njs_str("var o = {a:1}; o[{toString:()=>'a'}]++; o.a"), + njs_str("2") }, + { njs_str("var a = undefined; a.b++; a.b"), njs_str("TypeError: cannot get property \"b\" of undefined") }, -- 2.47.3