diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2018-04-23 13:28:58 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2018-04-26 09:56:39 +0000 |
commit | 1a3447a0405831fa5502247f9eaff48afdfe0dea (patch) | |
tree | f40e71aadfda2ddc251ebab18a983a80b5d9b33f /src/qml/qml | |
parent | 78be6b2aa4da54cb41ed60a31abfb7312fb44c9a (diff) |
Clean up manual reference of QQmlTypeData and QQmlPropertyCache
We have a few places in the type loader where we do adventurous manual
reference counting, where getType() returns a raw pointer that has been
addref()'ed and then sometimes somehow we call release() later. Commit
0b394e30bba4f6bb7e6f7dbe5585a2e15aa0f21d is an example of where this can
easily go wrong. As a consequence and also in preparation for future
work on the type loader, this patch starts replacing the manual
reference counting there.
Changing the return type from QQmlTypeData *getType() to a
QQmlRefPointer<> itself is not sufficient though, as the implicit
operator T*() will still allow the caller to store the result as a raw
pointer. Therefore this patch removes the "unsafe" implicit extraction
operator.
As a result of that change, other types that are sometimes stored in
QQmlRefPointer are also affected and their usage needs to be adapted
to QQmlRefPointer usage or manual raw pointer extraction with .data().
Change-Id: I18fd40634047f13196a237f4e6766cbef3bfbea2
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/qml/qml')
-rw-r--r-- | src/qml/qml/ftw/qqmlrefcount_p.h | 4 | ||||
-rw-r--r-- | src/qml/qml/qqmlbinding.cpp | 4 | ||||
-rw-r--r-- | src/qml/qml/qqmlbinding_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlcomponent.cpp | 11 | ||||
-rw-r--r-- | src/qml/qml/qqmlcomponent_p.h | 6 | ||||
-rw-r--r-- | src/qml/qml/qqmldata_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlengine.cpp | 10 | ||||
-rw-r--r-- | src/qml/qml/qqmljavascriptexpression.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmljavascriptexpression_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetatype.cpp | 8 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 22 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator_p.h | 4 | ||||
-rw-r--r-- | src/qml/qml/qqmlproperty.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertycache_p.h | 6 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader.cpp | 31 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader_p.h | 8 | ||||
-rw-r--r-- | src/qml/qml/qqmltypewrapper.cpp | 7 | ||||
-rw-r--r-- | src/qml/qml/qqmltypewrapper_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlvmemetaobject.cpp | 4 | ||||
-rw-r--r-- | src/qml/qml/qqmlvmemetaobject_p.h | 6 | ||||
-rw-r--r-- | src/qml/qml/v8/qqmlbuiltinfunctions.cpp | 2 |
21 files changed, 67 insertions, 78 deletions
diff --git a/src/qml/qml/ftw/qqmlrefcount_p.h b/src/qml/qml/ftw/qqmlrefcount_p.h index 3cfb345b30..e8fa1ff2a6 100644 --- a/src/qml/qml/ftw/qqmlrefcount_p.h +++ b/src/qml/qml/ftw/qqmlrefcount_p.h @@ -93,11 +93,13 @@ public: inline T* operator->() const { return o; } inline T& operator*() const { return *o; } - inline operator T*() const { return o; } + explicit inline operator bool() const { return o != nullptr; } inline T* data() const { return o; } inline QQmlRefPointer<T> &adopt(T *); + inline T* take() { T *res = o; o = nullptr; return res; } + private: T *o; }; diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index 30a18440a8..5fcd38aa54 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -337,7 +337,7 @@ protected: class QQmlTranslationBinding : public GenericBinding<QMetaType::QString> { public: - QQmlTranslationBinding(QV4::CompiledData::CompilationUnit *compilationUnit, const QV4::CompiledData::Binding *binding) + QQmlTranslationBinding(const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit, const QV4::CompiledData::Binding *binding) { setCompilationUnit(compilationUnit); m_binding = binding; @@ -378,7 +378,7 @@ private: const QV4::CompiledData::Binding *m_binding; }; -QQmlBinding *QQmlBinding::createTranslationBinding(QV4::CompiledData::CompilationUnit *unit, const QV4::CompiledData::Binding *binding, QObject *obj, QQmlContextData *ctxt) +QQmlBinding *QQmlBinding::createTranslationBinding(const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &unit, const QV4::CompiledData::Binding *binding, QObject *obj, QQmlContextData *ctxt) { QQmlTranslationBinding *b = new QQmlTranslationBinding(unit, binding); diff --git a/src/qml/qml/qqmlbinding_p.h b/src/qml/qml/qqmlbinding_p.h index a1295bd0ac..6cd64c7ca0 100644 --- a/src/qml/qml/qqmlbinding_p.h +++ b/src/qml/qml/qqmlbinding_p.h @@ -79,7 +79,7 @@ public: const QString &url = QString(), quint16 lineNumber = 0); static QQmlBinding *create(const QQmlPropertyData *property, QV4::Function *function, QObject *obj, QQmlContextData *ctxt, QV4::ExecutionContext *scope); - static QQmlBinding *createTranslationBinding(QV4::CompiledData::CompilationUnit *unit, const QV4::CompiledData::Binding *binding, + static QQmlBinding *createTranslationBinding(const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &unit, const QV4::CompiledData::Binding *binding, QObject *obj, QQmlContextData *ctxt); ~QQmlBinding() override; diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index 517c216873..1802932f45 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -334,7 +334,7 @@ void QQmlComponentPrivate::typeDataProgress(QQmlTypeData *, qreal p) emit q->progressChanged(p); } -void QQmlComponentPrivate::fromTypeData(QQmlTypeData *data) +void QQmlComponentPrivate::fromTypeData(const QQmlRefPointer<QQmlTypeData> &data) { url = data->finalUrl(); compilationUnit = data->compilationUnit(); @@ -343,15 +343,12 @@ void QQmlComponentPrivate::fromTypeData(QQmlTypeData *data) Q_ASSERT(data->isError()); state.errors = data->errors(); } - - data->release(); } void QQmlComponentPrivate::clear() { if (typeData) { typeData->unregisterCallback(this); - typeData->release(); typeData = nullptr; } @@ -387,7 +384,7 @@ QQmlComponent::~QQmlComponent() if (d->typeData) { d->typeData->unregisterCallback(d); - d->typeData->release(); + d->typeData = nullptr; } } @@ -580,7 +577,7 @@ void QQmlComponent::setData(const QByteArray &data, const QUrl &url) d->url = url; - QQmlTypeData *typeData = QQmlEnginePrivate::get(d->engine)->typeLoader.getType(data, url); + QQmlRefPointer<QQmlTypeData> typeData = QQmlEnginePrivate::get(d->engine)->typeLoader.getType(data, url); if (typeData->isCompleteOrError()) { d->fromTypeData(typeData); @@ -667,7 +664,7 @@ void QQmlComponentPrivate::loadUrl(const QUrl &newUrl, QQmlComponent::Compilatio ? QQmlTypeLoader::Asynchronous : QQmlTypeLoader::PreferSynchronous; - QQmlTypeData *data = QQmlEnginePrivate::get(engine)->typeLoader.getType(url, loaderMode); + QQmlRefPointer<QQmlTypeData> data = QQmlEnginePrivate::get(engine)->typeLoader.getType(url, loaderMode); if (data->isCompleteOrError()) { fromTypeData(data); diff --git a/src/qml/qml/qqmlcomponent_p.h b/src/qml/qml/qqmlcomponent_p.h index 2a8d36f317..83af5074b8 100644 --- a/src/qml/qml/qqmlcomponent_p.h +++ b/src/qml/qml/qqmlcomponent_p.h @@ -79,7 +79,7 @@ class Q_QML_PRIVATE_EXPORT QQmlComponentPrivate : public QObjectPrivate, public public: QQmlComponentPrivate() - : typeData(nullptr), progress(0.), start(-1), engine(nullptr), creationContext(nullptr), depthIncreased(false) {} + : progress(0.), start(-1), engine(nullptr), creationContext(nullptr), depthIncreased(false) {} void loadUrl(const QUrl &newUrl, QQmlComponent::CompilationMode mode = QQmlComponent::PreferSynchronous); @@ -95,11 +95,11 @@ public: QQmlContextData *context, QQmlContextData *forContext); - QQmlTypeData *typeData; + QQmlRefPointer<QQmlTypeData> typeData; void typeDataReady(QQmlTypeData *) override; void typeDataProgress(QQmlTypeData *, qreal) override; - void fromTypeData(QQmlTypeData *data); + void fromTypeData(const QQmlRefPointer<QQmlTypeData> &data); QUrl url; qreal progress; diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h index 59fefde893..2468de6857 100644 --- a/src/qml/qml/qqmldata_p.h +++ b/src/qml/qml/qqmldata_p.h @@ -232,7 +232,7 @@ public: QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit; QVector<DeferredData *> deferredData; - void deferData(int objectIndex, QV4::CompiledData::CompilationUnit *, QQmlContextData *); + void deferData(int objectIndex, const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &, QQmlContextData *); void releaseDeferredData(); QV4::WeakValue jsWrapper; diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index b72e07d97b..1ae39423e9 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -1706,7 +1706,7 @@ void QQmlData::NotifyList::layout() todo = nullptr; } -void QQmlData::deferData(int objectIndex, QV4::CompiledData::CompilationUnit *compilationUnit, QQmlContextData *context) +void QQmlData::deferData(int objectIndex, const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit, QQmlContextData *context) { QQmlData::DeferredData *deferData = new QQmlData::DeferredData; deferData->deferredIdx = objectIndex; @@ -2273,7 +2273,7 @@ QQmlMetaObject QQmlEnginePrivate::rawMetaObjectForType(int t) const Locker locker(this); auto iter = m_compositeTypes.constFind(t); if (iter != m_compositeTypes.cend()) { - return QQmlMetaObject((*iter)->rootPropertyCache()); + return QQmlMetaObject((*iter)->rootPropertyCache().data()); } else { QQmlType type = QQmlMetaType::qmlType(t); return QQmlMetaObject(type.baseMetaObject()); @@ -2285,7 +2285,7 @@ QQmlMetaObject QQmlEnginePrivate::metaObjectForType(int t) const Locker locker(this); auto iter = m_compositeTypes.constFind(t); if (iter != m_compositeTypes.cend()) { - return QQmlMetaObject((*iter)->rootPropertyCache()); + return QQmlMetaObject((*iter)->rootPropertyCache().data()); } else { QQmlType type = QQmlMetaType::qmlType(t); return QQmlMetaObject(type.metaObject()); @@ -2297,7 +2297,7 @@ QQmlPropertyCache *QQmlEnginePrivate::propertyCacheForType(int t) Locker locker(this); auto iter = m_compositeTypes.constFind(t); if (iter != m_compositeTypes.cend()) { - return (*iter)->rootPropertyCache(); + return (*iter)->rootPropertyCache().data(); } else { QQmlType type = QQmlMetaType::qmlType(t); locker.unlock(); @@ -2310,7 +2310,7 @@ QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t, int minorVe Locker locker(this); auto iter = m_compositeTypes.constFind(t); if (iter != m_compositeTypes.cend()) { - return (*iter)->rootPropertyCache(); + return (*iter)->rootPropertyCache().data(); } else { QQmlType type = QQmlMetaType::qmlType(t); locker.unlock(); diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp index 93ec9421ed..f0a5f18a15 100644 --- a/src/qml/qml/qqmljavascriptexpression.cpp +++ b/src/qml/qml/qqmljavascriptexpression.cpp @@ -458,7 +458,7 @@ void QQmlJavaScriptExpression::setupFunction(QV4::ExecutionContext *qmlContext, setCompilationUnit(m_v4Function->compilationUnit); } -void QQmlJavaScriptExpression::setCompilationUnit(QV4::CompiledData::CompilationUnit *compilationUnit) +void QQmlJavaScriptExpression::setCompilationUnit(const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit) { m_compilationUnit = compilationUnit; } diff --git a/src/qml/qml/qqmljavascriptexpression_p.h b/src/qml/qml/qqmljavascriptexpression_p.h index 01af3b89ca..9562476940 100644 --- a/src/qml/qml/qqmljavascriptexpression_p.h +++ b/src/qml/qml/qqmljavascriptexpression_p.h @@ -162,7 +162,7 @@ protected: } void setupFunction(QV4::ExecutionContext *qmlContext, QV4::Function *f); - void setCompilationUnit(QV4::CompiledData::CompilationUnit *compilationUnit); + void setCompilationUnit(const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit); // We store some flag bits in the following flag pointers. // activeGuards:flag1 - notifyOnValueChanged diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index 8fda7f6f77..0ef0ad959e 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -576,7 +576,7 @@ QQmlType QQmlType::resolveCompositeBaseType(QQmlEnginePrivate *engine) const Q_ASSERT(isComposite()); if (!engine || !d) return QQmlType(); - QQmlRefPointer<QQmlTypeData> td(engine->typeLoader.getType(sourceUrl()), QQmlRefPointer<QQmlTypeData>::Adopt); + QQmlRefPointer<QQmlTypeData> td(engine->typeLoader.getType(sourceUrl())); if (td.isNull() || !td->isComplete()) return QQmlType(); QV4::CompiledData::CompilationUnit *compilationUnit = td->compilationUnit(); @@ -590,11 +590,11 @@ QQmlPropertyCache *QQmlType::compositePropertyCache(QQmlEnginePrivate *engine) c Q_ASSERT(isComposite()); if (!engine) return nullptr; - QQmlRefPointer<QQmlTypeData> td(engine->typeLoader.getType(sourceUrl()), QQmlRefPointer<QQmlTypeData>::Adopt); + QQmlRefPointer<QQmlTypeData> td(engine->typeLoader.getType(sourceUrl())); if (td.isNull() || !td->isComplete()) return nullptr; QV4::CompiledData::CompilationUnit *compilationUnit = td->compilationUnit(); - return compilationUnit->rootPropertyCache(); + return compilationUnit->rootPropertyCache().data(); } static void clone(QMetaObjectBuilder &builder, const QMetaObject *mo, @@ -841,7 +841,7 @@ QQmlPropertyCache *QQmlTypePrivate::propertyCacheForMinorVersion(int minorVersio { for (int i = 0; i < propertyCaches.count(); ++i) if (propertyCaches.at(i).minorVersion == minorVersion) - return propertyCaches.at(i).cache; + return propertyCaches.at(i).cache.data(); return nullptr; } diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 7051fb51da..17734a0f97 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -71,7 +71,7 @@ struct ActiveOCRestorer }; } -QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QV4::CompiledData::CompilationUnit *compilationUnit, QQmlContextData *creationContext, +QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit, QQmlContextData *creationContext, QQmlIncubatorPrivate *incubator) : phase(Startup) , compilationUnit(compilationUnit) @@ -99,7 +99,7 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QV4::Compil } } -QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QV4::CompiledData::CompilationUnit *compilationUnit, QQmlObjectCreatorSharedState *inheritedSharedState) +QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit, QQmlObjectCreatorSharedState *inheritedSharedState) : phase(Startup) , compilationUnit(compilationUnit) , resolvedTypes(compilationUnit->resolvedTypes) @@ -1144,9 +1144,9 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo if (obj->flags & QV4::CompiledData::Object::IsComponent) { isComponent = true; - QQmlComponent *component = new QQmlComponent(engine, compilationUnit, index, parent); + QQmlComponent *component = new QQmlComponent(engine, compilationUnit.data(), index, parent); Q_QML_OC_PROFILE(sharedState->profiler, profiler.update( - compilationUnit, obj, QStringLiteral("<component>"), context->url())); + compilationUnit.data(), obj, QStringLiteral("<component>"), context->url())); QQmlComponentPrivate::get(component)->creationContext = context; instance = component; ddata = QQmlData::get(instance, /*create*/true); @@ -1157,7 +1157,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo QQmlType type = typeRef->type; if (type.isValid()) { Q_QML_OC_PROFILE(sharedState->profiler, profiler.update( - compilationUnit, obj, type.qmlTypeName(), context->url())); + compilationUnit.data(), obj, type.qmlTypeName(), context->url())); void *ddataMemory = nullptr; type.create(&instance, &ddataMemory, sizeof(QQmlData)); @@ -1190,8 +1190,8 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo } else { Q_ASSERT(typeRef->compilationUnit); Q_QML_OC_PROFILE(sharedState->profiler, profiler.update( - compilationUnit, obj, typeRef->compilationUnit->fileName(), - context->url())); + compilationUnit.data(), obj, typeRef->compilationUnit->fileName(), + context->url())); if (typeRef->compilationUnit->data->isSingleton()) { recordError(obj->location, tr("Composite Singleton Type %1 is not creatable").arg(stringAt(obj->inheritedTypeNameIndex))); @@ -1254,7 +1254,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo if (customParser && obj->flags & QV4::CompiledData::Object::HasCustomParserBindings) { customParser->engine = QQmlEnginePrivate::get(engine); - customParser->imports = compilationUnit->typeNameCache; + customParser->imports = compilationUnit->typeNameCache.data(); QList<const QV4::CompiledData::Binding *> bindings; const QV4::CompiledData::Object *obj = qmlUnit->objectAt(index); @@ -1264,7 +1264,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo bindings << binding; } } - customParser->applyBindings(instance, compilationUnit, bindings); + customParser->applyBindings(instance, compilationUnit.data(), bindings); customParser->engine = nullptr; customParser->imports = (QQmlTypeNameCache*)nullptr; @@ -1280,7 +1280,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo if (installPropertyCache) { if (ddata->propertyCache) ddata->propertyCache->release();; - ddata->propertyCache = cache; + ddata->propertyCache = cache.data(); ddata->propertyCache->addref(); } @@ -1436,7 +1436,7 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject * vmeMetaObject = new QQmlVMEMetaObject(v4, _qobject, cache, compilationUnit, _compiledObjectIndex); if (_ddata->propertyCache) _ddata->propertyCache->release(); - _ddata->propertyCache = cache; + _ddata->propertyCache = cache.data(); _ddata->propertyCache->addref(); scopeObjectProtector = _ddata->jsWrapper.value(); } else { diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h index 67a5bdd827..435b213341 100644 --- a/src/qml/qml/qqmlobjectcreator_p.h +++ b/src/qml/qml/qqmlobjectcreator_p.h @@ -85,7 +85,7 @@ class Q_QML_PRIVATE_EXPORT QQmlObjectCreator { Q_DECLARE_TR_FUNCTIONS(QQmlObjectCreator) public: - QQmlObjectCreator(QQmlContextData *parentContext, QV4::CompiledData::CompilationUnit *compilationUnit, QQmlContextData *creationContext, QQmlIncubatorPrivate *incubator = nullptr); + QQmlObjectCreator(QQmlContextData *parentContext, const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit, QQmlContextData *creationContext, QQmlIncubatorPrivate *incubator = nullptr); ~QQmlObjectCreator(); QObject *create(int subComponentIndex = -1, QObject *parent = nullptr, QQmlInstantiationInterrupt *interrupt = nullptr); @@ -104,7 +104,7 @@ public: QFiniteStack<QPointer<QObject> > &allCreatedObjects() const { return sharedState->allCreatedObjects; } private: - QQmlObjectCreator(QQmlContextData *contextData, QV4::CompiledData::CompilationUnit *compilationUnit, QQmlObjectCreatorSharedState *inheritedSharedState); + QQmlObjectCreator(QQmlContextData *contextData, const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit, QQmlObjectCreatorSharedState *inheritedSharedState); void init(QQmlContextData *parentContext); diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index c4487f91a3..bc0124eeab 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -255,7 +255,7 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name) { if (!obj) return; - QQmlTypeNameCache *typeNameCache = context?context->imports:nullptr; + QQmlRefPointer<QQmlTypeNameCache> typeNameCache = context?context->imports:nullptr; QObject *currentObject = obj; QVector<QStringRef> path; diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h index b78a2ddd20..0785910cec 100644 --- a/src/qml/qml/qqmlpropertycache_p.h +++ b/src/qml/qml/qqmlpropertycache_p.h @@ -979,13 +979,13 @@ public: void append(QQmlPropertyCache *cache) { cache->addref(); data.append(cache); } QQmlPropertyCache *at(int index) const { return data.at(index).data(); } - void set(int index, QQmlPropertyCache *replacement) { + void set(int index, const QQmlRefPointer<QQmlPropertyCache> &replacement) { if (QQmlPropertyCache *oldCache = data.at(index).data()) { - if (replacement == oldCache) + if (replacement.data() == oldCache) return; oldCache->release(); } - data[index] = replacement; + data[index] = replacement.data(); replacement->addref(); } diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 5572fdad44..c49c2b3036 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -505,7 +505,7 @@ void QQmlDataBlob::addDependency(QQmlDataBlob *blob) m_waitingFor.contains(blob)) return; - blob->addref(); + blob->addref(); // balanced in notifyComplete m_data.setStatus(WaitingForDependencies); @@ -1653,7 +1653,7 @@ QQmlImportDatabase *QQmlTypeLoader::importDatabase() const /*! Returns a QQmlTypeData for the specified \a url. The QQmlTypeData may be cached. */ -QQmlTypeData *QQmlTypeLoader::getType(const QUrl &url, Mode mode) +QQmlRefPointer<QQmlTypeData> QQmlTypeLoader::getType(const QUrl &url, Mode mode) { Q_ASSERT(!url.isRelative() && (QQmlFile::urlToLocalFileOrQrc(url).isEmpty() || @@ -1694,8 +1694,6 @@ QQmlTypeData *QQmlTypeLoader::getType(const QUrl &url, Mode mode) } } - typeData->addref(); - return typeData; } @@ -1703,14 +1701,14 @@ QQmlTypeData *QQmlTypeLoader::getType(const QUrl &url, Mode mode) Returns a QQmlTypeData for the given \a data with the provided base \a url. The QQmlTypeData will not be cached. */ -QQmlTypeData *QQmlTypeLoader::getType(const QByteArray &data, const QUrl &url, Mode mode) +QQmlRefPointer<QQmlTypeData> QQmlTypeLoader::getType(const QByteArray &data, const QUrl &url, Mode mode) { LockHolder<QQmlTypeLoader> holder(this); QQmlTypeData *typeData = new QQmlTypeData(url, this); QQmlTypeLoader::loadWithStaticData(typeData, data, mode); - return typeData; + return QQmlRefPointer<QQmlTypeData>(typeData, QQmlRefPointer<QQmlTypeData>::Adopt); } /*! @@ -2068,15 +2066,8 @@ QQmlTypeData::~QQmlTypeData() { for (int ii = 0; ii < m_scripts.count(); ++ii) m_scripts.at(ii).script->release(); - for (int ii = 0; ii < m_compositeSingletons.count(); ++ii) { - if (QQmlTypeData *tdata = m_compositeSingletons.at(ii).typeData) - tdata->release(); - } - for (auto it = m_resolvedTypes.constBegin(), end = m_resolvedTypes.constEnd(); - it != end; ++it) { - if (QQmlTypeData *tdata = it->typeData) - tdata->release(); - } + m_compositeSingletons.clear(); + m_resolvedTypes.clear(); } const QList<QQmlTypeData::ScriptReference> &QQmlTypeData::resolvedScripts() const @@ -2194,7 +2185,7 @@ void QQmlTypeData::createTypeAndPropertyCaches(const QQmlRefPointer<QQmlTypeName { QQmlPropertyCacheCreator<QV4::CompiledData::CompilationUnit> propertyCacheCreator(&m_compiledData->propertyCaches, &pendingGroupPropertyBindings, - engine, m_compiledData, &m_importCache); + engine, m_compiledData.data(), &m_importCache); QQmlCompileError error = propertyCacheCreator.buildMetaObjects(); if (error.isSet()) { setError(error); @@ -2202,7 +2193,7 @@ void QQmlTypeData::createTypeAndPropertyCaches(const QQmlRefPointer<QQmlTypeName } } - QQmlPropertyCacheAliasCreator<QV4::CompiledData::CompilationUnit> aliasCreator(&m_compiledData->propertyCaches, m_compiledData); + QQmlPropertyCacheAliasCreator<QV4::CompiledData::CompilationUnit> aliasCreator(&m_compiledData->propertyCaches, m_compiledData.data()); aliasCreator.appendAliasPropertiesToMetaObjects(); pendingGroupPropertyBindings.resolveMissingPropertyCaches(engine, &m_compiledData->propertyCaches); @@ -2674,7 +2665,7 @@ void QQmlTypeData::resolveTypes() // TODO: give an error message? If so, we should record and show the path of the cycle. continue; } - addDependency(ref.typeData); + addDependency(ref.typeData.data()); ref.prefix = csRef.prefix; m_compositeSingletons << ref; @@ -2704,7 +2695,7 @@ void QQmlTypeData::resolveTypes() if (ref.type.isComposite()) { ref.typeData = typeLoader()->getType(ref.type.sourceUrl()); - addDependency(ref.typeData); + addDependency(ref.typeData.data()); } ref.majorVersion = majorVersion; ref.minorVersion = minorVersion; @@ -2736,7 +2727,7 @@ QQmlCompileError QQmlTypeData::buildTypeResolutionCaches( for (const QQmlTypeData::TypeReference &singleton: m_compositeSingletons) (*typeNameCache)->add(singleton.type.qmlTypeName(), singleton.type.sourceUrl(), singleton.prefix); - m_importCache.populateCache(*typeNameCache); + m_importCache.populateCache(typeNameCache->data()); QQmlEnginePrivate * const engine = QQmlEnginePrivate::get(typeLoader()->engine()); diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h index 5988632547..0494034b3e 100644 --- a/src/qml/qml/qqmltypeloader_p.h +++ b/src/qml/qml/qqmltypeloader_p.h @@ -305,8 +305,8 @@ public: QQmlImportDatabase *importDatabase() const; - QQmlTypeData *getType(const QUrl &url, Mode mode = PreferSynchronous); - QQmlTypeData *getType(const QByteArray &, const QUrl &url, Mode mode = PreferSynchronous); + QQmlRefPointer<QQmlTypeData> getType(const QUrl &url, Mode mode = PreferSynchronous); + QQmlRefPointer<QQmlTypeData> getType(const QByteArray &, const QUrl &url, Mode mode = PreferSynchronous); QQmlScriptBlob *getScript(const QUrl &); QQmlQmldirData *getQmldir(const QUrl &); @@ -422,13 +422,13 @@ class Q_AUTOTEST_EXPORT QQmlTypeData : public QQmlTypeLoader::Blob public: struct TypeReference { - TypeReference() : majorVersion(0), minorVersion(0), typeData(nullptr), needsCreation(true) {} + TypeReference() : majorVersion(0), minorVersion(0), needsCreation(true) {} QV4::CompiledData::Location location; QQmlType type; int majorVersion; int minorVersion; - QQmlTypeData *typeData; + QQmlRefPointer<QQmlTypeData> typeData; QString prefix; // used by CompositeSingleton types QString qualifiedName() const; bool needsCreation; diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp index de077b6d38..8ddfa860d1 100644 --- a/src/qml/qml/qqmltypewrapper.cpp +++ b/src/qml/qml/qqmltypewrapper.cpp @@ -120,7 +120,7 @@ ReturnedValue QQmlTypeWrapper::create(QV4::ExecutionEngine *engine, QObject *o, // Returns a type wrapper for importNamespace (of t) on o. This allows nested resolution of a type in a // namespace. -ReturnedValue QQmlTypeWrapper::create(QV4::ExecutionEngine *engine, QObject *o, QQmlTypeNameCache *t, const QQmlImportRef *importNamespace, +ReturnedValue QQmlTypeWrapper::create(QV4::ExecutionEngine *engine, QObject *o, const QQmlRefPointer<QQmlTypeNameCache> &t, const QQmlImportRef *importNamespace, Heap::QQmlTypeWrapper::TypeNameMode mode) { Q_ASSERT(t); @@ -128,7 +128,7 @@ ReturnedValue QQmlTypeWrapper::create(QV4::ExecutionEngine *engine, QObject *o, Scope scope(engine); Scoped<QQmlTypeWrapper> w(scope, engine->memoryManager->allocate<QQmlTypeWrapper>()); - w->d()->mode = mode; w->d()->object = o; w->d()->typeNamespace = t; w->d()->importNamespace = importNamespace; + w->d()->mode = mode; w->d()->object = o; w->d()->typeNamespace = t.data(); w->d()->importNamespace = importNamespace; t->addref(); return w.asReturnedValue(); } @@ -385,10 +385,9 @@ ReturnedValue QQmlTypeWrapper::instanceOf(const Object *typeObject, const Value if (!theirDData->compilationUnit) return Encode(false); - QQmlTypeData *td = qenginepriv->typeLoader.getType(typeWrapper->d()->type().sourceUrl()); + QQmlRefPointer<QQmlTypeData> td = qenginepriv->typeLoader.getType(typeWrapper->d()->type().sourceUrl()); CompiledData::CompilationUnit *cu = td->compilationUnit(); myQmlType = qenginepriv->metaObjectForType(cu->metaTypeId); - td->release(); } else { myQmlType = qenginepriv->metaObjectForType(myTypeId); } diff --git a/src/qml/qml/qqmltypewrapper_p.h b/src/qml/qml/qqmltypewrapper_p.h index 25ff7ba7c8..dbaf83790f 100644 --- a/src/qml/qml/qqmltypewrapper_p.h +++ b/src/qml/qml/qqmltypewrapper_p.h @@ -108,7 +108,7 @@ struct Q_QML_EXPORT QQmlTypeWrapper : Object static ReturnedValue create(ExecutionEngine *, QObject *, const QQmlType &, Heap::QQmlTypeWrapper::TypeNameMode = Heap::QQmlTypeWrapper::IncludeEnums); - static ReturnedValue create(ExecutionEngine *, QObject *, QQmlTypeNameCache *, const QQmlImportRef *, + static ReturnedValue create(ExecutionEngine *, QObject *, const QQmlRefPointer<QQmlTypeNameCache> &, const QQmlImportRef *, Heap::QQmlTypeWrapper::TypeNameMode = Heap::QQmlTypeWrapper::IncludeEnums); diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index c1d3980b58..b7e80f3b06 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -176,7 +176,7 @@ void QQmlVMEMetaObjectEndpoint::tryConnect() } -QQmlInterceptorMetaObject::QQmlInterceptorMetaObject(QObject *obj, QQmlPropertyCache *cache) +QQmlInterceptorMetaObject::QQmlInterceptorMetaObject(QObject *obj, const QQmlRefPointer<QQmlPropertyCache> &cache) : object(obj), cache(cache), interceptors(nullptr), @@ -316,7 +316,7 @@ QAbstractDynamicMetaObject *QQmlInterceptorMetaObject::toDynamicMetaObject(QObje QQmlVMEMetaObject::QQmlVMEMetaObject(QV4::ExecutionEngine *engine, QObject *obj, - QQmlPropertyCache *cache, QV4::CompiledData::CompilationUnit *qmlCompilationUnit, int qmlObjectId) + const QQmlRefPointer<QQmlPropertyCache> &cache, const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &qmlCompilationUnit, int qmlObjectId) : QQmlInterceptorMetaObject(obj, cache), engine(engine), ctxt(QQmlData::get(obj, true)->outerContext), diff --git a/src/qml/qml/qqmlvmemetaobject_p.h b/src/qml/qml/qqmlvmemetaobject_p.h index 0c82686d47..dbcc9d2884 100644 --- a/src/qml/qml/qqmlvmemetaobject_p.h +++ b/src/qml/qml/qqmlvmemetaobject_p.h @@ -94,7 +94,7 @@ public: class Q_QML_PRIVATE_EXPORT QQmlInterceptorMetaObject : public QAbstractDynamicMetaObject { public: - QQmlInterceptorMetaObject(QObject *obj, QQmlPropertyCache *cache); + QQmlInterceptorMetaObject(QObject *obj, const QQmlRefPointer<QQmlPropertyCache> &cache); ~QQmlInterceptorMetaObject() override; void registerInterceptor(QQmlPropertyIndex index, QQmlPropertyValueInterceptor *interceptor); @@ -104,7 +104,7 @@ public: QAbstractDynamicMetaObject *toDynamicMetaObject(QObject *o) override; // Used by auto-tests for inspection - QQmlPropertyCache *propertyCache() const { return cache; } + QQmlPropertyCache *propertyCache() const { return cache.data(); } bool intercepts(QQmlPropertyIndex propertyIndex) const { @@ -146,7 +146,7 @@ class QQmlVMEMetaObjectEndpoint; class Q_QML_PRIVATE_EXPORT QQmlVMEMetaObject : public QQmlInterceptorMetaObject { public: - QQmlVMEMetaObject(QV4::ExecutionEngine *engine, QObject *obj, QQmlPropertyCache *cache, QV4::CompiledData::CompilationUnit *qmlCompilationUnit, int qmlObjectId); + QQmlVMEMetaObject(QV4::ExecutionEngine *engine, QObject *obj, const QQmlRefPointer<QQmlPropertyCache> &cache, const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &qmlCompilationUnit, int qmlObjectId); ~QQmlVMEMetaObject() override; bool aliasTarget(int index, QObject **target, int *coreIndex, int *valueTypeIndex) const; diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index 2ec1d7e87b..0af0f79945 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -1156,7 +1156,7 @@ ReturnedValue QtObject::method_createQmlObject(const FunctionObject *b, const Va if (!parentArg) THROW_GENERIC_ERROR("Qt.createQmlObject(): Missing parent object"); - QQmlTypeData *typeData = QQmlEnginePrivate::get(engine)->typeLoader.getType( + QQmlRefPointer<QQmlTypeData> typeData = QQmlEnginePrivate::get(engine)->typeLoader.getType( qml.toUtf8(), url, QQmlTypeLoader::Synchronous); Q_ASSERT(typeData->isCompleteOrError()); QQmlComponent component(engine); |