[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