[njs] Fixed code generation for "in" operation with side effect.

Igor Sysoev igor at sysoev.ru
Tue Jan 3 15:35:31 UTC 2017


details:   http://hg.nginx.org/njs/rev/9672a3c3aaae
branches:  
changeset: 296:9672a3c3aaae
user:      Igor Sysoev <igor at sysoev.ru>
date:      Mon Jan 02 22:59:33 2017 +0300
description:
Fixed code generation for "in" operation with side effect.

diffstat:

 njs/njs_generator.c      |  41 +++++++++++++++++++++--------------------
 njs/test/njs_unit_test.c |   3 +++
 2 files changed, 24 insertions(+), 20 deletions(-)

diffs (99 lines):

diff -r 8e1de8ab59e6 -r 9672a3c3aaae njs/njs_generator.c
--- a/njs/njs_generator.c	Mon Jan 02 22:59:31 2017 +0300
+++ b/njs/njs_generator.c	Mon Jan 02 22:59:33 2017 +0300
@@ -81,7 +81,7 @@ static nxt_int_t njs_generate_regexp(njs
 static nxt_int_t njs_generate_test_jump_expression(njs_vm_t *vm,
     njs_parser_t *parser, njs_parser_node_t *node);
 static nxt_int_t njs_generate_3addr_operation(njs_vm_t *vm,
-    njs_parser_t *parser, njs_parser_node_t *node);
+    njs_parser_t *parser, njs_parser_node_t *node, nxt_bool_t swap);
 static nxt_int_t njs_generate_2addr_operation(njs_vm_t *vm,
     njs_parser_t *parser, njs_parser_node_t *node);
 static nxt_int_t njs_generate_typeof_operation(njs_vm_t *vm,
@@ -128,8 +128,6 @@ static const nxt_str_t  no_label = { 0, 
 static nxt_int_t
 njs_generator(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *node)
 {
-    njs_parser_node_t  *left;
-
     if (node == NULL) {
         return NXT_OK;
     }
@@ -195,19 +193,6 @@ njs_generator(njs_vm_t *vm, njs_parser_t
     case NJS_TOKEN_REMAINDER_ASSIGNMENT:
         return njs_generate_operation_assignment(vm, parser, node);
 
-    case NJS_TOKEN_IN:
-        /*
-         * An "in" operation is parsed as standard binary expression
-         * by njs_parser_binary_expression().  However, its operands
-         * should be swapped to be uniform with other property operations
-         * (get/set and delete) to use the property trap.
-         */
-        left = node->left;
-        node->left = node->right;
-        node->right = left;
-
-        /* Fall through. */
-
     case NJS_TOKEN_BITWISE_OR:
     case NJS_TOKEN_BITWISE_XOR:
     case NJS_TOKEN_BITWISE_AND:
@@ -231,7 +216,16 @@ njs_generator(njs_vm_t *vm, njs_parser_t
     case NJS_TOKEN_REMAINDER:
     case NJS_TOKEN_PROPERTY_DELETE:
     case NJS_TOKEN_PROPERTY:
-        return njs_generate_3addr_operation(vm, parser, node);
+        return njs_generate_3addr_operation(vm, parser, node, 0);
+
+    case NJS_TOKEN_IN:
+        /*
+         * An "in" operation is parsed as standard binary expression
+         * by njs_parser_binary_expression().  However, its operands
+         * should be swapped to be uniform with other property operations
+         * (get/set and delete) to use the property trap.
+         */
+        return njs_generate_3addr_operation(vm, parser, node, 1);
 
     case NJS_TOKEN_LOGICAL_AND:
     case NJS_TOKEN_LOGICAL_OR:
@@ -1707,7 +1701,7 @@ njs_generate_test_jump_expression(njs_vm
 
 static nxt_int_t
 njs_generate_3addr_operation(njs_vm_t *vm, njs_parser_t *parser,
-    njs_parser_node_t *node)
+    njs_parser_node_t *node, nxt_bool_t swap)
 {
     nxt_int_t           ret;
     njs_index_t         index;
@@ -1751,8 +1745,15 @@ njs_generate_3addr_operation(njs_vm_t *v
     code->code.operation = node->u.operation;
     code->code.operands = NJS_VMCODE_3OPERANDS;
     code->code.retval = NJS_VMCODE_RETVAL;
-    code->src1 = left->index;
-    code->src2 = right->index;
+
+    if (!swap) {
+        code->src1 = left->index;
+        code->src2 = right->index;
+
+    } else {
+        code->src1 = right->index;
+        code->src2 = left->index;
+    }
 
     /*
      * The temporary index of MOVE destination
diff -r 8e1de8ab59e6 -r 9672a3c3aaae njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c	Mon Jan 02 22:59:31 2017 +0300
+++ b/njs/test/njs_unit_test.c	Mon Jan 02 22:59:33 2017 +0300
@@ -224,6 +224,9 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("var a = 1; function f(x) { a = x; return 2 }; a += f(5)"),
       nxt_string("3") },
 
+    { nxt_string("var x; x in (x = 1, [1, 2, 3])"),
+      nxt_string("false") },
+
     /* Exponentiation. */
 
     { nxt_string("2 ** 3 ** 2"),


More information about the nginx-devel mailing list