[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