Fix tst_qjsengine::jsIncDecNonObjectProperty
authorSimon Hausmann <simon.hausmann@digia.com>
Sun, 23 Jun 2013 18:11:21 +0000 (20:11 +0200)
committerLars Knoll <lars.knoll@digia.com>
Sun, 23 Jun 2013 19:42:21 +0000 (21:42 +0200)
With pre increment/decrement expressions, don't rely on the
target expr to be readable after the write to it. In case of
++someString.length for example the value of the property may not
change, but the result of the expression still has to be the
incremented value.

Change-Id: I2389eeee38dbed75aa2764638cb40950e32b8a68
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
src/qml/qml/v4/qv4codegen.cpp

index 164aa97..7f2fe72 100644 (file)
@@ -1712,11 +1712,14 @@ bool Codegen::visit(PreDecrementExpression *ast)
 {
     Result expr = expression(ast->expression);
     throwSyntaxErrorOnEvalOrArgumentsInStrictMode(*expr, ast->decrementToken);
-    move(*expr, binop(V4IR::OpSub, *expr, _block->CONST(V4IR::NumberType, 1)));
+    V4IR::Expr *op = binop(V4IR::OpSub, *expr, _block->CONST(V4IR::NumberType, 1));
     if (_expr.accept(nx)) {
-        // nothing to do
+        move(*expr, op);
     } else {
-        _expr.code = *expr;
+        const unsigned t = _block->newTemp();
+        move(_block->TEMP(t), op);
+        move(*expr, _block->TEMP(t));
+        _expr.code = _block->TEMP(t);
     }
     return false;
 }
@@ -1725,11 +1728,14 @@ bool Codegen::visit(PreIncrementExpression *ast)
 {
     Result expr = expression(ast->expression);
     throwSyntaxErrorOnEvalOrArgumentsInStrictMode(*expr, ast->incrementToken);
-    move(*expr, binop(V4IR::OpAdd, unop(V4IR::OpUPlus, *expr), _block->CONST(V4IR::NumberType, 1)));
+    V4IR::Expr *op = binop(V4IR::OpAdd, unop(V4IR::OpUPlus, *expr), _block->CONST(V4IR::NumberType, 1));
     if (_expr.accept(nx)) {
-        // nothing to do
+        move(*expr, op);
     } else {
-        _expr.code = *expr;
+        const unsigned t = _block->newTemp();
+        move(_block->TEMP(t), op);
+        move(*expr, _block->TEMP(t));
+        _expr.code = _block->TEMP(t);
     }
     return false;
 }