diff options
-rw-r--r-- | src/qml/qml/v4/qv4compiler.cpp | 24 | ||||
-rw-r--r-- | src/qml/qml/v4/qv4ir.cpp | 6 | ||||
-rw-r--r-- | src/qml/qml/v4/qv4irbuilder.cpp | 9 |
3 files changed, 33 insertions, 6 deletions
diff --git a/src/qml/qml/v4/qv4compiler.cpp b/src/qml/qml/v4/qv4compiler.cpp index 9afbb7e16f..08cfed9383 100644 --- a/src/qml/qml/v4/qv4compiler.cpp +++ b/src/qml/qml/v4/qv4compiler.cpp @@ -740,12 +740,26 @@ void QV4CompilerPrivate::visitBinop(IR::Binop *e) int left = currentReg; int right = currentReg + 1; - traceExpression(e->left, left); - traceExpression(e->right, right); + if (e->left->asTemp() && e->type != IR::StringType) + left = e->left->asTemp()->index; + else + traceExpression(e->left, left); + + if (IR::Temp *t = e->right->asTemp()) + right = t->index; + else + traceExpression(e->right, right); - // At this point it is possible that the type of the - // subexpressions is different. This can happen because - // we keep BINOP expressions in HIR. + if (e->left->type != e->right->type) { + if (qmlVerboseCompiler()) + qWarning().nospace() << "invalid operands to binary operator " << IR::binaryOperator(e->op) + << "(`" << IR::binaryOperator(e->left->type) + << "' and `" + << IR::binaryOperator(e->right->type) + << "'"; + discard(); + return; + } switch (e->op) { case IR::OpInvalid: diff --git a/src/qml/qml/v4/qv4ir.cpp b/src/qml/qml/v4/qv4ir.cpp index 982742c781..8fc4719791 100644 --- a/src/qml/qml/v4/qv4ir.cpp +++ b/src/qml/qml/v4/qv4ir.cpp @@ -606,6 +606,12 @@ Expr *BasicBlock::BINOP(AluOp op, Expr *left, Expr *right) break; } } + } else if (op == OpAdd) { + if (String *s1 = left->asString()) { + if (String *s2 = right->asString()) { + return STRING(function->newString(s1->value.toString() + s2->value)); + } + } } } diff --git a/src/qml/qml/v4/qv4irbuilder.cpp b/src/qml/qml/v4/qv4irbuilder.cpp index b8210b863f..31ed9a5a6a 100644 --- a/src/qml/qml/v4/qv4irbuilder.cpp +++ b/src/qml/qml/v4/qv4irbuilder.cpp @@ -892,7 +892,14 @@ void QV4IRBuilder::binop(AST::BinaryExpression *ast, ExprResult left, ExprResult _expr.format = ExprResult::cx; _block->CJUMP(_block->BINOP(IR::binaryOperator(ast->op), left, right), _expr.iftrue, _expr.iffalse); } else { - _expr.code = _block->BINOP(IR::binaryOperator(ast->op), left, right); + IR::Expr *e = _block->BINOP(IR::binaryOperator(ast->op), left, right); + if (e->asConst() != 0 || e->asString() != 0) + _expr.code = e; + else { + IR::Temp *t = _block->TEMP(e->type); + _block->MOVE(t, e); + _expr.code = t; + } } } |