njs_parser_node_t *node)
{
njs_int_t ret;
- njs_index_t index;
+ njs_index_t index, src;
njs_parser_node_t *lvalue, *expr, *object, *property;
njs_vmcode_move_t *move;
njs_vmcode_3addr_t *code;
return ret;
}
+ if (njs_slow_path(njs_parser_has_side_effect(node->right))) {
+ /*
+ * Preserve object and property values stored in variables in a case
+ * if the variables can be changed by side effects in expression.
+ */
+ if (object->token_type == NJS_TOKEN_NAME) {
+ src = object->index;
+
+ index = njs_generate_node_temp_index_get(vm, generator, object);
+ if (njs_slow_path(index == NJS_INDEX_ERROR)) {
+ return NJS_ERROR;
+ }
+
+ njs_generate_code_move(generator, move, index, src, object);
+ }
+
+ if (property->token_type == NJS_TOKEN_NAME) {
+ src = property->index;
+
+ index = njs_generate_node_temp_index_get(vm, generator, property);
+ if (njs_slow_path(index == NJS_INDEX_ERROR)) {
+ return NJS_ERROR;
+ }
+
+ njs_generate_code_move(generator, move, index, src, property);
+ }
+ }
+
index = njs_generate_node_temp_index_get(vm, generator, node);
if (njs_slow_path(index == NJS_INDEX_ERROR)) {
return NJS_ERROR;
NJS_TOKEN_BITWISE_XOR_ASSIGNMENT,
NJS_TOKEN_BITWISE_AND_ASSIGNMENT,
-#define NJS_TOKEN_LAST_ASSIGNMENT NJS_TOKEN_BITWISE_AND_ASSIGNMENT
+ NJS_TOKEN_INCREMENT,
+ NJS_TOKEN_DECREMENT,
+ NJS_TOKEN_POST_INCREMENT,
+ NJS_TOKEN_POST_DECREMENT,
+
+#define NJS_TOKEN_LAST_ASSIGNMENT NJS_TOKEN_POST_DECREMENT
NJS_TOKEN_EQUAL,
NJS_TOKEN_STRICT_EQUAL,
NJS_TOKEN_ADDITION,
NJS_TOKEN_UNARY_PLUS,
- NJS_TOKEN_INCREMENT,
- NJS_TOKEN_POST_INCREMENT,
NJS_TOKEN_SUBSTRACTION,
NJS_TOKEN_UNARY_NEGATION,
- NJS_TOKEN_DECREMENT,
- NJS_TOKEN_POST_DECREMENT,
NJS_TOKEN_MULTIPLICATION,
"var b = ++a; a +' '+ b"),
njs_str("NaN NaN") },
+ { njs_str("var a = 0; a = a + ++a; a"),
+ njs_str("1") },
+
+ { njs_str("var a = 0; a += a + ++a; a"),
+ njs_str("1") },
+
+ { njs_str("var i = 0, arr = ['a', 'b'];"
+ "arr[i] = arr[i] + arr[++i]; arr"),
+ njs_str("ab,b") },
+
+ { njs_str("var i = 0, arr = ['a', 'b'];"
+ "arr[i] += arr[i] + arr[++i]; arr"),
+ njs_str("aab,b") },
+
/* Post increment. */
{ njs_str("var a = 1; a++"),
"var b = a++; a +' '+ b"),
njs_str("NaN NaN") },
+ { njs_str("var a = 0; a = a + a++; a"),
+ njs_str("0") },
+
+ { njs_str("var a = 0; a += a + a++; a"),
+ njs_str("0") },
+
+ { njs_str("var i = 1, arr = ['a', 'b'];"
+ "arr[i] = arr[i] + arr[i++]; arr"),
+ njs_str("a,bb") },
+
+ { njs_str("var i = 1, arr = ['a', 'b'];"
+ "arr[i] += arr[i] + arr[i++]; arr"),
+ njs_str("a,bbb") },
+
/* Decrement. */
{ njs_str("var a = 1; --a"),
"var b = --a; a +' '+ b"),
njs_str("NaN NaN") },
+ { njs_str("var a = 0; a = a + --a; a"),
+ njs_str("-1") },
+
+ { njs_str("var a = 0; a -= a + --a; a"),
+ njs_str("1") },
+
+ { njs_str("var i = 1, arr = ['a', 'b'];"
+ "arr[i] = arr[i] + arr[--i]; arr"),
+ njs_str("a,ba") },
+
+ { njs_str("var i = 1, arr = ['a', 'b'];"
+ "arr[i] += arr[i] + arr[--i]; arr"),
+ njs_str("a,bba") },
+
/* Post decrement. */
{ njs_str("var a = 1; a--"),
"var b = a--; a +' '+ b"),
njs_str("NaN NaN") },
+ { njs_str("var a = 0; a = a + a--; a"),
+ njs_str("0") },
+
+ { njs_str("var a = 0; a += a + a--; a"),
+ njs_str("0") },
+
+ { njs_str("var i = 1, arr = ['a', 'b'];"
+ "arr[i] = arr[i] + arr[i--]; arr"),
+ njs_str("a,bb") },
+
+ { njs_str("var i = 1, arr = ['a', 'b'];"
+ "arr[i] += arr[i] + arr[i--]; arr"),
+ njs_str("a,bbb") },
+
/**/
{ njs_str("var a, b; a = 2; b = ++a + ++a; a + ' ' + b"),