summaryrefslogtreecommitdiffstats
path: root/src/declarative/qml/qmlcompiler.cpp
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2009-06-10 05:03:29 (GMT)
committerAaron Kennedy <aaron.kennedy@nokia.com>2009-06-10 05:03:29 (GMT)
commit6b88d7152a72a3a6ba12cb6b4eeeecc1a0c24c51 (patch)
treef4a61bb049df2d3c83ce50bcd85b9772fc115251 /src/declarative/qml/qmlcompiler.cpp
parent5c24620b91ee57629b4356885f8b5517e3d82e32 (diff)
downloadQt-6b88d7152a72a3a6ba12cb6b4eeeecc1a0c24c51.zip
Qt-6b88d7152a72a3a6ba12cb6b4eeeecc1a0c24c51.tar.gz
Qt-6b88d7152a72a3a6ba12cb6b4eeeecc1a0c24c51.tar.bz2
Improve list assignment performance
Diffstat (limited to 'src/declarative/qml/qmlcompiler.cpp')
-rw-r--r--src/declarative/qml/qmlcompiler.cpp68
1 files changed, 58 insertions, 10 deletions
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index 04a488d..16e1b13 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -1091,7 +1091,9 @@ bool QmlCompiler::compileListProperty(QmlParser::Property *prop,
fetch.line = prop->location.start.line;
fetch.type = QmlInstruction::FetchQmlList;
fetch.fetchQmlList.property = prop->index;
- fetch.fetchQmlList.type = QmlMetaType::qmlListType(t);
+ int listType = QmlMetaType::qmlListType(t);
+ bool listTypeIsInterface = QmlMetaType::isInterface(listType);
+ fetch.fetchQmlList.type = listType;
output->bytecode << fetch;
for (int ii = 0; ii < prop->values.count(); ++ii) {
@@ -1099,10 +1101,23 @@ bool QmlCompiler::compileListProperty(QmlParser::Property *prop,
if (v->object) {
v->type = Value::CreatedObject;
COMPILE_CHECK(compileObject(v->object, ctxt));
- QmlInstruction assign;
- assign.type = QmlInstruction::AssignObjectList;
- assign.line = prop->location.start.line;
- output->bytecode << assign;
+
+ if (!listTypeIsInterface) {
+ if (canConvert(listType, v->object)) {
+ QmlInstruction store;
+ store.type = QmlInstruction::StoreObjectQmlList;
+ store.line = prop->location.start.line;
+ output->bytecode << store;
+ } else {
+ COMPILE_EXCEPTION("Cannot assign object to list");
+ }
+
+ } else {
+ QmlInstruction assign;
+ assign.type = QmlInstruction::AssignObjectList;
+ assign.line = prop->location.start.line;
+ output->bytecode << assign;
+ }
} else {
COMPILE_EXCEPTION("Cannot assign primitives to lists");
}
@@ -1116,7 +1131,10 @@ bool QmlCompiler::compileListProperty(QmlParser::Property *prop,
QmlInstruction fetch;
fetch.type = QmlInstruction::FetchQList;
fetch.line = prop->location.start.line;
- fetch.fetch.property = prop->index;
+ fetch.fetchQmlList.property = prop->index;
+ int listType = QmlMetaType::listType(t);
+ bool listTypeIsInterface = QmlMetaType::isInterface(listType);
+ fetch.fetchQmlList.type = listType;
output->bytecode << fetch;
bool assignedBinding = false;
@@ -1125,10 +1143,22 @@ bool QmlCompiler::compileListProperty(QmlParser::Property *prop,
if (v->object) {
v->type = Value::CreatedObject;
COMPILE_CHECK(compileObject(v->object, ctxt));
- QmlInstruction assign;
- assign.type = QmlInstruction::AssignObjectList;
- assign.line = v->location.start.line;
- output->bytecode << assign;
+
+ if (!listTypeIsInterface) {
+ if (canConvert(listType, v->object)) {
+ QmlInstruction store;
+ store.type = QmlInstruction::StoreObjectQList;
+ store.line = prop->location.start.line;
+ output->bytecode << store;
+ } else {
+ COMPILE_EXCEPTION("Cannot assign object to list");
+ }
+ } else {
+ QmlInstruction assign;
+ assign.type = QmlInstruction::AssignObjectList;
+ assign.line = v->location.start.line;
+ output->bytecode << assign;
+ }
} else if (v->value.isScript()) {
if (assignedBinding)
COMPILE_EXCEPTION("Can only assign one binding to lists");
@@ -1575,6 +1605,24 @@ void QmlCompiler::finalizeBinding(const BindingReference &binding)
instr.assignBinding.category = QmlMetaProperty::propertyCategory(mp);
}
+/*!
+ Returns true if object can be assigned to a (QObject) property of type
+ convertType.
+*/
+bool QmlCompiler::canConvert(int convertType, QmlParser::Object *object)
+{
+ const QMetaObject *convertTypeMo =
+ QmlMetaType::rawMetaObjectForType(convertType);
+ const QMetaObject *objectMo = object->metaObject();
+
+ while (objectMo) {
+ if (objectMo == convertTypeMo)
+ return true;
+ objectMo = objectMo->superClass();
+ }
+ return false;
+}
+
QmlCompiledData::QmlCompiledData()
{
}