diff options
47 files changed, 283 insertions, 301 deletions
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp index 614890a8fd..c84ba7269a 100644 --- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp +++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp @@ -92,11 +92,11 @@ void QQmlProfilerServiceImpl::engineAboutToBeAdded(QJSEngine *engine) QMutexLocker lock(&m_configMutex); if (QQmlEngine *qmlEngine = qobject_cast<QQmlEngine *>(engine)) { - QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(qmlEngine); - QQmlProfilerAdapter *qmlAdapter = new QQmlProfilerAdapter(this, enginePrivate); + QQmlProfilerAdapter *qmlAdapter + = new QQmlProfilerAdapter(this, QQmlEnginePrivate::get(qmlEngine)); addEngineProfiler(qmlAdapter, engine); QQmlProfilerAdapter *compileAdapter - = new QQmlProfilerAdapter(this, &(enginePrivate->typeLoader)); + = new QQmlProfilerAdapter(this, QQmlTypeLoader::get(engine)); addEngineProfiler(compileAdapter, engine); } QV4ProfilerAdapter *v4Adapter = new QV4ProfilerAdapter(this, engine->handle()); diff --git a/src/qml/jsapi/qjsengine_p.h b/src/qml/jsapi/qjsengine_p.h index 0ab893d02a..c1f7895549 100644 --- a/src/qml/jsapi/qjsengine_p.h +++ b/src/qml/jsapi/qjsengine_p.h @@ -35,9 +35,11 @@ class Q_QML_EXPORT QJSEnginePrivate : public QObjectPrivate Q_DECLARE_PUBLIC(QJSEngine) public: - static QJSEnginePrivate* get(QJSEngine*e) { return e->d_func(); } + static QJSEnginePrivate *get(QJSEngine*e) { return e->d_func(); } static const QJSEnginePrivate* get(const QJSEngine*e) { return e->d_func(); } - static QJSEnginePrivate* get(QV4::ExecutionEngine *e); + static QJSEngine *get(QJSEnginePrivate *e) { return e->q_func(); } + static const QJSEngine *get(const QJSEnginePrivate *e) { return e->q_func(); } + static QJSEnginePrivate *get(QV4::ExecutionEngine *e); QJSEnginePrivate() = default; ~QJSEnginePrivate() override; diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 82e653a645..1f27ca1f1e 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -856,6 +856,10 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine) ExecutionEngine::~ExecutionEngine() { +#if QT_CONFIG(qml_network) + delete networkAccessManager; +#endif + m_typeLoader.reset(); qDeleteAll(m_extensionData); delete m_multiplyWrappedQObjects; m_multiplyWrappedQObjects = nullptr; @@ -884,6 +888,15 @@ ExecutionEngine::~ExecutionEngine() #endif } +#if QT_CONFIG(qml_network) +QNetworkAccessManager *ExecutionEngine::getNetworkAccessManager() +{ + if (!networkAccessManager) + networkAccessManager = typeLoader()->createNetworkAccessManager(nullptr); + return networkAccessManager; +} +#endif + #if QT_CONFIG(qml_debug) void ExecutionEngine::setDebugger(Debugging::Debugger *debugger) { @@ -2194,13 +2207,10 @@ ExecutionEngine::Module ExecutionEngine::registerNativeModule( return Module(); QQmlRefPointer<CompiledData::CompilationUnit> cu; - if (m_qmlEngine) { - // Make sure the type loader doesn't try to resolve the module anymore. - // If some other code requests that same module, we need to produce the same CU. - cu = QQmlEnginePrivate::get(m_qmlEngine)->typeLoader.injectModule(url, unit); - } else { - cu = QQml::makeRefPointer<CompiledData::CompilationUnit>(unit); - } + + // Make sure the type loader doesn't try to resolve the module anymore. + // If some other code requests that same module, we need to produce the same CU. + cu = typeLoader()->injectModule(url, unit); QQmlRefPointer<ExecutableCompilationUnit> newModule = insertCompilationUnit(std::move(cu)); @@ -2956,11 +2966,4 @@ int ExecutionEngine::registerExtension() return registrationData()->extensionCount++; } -#if QT_CONFIG(qml_network) -QNetworkAccessManager *QV4::detail::getNetworkAccessManager(ExecutionEngine *engine) -{ - return engine->qmlEngine()->networkAccessManager(); -} -#endif // qml_network - QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index 764a796f9d..8c1c12e543 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -57,16 +57,8 @@ QT_BEGIN_NAMESPACE #if QT_CONFIG(qml_network) class QNetworkAccessManager; - -namespace QV4 { -struct QObjectMethod; -namespace detail { -QNetworkAccessManager *getNetworkAccessManager(ExecutionEngine *engine); -} -} -#else -namespace QV4 { struct QObjectMethod; } #endif // qml_network +namespace QV4 { struct QObjectMethod; } // Used to allow a QObject method take and return raw V4 handles without having to expose // 48 in the public API. @@ -176,9 +168,9 @@ public: template<typename TypeLoader = QQmlTypeLoader> TypeLoader *typeLoader() { - if (m_qmlEngine) - return TypeLoader::get(m_qmlEngine); - return nullptr; + if (!m_typeLoader) + m_typeLoader = std::make_unique<TypeLoader>(this); + return m_typeLoader.get(); } enum JSObjects { @@ -359,7 +351,8 @@ public: FunctionObject *thrower() const { return reinterpret_cast<FunctionObject *>(jsObjects + ThrowerObject); } #if QT_CONFIG(qml_network) - QNetworkAccessManager* (*networkAccessManager)(ExecutionEngine*) = detail::getNetworkAccessManager; + QNetworkAccessManager *getNetworkAccessManager(); + QNetworkAccessManager *networkAccessManager = nullptr; #endif enum JSStrings { @@ -866,6 +859,7 @@ private: void *m_xmlHttpRequestData = nullptr; #endif + std::unique_ptr<QQmlTypeLoader> m_typeLoader; QQmlEngine *m_qmlEngine = nullptr; QQmlDelayedCallQueue m_delayedCallQueue; diff --git a/src/qml/jsruntime/qv4qmlcontext.cpp b/src/qml/jsruntime/qv4qmlcontext.cpp index baef0b4864..4d29d6b890 100644 --- a/src/qml/jsruntime/qv4qmlcontext.cpp +++ b/src/qml/jsruntime/qv4qmlcontext.cpp @@ -201,7 +201,7 @@ ReturnedValue QQmlContextWrapper::getPropertyAndBase(const QQmlContextWrapper *r if (context->imports() && (name->startsWithUpper() || context->valueTypesAreAddressable())) { // Search for attached properties, enums and imported scripts QQmlTypeNameCache::Result r = context->imports()->query<QQmlImport::AllowRecursion>( - name, QQmlTypeLoader::get(ep)); + name, v4->typeLoader()); if (r.isValid()) { if (hasProperty) diff --git a/src/qml/qml/ftw/qqmlthread_impl.cpp b/src/qml/qml/ftw/qqmlthread_impl.cpp index 7a5e40e995..1114e71e29 100644 --- a/src/qml/qml/ftw/qqmlthread_impl.cpp +++ b/src/qml/qml/ftw/qqmlthread_impl.cpp @@ -224,6 +224,12 @@ bool QQmlThread::isThisThread() const return d->isCurrentThread(); } +bool QQmlThread::isParentThread() const +{ + // The thread() of the QQmlThread is its parent thread. + return d->thread()->isCurrentThread(); +} + QThread *QQmlThread::thread() const { return const_cast<QThread *>(static_cast<const QThread *>(d)); diff --git a/src/qml/qml/ftw/qqmlthread_p.h b/src/qml/qml/ftw/qqmlthread_p.h index 75d2efca4d..b373ee988d 100644 --- a/src/qml/qml/ftw/qqmlthread_p.h +++ b/src/qml/qml/ftw/qqmlthread_p.h @@ -38,6 +38,7 @@ public: void wait(); bool isThisThread() const; + bool isParentThread() const; // Synchronously invoke a method in the thread template<typename Method, typename ...Args> diff --git a/src/qml/qml/ftw/qqmlthread_stub.cpp b/src/qml/qml/ftw/qqmlthread_stub.cpp index d65ebc7db6..0c30bce848 100644 --- a/src/qml/qml/ftw/qqmlthread_stub.cpp +++ b/src/qml/qml/ftw/qqmlthread_stub.cpp @@ -71,6 +71,11 @@ bool QQmlThread::isThisThread() const return d->thread()->isCurrentThread(); } +bool QQmlThread::isParentThread() const +{ + return d->thread()->isCurrentThread(); +} + void QQmlThread::internalCallMethodInThread(Message *message) { internalCallMethodInMain(message); diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp index c55064c600..c12e64b7ce 100644 --- a/src/qml/qml/qqml.cpp +++ b/src/qml/qml/qqml.cpp @@ -116,8 +116,8 @@ QQmlAttachedPropertiesFunc qmlAttachedPropertiesFunction(QObject *object, const QMetaObject *attachedMetaObject) { QQmlEngine *engine = object ? qmlEngine(object) : nullptr; - return QQmlMetaType::attachedPropertiesFunc(engine ? QQmlEnginePrivate::get(engine) : nullptr, - attachedMetaObject); + return QQmlMetaType::attachedPropertiesFunc( + engine ? QQmlTypeLoader::get(engine) : nullptr, attachedMetaObject); } QObject *qmlAttachedPropertiesObject(QObject *object, QQmlAttachedPropertiesFunc func, bool create) @@ -507,7 +507,7 @@ int qmlTypeId(const char *uri, int versionMajor, int versionMinor, const char *q Types; internal code should use QQmlMetaType API. */ QQmlEngine engine; - QQmlTypeLoader *typeLoader = &QQmlEnginePrivate::get(&engine)->typeLoader; + QQmlTypeLoader *typeLoader = QQmlTypeLoader::get(&engine); auto loadHelper = QQml::makeRefPointer<LoadHelper>( typeLoader, uri, qmlName, QQmlTypeLoader::Synchronous); const QQmlType type = loadHelper->type(); @@ -2615,8 +2615,7 @@ bool AOTCompiledContext::loadAttachedLookup(uint index, QObject *object, void *t QV4::Scoped<QV4::QQmlTypeWrapper> wrapper(scope, lookup->qmlTypeLookup.qmlTypeWrapper); Q_ASSERT(wrapper); *static_cast<QObject **>(target) = qmlAttachedPropertiesObject( - object, wrapper->d()->type().attachedPropertiesFunction( - QQmlEnginePrivate::get(qmlEngine()))); + object, wrapper->d()->type().attachedPropertiesFunction(scope.engine->typeLoader())); return true; } diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp index 221153b7f1..108312a859 100644 --- a/src/qml/qml/qqmlapplicationengine.cpp +++ b/src/qml/qml/qqmlapplicationengine.cpp @@ -15,8 +15,8 @@ using namespace Qt::Literals::StringLiterals; QT_BEGIN_NAMESPACE -QQmlApplicationEnginePrivate::QQmlApplicationEnginePrivate(QQmlEngine *e) - : QQmlEnginePrivate(e) +QQmlApplicationEnginePrivate::QQmlApplicationEnginePrivate() + : QQmlEnginePrivate() { uiLanguage = QLocale().bcp47Name(); } @@ -126,7 +126,7 @@ void QQmlApplicationEnginePrivate::startLoad(QAnyStringView uri, QAnyStringView const QQmlType type = componentPriv->loadHelperType(); if (type.sourceUrl().isValid()) { - const auto qmlDirData = typeLoader.getQmldir(type.sourceUrl()); + const auto qmlDirData = QQmlTypeLoader::get(q)->getQmldir(type.sourceUrl()); const QUrl url = qmlDirData->finalUrl(); // A QRC URL coming from a qmldir cannot contain a relative path Q_ASSERT(url.scheme() != "qrc"_L1 || url.path().startsWith('/'_L1)); @@ -296,7 +296,7 @@ void QQmlApplicationEnginePrivate::updateTranslationDirectory(const QUrl &url) order to load a QML file. */ QQmlApplicationEngine::QQmlApplicationEngine(QObject *parent) -: QQmlEngine(*(new QQmlApplicationEnginePrivate(this)), parent) +: QQmlEngine(*(new QQmlApplicationEnginePrivate), parent) { QJSEnginePrivate::addToDebugServer(this); } diff --git a/src/qml/qml/qqmlapplicationengine_p.h b/src/qml/qml/qqmlapplicationengine_p.h index fa74de876f..45107deb43 100644 --- a/src/qml/qml/qqmlapplicationengine_p.h +++ b/src/qml/qml/qqmlapplicationengine_p.h @@ -28,7 +28,7 @@ class Q_QML_EXPORT QQmlApplicationEnginePrivate : public QQmlEnginePrivate { Q_DECLARE_PUBLIC(QQmlApplicationEngine) public: - QQmlApplicationEnginePrivate(QQmlEngine *e); + QQmlApplicationEnginePrivate(); ~QQmlApplicationEnginePrivate(); void ensureInitialized(); void init(); diff --git a/src/qml/qml/qqmlbuiltinfunctions.cpp b/src/qml/qml/qqmlbuiltinfunctions.cpp index d0a30e7113..9b2bbd8dd0 100644 --- a/src/qml/qml/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/qqmlbuiltinfunctions.cpp @@ -1374,7 +1374,7 @@ QObject *QtObject::createQmlObject(const QString &qml, QObject *parent, const QU return nullptr; } - QQmlRefPointer<QQmlTypeData> typeData = QQmlEnginePrivate::get(engine)->typeLoader.getType( + QQmlRefPointer<QQmlTypeData> typeData = v4Engine()->typeLoader()->getType( qml.toUtf8(), resolvedUrl, QQmlTypeLoader::Synchronous); if (!typeData->isCompleteOrError()) { @@ -1738,10 +1738,10 @@ QVariant QtObject::enumStringToValue(QJSValue enumType, QJSValue string) QQmlType type = enumWrapper->d()->type(); int enumIndex = enumWrapper->d()->enumIndex; QString keyString = string.toString(); - auto &typeLoader = QQmlEnginePrivate::get(m_engine->qmlEngine())->typeLoader; + auto *typeLoader = m_engine->typeLoader(); int value = enumWrapper->d()->scoped - ? type.scopedEnumValue(&typeLoader, enumIndex, keyString, &ok) - : type.unscopedEnumValue(&typeLoader, enumIndex, keyString, &ok); + ? type.scopedEnumValue(typeLoader, enumIndex, keyString, &ok) + : type.unscopedEnumValue(typeLoader, enumIndex, keyString, &ok); if (ok) return value; @@ -1773,10 +1773,10 @@ QVariant QtObject::enumValueToString(QJSValue enumType, QJSValue value) QQmlType type = enumWrapper->d()->type(); int enumIndex = enumWrapper->d()->enumIndex; int keyValue = value.toInt(); - auto &typeLoader = QQmlEnginePrivate::get(m_engine->qmlEngine())->typeLoader; + auto *typeLoader = m_engine->typeLoader(); QString key = enumWrapper->d()->scoped - ? type.scopedEnumKey(&typeLoader, enumIndex, keyValue, &ok) - : type.unscopedEnumKey(&typeLoader, enumIndex, keyValue, &ok); + ? type.scopedEnumKey(typeLoader, enumIndex, keyValue, &ok) + : type.unscopedEnumKey(typeLoader, enumIndex, keyValue, &ok); if (ok) return key; @@ -1805,11 +1805,11 @@ QVariant QtObject::enumValueToStrings(QJSValue enumType, QJSValue value) QQmlType type = enumWrapper->d()->type(); int enumIndex = enumWrapper->d()->enumIndex; int keyValue = value.toInt(); - auto &typeLoader = QQmlEnginePrivate::get(m_engine->qmlEngine())->typeLoader; + auto *typeLoader = m_engine->typeLoader(); Scope scope(m_engine); QStringList keys = enumWrapper->d()->scoped - ? type.scopedEnumKeys(&typeLoader, enumIndex, keyValue, &ok) - : type.unscopedEnumKeys(&typeLoader, enumIndex, keyValue, &ok); + ? type.scopedEnumKeys(typeLoader, enumIndex, keyValue, &ok) + : type.unscopedEnumKeys(typeLoader, enumIndex, keyValue, &ok); if (ok) return keys; diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index 1dc73b9321..6ba59fad9e 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -467,8 +467,7 @@ QQmlComponent::~QQmlComponent() if (d->m_engine && !d->m_typeData->isCompleteOrError()) { // In this case we have to send it to the type loader thread to be dropped. It will // manipulate its "waiting" lists that other blobs may be using concurrently. - QQmlEnginePrivate::get(d->m_engine)->typeLoader.drop( - QQmlDataBlob::Ptr(d->m_typeData.data())); + QQmlTypeLoader::get(d->m_engine)->drop(QQmlDataBlob::Ptr(d->m_typeData.data())); } d->m_typeData.reset(); } @@ -725,7 +724,7 @@ void QQmlComponent::setData(const QByteArray &data, const QUrl &url) d->m_url = url; - QQmlRefPointer<QQmlTypeData> typeData = QQmlEnginePrivate::get(d->m_engine)->typeLoader.getType(data, url); + QQmlRefPointer<QQmlTypeData> typeData = QQmlTypeLoader::get(d->m_engine)->getType(data, url); if (typeData->isCompleteOrError()) { d->fromTypeData(typeData); @@ -824,8 +823,7 @@ void QQmlComponentPrivate::loadUrl(const QUrl &newUrl, QQmlComponent::Compilatio QQmlTypeLoader::Mode loaderMode = (mode == QQmlComponent::Asynchronous) ? QQmlTypeLoader::Asynchronous : QQmlTypeLoader::PreferSynchronous; - QQmlRefPointer<QQmlTypeData> data - = QQmlEnginePrivate::get(m_engine)->typeLoader.getType(m_url, loaderMode); + QQmlRefPointer<QQmlTypeData> data = QQmlTypeLoader::get(m_engine)->getType(m_url, loaderMode); if (data->isCompleteOrError()) { fromTypeData(data); @@ -1420,9 +1418,8 @@ void QQmlComponentPrivate::prepareLoadFromModule( if (m_loadHelper) m_loadHelper->unregisterCallback(this); - QQmlTypeLoader *typeLoader = &QQmlEnginePrivate::get(m_engine)->typeLoader; // LoadHelper must be on the Heap as it derives from QQmlRefCount - m_loadHelper = QQml::makeRefPointer<LoadHelper>(typeLoader, uri, typeName, mode); + m_loadHelper = QQml::makeRefPointer<LoadHelper>(QQmlTypeLoader::get(m_engine), uri, typeName, mode); } void QQmlComponentPrivate::completeLoadFromModule(QAnyStringView uri, QAnyStringView typeName) diff --git a/src/qml/qml/qqmlcontext.cpp b/src/qml/qml/qqmlcontext.cpp index 39dacb80f4..f7d1c95292 100644 --- a/src/qml/qml/qqmlcontext.cpp +++ b/src/qml/qml/qqmlcontext.cpp @@ -453,8 +453,9 @@ QJSValue QQmlContext::importedScript(const QString &name) const { Q_D(const QQmlContext); - QQmlTypeNameCache::Result r = d->m_data->imports()->query(name, QQmlTypeLoader::get(engine())); - QV4::Scope scope(engine()->handle()); + QV4::ExecutionEngine *v4 = engine()->handle(); + QQmlTypeNameCache::Result r = d->m_data->imports()->query(name, v4->typeLoader()); + QV4::Scope scope(v4); QV4::ScopedObject scripts(scope, d->m_data->importedScripts()); return scripts ? QJSValuePrivate::fromReturnedValue(scripts->get(r.scriptIndex)) : QJSValue(QJSValue::UndefinedValue); diff --git a/src/qml/qml/qqmlcustomparser.cpp b/src/qml/qml/qqmlcustomparser.cpp index c16d4911ae..6eddb07b41 100644 --- a/src/qml/qml/qqmlcustomparser.cpp +++ b/src/qml/qml/qqmlcustomparser.cpp @@ -221,7 +221,7 @@ QQmlTypeLoader *QQmlCustomParser::typeLoader() const if (!engine && !validator) return nullptr; - return validator ? validator->typeLoader() : &engine->typeLoader; + return validator ? validator->typeLoader() : QQmlTypeLoader::get(engine); } QT_END_NAMESPACE diff --git a/src/qml/qml/qqmldatablob_p.h b/src/qml/qml/qqmldatablob_p.h index 8874c2c395..82e430eb2d 100644 --- a/src/qml/qml/qqmldatablob_p.h +++ b/src/qml/qml/qqmldatablob_p.h @@ -60,6 +60,7 @@ public: void startLoading(); QQmlTypeLoader *typeLoader() const { return m_typeLoader; } + void resetTypeLoader() { m_typeLoader = nullptr; } Type type() const; @@ -116,10 +117,17 @@ public: } template<typename Loader = QQmlTypeLoader> + void assertEngineThreadIfRunning() const + { + const Loader *loader = m_typeLoader; + Q_ASSERT(!loader || !loader->thread() || loader->thread()->isParentThread()); + } + + template<typename Loader = QQmlTypeLoader> void assertEngineThread() const { const Loader *loader = m_typeLoader; - Q_ASSERT(loader && loader->engine() && loader->engine()->thread()->isCurrentThread()); + Q_ASSERT(loader && loader->thread() && loader->thread()->isParentThread()); } protected: diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index cc13b5006d..f4c3cfb1f2 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -509,7 +509,7 @@ void QQmlEnginePrivate::init() Create a new QQmlEngine with the given \a parent. */ QQmlEngine::QQmlEngine(QObject *parent) -: QJSEngine(*new QQmlEnginePrivate(this), parent) +: QJSEngine(*new QQmlEnginePrivate, parent) { Q_D(QQmlEngine); d->init(); @@ -538,7 +538,15 @@ QQmlEngine::QQmlEngine(QQmlEnginePrivate &dd, QObject *parent) QQmlEngine::~QQmlEngine() { Q_D(QQmlEngine); - handle()->inShutdown = true; + +#if QT_CONFIG(qml_worker_script) + // Delete the workerscript engine early + // so that it won't be able to use the type loader anymore. + delete std::exchange(d->workerScriptEngine, nullptr); +#endif + + QV4::ExecutionEngine *v4 = handle(); + v4->inShutdown = true; QJSEnginePrivate::removeFromDebugServer(this); // Emit onDestruction signals for the root context before @@ -555,7 +563,7 @@ QQmlEngine::~QQmlEngine() delete d->rootContext; d->rootContext = nullptr; - d->typeLoader.invalidate(); + v4->typeLoader()->invalidate(); // QQmlGadgetPtrWrapper can have QQmlData with various references. qDeleteAll(d->cachedValueTypeInstances); @@ -612,8 +620,6 @@ QQmlEngine::~QQmlEngine() */ void QQmlEngine::clearComponentCache() { - Q_D(QQmlEngine); - // Contexts can hold on to CUs but live on the JS heap. // Use a non-incremental GC run to get rid of those. QV4::MemoryManager *mm = handle()->memoryManager; @@ -622,8 +628,9 @@ void QQmlEngine::clearComponentCache() mm->runGC(); mm->gcStateMachine->timeLimit = std::move(oldLimit); - handle()->trimCompilationUnits(); - d->typeLoader.clearCache(); + QV4::ExecutionEngine *v4 = handle(); + v4->trimCompilationUnits(); + v4->typeLoader()->clearCache(); QQmlMetaType::freeUnusedTypesAndCaches(); } @@ -641,9 +648,9 @@ void QQmlEngine::clearComponentCache() */ void QQmlEngine::trimComponentCache() { - Q_D(QQmlEngine); - handle()->trimCompilationUnits(); - d->typeLoader.trimCache(); + QV4::ExecutionEngine *v4 = handle(); + v4->trimCompilationUnits(); + v4->typeLoader()->trimCache(); } /*! @@ -695,8 +702,7 @@ QQmlContext *QQmlEngine::rootContext() const */ QQmlAbstractUrlInterceptor *QQmlEngine::urlInterceptor() const { - Q_D(const QQmlEngine); - return d->typeLoader.urlInterceptors().last(); + return QQmlTypeLoader::get(this)->urlInterceptors().last(); } #endif @@ -711,8 +717,7 @@ QQmlAbstractUrlInterceptor *QQmlEngine::urlInterceptor() const */ void QQmlEngine::addUrlInterceptor(QQmlAbstractUrlInterceptor *urlInterceptor) { - Q_D(QQmlEngine); - d->typeLoader.addUrlInterceptor(urlInterceptor); + QQmlTypeLoader::get(this)->addUrlInterceptor(urlInterceptor); } /*! @@ -725,8 +730,7 @@ void QQmlEngine::addUrlInterceptor(QQmlAbstractUrlInterceptor *urlInterceptor) */ void QQmlEngine::removeUrlInterceptor(QQmlAbstractUrlInterceptor *urlInterceptor) { - Q_D(QQmlEngine); - d->typeLoader.removeUrlInterceptor(urlInterceptor); + QQmlTypeLoader::get(this)->removeUrlInterceptor(urlInterceptor); } /*! @@ -735,8 +739,7 @@ void QQmlEngine::removeUrlInterceptor(QQmlAbstractUrlInterceptor *urlInterceptor */ QUrl QQmlEngine::interceptUrl(const QUrl &url, QQmlAbstractUrlInterceptor::DataType type) const { - Q_D(const QQmlEngine); - return d->typeLoader.interceptUrl(url, type); + return QQmlTypeLoader::get(this)->interceptUrl(url, type); } /*! @@ -744,8 +747,7 @@ QUrl QQmlEngine::interceptUrl(const QUrl &url, QQmlAbstractUrlInterceptor::DataT */ QList<QQmlAbstractUrlInterceptor *> QQmlEngine::urlInterceptors() const { - Q_D(const QQmlEngine); - return d->typeLoader.urlInterceptors(); + return QQmlTypeLoader::get(this)->urlInterceptors(); } QSharedPointer<QQmlImageProviderBase> QQmlEnginePrivate::imageProvider(const QString &providerId) const @@ -770,8 +772,7 @@ QSharedPointer<QQmlImageProviderBase> QQmlEnginePrivate::imageProvider(const QSt */ void QQmlEngine::setNetworkAccessManagerFactory(QQmlNetworkAccessManagerFactory *factory) { - Q_D(QQmlEngine); - d->typeLoader.setNetworkAccessManagerFactory(factory); + QQmlTypeLoader::get(this)->setNetworkAccessManagerFactory(factory); } class QQmlEnginePublicAPIToken {}; @@ -783,16 +784,7 @@ class QQmlEnginePublicAPIToken {}; */ QQmlNetworkAccessManagerFactory *QQmlEngine::networkAccessManagerFactory() const { - Q_D(const QQmlEngine); - return d->typeLoader.networkAccessManagerFactory().get(QQmlEnginePublicAPIToken()); -} - -QNetworkAccessManager *QQmlEnginePrivate::getNetworkAccessManager() -{ - Q_Q(QQmlEngine); - if (!networkAccessManager) - networkAccessManager = typeLoader.createNetworkAccessManager(q); - return networkAccessManager; + return QQmlTypeLoader::get(this)->networkAccessManagerFactory().get(QQmlEnginePublicAPIToken()); } /*! @@ -809,9 +801,7 @@ QNetworkAccessManager *QQmlEnginePrivate::getNetworkAccessManager() */ QNetworkAccessManager *QQmlEngine::networkAccessManager() const { - // ### Qt7: This method is clearly not const since it _creates_ the network access manager. - Q_D(const QQmlEngine); - return const_cast<QQmlEnginePrivate *>(d)->getNetworkAccessManager(); + return handle()->getNetworkAccessManager(); } #endif // qml_network @@ -1066,7 +1056,7 @@ QJSValue QQmlEngine::singletonInstance<QJSValue>(QAnyStringView uri, QAnyStringV Q_D(QQmlEngine); auto loadHelper = QQml::makeRefPointer<LoadHelper>( - &d->typeLoader, uri, typeName, QQmlTypeLoader::Synchronous); + QQmlTypeLoader::get(this), uri, typeName, QQmlTypeLoader::Synchronous); const QQmlType type = loadHelper->type(); if (!type.isSingleton()) @@ -1610,8 +1600,7 @@ void QQmlEnginePrivate::cleanupScarceResources() */ void QQmlEngine::addImportPath(const QString& path) { - Q_D(QQmlEngine); - d->typeLoader.addImportPath(path); + QQmlTypeLoader::get(this)->addImportPath(path); } /*! @@ -1631,8 +1620,7 @@ void QQmlEngine::addImportPath(const QString& path) */ QStringList QQmlEngine::importPathList() const { - Q_D(const QQmlEngine); - return d->typeLoader.importPathList(); + return QQmlTypeLoader::get(this)->importPathList(); } /*! @@ -1649,8 +1637,7 @@ QStringList QQmlEngine::importPathList() const */ void QQmlEngine::setImportPathList(const QStringList &paths) { - Q_D(QQmlEngine); - d->typeLoader.setImportPathList(paths); + QQmlTypeLoader::get(this)->setImportPathList(paths); } @@ -1667,8 +1654,7 @@ void QQmlEngine::setImportPathList(const QStringList &paths) */ void QQmlEngine::addPluginPath(const QString& path) { - Q_D(QQmlEngine); - d->typeLoader.addPluginPath(path); + QQmlTypeLoader::get(this)->addPluginPath(path); } /*! @@ -1682,8 +1668,7 @@ void QQmlEngine::addPluginPath(const QString& path) */ QStringList QQmlEngine::pluginPathList() const { - Q_D(const QQmlEngine); - return d->typeLoader.pluginPathList(); + return QQmlTypeLoader::get(this)->pluginPathList(); } /*! @@ -1698,8 +1683,7 @@ QStringList QQmlEngine::pluginPathList() const */ void QQmlEngine::setPluginPathList(const QStringList &paths) { - Q_D(QQmlEngine); - d->typeLoader.setPluginPathList(paths); + QQmlTypeLoader::get(this)->setPluginPathList(paths); } #if QT_CONFIG(library) @@ -1720,9 +1704,8 @@ void QQmlEngine::setPluginPathList(const QStringList &paths) */ bool QQmlEngine::importPlugin(const QString &filePath, const QString &uri, QList<QQmlError> *errors) { - Q_D(QQmlEngine); QQmlTypeLoaderQmldirContent qmldir; - QQmlPluginImporter importer(uri, QTypeRevision(), &qmldir, &d->typeLoader, errors); + QQmlPluginImporter importer(uri, QTypeRevision(), &qmldir, QQmlTypeLoader::get(this), errors); return importer.importDynamicPlugin(filePath, uri, false).isValid(); } #endif @@ -1907,16 +1890,6 @@ QJSValue QQmlEnginePrivate::singletonInstance<QJSValue>(const QQmlType &type) return value; } -bool QQmlEnginePrivate::isTypeLoaded(const QUrl &url) const -{ - return typeLoader.isTypeLoaded(url); -} - -bool QQmlEnginePrivate::isScriptLoaded(const QUrl &url) const -{ - return typeLoader.isScriptLoaded(url); -} - void QQmlEnginePrivate::executeRuntimeFunction(const QUrl &url, qsizetype functionIndex, QObject *thisObject, int argc, void **args, QMetaType *types) @@ -1985,7 +1958,7 @@ QV4::ExecutableCompilationUnit *QQmlEnginePrivate::compilationUnitFromUrl(const return unit.data(); } - auto unit = typeLoader.getType(url)->compilationUnit(); + auto unit = v4->typeLoader()->getType(url)->compilationUnit(); if (!unit) return nullptr; diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h index 322f4d6812..4d923c983f 100644 --- a/src/qml/qml/qqmlengine_p.h +++ b/src/qml/qml/qqmlengine_p.h @@ -100,7 +100,6 @@ class Q_QML_EXPORT QQmlEnginePrivate : public QJSEnginePrivate { Q_DECLARE_PUBLIC(QQmlEngine) public: - explicit QQmlEnginePrivate(QQmlEngine *q) : typeLoader(q) {} ~QQmlEnginePrivate() override; void init(); @@ -137,10 +136,7 @@ public: QUrl baseUrl; QQmlObjectCreator *activeObjectCreator = nullptr; -#if QT_CONFIG(qml_network) - QNetworkAccessManager *getNetworkAccessManager(); - QNetworkAccessManager *networkAccessManager = nullptr; -#endif + mutable QRecursiveMutex imageProviderMutex; QHash<QString,QSharedPointer<QQmlImageProviderBase> > imageProviders; QSharedPointer<QQmlImageProviderBase> imageProvider(const QString &providerId) const; @@ -149,8 +145,6 @@ public: void referenceScarceResources(); void dereferenceScarceResources(); - QQmlTypeLoader typeLoader; - QString offlineStoragePath; // Unfortunate workaround to avoid a circular dependency between @@ -166,9 +160,6 @@ public: // These methods may be called from any thread QString offlineStorageDatabaseDirectory() const; - bool isTypeLoaded(const QUrl &url) const; - bool isScriptLoaded(const QUrl &url) const; - template <typename T> T singletonInstance(const QQmlType &type); @@ -181,14 +172,15 @@ public: static void warning(QQmlEnginePrivate *, const QQmlError &); static void warning(QQmlEnginePrivate *, const QList<QQmlError> &); - inline static QV4::ExecutionEngine *getV4Engine(QQmlEngine *e); inline static QQmlEnginePrivate *get(QQmlEngine *e); inline static const QQmlEnginePrivate *get(const QQmlEngine *e); - inline static QQmlEnginePrivate *get(QQmlContext *c); - inline static QQmlEnginePrivate *get(const QQmlRefPointer<QQmlContextData> &c); inline static QQmlEngine *get(QQmlEnginePrivate *p); + inline static const QQmlEngine *get(const QQmlEnginePrivate *p); inline static QQmlEnginePrivate *get(QV4::ExecutionEngine *e); + inline static QQmlEnginePrivate *get(QQmlContext *c); + inline static QQmlEnginePrivate *get(const QQmlRefPointer<QQmlContextData> &c); + static QList<QQmlError> qmlErrorFromDiagnostics(const QString &fileName, const QList<QQmlJS::DiagnosticMessage> &diagnosticMessages); static bool designerMode(); @@ -319,13 +311,6 @@ inline void QQmlEnginePrivate::dereferenceScarceResources() } } -QV4::ExecutionEngine *QQmlEnginePrivate::getV4Engine(QQmlEngine *e) -{ - Q_ASSERT(e); - - return e->handle(); -} - QQmlEnginePrivate *QQmlEnginePrivate::get(QQmlEngine *e) { Q_ASSERT(e); diff --git a/src/qml/qml/qqmlfileselector.cpp b/src/qml/qml/qqmlfileselector.cpp index 903f67637f..4bd54fa95c 100644 --- a/src/qml/qml/qqmlfileselector.cpp +++ b/src/qml/qml/qqmlfileselector.cpp @@ -167,7 +167,7 @@ QQmlFileSelector* QQmlFileSelector::get(QQmlEngine* engine) } const QUrl nonEmptyInvalid(QLatin1String(":")); - const auto interceptors = enginePrivate->typeLoader.urlInterceptors(); + const auto interceptors = QQmlTypeLoader::get(engine)->urlInterceptors(); for (QQmlAbstractUrlInterceptor *interceptor : interceptors) { const QUrl result = interceptor->intercept( nonEmptyInvalid, QQmlAbstractUrlInterceptor::UrlString); diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index 7491ce90e1..4a37c446e8 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -1154,13 +1154,13 @@ QMetaType QQmlMetaType::listValueType(QMetaType metaType) return QMetaType {}; } -QQmlAttachedPropertiesFunc QQmlMetaType::attachedPropertiesFunc(QQmlEnginePrivate *engine, - const QMetaObject *mo) +QQmlAttachedPropertiesFunc QQmlMetaType::attachedPropertiesFunc( + QQmlTypeLoader *typeLoader, const QMetaObject *mo) { QQmlMetaTypeDataPtr data; QQmlType type(data->metaObjectToType.value(mo)); - return type.attachedPropertiesFunction(engine); + return type.attachedPropertiesFunction(typeLoader); } QMetaProperty QQmlMetaType::defaultProperty(const QMetaObject *metaObject) diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index 9e5a79630c..01ce721781 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -178,8 +178,8 @@ public: static QObject *toQObject(const QVariant &, bool *ok = nullptr); static QMetaType listValueType(QMetaType type); - static QQmlAttachedPropertiesFunc attachedPropertiesFunc(QQmlEnginePrivate *, - const QMetaObject *); + static QQmlAttachedPropertiesFunc attachedPropertiesFunc( + QQmlTypeLoader *typeLoader, const QMetaObject *); static bool isInterface(QMetaType type); static const char *interfaceIId(QMetaType type); static bool isList(QMetaType type); diff --git a/src/qml/qml/qqmlnotifyingblob.cpp b/src/qml/qml/qqmlnotifyingblob.cpp index fc46ae942f..f3581b6b5c 100644 --- a/src/qml/qml/qqmlnotifyingblob.cpp +++ b/src/qml/qml/qqmlnotifyingblob.cpp @@ -19,7 +19,7 @@ void QQmlNotifyingBlob::registerCallback(Callback *callback) void QQmlNotifyingBlob::unregisterCallback(Callback *callback) { - assertEngineThread(); + assertEngineThreadIfRunning(); Q_ASSERT(m_callbacks.contains(callback)); m_callbacks.removeOne(callback); Q_ASSERT(!m_callbacks.contains(callback)); diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 5da9c3118d..0c69d48c33 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -840,10 +840,10 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper QV4::ResolvedTypeReference *tr = resolvedType(binding->propertyNameIndex); Q_ASSERT(tr); QQmlType attachedType = tr->type(); - QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(engine); + QQmlTypeLoader *typeLoader = QQmlTypeLoader::get(engine); if (!attachedType.isValid()) { - QQmlTypeNameCache::Result res = context->imports()->query( - stringAt(binding->propertyNameIndex), QQmlTypeLoader::get(enginePrivate)); + QQmlTypeNameCache::Result res + = context->imports()->query(stringAt(binding->propertyNameIndex), typeLoader); if (res.isValid()) attachedType = res.type; else @@ -856,7 +856,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper context->url())); QObject *qmlObject = qmlAttachedPropertiesObject( - _qobject, attachedType.attachedPropertiesFunction(enginePrivate)); + _qobject, attachedType.attachedPropertiesFunction(typeLoader)); if (!qmlObject) { recordError(binding->location, QStringLiteral("Could not create attached properties object '%1'") @@ -866,7 +866,8 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper const size_t objectIndex = sharedState->allCreatedObjects.size(); sharedState->allCreatedObjects.push_back(qmlObject); - const QQmlType attachedObjectType = QQmlMetaType::qmlType(attachedType.attachedPropertiesType(QQmlEnginePrivate::get((engine)))); + const QQmlType attachedObjectType + = QQmlMetaType::qmlType(attachedType.attachedPropertiesType(typeLoader)); const int parserStatusCast = attachedObjectType.parserStatusCast(); QQmlParserStatus *parserStatus = nullptr; if (parserStatusCast != -1) diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index 3fc8fac6c5..51b73bb3f6 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -248,12 +248,11 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name, // Types must begin with an uppercase letter (see checkRegistration() // in qqmlmetatype.cpp for the enforcement of this). if (typeNameCache && !pathName.isEmpty() && pathName.at(0).isUpper()) { - QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(engine); - QQmlTypeLoader *typeLoader = QQmlTypeLoader::get(enginePrivate); + QQmlTypeLoader *typeLoader = QQmlTypeLoader::get(engine.data()); QQmlTypeNameCache::Result r = typeNameCache->query(pathName, typeLoader); if (r.isValid()) { if (r.type.isValid()) { - QQmlAttachedPropertiesFunc func = r.type.attachedPropertiesFunction(enginePrivate); + QQmlAttachedPropertiesFunc func = r.type.attachedPropertiesFunction(typeLoader); if (!func) return; // Not an attachable type currentObject = qmlAttachedPropertiesObject(currentObject, func); @@ -269,7 +268,7 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name, if (!r.type.isValid()) return; // Invalid type in namespace - QQmlAttachedPropertiesFunc func = r.type.attachedPropertiesFunction(enginePrivate); + QQmlAttachedPropertiesFunc func = r.type.attachedPropertiesFunction(typeLoader); if (!func) return; // Not an attachable type diff --git a/src/qml/qml/qqmltype.cpp b/src/qml/qml/qqmltype.cpp index aa7327ffa0..89f9df7078 100644 --- a/src/qml/qml/qqmltype.cpp +++ b/src/qml/qml/qqmltype.cpp @@ -710,12 +710,6 @@ QTypeRevision QQmlType::metaObjectRevision() const return d ? d->revision : QTypeRevision(); } -QQmlAttachedPropertiesFunc QQmlType::attachedPropertiesFunction( - QQmlEnginePrivate *enginePrivate) const -{ - return attachedPropertiesFunction(&enginePrivate->typeLoader); -} - QQmlAttachedPropertiesFunc QQmlType::attachedPropertiesFunction(QQmlTypeLoader *typeLoader) const { if (const QQmlTypePrivate *base = d ? d->attachedPropertiesBase(typeLoader) : nullptr) @@ -723,11 +717,6 @@ QQmlAttachedPropertiesFunc QQmlType::attachedPropertiesFunction(QQmlTypeLoader * return nullptr; } -const QMetaObject *QQmlType::attachedPropertiesType(QQmlEnginePrivate *enginePrivate) const -{ - return attachedPropertiesType(&enginePrivate->typeLoader); -} - const QMetaObject *QQmlType::attachedPropertiesType(QQmlTypeLoader *typeLoader) const { if (const QQmlTypePrivate *base = d ? d->attachedPropertiesBase(typeLoader) : nullptr) diff --git a/src/qml/qml/qqmltype_p.h b/src/qml/qml/qqmltype_p.h index 70155637d1..c1108581b1 100644 --- a/src/qml/qml/qqmltype_p.h +++ b/src/qml/qml/qqmltype_p.h @@ -108,10 +108,7 @@ public: QTypeRevision metaObjectRevision() const; bool containsRevisionedAttributes() const; - QQmlAttachedPropertiesFunc attachedPropertiesFunction(QQmlEnginePrivate *enginePrivate) const; QQmlAttachedPropertiesFunc attachedPropertiesFunction(QQmlTypeLoader *typeLoader) const; - - const QMetaObject *attachedPropertiesType(QQmlEnginePrivate *enginePrivate) const; const QMetaObject *attachedPropertiesType(QQmlTypeLoader *typeLoader) const; int parserStatusCast() const; diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index a3b1e84e05..d4d711332b 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -35,8 +35,10 @@ #include <functional> -#define ASSERT_LOADTHREAD() Q_ASSERT(thread() && thread()->isThisThread()) -#define ASSERT_ENGINETHREAD() Q_ASSERT(engine()->thread()->isCurrentThread()) +#define ASSERT_LOADTHREAD() \ + Q_ASSERT(thread() && thread()->isThisThread()) +#define ASSERT_ENGINETHREAD() \ + Q_ASSERT(!engine()->jsEngine() || engine()->jsEngine()->thread()->isCurrentThread()) QT_BEGIN_NAMESPACE @@ -413,7 +415,7 @@ void doInitializeEngine( if (thread && thread->isThisThread()) thread->initializeEngine(iface, uri); else - iface->initializeEngine(data->engine(), uri); + iface->initializeEngine(data->engine()->qmlEngine(), uri); } void QQmlTypeLoader::initializeEngine(QQmlEngineExtensionInterface *iface, const char *uri) @@ -647,11 +649,10 @@ void QQmlTypeLoader::clearQmldirInfo() } static void initializeConfiguredData( - const QQmlTypeLoaderConfiguredDataPtr &data, QQmlEngine *engine) + const QQmlTypeLoaderConfiguredDataPtr &data, QV4::ExecutionEngine *engine) { - QV4::ExecutionEngine *v4 = engine->handle(); - data->diskCacheOptions = v4->diskCacheOptions(); - data->isDebugging = v4->debugger() != nullptr; + data->diskCacheOptions = engine->diskCacheOptions(); + data->isDebugging = engine->debugger() != nullptr; data->initialized = true; } @@ -1201,7 +1202,7 @@ static QStringList parseEnvPath(const QString &envImportPath) /*! Constructs a new type loader that uses the given \a engine. */ -QQmlTypeLoader::QQmlTypeLoader(QQmlEngine *engine) +QQmlTypeLoader::QQmlTypeLoader(QV4::ExecutionEngine *engine) : m_data(engine) { QQmlTypeLoaderConfiguredDataPtr data(&m_data); @@ -1724,6 +1725,15 @@ void QQmlTypeLoader::setQmldirContent(const QString &url, const QString &content qmldir->setContent(url, content); } +template<typename Blob> +void clearBlobs(QHash<QUrl, QQmlRefPointer<Blob>> *blobs) +{ + std::for_each(blobs->cbegin(), blobs->cend(), [](const QQmlRefPointer<Blob> &blob) { + blob->resetTypeLoader(); + }); + blobs->clear(); +} + /*! Clears cached information about loaded files, including any type data, scripts and qmldir information. @@ -1745,10 +1755,10 @@ void QQmlTypeLoader::clearCache() threadData->importQmlDirCache.clear(); QQmlTypeLoaderSharedDataPtr data(&m_data); - data->typeCache.clear(); + clearBlobs(&data->typeCache); + clearBlobs(&data->scriptCache); + clearBlobs(&data->qmldirCache); data->typeCacheTrimThreshold = QQmlTypeLoaderSharedData::MinimumTypeCacheTrimThreshold; - data->scriptCache.clear(); - data->qmldirCache.clear(); data->importDirCache.clear(); // The thread will auto-restart next time we need it. diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h index 757c5412bc..d207acdf34 100644 --- a/src/qml/qml/qqmltypeloader_p.h +++ b/src/qml/qml/qqmltypeloader_p.h @@ -129,24 +129,24 @@ public: QQmlMetaType::CachedUnitLookupError m_cachedUnitStatus = QQmlMetaType::CachedUnitLookupError::NoError; }; - QQmlTypeLoader(QQmlEngine *); + QQmlTypeLoader(QV4::ExecutionEngine *engine); ~QQmlTypeLoader(); template< typename Engine, typename EnginePrivate = QQmlEnginePrivate, - typename = std::enable_if_t<std::is_same_v<Engine, QQmlEngine>>> + typename = std::enable_if_t<std::is_base_of_v<QJSEngine, Engine>>> static QQmlTypeLoader *get(Engine *engine) { - return get(EnginePrivate::get(engine)); + return engine->handle()->typeLoader(); } template< typename Engine, - typename = std::enable_if_t<std::is_same_v<Engine, QQmlEnginePrivate>>> + typename = std::enable_if_t<std::is_base_of_v<QJSEnginePrivate, Engine>>> static QQmlTypeLoader *get(Engine *engine) { - return &engine->typeLoader; + return Engine::get(engine)->handle()->typeLoader(); } static void sanitizeUNCPath(QString *path) @@ -298,7 +298,7 @@ private: }; QQmlTypeLoaderThread *thread() const { return m_data.thread(); } - QQmlEngine *engine() const { return m_data.engine(); } + QV4::ExecutionEngine *engine() const { return m_data.engine(); } void startThread(); void shutdownThread(); diff --git a/src/qml/qml/qqmltypeloaderdata.cpp b/src/qml/qml/qqmltypeloaderdata.cpp index 4fcece621c..6743cc4d41 100644 --- a/src/qml/qml/qqmltypeloaderdata.cpp +++ b/src/qml/qml/qqmltypeloaderdata.cpp @@ -10,9 +10,8 @@ QT_BEGIN_NAMESPACE -QQmlTypeLoaderLockedData::QQmlTypeLoaderLockedData(QQmlEngine *engine) +QQmlTypeLoaderLockedData::QQmlTypeLoaderLockedData(QV4::ExecutionEngine *engine) : m_engine(engine) -{ -} +{} QT_END_NAMESPACE diff --git a/src/qml/qml/qqmltypeloaderdata_p.h b/src/qml/qml/qqmltypeloaderdata_p.h index fa63a81003..dc2cf7f549 100644 --- a/src/qml/qml/qqmltypeloaderdata_p.h +++ b/src/qml/qml/qqmltypeloaderdata_p.h @@ -148,20 +148,20 @@ class QQmlTypeLoaderLockedData Q_DISABLE_COPY_MOVE(QQmlTypeLoaderLockedData) public: - QQmlTypeLoaderLockedData(QQmlEngine *engine); + QQmlTypeLoaderLockedData(QV4::ExecutionEngine *engine); QQmlTypeLoaderThread *thread() const { return m_thread; } void createThread(QQmlTypeLoader *loader) { - Q_ASSERT(m_engine->thread()->isCurrentThread()); + Q_ASSERT(isCurrentJsEngineThread()); m_thread = new QQmlTypeLoaderThread(loader); m_thread->startup(); } void deleteThread() { - Q_ASSERT(m_engine->thread()->isCurrentThread()); + Q_ASSERT(isCurrentJsEngineThread()); Q_ASSERT(m_thread); // Shut it down first, then set it to nullptr, then delete it. @@ -171,13 +171,23 @@ public: delete std::exchange(m_thread, nullptr); } - QQmlEngine *engine() const + QV4::ExecutionEngine *engine() const { - Q_ASSERT(m_engine->thread()->isCurrentThread()); + Q_ASSERT(isCurrentJsEngineThread()); return m_engine; } private: + bool isCurrentJsEngineThread() const + { + if (QJSEngine *jsEngine = m_engine->jsEngine()) + return jsEngine->thread()->isCurrentThread(); + + // If we can't determine the thread, assume it's the right one + return true; + } + + QQmlTypeLoaderSharedData m_sharedData; QQmlTypeLoaderThreadData m_threadData; QQmlTypeLoaderConfiguredData m_configuredData; @@ -185,7 +195,7 @@ private: QQmlTypeLoaderNetworkAccessManagerData m_networkAccessManagerData; #endif - QQmlEngine *m_engine = nullptr; + QV4::ExecutionEngine *m_engine = nullptr; QQmlTypeLoaderThread *m_thread = nullptr; }; diff --git a/src/qml/qml/qqmltypeloaderthread.cpp b/src/qml/qml/qqmltypeloaderthread.cpp index 39a88de0c8..0fe5bf83b9 100644 --- a/src/qml/qml/qqmltypeloaderthread.cpp +++ b/src/qml/qml/qqmltypeloaderthread.cpp @@ -141,8 +141,8 @@ void QQmlTypeLoaderThread::initializeExtensionMain(QQmlExtensionInterface *iface const char *uri) { // We can use m_engine because we're on the engine thread. - QQmlEngine *engine = m_loader->engine(); - Q_ASSERT(engine->thread() == QThread::currentThread()); + QQmlEngine *engine = m_loader->engine()->qmlEngine(); + Q_ASSERT(engine && engine->thread() == QThread::currentThread()); iface->initializeEngine(engine, uri); } @@ -150,8 +150,8 @@ void QQmlTypeLoaderThread::initializeEngineExtensionMain(QQmlEngineExtensionInte const char *uri) { // We can use m_engine because we're on the engine thread. - QQmlEngine *engine = m_loader->engine(); - Q_ASSERT(engine->thread() == QThread::currentThread()); + QQmlEngine *engine = m_loader->engine()->qmlEngine(); + Q_ASSERT(engine && engine->thread() == QThread::currentThread()); iface->initializeEngine(engine, uri); } diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp index c56ed6e59d..826748dca1 100644 --- a/src/qml/qml/qqmltypewrapper.cpp +++ b/src/qml/qml/qqmltypewrapper.cpp @@ -82,12 +82,12 @@ QQmlType Heap::QQmlTypeWrapper::type() const } QQmlTypeNameCache::Result Heap::QQmlTypeWrapper::queryNamespace( - const QV4::String *name, QQmlEnginePrivate *enginePrivate) const + const QV4::String *name, QV4::ExecutionEngine *engine) const { Q_ASSERT(kind() == Namespace); Q_ASSERT(n.typeNamespace); Q_ASSERT(n.importNamespace); - return n.typeNamespace->query(name, n.importNamespace, QQmlTypeLoader::get(enginePrivate)); + return n.typeNamespace->query(name, n.importNamespace, engine->typeLoader()); } @@ -155,7 +155,7 @@ const QMetaObject *QQmlTypeWrapper::metaObject() const return metaObjectCandidate; } - return type.attachedPropertiesType(QQmlEnginePrivate::get(engine()->qmlEngine())); + return type.attachedPropertiesType(engine()->typeLoader()); } QObject *QQmlTypeWrapper::object() const @@ -164,13 +164,12 @@ QObject *QQmlTypeWrapper::object() const if (!type.isValid()) return nullptr; - QQmlEnginePrivate *qmlEngine = QQmlEnginePrivate::get(engine()->qmlEngine()); if (type.isSingleton()) - return qmlEngine->singletonInstance<QObject *>(type); + return QQmlEnginePrivate::get(engine()->qmlEngine())->singletonInstance<QObject *>(type); return qmlAttachedPropertiesObject( d()->object, - type.attachedPropertiesFunction(qmlEngine)); + type.attachedPropertiesFunction(engine()->typeLoader())); } QObject* QQmlTypeWrapper::singletonObject() const @@ -184,14 +183,14 @@ QObject* QQmlTypeWrapper::singletonObject() const QVariant QQmlTypeWrapper::toVariant() const { - QQmlEnginePrivate *e = QQmlEnginePrivate::get(engine()->qmlEngine()); const QQmlType type = d()->type(); if (!isSingleton()) { return QVariant::fromValue(qmlAttachedPropertiesObject( - d()->object, type.attachedPropertiesFunction(e))); + d()->object, type.attachedPropertiesFunction(engine()->typeLoader()))); } + QQmlEnginePrivate *e = QQmlEnginePrivate::get(engine()->qmlEngine()); if (type.isQJSValueSingleton()) return QVariant::fromValue<QJSValue>(e->singletonInstance<QJSValue>(type)); @@ -323,15 +322,15 @@ ReturnedValue QQmlTypeWrapper::virtualGet(const Managed *m, PropertyKey id, cons = w->d()->typeNameMode() == Heap::QQmlTypeWrapper::IncludeEnums; if (includeEnums && name->startsWithUpper()) { bool ok = false; - int value = enumForSingleton(&enginePrivate->typeLoader, name, type, &ok); + int value = enumForSingleton(v4->typeLoader(), name, type, &ok); if (ok) return QV4::Value::fromInt32(value).asReturnedValue(); - value = type.scopedEnumIndex(&enginePrivate->typeLoader, name, &ok); + value = type.scopedEnumIndex(v4->typeLoader(), name, &ok); if (ok) return createEnumWrapper(v4, scope, type, value, true); - value = type.unscopedEnumIndex(&enginePrivate->typeLoader, name, &ok); + value = type.unscopedEnumIndex(v4->typeLoader(), name, &ok); if (ok) return createEnumWrapper(v4, scope, type, value, false); } @@ -362,15 +361,15 @@ ReturnedValue QQmlTypeWrapper::virtualGet(const Managed *m, PropertyKey id, cons if (name->startsWithUpper()) { bool ok = false; - int value = type.enumValue(&enginePrivate->typeLoader, name, &ok); + int value = type.enumValue(v4->typeLoader(), name, &ok); if (ok) return QV4::Value::fromInt32(value).asReturnedValue(); - value = type.scopedEnumIndex(&enginePrivate->typeLoader, name, &ok); + value = type.scopedEnumIndex(v4->typeLoader(), name, &ok); if (ok) return createEnumWrapper(v4, scope, type, value, true); - value = type.unscopedEnumIndex(&enginePrivate->typeLoader, name, &ok); + value = type.unscopedEnumIndex(v4->typeLoader(), name, &ok); if (ok) return createEnumWrapper(v4, scope, type, value, false); @@ -378,8 +377,7 @@ ReturnedValue QQmlTypeWrapper::virtualGet(const Managed *m, PropertyKey id, cons } else if (w->d()->object) { QObject *ao = qmlAttachedPropertiesObject( - object, - type.attachedPropertiesFunction(QQmlEnginePrivate::get(v4->qmlEngine()))); + object, type.attachedPropertiesFunction(v4->typeLoader())); if (ao) return QV4::QObjectWrapper::getQmlProperty( v4, context, w->d(), ao, name, QV4::QObjectWrapper::AttachMethods, @@ -394,7 +392,7 @@ ReturnedValue QQmlTypeWrapper::virtualGet(const Managed *m, PropertyKey id, cons // Fall through to base implementation } else if (w->d()->kind() == Heap::QQmlTypeWrapper::Namespace) { - const QQmlTypeNameCache::Result r = w->d()->queryNamespace(name, enginePrivate); + const QQmlTypeNameCache::Result r = w->d()->queryNamespace(name, v4); if (r.isValid()) { if (r.type.isValid()) { return create(scope.engine, object, r.type, w->d()->typeNameMode()); @@ -442,9 +440,8 @@ bool QQmlTypeWrapper::virtualPut(Managed *m, PropertyKey id, const Value &value, QQmlType type = w->d()->type(); if (type.isValid() && !type.isSingleton() && w->d()->object) { QObject *object = w->d()->object; - QQmlEngine *e = scope.engine->qmlEngine(); QObject *ao = qmlAttachedPropertiesObject( - object, type.attachedPropertiesFunction(QQmlEnginePrivate::get(e))); + object, type.attachedPropertiesFunction(scope.engine->typeLoader())); if (ao) return QV4::QObjectWrapper::setQmlProperty( scope.engine, context, ao, name, QV4::QObjectWrapper::NoFlag, value); @@ -521,8 +518,8 @@ static ReturnedValue instanceOfQObject( if (!theirDData->compilationUnit) return Encode(false); - QQmlEnginePrivate *qenginepriv = QQmlEnginePrivate::get(engine->qmlEngine()); - QQmlRefPointer<QQmlTypeData> td = qenginepriv->typeLoader.getType(typeWrapper->d()->type().sourceUrl()); + QQmlRefPointer<QQmlTypeData> td + = engine->typeLoader()->getType(typeWrapper->d()->type().sourceUrl()); if (CompiledData::CompilationUnit *cu = td->compilationUnit()) myQmlType = QQmlMetaType::metaObjectForType(cu->metaType()); else @@ -663,7 +660,7 @@ ReturnedValue QQmlTypeWrapper::virtualResolveLookupGetter(const Object *object, if (name->startsWithUpper()) { bool ok = false; - QQmlTypeLoader *typeLoader = &QQmlEnginePrivate::get(engine->qmlEngine())->typeLoader; + QQmlTypeLoader *typeLoader = engine->typeLoader(); int value = type.enumValue(typeLoader, name, &ok); if (ok) { lookup->qmlEnumValueLookup.ic.set(engine, This->internalClass()); @@ -698,8 +695,7 @@ ReturnedValue QQmlTypeWrapper::virtualResolveLookupGetter(const Object *object, // Fall through to base implementation } else if (w->d()->object) { QObject *ao = qmlAttachedPropertiesObject( - w->d()->object, - type.attachedPropertiesFunction(QQmlEnginePrivate::get(engine->qmlEngine()))); + w->d()->object, type.attachedPropertiesFunction(engine->typeLoader())); if (ao) { // ### QTBUG-126877: Optimize this case lookup->call = QV4::Lookup::Call::GetterQObjectPropertyFallback; @@ -876,7 +872,7 @@ ReturnedValue QQmlEnumWrapper::virtualGet(const Managed *m, PropertyKey id, cons int index = resource->d()->enumIndex; bool ok = false; - auto *typeLoader = &QQmlEnginePrivate::get(v4->qmlEngine())->typeLoader; + auto *typeLoader = v4->typeLoader(); int value = resource->d()->scoped ? type.scopedEnumValue(typeLoader, index, name, &ok) : type.unscopedEnumValue(typeLoader, index, name, &ok); if (hasProperty) diff --git a/src/qml/qml/qqmltypewrapper_p.h b/src/qml/qml/qqmltypewrapper_p.h index 454bcf7584..9e20be17ac 100644 --- a/src/qml/qml/qqmltypewrapper_p.h +++ b/src/qml/qml/qqmltypewrapper_p.h @@ -72,7 +72,7 @@ struct QQmlTypeWrapper : FunctionObject { void warnIfUncreatable() const; QQmlTypeNameCache::Result queryNamespace( - const QV4::String *name, QQmlEnginePrivate *enginePrivate) const; + const QV4::String *name, QV4::ExecutionEngine *engine) const; QV4QPointer<QObject> object; diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp index d2d663bfc3..f5eb50449d 100644 --- a/src/qml/qml/qqmlxmlhttprequest.cpp +++ b/src/qml/qml/qqmlxmlhttprequest.cpp @@ -1670,7 +1670,8 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject Scope scope(f->engine()); const QQmlXMLHttpRequestCtor *ctor = static_cast<const QQmlXMLHttpRequestCtor *>(f); - QQmlXMLHttpRequest *r = new QQmlXMLHttpRequest(scope.engine->networkAccessManager(scope.engine), scope.engine); + QQmlXMLHttpRequest *r = new QQmlXMLHttpRequest( + scope.engine->getNetworkAccessManager(), scope.engine); Scoped<QQmlXMLHttpRequestWrapper> w(scope, scope.engine->memoryManager->allocate<QQmlXMLHttpRequestWrapper>(r)); ScopedObject proto(scope, ctor->d()->proto); w->setPrototypeUnchecked(proto); diff --git a/src/qmlmeta/types/qqmlbind.cpp b/src/qmlmeta/types/qqmlbind.cpp index 0902778fe7..f82fb2d938 100644 --- a/src/qmlmeta/types/qqmlbind.cpp +++ b/src/qmlmeta/types/qqmlbind.cpp @@ -1000,8 +1000,7 @@ void QQmlBindPrivate::decodeBinding( QQmlContext *context = qmlContext(q); QObject *attachedObject = qmlAttachedPropertiesObject( - q, attachedType.attachedPropertiesFunction( - QQmlEnginePrivate::get(context->engine()))); + q, attachedType.attachedPropertiesFunction(QQmlTypeLoader::get(context->engine()))); if (!attachedObject) { qmlWarning(q).nospace() <<"Could not create attached properties object '" << attachedType.typeName() << "'"; diff --git a/src/qmlworkerscript/qquickworkerscript.cpp b/src/qmlworkerscript/qquickworkerscript.cpp index dbb8281a99..14cd783c32 100644 --- a/src/qmlworkerscript/qquickworkerscript.cpp +++ b/src/qmlworkerscript/qquickworkerscript.cpp @@ -105,7 +105,11 @@ public: WorkerDestroyEvent() : QEvent(QEvent::Type(WorkerEventType::Destroy)) {} }; -struct WorkerScript : public QV4::ExecutionEngine::Deletable +struct WorkerScript + : public QV4::ExecutionEngine::Deletable +#if QT_CONFIG(qml_network) + , public QQmlNetworkAccessManagerFactory +#endif { WorkerScript(QV4::ExecutionEngine *); ~WorkerScript() = default; @@ -113,7 +117,7 @@ struct WorkerScript : public QV4::ExecutionEngine::Deletable QQuickWorkerScriptEnginePrivate *p = nullptr; QQuickWorkerScript *owner = nullptr; #if QT_CONFIG(qml_network) - QScopedPointer<QNetworkAccessManager> scriptLocalNAM; + QNetworkAccessManager *create(QObject *parent) final; #endif }; @@ -222,6 +226,10 @@ QV4::ExecutionEngine *QQuickWorkerScriptEnginePrivate::workerEngine(int id) WorkerScript *script = workerScriptExtension(engine); script->owner = owner; script->p = this; +#if QT_CONFIG(qml_network) + // Eagerly create a network access manager that can outlive the parent engine. + engine->getNetworkAccessManager(); +#endif *it = engine; return engine; } @@ -305,7 +313,7 @@ void QQuickWorkerScriptEnginePrivate::reportScriptException(WorkerScript *script QQuickWorkerScriptEngine::QQuickWorkerScriptEngine(QQmlEngine *parent) : QThread(parent) - , d(new QQuickWorkerScriptEnginePrivate(&QQmlEnginePrivate::get(parent)->typeLoader)) + , d(new QQuickWorkerScriptEnginePrivate(QQmlTypeLoader::get(parent))) { connect(d, SIGNAL(stopThread()), this, SLOT(quit()), Qt::DirectConnection); QMutexLocker locker(&d->m_lock); @@ -348,17 +356,17 @@ WorkerScript::WorkerScript(QV4::ExecutionEngine *engine) engine->globalObject->put(workerScriptName, api); #if QT_CONFIG(qml_network) - engine->networkAccessManager = [](QV4::ExecutionEngine *engine) { - WorkerScript *workerScript = workerScriptExtension(engine); - if (!workerScript->scriptLocalNAM) { - workerScript->scriptLocalNAM.reset( - workerScript->p->m_typeLoader->createNetworkAccessManager(workerScript->p)); - } - return workerScript->scriptLocalNAM.get(); - }; + engine->typeLoader()->setNetworkAccessManagerFactory(this); #endif // qml_network } +#if QT_CONFIG(qml_network) +QNetworkAccessManager *WorkerScript::create(QObject *parent) +{ + return p->m_typeLoader->createNetworkAccessManager(parent); +} +#endif + int QQuickWorkerScriptEngine::registerWorkerScript(QQuickWorkerScript *owner) { const int id = d->m_nextId++; diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp index 347e0e3936..3f412bf84a 100644 --- a/src/quick/util/qquickpixmapcache.cpp +++ b/src/quick/util/qquickpixmapcache.cpp @@ -443,7 +443,7 @@ QNetworkAccessManager *QQuickPixmapReader::networkAccessManager() { if (!accessManager) { Q_ASSERT(readerThreadExecutionEnforcer()); - accessManager = QQmlEnginePrivate::get(engine)->typeLoader.createNetworkAccessManager( + accessManager = QQmlTypeLoader::get(engine)->createNetworkAccessManager( readerThreadExecutionEnforcer()); } return accessManager; diff --git a/src/quicktemplates/qquickspinbox.cpp b/src/quicktemplates/qquickspinbox.cpp index 8b8f1c4d51..ececf39883 100644 --- a/src/quicktemplates/qquickspinbox.cpp +++ b/src/quicktemplates/qquickspinbox.cpp @@ -432,9 +432,8 @@ QString QQuickSpinBoxPrivate::evaluateTextFromValue(int val) const if (engine && textFromValue.isCallable()) { QJSValue loc; #if QT_CONFIG(qml_locale) - QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(engine); loc = QJSValuePrivate::fromReturnedValue( - v4->fromData(QMetaType::fromType<QLocale>(), &locale)); + engine->handle()->fromData(QMetaType::fromType<QLocale>(), &locale)); #endif text = textFromValue.call(QJSValueList() << val << loc).toString(); } else { @@ -451,9 +450,8 @@ int QQuickSpinBoxPrivate::evaluateValueFromText(const QString &text) const if (engine && valueFromText.isCallable()) { QJSValue loc; #if QT_CONFIG(qml_locale) - QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(engine); loc = QJSValuePrivate::fromReturnedValue( - v4->fromData(QMetaType::fromType<QLocale>(), &locale)); + engine->handle()->fromData(QMetaType::fromType<QLocale>(), &locale)); #endif value = valueFromText.call(QJSValueList() << text << loc).toInt(); } else { diff --git a/src/quicktemplates/qquickstackelement.cpp b/src/quicktemplates/qquickstackelement.cpp index 141fa1819d..04f1d92d8d 100644 --- a/src/quicktemplates/qquickstackelement.cpp +++ b/src/quicktemplates/qquickstackelement.cpp @@ -207,14 +207,13 @@ void QQuickStackElement::initialize(RequiredProperties *requiredProperties) if (!properties.isUndefined()) { QQmlEngine *engine = qmlEngine(view); Q_ASSERT(engine); - QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(engine); - Q_ASSERT(v4); - QV4::Scope scope(v4); + QV4::Scope scope(engine->handle()); + Q_ASSERT(scope.engine); QV4::ScopedValue ipv(scope, properties.value()); QV4::Scoped<QV4::QmlContext> qmlContext(scope, qmlCallingContext.value()); - QV4::ScopedValue qmlObject(scope, QV4::QObjectWrapper::wrap(v4, item)); + QV4::ScopedValue qmlObject(scope, QV4::QObjectWrapper::wrap(scope.engine, item)); QQmlComponentPrivate::setInitialProperties( - v4, qmlContext, qmlObject, ipv, requiredProperties, item, + scope.engine, qmlContext, qmlObject, ipv, requiredProperties, item, component ? QQmlComponentPrivate::get(component)->creator() : nullptr); properties.clear(); } diff --git a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp index 86de5c3f32..0d83f9a33c 100644 --- a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp +++ b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp @@ -461,12 +461,14 @@ public: Q_INVOKABLE bool isTypeLoaded(QString file) { - return QQmlEnginePrivate::get(engine)->isTypeLoaded(tst_qqmlengine::instance()->testFileUrl(file)); + return QQmlTypeLoader::get(engine) + ->isTypeLoaded(tst_qqmlengine::instance()->testFileUrl(file)); } Q_INVOKABLE bool isScriptLoaded(QString file) { - return QQmlEnginePrivate::get(engine)->isScriptLoaded(tst_qqmlengine::instance()->testFileUrl(file)); + return QQmlTypeLoader::get(engine) + ->isScriptLoaded(tst_qqmlengine::instance()->testFileUrl(file)); } Q_INVOKABLE void beginIncubation() @@ -1113,22 +1115,22 @@ void tst_qqmlengine::componentFromEval() void tst_qqmlengine::qrcUrls() { QQmlEngine engine; - QQmlEnginePrivate *pEngine = QQmlEnginePrivate::get(&engine); + QQmlTypeLoader *typeLoader = QQmlTypeLoader::get(&engine); { - QQmlRefPointer<QQmlTypeData> oneQml(pEngine->typeLoader.getType(QUrl("qrc:/qrcurls.qml"))); + QQmlRefPointer<QQmlTypeData> oneQml(typeLoader->getType(QUrl("qrc:/qrcurls.qml"))); QVERIFY(oneQml.data() != nullptr); QVERIFY(!oneQml->backupSourceCode().isValid()); - QQmlRefPointer<QQmlTypeData> twoQml(pEngine->typeLoader.getType(QUrl("qrc:///qrcurls.qml"))); + QQmlRefPointer<QQmlTypeData> twoQml(typeLoader->getType(QUrl("qrc:///qrcurls.qml"))); QVERIFY(twoQml.data() != nullptr); QCOMPARE(oneQml.data(), twoQml.data()); } { - QQmlRefPointer<QQmlTypeData> oneJS(pEngine->typeLoader.getType(QUrl("qrc:/qrcurls.js"))); + QQmlRefPointer<QQmlTypeData> oneJS(typeLoader->getType(QUrl("qrc:/qrcurls.js"))); QVERIFY(oneJS.data() != nullptr); QVERIFY(!oneJS->backupSourceCode().isValid()); - QQmlRefPointer<QQmlTypeData> twoJS(pEngine->typeLoader.getType(QUrl("qrc:///qrcurls.js"))); + QQmlRefPointer<QQmlTypeData> twoJS(typeLoader->getType(QUrl("qrc:///qrcurls.js"))); QVERIFY(twoJS.data() != nullptr); QCOMPARE(oneJS.data(), twoJS.data()); } diff --git a/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp b/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp index 25275a4028..0f1956c0cd 100644 --- a/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp +++ b/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp @@ -104,7 +104,7 @@ void tst_QQmlImport::envResourceImportPath() qputenv("QML_IMPORT_PATH", envPaths.join(QDir::listSeparator()).toUtf8()); QQmlEngine engine; - const QStringList importPaths = QQmlEnginePrivate::get(&engine)->typeLoader.importPathList(); + const QStringList importPaths = QQmlTypeLoader::get(&engine)->importPathList(); for (const QString &path : envPaths) QVERIFY((importPaths.contains(path.startsWith(u':') ? QLatin1String("qrc") + path : path))); diff --git a/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp b/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp index b1e1a8c8db..2197a1b372 100644 --- a/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp +++ b/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp @@ -1161,7 +1161,7 @@ void tst_qqmlincubator::garbageCollection() // turn the last strong reference to the incubator into a weak one and collect QV4::WeakValue weakIncubatorRef; - weakIncubatorRef.set(QQmlEnginePrivate::getV4Engine(&engine), QJSValuePrivate::asReturnedValue(&strongRef)); + weakIncubatorRef.set(engine.handle(), QJSValuePrivate::asReturnedValue(&strongRef)); strongRef = QJSValue(); incubatorVariant.clear(); diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index 09c7e75966..f8081b697e 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -2755,8 +2755,7 @@ void tst_qqmllanguage::scriptStringWithoutSourceCode() QUrl url = testFileUrl("scriptString7.qml"); QScopedPointer<const QV4::CompiledData::Unit, FreeUnitData> readOnlyQmlUnit; { - QQmlEnginePrivate *eng = QQmlEnginePrivate::get(&engine); - QQmlRefPointer<QQmlTypeData> td = eng->typeLoader.getType(url); + QQmlRefPointer<QQmlTypeData> td = QQmlTypeLoader::get(&engine)->getType(url); Q_ASSERT(td); QVERIFY(!td->backupSourceCode().isValid()); diff --git a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp index c0fa508acf..e7356cc2b0 100644 --- a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp +++ b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp @@ -602,7 +602,7 @@ void tst_qqmlmetatype::unregisterAttachedProperties() const QQmlType attachedType = QQmlMetaType::qmlType("QtQuick/KeyNavigation", QTypeRevision::fromVersion(2, 2)); - QCOMPARE(attachedType.attachedPropertiesType(QQmlEnginePrivate::get(&e)), + QCOMPARE(attachedType.attachedPropertiesType(QQmlTypeLoader::get(&e)), attachedType.metaObject()); QScopedPointer<QObject> obj(c.create()); diff --git a/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp b/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp index 69dbd6179b..40c7b5d519 100644 --- a/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp +++ b/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp @@ -57,8 +57,8 @@ void tst_qqmltranslation::translation() if (verifyCompiledData) { QQmlContext *context = qmlContext(object.get()); - QQmlEnginePrivate *engine = QQmlEnginePrivate::get(context->engine()); - QQmlRefPointer<QQmlTypeData> typeData = engine->typeLoader.getType(context->baseUrl()); + QQmlRefPointer<QQmlTypeData> typeData + = QQmlTypeLoader::get(context->engine())->getType(context->baseUrl()); QVERIFY(!typeData->backupSourceCode().isValid()); QV4::CompiledData::CompilationUnit *compilationUnit = typeData->compilationUnit(); QVERIFY(compilationUnit); @@ -122,8 +122,8 @@ void tst_qqmltranslation::idTranslation() { QQmlContext *context = qmlContext(object.get()); - QQmlEnginePrivate *engine = QQmlEnginePrivate::get(context->engine()); - QQmlRefPointer<QQmlTypeData> typeData = engine->typeLoader.getType(context->baseUrl()); + QQmlRefPointer<QQmlTypeData> typeData + = QQmlTypeLoader::get(context->engine())->getType(context->baseUrl()); QVERIFY(!typeData->backupSourceCode().isValid()); QV4::CompiledData::CompilationUnit *compilationUnit = typeData->compilationUnit(); QVERIFY(compilationUnit); diff --git a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp index 02435f7cdd..995867ea9f 100644 --- a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp +++ b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp @@ -109,14 +109,14 @@ void tst_QQMLTypeLoader::loadComponentSynchronously() void tst_QQMLTypeLoader::trimCache() { QQmlEngine engine; - QQmlTypeLoader &loader = QQmlEnginePrivate::get(&engine)->typeLoader; + QQmlTypeLoader *loader = QQmlTypeLoader::get(&engine); QVector<QQmlTypeData *> releaseLater; QVector<QV4::CompiledData::CompilationUnit *> releaseCompilationUnitLater; for (int i = 0; i < 256; ++i) { QUrl url = testFileUrl("trim_cache.qml"); url.setQuery(QString::number(i)); - QQmlTypeData *data = loader.getType(url).take(); + QQmlTypeData *data = loader->getType(url).take(); // Backup source code should be dropped right after loading, even without cache trimming. QVERIFY(!data->backupSourceCode().isValid()); @@ -142,9 +142,9 @@ void tst_QQMLTypeLoader::trimCache() QUrl url = testFileUrl("trim_cache.qml"); url.setQuery(QString::number(i)); if (i % 5 == 0) - QVERIFY(loader.isTypeLoaded(url)); + QVERIFY(loader->isTypeLoaded(url)); else if (i < 128) - QVERIFY(!loader.isTypeLoaded(url)); + QVERIFY(!loader->isTypeLoaded(url)); // The cache is free to keep the others. } @@ -159,13 +159,13 @@ void tst_QQMLTypeLoader::trimCache2() { QScopedPointer<QQuickView> window(new QQuickView()); window->setSource(testFileUrl("trim_cache2.qml")); - QQmlTypeLoader &loader = QQmlEnginePrivate::get(window->engine())->typeLoader; + QQmlTypeLoader *loader = QQmlTypeLoader::get(window->engine()); // in theory if gc has already run this could be false // QCOMPARE(loader.isTypeLoaded(testFileUrl("MyComponent2.qml")), true); window->engine()->collectGarbage(); QTest::qWait(1); // force event loop window->engine()->trimComponentCache(); - QCOMPARE(loader.isTypeLoaded(testFileUrl("MyComponent2.qml")), false); + QCOMPARE(loader->isTypeLoaded(testFileUrl("MyComponent2.qml")), false); } // test trimming the cache of an item that contains sub-items created via incubation @@ -173,8 +173,8 @@ void tst_QQMLTypeLoader::trimCache3() { QScopedPointer<QQuickView> window(new QQuickView()); window->setSource(testFileUrl("trim_cache3.qml")); - QQmlTypeLoader &loader = QQmlEnginePrivate::get(window->engine())->typeLoader; - QCOMPARE(loader.isTypeLoaded(testFileUrl("ComponentWithIncubator.qml")), true); + QQmlTypeLoader *loader = QQmlTypeLoader::get(window->engine()); + QCOMPARE(loader->isTypeLoaded(testFileUrl("ComponentWithIncubator.qml")), true); QQmlProperty::write(window->rootObject(), "source", QString()); @@ -185,7 +185,7 @@ void tst_QQMLTypeLoader::trimCache3() window->engine()->trimComponentCache(); - QCOMPARE(loader.isTypeLoaded(testFileUrl("ComponentWithIncubator.qml")), false); + QCOMPARE(loader->isTypeLoaded(testFileUrl("ComponentWithIncubator.qml")), false); } void tst_QQMLTypeLoader::checkSingleton(const QString &dataDirectory) @@ -739,8 +739,8 @@ static void getCompilationUnitAndRuntimeInfo(QQmlRefPointer<QV4::ExecutableCompi QList<int> &runtimeFunctionIndices, const QUrl &url, QQmlEngine *engine) { - QQmlTypeLoader &loader = QQmlEnginePrivate::get(engine)->typeLoader; - auto typeData = loader.getType(url); + QQmlTypeLoader *loader = QQmlTypeLoader::get(engine); + auto typeData = loader->getType(url); QVERIFY(typeData); QVERIFY(!typeData->backupSourceCode().isValid()); diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp index c6c96dcd90..36907a7edf 100644 --- a/tools/qmlplugindump/main.cpp +++ b/tools/qmlplugindump/main.cpp @@ -142,12 +142,13 @@ void collectReachableMetaObjects(QObject *object, QSet<const QMetaObject *> *met } } -void collectReachableMetaObjects(QQmlEnginePrivate *engine, const QQmlType &ty, QSet<const QMetaObject *> *metas, const QmlVersionInfo& info) +void collectReachableMetaObjects( + QQmlTypeLoader *typeLoader, const QQmlType &ty, QSet<const QMetaObject *> *metas, + const QmlVersionInfo& info) { collectReachableMetaObjects(ty.baseMetaObject(), metas, info, ty.isExtendedType()); - if (ty.attachedPropertiesType(engine) && matchingImportUri(ty, info)) { - collectReachableMetaObjects(ty.attachedPropertiesType(engine), metas, info); - } + if (ty.attachedPropertiesType(typeLoader) && matchingImportUri(ty, info)) + collectReachableMetaObjects(ty.attachedPropertiesType(typeLoader), metas, info); } /* When we dump a QMetaObject, we want to list all the types it is exported as. @@ -197,13 +198,14 @@ QByteArray convertToId(const QMetaObject *mo) // Collect all metaobjects for types registered with qmlRegisterType() without parameters -void collectReachableMetaObjectsWithoutQmlName(QQmlEnginePrivate *engine, QSet<const QMetaObject *>& metas, - QMap<QString, QList<QQmlType>> &compositeTypes, const QmlVersionInfo &info) { +void collectReachableMetaObjectsWithoutQmlName( + QQmlTypeLoader *typeLoader, QSet<const QMetaObject *>& metas, + QMap<QString, QList<QQmlType>> &compositeTypes, const QmlVersionInfo &info) { const auto qmlAllTypes = QQmlMetaType::qmlAllTypes(); for (const QQmlType &ty : qmlAllTypes) { if (!metas.contains(ty.baseMetaObject())) { if (!ty.isComposite()) { - collectReachableMetaObjects(engine, ty, &metas, info); + collectReachableMetaObjects(typeLoader, ty, &metas, info); } else if (matchingImportUri(ty, info)) { compositeTypes[ty.elementName()].append(ty); } @@ -211,13 +213,10 @@ void collectReachableMetaObjectsWithoutQmlName(QQmlEnginePrivate *engine, QSet<c } } -QSet<const QMetaObject *> collectReachableMetaObjects(QQmlEngine *engine, - QSet<const QMetaObject *> &noncreatables, - QSet<const QMetaObject *> &singletons, - QMap<QString, QList<QQmlType>> &compositeTypes, - const QmlVersionInfo &info, - const QList<QQmlType> &skip = QList<QQmlType>() - ) +QSet<const QMetaObject *> collectReachableMetaObjects( + QQmlEngine *engine, QSet<const QMetaObject *> &noncreatables, + QSet<const QMetaObject *> &singletons, QMap<QString, QList<QQmlType>> &compositeTypes, + const QmlVersionInfo &info, const QList<QQmlType> &skip = QList<QQmlType>()) { QSet<const QMetaObject *> metas; metas.insert(&Qt::staticMetaObject); @@ -233,7 +232,7 @@ QSet<const QMetaObject *> collectReachableMetaObjects(QQmlEngine *engine, if (!ty.isComposite()) { if (const QMetaObject *mo = ty.baseMetaObject()) qmlTypesByCppName[mo->className()].insert(ty); - collectReachableMetaObjects(QQmlEnginePrivate::get(engine), ty, &metas, info); + collectReachableMetaObjects(QQmlTypeLoader::get(engine), ty, &metas, info); } else { compositeTypes[ty.elementName()].append(ty); } @@ -302,7 +301,7 @@ QSet<const QMetaObject *> collectReachableMetaObjects(QQmlEngine *engine, } } - collectReachableMetaObjectsWithoutQmlName(QQmlEnginePrivate::get(engine), metas, compositeTypes, info); + collectReachableMetaObjectsWithoutQmlName(QQmlTypeLoader::get(engine), metas, compositeTypes, info); return metas; } @@ -535,7 +534,8 @@ public: QByteArray attachedTypeId; }; - void dump(QQmlEnginePrivate *engine, const QMetaObject *meta, bool isUncreatable, bool isSingleton) + void dump(QQmlTypeLoader *typeLoader, const QMetaObject *meta, + bool isUncreatable, bool isSingleton) { qml->writeStartObject("Component"); @@ -548,7 +548,7 @@ public: for (const QQmlType &type : types) { const QMetaObject *extendedObject = type.extensionFunction() ? type.metaObject() : nullptr; QByteArray attachedTypeId; - if (const QMetaObject *attachedType = type.attachedPropertiesType(engine)) { + if (const QMetaObject *attachedType = type.attachedPropertiesType(typeLoader)) { // Can happen when a type is registered that returns itself as attachedPropertiesType() // because there is no creatable type to attach to. if (attachedType != meta) @@ -1355,7 +1355,8 @@ int main(int argc, char *argv[]) if (relocatable) dumper.setRelocatableModuleUri(pluginImportUri); for (const QMetaObject *meta : std::as_const(nameToMeta)) { - dumper.dump(QQmlEnginePrivate::get(&engine), meta, uncreatableMetas.contains(meta), singletonMetas.contains(meta)); + dumper.dump(QQmlTypeLoader::get(&engine), meta, uncreatableMetas.contains(meta), + singletonMetas.contains(meta)); } QMap<QString, QList<QQmlType>>::const_iterator iter = compositeTypes.constBegin(); |
