summaryrefslogtreecommitdiffstats
path: root/src/declarative/qml
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2009-12-21 06:40:06 (GMT)
committerAaron Kennedy <aaron.kennedy@nokia.com>2009-12-21 06:40:06 (GMT)
commit178a508040bd43320a19ec2ae3250278d7b133bc (patch)
tree4e61973f3f6a5dd8e36720e9e7f2e20689b8e568 /src/declarative/qml
parent8216b5d7e5c47a2f3f04b5516bda49b68bd1da15 (diff)
downloadQt-178a508040bd43320a19ec2ae3250278d7b133bc.zip
Qt-178a508040bd43320a19ec2ae3250278d7b133bc.tar.gz
Qt-178a508040bd43320a19ec2ae3250278d7b133bc.tar.bz2
More binding optimizations
Diffstat (limited to 'src/declarative/qml')
-rw-r--r--src/declarative/qml/qmlbindingvme.cpp157
1 files changed, 143 insertions, 14 deletions
diff --git a/src/declarative/qml/qmlbindingvme.cpp b/src/declarative/qml/qmlbindingvme.cpp
index b239883..043cbb3 100644
--- a/src/declarative/qml/qmlbindingvme.cpp
+++ b/src/declarative/qml/qmlbindingvme.cpp
@@ -97,9 +97,11 @@ struct Instr {
Real, // real_value
Int, // int_value
Bool, // bool_value
+ String, // string_value
AddReal, // binaryop
AddInt, // binaryop
+ AddString, // binaryop
MinusReal, // binaryop
MinusInt, // binaryop
@@ -191,6 +193,11 @@ struct Instr {
bool value;
} bool_value;
struct {
+ int reg;
+ int offset;
+ int length;
+ } string_value;
+ struct {
int output;
int src1;
int src2;
@@ -280,6 +287,8 @@ struct QmlBindingCompilerPrivate
bool tryArith(QmlJS::AST::Node *);
bool parseArith(QmlJS::AST::Node *, Result &);
+ bool numberArith(Result &, const Result &, const Result &, QSOperator::Op op);
+ bool stringArith(Result &, const Result &, const Result &, QSOperator::Op op);
bool tryLogic(QmlJS::AST::Node *);
bool parseLogic(QmlJS::AST::Node *, Result &);
@@ -302,6 +311,7 @@ struct QmlBindingCompilerPrivate
void registerCleanup(int reg, int cleanup, int cleanupType = 0);
void releaseReg(int);
+ int registerLiteralString(const QString &);
int registerString(const QString &);
QHash<QString, QPair<int, int> > registeredStrings;
QByteArray data;
@@ -675,6 +685,11 @@ void QmlBindingVME::run(const char *programData, int instrIndex,
registers[instr->bool_value.reg].setbool(instr->bool_value.value);
break;
+ case Instr::String:
+ new (registers[instr->bool_value.reg].getstringptr())
+ QString((QChar *)(data + instr->string_value.offset), instr->string_value.length);
+ break;
+
case Instr::AddReal:
registers[instr->binaryop.output].setqreal(registers[instr->binaryop.src1].getqreal() +
registers[instr->binaryop.src2].getqreal());
@@ -684,6 +699,12 @@ void QmlBindingVME::run(const char *programData, int instrIndex,
registers[instr->binaryop.output].setint(registers[instr->binaryop.src1].getint() +
registers[instr->binaryop.src2].getint());
break;
+
+ case Instr::AddString:
+ new (registers[instr->binaryop.output].getstringptr())
+ QString(*registers[instr->binaryop.src1].getstringptr() +
+ *registers[instr->binaryop.src2].getstringptr());
+ break;
case Instr::MinusReal:
registers[instr->binaryop.output].setqreal(registers[instr->binaryop.src1].getqreal() -
@@ -911,12 +932,18 @@ void QmlBindingVME::dump(const QByteArray &programData)
case Instr::Bool:
qWarning().nospace() << "Bool" << "\t\t\t" << instr->bool_value.reg << "\t" << instr->bool_value.value;
break;
+ case Instr::String:
+ qWarning().nospace() << "String" << "\t\t\t" << instr->string_value.reg << "\t" << instr->string_value.offset << "\t" << instr->string_value.length;
+ break;
case Instr::AddReal:
qWarning().nospace() << "AddReal" << "\t\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
break;
case Instr::AddInt:
qWarning().nospace() << "AddInt" << "\t\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
break;
+ case Instr::AddString:
+ qWarning().nospace() << "AddString" << "\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
+ break;
case Instr::MinusReal:
qWarning().nospace() << "MinusReal" << "\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
break;
@@ -1451,17 +1478,25 @@ bool QmlBindingCompilerPrivate::parseArith(QmlJS::AST::Node *node, Result &type)
if (!parseExpression(expression->left, lhs)) return false;
if (!parseExpression(expression->right, rhs)) return false;
- if (lhs.type != QVariant::Int &
- lhs.type != QMetaType::QReal)
- return false;
-
- if (rhs.type != QVariant::Int &
- rhs.type != QMetaType::QReal)
+ if ((lhs.type == QVariant::Int || lhs.type == QMetaType::QReal) &&
+ (rhs.type == QVariant::Int || rhs.type == QMetaType::QReal))
+ return numberArith(type, lhs, rhs, (QSOperator::Op)expression->op);
+ else if(expression->op == QSOperator::Sub)
+ return numberArith(type, lhs, rhs, (QSOperator::Op)expression->op);
+ else if ((lhs.type == QMetaType::QString || lhs.unknownType) &&
+ (rhs.type == QMetaType::QString || rhs.unknownType) &&
+ (lhs.type == QMetaType::QString || rhs.type == QMetaType::QString))
+ return stringArith(type, lhs, rhs, (QSOperator::Op)expression->op);
+ else
return false;
+}
+bool QmlBindingCompilerPrivate::numberArith(Result &type, const Result &lhs, const Result &rhs, QSOperator::Op op)
+{
bool nativeReal = rhs.type == QMetaType::QReal ||
- lhs.type == QMetaType::QReal;
-
+ lhs.type == QMetaType::QReal ||
+ lhs.unknownType ||
+ rhs.unknownType;
if (nativeReal && lhs.type == QMetaType::Int) {
Instr convert;
@@ -1479,18 +1514,40 @@ bool QmlBindingCompilerPrivate::parseArith(QmlJS::AST::Node *node, Result &type)
bytecode << convert;
}
+ int lhsTmp = -1;
+ int rhsTmp = -1;
+ if (lhs.unknownType) {
+ lhsTmp = acquireReg();
+
+ Instr conv;
+ conv.type = Instr::ConvertGenericToReal;
+ conv.genericunaryop.output = lhsTmp;
+ conv.genericunaryop.src = lhs.reg;
+ bytecode << conv;
+ }
+
+ if (rhs.unknownType) {
+ rhsTmp = acquireReg();
+
+ Instr conv;
+ conv.type = Instr::ConvertGenericToReal;
+ conv.genericunaryop.output = rhsTmp;
+ conv.genericunaryop.src = rhs.reg;
+ bytecode << conv;
+ }
+
Instr arith;
- if (expression->op == QSOperator::Add) {
+ if (op == QSOperator::Add) {
arith.type = nativeReal?Instr::AddReal:Instr::AddInt;
- } else if (expression->op == QSOperator::Sub) {
+ } else if (op == QSOperator::Sub) {
arith.type = nativeReal?Instr::MinusReal:Instr::MinusInt;
} else {
qFatal("Unsupported arithmetic operator");
}
arith.binaryop.output = type.reg;
- arith.binaryop.src1 = lhs.reg;
- arith.binaryop.src2 = rhs.reg;
+ arith.binaryop.src1 = (lhsTmp == -1)?lhs.reg:lhsTmp;
+ arith.binaryop.src2 = (rhsTmp == -1)?rhs.reg:rhsTmp;
bytecode << arith;
type.metaObject = 0;
@@ -1498,12 +1555,58 @@ bool QmlBindingCompilerPrivate::parseArith(QmlJS::AST::Node *node, Result &type)
type.subscriptionSet.unite(lhs.subscriptionSet);
type.subscriptionSet.unite(rhs.subscriptionSet);
+ if (lhsTmp != -1) releaseReg(lhsTmp);
+ if (rhsTmp != -1) releaseReg(rhsTmp);
releaseReg(lhs.reg);
releaseReg(rhs.reg);
return true;
}
+bool QmlBindingCompilerPrivate::stringArith(Result &type, const Result &lhs, const Result &rhs, QSOperator::Op op)
+{
+ if (op != QSOperator::Add)
+ return false;
+
+ int lhsTmp = -1;
+ int rhsTmp = -1;
+
+ if (lhs.unknownType) {
+ lhsTmp = acquireReg(Instr::CleanupString);
+
+ Instr convert;
+ convert.type = Instr::ConvertGenericToString;
+ convert.genericunaryop.output = lhsTmp;
+ convert.genericunaryop.src = lhs.reg;
+ bytecode << convert;
+ }
+
+ if (rhs.unknownType) {
+ rhsTmp = acquireReg(Instr::CleanupString);
+
+ Instr convert;
+ convert.type = Instr::ConvertGenericToString;
+ convert.genericunaryop.output = rhsTmp;
+ convert.genericunaryop.src = rhs.reg;
+ bytecode << convert;
+ }
+
+ type.reg = acquireReg(Instr::CleanupString);
+ type.type = QMetaType::QString;
+
+ Instr add;
+ add.type = Instr::AddString;
+ add.binaryop.output = type.reg;
+ add.binaryop.src1 = (lhsTmp == -1)?lhs.reg:lhsTmp;
+ add.binaryop.src2 = (rhsTmp == -1)?rhs.reg:rhsTmp;
+ bytecode << add;
+
+ if (lhsTmp != -1) releaseReg(lhsTmp);
+ if (rhsTmp != -1) releaseReg(rhsTmp);
+
+ return true;
+}
+
bool QmlBindingCompilerPrivate::tryLogic(QmlJS::AST::Node *node)
{
if (node->kind != AST::Node::Kind_BinaryExpression)
@@ -1645,7 +1748,8 @@ bool QmlBindingCompilerPrivate::tryConstant(QmlJS::AST::Node *node)
{
return node->kind == AST::Node::Kind_TrueLiteral ||
node->kind == AST::Node::Kind_FalseLiteral ||
- node->kind == AST::Node::Kind_NumericLiteral;
+ node->kind == AST::Node::Kind_NumericLiteral ||
+ node->kind == AST::Node::Kind_StringLiteral;
}
bool QmlBindingCompilerPrivate::parseConstant(QmlJS::AST::Node *node, Result &type)
@@ -1678,6 +1782,11 @@ bool QmlBindingCompilerPrivate::parseConstant(QmlJS::AST::Node *node, Result &ty
instr.real_value.value = qreal(static_cast<AST::NumericLiteral *>(node)->value);
bytecode << instr;
return true;
+ } else if (node->kind == AST::Node::Kind_StringLiteral) {
+ QString str = static_cast<AST::StringLiteral *>(node)->value->asString();
+ type.type = QMetaType::QString;
+ type.reg = registerLiteralString(str);
+ return true;
} else {
return false;
}
@@ -1857,6 +1966,26 @@ void QmlBindingCompilerPrivate::releaseReg(int reg)
registers &= ~mask;
}
+// Returns a reg
+int QmlBindingCompilerPrivate::registerLiteralString(const QString &str)
+{
+ QByteArray strdata((const char *)str.constData(), str.length() * sizeof(QChar));
+ int offset = data.count();
+ data += strdata;
+
+ int reg = acquireReg(Instr::CleanupString);
+
+ Instr string;
+ string.type = Instr::String;
+ string.string_value.reg = reg;
+ string.string_value.offset = offset;
+ string.string_value.length = str.length();
+ bytecode << string;
+
+ return reg;
+}
+
+// Returns an identifier offset
int QmlBindingCompilerPrivate::registerString(const QString &string)
{
Q_ASSERT(!string.isEmpty());
@@ -1869,7 +1998,7 @@ int QmlBindingCompilerPrivate::registerString(const QString &string)
data += strdata;
iter = registeredStrings.insert(string, qMakePair(registeredStrings.count(), rv));
- }
+ }
Instr reg;
reg.type = Instr::InitString;