[njs] Improved complex assignments when key is a primitive object.
Dmitry Volyntsev
xeioex at nginx.com
Tue Sep 20 00:39:12 UTC 2022
details: https://hg.nginx.org/njs/rev/33fcc9fc6704
branches:
changeset: 1959:33fcc9fc6704
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Mon Sep 19 17:36:02 2022 -0700
description:
Improved complex assignments when key is a primitive object.
When key is a primitive object NJS_VMCODE_TO_PROPERTY_KEY is not
necessary.
diffstat:
src/njs_generator.c | 52 +++++++++++++++++++++++++++--------------------
src/njs_parser.h | 5 ++++
src/test/njs_unit_test.c | 30 +++++++++++++++++++++++++++
3 files changed, 65 insertions(+), 22 deletions(-)
diffs (124 lines):
diff -r 75e7a7bb6b06 -r 33fcc9fc6704 src/njs_generator.c
--- a/src/njs_generator.c Fri Sep 16 17:07:04 2022 -0700
+++ b/src/njs_generator.c Mon Sep 19 17:36:02 2022 -0700
@@ -3054,17 +3054,21 @@ njs_generate_operation_assignment_prop(n
}
}
- 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);
-
- to_property_key->src2 = object->index;
- to_property_key->src1 = property->index;
- to_property_key->dst = prop_index;
+ 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);
+
+ 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_
found:
- 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);
-
- to_property_key->src2 = lvalue->left->index;
- to_property_key->src1 = lvalue->right->index;
- to_property_key->dst = prop_index;
+ 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);
+
+ 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 -r 75e7a7bb6b06 -r 33fcc9fc6704 src/njs_parser.h
--- a/src/njs_parser.h Fri Sep 16 17:07:04 2022 -0700
+++ b/src/njs_parser.h Mon Sep 19 17:36:02 2022 -0700
@@ -157,6 +157,11 @@ njs_int_t njs_parser_serialize_ast(njs_p
|| (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 -r 75e7a7bb6b06 -r 33fcc9fc6704 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c Fri Sep 16 17:07:04 2022 -0700
+++ b/src/test/njs_unit_test.c Mon Sep 19 17:36:02 2022 -0700
@@ -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") },
More information about the nginx-devel
mailing list