]> git.kaiwu.me - njs.git/commitdiff
Fixed code generation for "in" operation with side effect.
authorIgor Sysoev <igor@sysoev.ru>
Mon, 2 Jan 2017 19:59:33 +0000 (22:59 +0300)
committerIgor Sysoev <igor@sysoev.ru>
Mon, 2 Jan 2017 19:59:33 +0000 (22:59 +0300)
njs/njs_generator.c
njs/test/njs_unit_test.c

index de80b8d12111f930d6e6d890a3b1b007720d8d9e..85eeb20dde4c91a8aedaff6a80a937ef43ad1413 100644 (file)
@@ -81,7 +81,7 @@ static nxt_int_t njs_generate_regexp(njs_vm_t *vm, njs_parser_t *parser,
 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, NULL };
 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 *parser, njs_parser_node_t *node)
     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 *parser, njs_parser_node_t *node)
     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_t *vm, njs_parser_t *parser,
 
 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 *vm, njs_parser_t *parser,
     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
index e7c73bcf53fe4212363e0771671b3b1400729a0f..b9cf00c0f8ab76483962c3279f38d63ffe0dcbc5 100644 (file)
@@ -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"),