diff options
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 34 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator_p.h | 7 | ||||
-rw-r--r-- | tools/qmlscene/main.cpp | 4 |
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()); |