aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2013-09-06 14:12:51 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-08 09:00:25 +0200
commit2ed0cd0602093d316bfbce6b1f3f8f8bfe026fca (patch)
treebe7ac70188f15c60706c2c05cad9a8917df4d3eb
parent34b6914970958ace37a3654600637b6fd3d2435c (diff)
Fix error reporting in the new object creator
Propagate error conditions from createVMEMetaObjectAndPropertyCache to the caller and properly clean up refcounts (using QQmlRefPointer) Also fixed qmlscene to report errors if create() failed. Change-Id: I75d984798a197c102078e5d5638ed92f167ab49f Reviewed-by: Lars Knoll <lars.knoll@digia.com>
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp34
-rw-r--r--src/qml/qml/qqmlobjectcreator_p.h7
-rw-r--r--tools/qmlscene/main.cpp4
3 files changed, 29 insertions, 16 deletions
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 8fdfe8e4f1..724f97ef12 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -204,20 +204,26 @@ QObject *QmlObjectCreator::create(int index, QObject *parent)
context->addObject(_object);
// ### avoid _object->metaObject
- QQmlPropertyCache *baseTypeCache = QQmlEnginePrivate::get(engine)->cache(_object->metaObject());
- baseTypeCache->addref();
+ QQmlRefPointer<QQmlPropertyCache> baseTypeCache = QQmlEnginePrivate::get(engine)->cache(_object->metaObject());
- QQmlPropertyCache *cache = 0;
+ QQmlRefPointer<QQmlPropertyCache> cache;
QByteArray vmeMetaData;
- bool needCustomMetaObject = createVMEMetaObjectAndPropertyCache(obj, baseTypeCache, &cache, &vmeMetaData);
- cache->addref();
- baseTypeCache->release();
+ const bool customMO = needsCustomMetaObject(obj);
+ if (customMO) {
+ QQmlPropertyCache *newCache = 0;
+ if (!createVMEMetaObjectAndPropertyCache(obj, baseTypeCache, &newCache, &vmeMetaData))
+ return 0;
+ cache = newCache;
+ } else {
+ cache = baseTypeCache;
+ }
+
baseTypeCache = 0;
qSwap(_propertyCache, cache);
- if (needCustomMetaObject) {
+ if (customMO) {
runtimeData->datas.append(vmeMetaData);
// install on _object
(void)new QQmlVMEMetaObject(_object, _propertyCache, reinterpret_cast<const QQmlVMEMetaData*>(runtimeData->datas.last().constData()));
@@ -249,22 +255,22 @@ QObject *QmlObjectCreator::create(int index, QObject *parent)
qSwap(_ddata, declarativeData);
qSwap(_object, result);
- cache->release();
-
return result;
}
+bool QmlObjectCreator::needsCustomMetaObject(const QV4::CompiledData::Object *obj)
+{
+ return obj->nProperties > 0 || obj->nSignals > 0 || obj->nFunctions > 0;
+}
+
// ###
#define COMPILE_EXCEPTION(token, desc) {}
static QAtomicInt classIndexCounter(0);
-bool QmlObjectCreator::createVMEMetaObjectAndPropertyCache(const QV4::CompiledData::Object *obj, QQmlPropertyCache *baseTypeCache, QQmlPropertyCache **outputCache, QByteArray *vmeMetaObjectData) const
+bool QmlObjectCreator::createVMEMetaObjectAndPropertyCache(const QV4::CompiledData::Object *obj, QQmlPropertyCache *baseTypeCache, QQmlPropertyCache **outputCache, QByteArray *vmeMetaObjectData)
{
- if (!obj->nProperties) {
- *outputCache = baseTypeCache;
- return false;
- }
+ Q_ASSERT(needsCustomMetaObject(obj));
QQmlPropertyCache *cache = baseTypeCache->copyAndReserve(engine, obj->nProperties, /*methodCount*/0, /*signalCount*/0);
*outputCache = cache;
diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h
index 6a2b28c35d..553be6f075 100644
--- a/src/qml/qml/qqmlobjectcreator_p.h
+++ b/src/qml/qml/qqmlobjectcreator_p.h
@@ -64,7 +64,10 @@ struct Q_QML_EXPORT QmlObjectCreator
QList<QQmlError> errors;
- bool createVMEMetaObjectAndPropertyCache(const QV4::CompiledData::Object *obj, QQmlPropertyCache *baseTypeCache, QQmlPropertyCache **cache, QByteArray *vmeMetaObjectData) const;
+ static bool needsCustomMetaObject(const QV4::CompiledData::Object *obj);
+ bool createVMEMetaObjectAndPropertyCache(const QV4::CompiledData::Object *obj, QQmlPropertyCache *baseTypeCache,
+ // out parameters
+ QQmlPropertyCache **cache, QByteArray *vmeMetaObjectData);
private:
QString stringAt(int idx) const { return unit->header.stringAt(idx); }
@@ -87,7 +90,7 @@ private:
QObject *_object;
QQmlData *_ddata;
- QQmlPropertyCache *_propertyCache;
+ QQmlRefPointer<QQmlPropertyCache> _propertyCache;
};
} // end namespace QtQml
diff --git a/tools/qmlscene/main.cpp b/tools/qmlscene/main.cpp
index 244e0af4ac..fcf89afb9f 100644
--- a/tools/qmlscene/main.cpp
+++ b/tools/qmlscene/main.cpp
@@ -483,6 +483,10 @@ int main(int argc, char ** argv)
}
QObject *topLevel = component->create();
+ if (!topLevel && component->isError()) {
+ qWarning("%s", qPrintable(component->errorString()));
+ return -1;
+ }
QScopedPointer<QQuickWindow> window(qobject_cast<QQuickWindow *>(topLevel));
if (window) {
engine.setIncubationController(window->incubationController());