From: Igor Sysoev Date: Mon, 2 Jan 2017 19:59:33 +0000 (+0300) Subject: Fixed code generation for "in" operation with side effect. X-Git-Tag: 0.1.8~8 X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=7d0be2a0a7db175dc9768585091aa9181a707120;p=njs.git Fixed code generation for "in" operation with side effect. --- diff --git a/njs/njs_generator.c b/njs/njs_generator.c index de80b8d1..85eeb20d 100644 --- a/njs/njs_generator.c +++ b/njs/njs_generator.c @@ -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 diff --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c index e7c73bcf..b9cf00c0 100644 --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -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"),