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>
This commit is contained in:
Simon Hausmann 2013-09-06 14:12:51 +02:00 committed by The Qt Project
parent 34b6914970
commit 2ed0cd0602
3 changed files with 29 additions and 16 deletions

View File

@ -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;

View File

@ -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

View File

@ -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());