]> git.kaiwu.me - njs.git/commitdiff
Improved complex assignments when key is a primitive object.
authorDmitry Volyntsev <xeioex@nginx.com>
Tue, 20 Sep 2022 00:36:02 +0000 (17:36 -0700)
committerDmitry Volyntsev <xeioex@nginx.com>
Tue, 20 Sep 2022 00:36:02 +0000 (17:36 -0700)
When key is a primitive object NJS_VMCODE_TO_PROPERTY_KEY is not
necessary.

src/njs_generator.c
src/njs_parser.h
src/test/njs_unit_test.c

index 74c4635d3581e8178a33b93eee54fbeeed8a1969..76a57e83926eef2f65dd9dd98c5dca640b6ac04d 100644 (file)
@@ -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);
 
index 2d343260d217acfaef2fd46d7abf1d166096be4d..9a8e9521f8ce112a1aa3370b08b88493f3afa42f 100644 (file)
@@ -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__)
index 1306f3d1a439ce37789427aa4ec0e83d5e1bf4fb..c67b509c909a1e2df415f7d5094b546e99bf74f8 100644 (file)
@@ -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") },