diff options
author | Morten Johan Sørvig <morten.sorvig@qt.io> | 2018-06-04 10:45:14 +0200 |
---|---|---|
committer | Morten Johan Sørvig <morten.sorvig@qt.io> | 2018-06-04 10:45:14 +0200 |
commit | 3ca5f33c8b9c273f0169ec4c11417328f8071e97 (patch) | |
tree | 155da80482fb4593ca074f7a1bf9b22d031dba4a /src/qml/qml | |
parent | 5f4698c4e7952d64e78e3a06de5ac28d68415b19 (diff) | |
parent | b7a1bcd83a8f68185b617b860cef6f2d2d7c8d9b (diff) |
Merge remote-tracking branch 'gerrit/5.11' into wip/webassembly
Change-Id: I7556ac62fd8e1aeb99186c929f1225f02f9d2430
Diffstat (limited to 'src/qml/qml')
-rw-r--r-- | src/qml/qml/qqmlcontext.cpp | 13 | ||||
-rw-r--r-- | src/qml/qml/qqmlcontext_p.h | 5 | ||||
-rw-r--r-- | src/qml/qml/qqmlengine.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetatype.cpp | 11 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetatype_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 4 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader.cpp | 62 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader_p.h | 6 | ||||
-rw-r--r-- | src/qml/qml/v8/qqmlbuiltinfunctions.cpp | 2 |
9 files changed, 62 insertions, 45 deletions
diff --git a/src/qml/qml/qqmlcontext.cpp b/src/qml/qml/qqmlcontext.cpp index 5dd3278b4c..3dcfa92416 100644 --- a/src/qml/qml/qqmlcontext.cpp +++ b/src/qml/qml/qqmlcontext.cpp @@ -536,7 +536,7 @@ QQmlContextData::QQmlContextData() QQmlContextData::QQmlContextData(QQmlContext *ctxt) : engine(nullptr), isInternal(false), isJSContext(false), isPragmaLibraryContext(false), unresolvedNames(false), hasEmittedDestruction(false), isRootObjectInCreation(false), - publicContext(ctxt), incubator(nullptr), componentObjectIndex(-1), + stronglyReferencedByParent(false), publicContext(ctxt), incubator(nullptr), componentObjectIndex(-1), contextObject(nullptr), nextChild(nullptr), prevChild(nullptr), expressions(nullptr), contextObjects(nullptr), idValues(nullptr), idValueCount(0), componentAttached(nullptr) @@ -577,7 +577,10 @@ void QQmlContextData::invalidate() while (childContexts) { Q_ASSERT(childContexts != this); - childContexts->invalidate(); + if (childContexts->stronglyReferencedByParent && !--childContexts->refCount) + childContexts->destroy(); + else + childContexts->invalidate(); } if (prevChild) { @@ -672,12 +675,16 @@ void QQmlContextData::destroy() delete this; } -void QQmlContextData::setParent(QQmlContextData *p) +void QQmlContextData::setParent(QQmlContextData *p, bool stronglyReferencedByParent) { if (p == parent) return; if (p) { + Q_ASSERT(!parent); parent = p; + this->stronglyReferencedByParent = stronglyReferencedByParent; + if (stronglyReferencedByParent) + ++refCount; // balanced in QQmlContextData::invalidate() engine = p->engine; nextChild = p->childContexts; if (nextChild) nextChild->prevChild = &nextChild; diff --git a/src/qml/qml/qqmlcontext_p.h b/src/qml/qml/qqmlcontext_p.h index 5dfee48848..290b7fc7ee 100644 --- a/src/qml/qml/qqmlcontext_p.h +++ b/src/qml/qml/qqmlcontext_p.h @@ -126,7 +126,7 @@ public: QQmlContextData *parent = nullptr; QQmlEngine *engine; - void setParent(QQmlContextData *); + void setParent(QQmlContextData *, bool stronglyReferencedByParent = false); void refreshExpressions(); void addObject(QObject *); @@ -144,7 +144,8 @@ public: quint32 unresolvedNames:1; // True if expressions in this context failed to resolve a toplevel name quint32 hasEmittedDestruction:1; quint32 isRootObjectInCreation:1; - quint32 dummy:26; + quint32 stronglyReferencedByParent:1; + quint32 dummy:25; QQmlContext *publicContext; // The incubator that is constructing this context if any diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 7e11177caa..b27bf3779a 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -1196,6 +1196,8 @@ void QQmlEnginePrivate::registerFinalizeCallback(QObject *obj, int index) support. The factory must be set before executing the engine. + + \note QQmlEngine does not take ownership of the factory. */ void QQmlEngine::setNetworkAccessManagerFactory(QQmlNetworkAccessManagerFactory *factory) { diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index 8fda7f6f77..d842a7795f 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -424,7 +424,7 @@ QQmlType::QQmlType(QQmlMetaTypeData *data, const QString &elementName, const QQm d->version_min = type.versionMinor; d->extraData.sd->singletonInstanceInfo = new SingletonInstanceInfo; - d->extraData.sd->singletonInstanceInfo->url = type.url; + d->extraData.sd->singletonInstanceInfo->url = QQmlTypeLoader::normalize(type.url); d->extraData.sd->singletonInstanceInfo->typeName = QString::fromUtf8(type.typeName); } @@ -477,7 +477,7 @@ QQmlType::QQmlType(QQmlMetaTypeData *data, const QString &elementName, const QQm d->version_maj = type.versionMajor; d->version_min = type.versionMinor; - d->extraData.fd->url = type.url; + d->extraData.fd->url = QQmlTypeLoader::normalize(type.url); } QQmlType::QQmlType() @@ -1710,7 +1710,7 @@ QQmlType QQmlMetaType::registerCompositeSingletonType(const QQmlPrivate::Registe addTypeToData(dtype.priv(), data); QQmlMetaTypeData::Files *files = fileImport ? &(data->urlToType) : &(data->urlToNonFileImportType); - files->insertMulti(type.url, dtype.priv()); + files->insertMulti(QQmlTypeLoader::normalize(type.url), dtype.priv()); return dtype; } @@ -1731,7 +1731,7 @@ QQmlType QQmlMetaType::registerCompositeType(const QQmlPrivate::RegisterComposit addTypeToData(dtype.priv(), data); QQmlMetaTypeData::Files *files = fileImport ? &(data->urlToType) : &(data->urlToNonFileImportType); - files->insertMulti(type.url, dtype.priv()); + files->insertMulti(QQmlTypeLoader::normalize(type.url), dtype.priv()); return dtype; } @@ -2253,8 +2253,9 @@ QQmlType QQmlMetaType::qmlType(int userType) Returns null if no such type is registered. */ -QQmlType QQmlMetaType::qmlType(const QUrl &url, bool includeNonFileImports /* = false */) +QQmlType QQmlMetaType::qmlType(const QUrl &unNormalizedUrl, bool includeNonFileImports /* = false */) { + const QUrl url = QQmlTypeLoader::normalize(unNormalizedUrl); QMutexLocker lock(metaTypeDataLock()); QQmlMetaTypeData *data = metaTypeData(); diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index cd7afc8a01..51bf485a3e 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -96,7 +96,7 @@ public: static QQmlType qmlType(const QMetaObject *); static QQmlType qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, int version_major, int version_minor); static QQmlType qmlType(int); - static QQmlType qmlType(const QUrl &url, bool includeNonFileImports = false); + static QQmlType qmlType(const QUrl &unNormalizedUrl, bool includeNonFileImports = false); static QQmlPropertyCache *propertyCache(const QMetaObject *metaObject); static QQmlPropertyCache *propertyCache(const QQmlType &type, int minorVersion); diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 7051fb51da..5aaf79c9e5 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -1217,9 +1217,9 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo } ddata = QQmlData::get(instance, /*create*/true); - ddata->lineNumber = obj->location.line; - ddata->columnNumber = obj->location.column; } + ddata->lineNumber = obj->location.line; + ddata->columnNumber = obj->location.column; ddata->setImplicitDestructible(); if (static_cast<quint32>(index) == /*root object*/0 || ddata->rootObjectInCreation) { diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 1cab827b9f..f4c612b187 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -358,9 +358,8 @@ qreal QQmlDataBlob::progress() const /*! Returns the physical url of the data. Initially this is the same as -finalUrl(), but if a network redirect happens while fetching the data, this url -is updated to reflect the new location. Also, if a URL interceptor is set, it -will work on this URL and leave finalUrl() alone. +finalUrl(), but if a URL interceptor is set, it will work on this URL +and leave finalUrl() alone. \sa finalUrl() */ @@ -381,8 +380,12 @@ QString QQmlDataBlob::urlString() const Returns the logical URL to be used for resolving further URLs referred to in the code. -This is the blob url passed to the constructor. If a network redirect -happens while fetching the data, this url remains the same. +This is the blob url passed to the constructor. If a URL interceptor rewrites +the URL, this one stays the same. If a network redirect happens while fetching +the data, this url is updated to reflect the new location. Therefore, if both +an interception and a redirection happen, the final url will indirectly +incorporate the result of the interception, potentially breaking further +lookups. \sa url() */ @@ -1184,15 +1187,15 @@ void QQmlTypeLoader::networkReplyFinished(QNetworkReply *reply) QVariant redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute); if (redirect.isValid()) { QUrl url = reply->url().resolved(redirect.toUrl()); - blob->m_url = url; - blob->m_urlString.clear(); + blob->m_finalUrl = url; + blob->m_finalUrlString.clear(); QNetworkReply *reply = m_thread->networkAccessManager()->get(QNetworkRequest(url)); QObject *nrp = m_thread->networkReplyProxy(); QObject::connect(reply, SIGNAL(finished()), nrp, SLOT(finished())); m_networkReplies.insert(reply, blob); #ifdef DATABLOB_DEBUG - qWarning("QQmlDataBlob: redirected to %s", qPrintable(blob->urlString())); + qWarning("QQmlDataBlob: redirected to %s", qPrintable(blob->finalUrlString())); #endif return; } @@ -1648,14 +1651,24 @@ QQmlImportDatabase *QQmlTypeLoader::importDatabase() const return &QQmlEnginePrivate::get(engine())->importDatabase; } +QUrl QQmlTypeLoader::normalize(const QUrl &unNormalizedUrl) +{ + QUrl normalized(unNormalizedUrl); + if (normalized.scheme() == QLatin1String("qrc")) + normalized.setHost(QString()); // map qrc:///a.qml to qrc:/a.qml + return normalized; +} + /*! Returns a QQmlTypeData for the specified \a url. The QQmlTypeData may be cached. */ -QQmlTypeData *QQmlTypeLoader::getType(const QUrl &url, Mode mode) +QQmlTypeData *QQmlTypeLoader::getType(const QUrl &unNormalizedUrl, Mode mode) { - Q_ASSERT(!url.isRelative() && - (QQmlFile::urlToLocalFileOrQrc(url).isEmpty() || - !QDir::isRelativePath(QQmlFile::urlToLocalFileOrQrc(url)))); + Q_ASSERT(!unNormalizedUrl.isRelative() && + (QQmlFile::urlToLocalFileOrQrc(unNormalizedUrl).isEmpty() || + !QDir::isRelativePath(QQmlFile::urlToLocalFileOrQrc(unNormalizedUrl)))); + + const QUrl url = normalize(unNormalizedUrl); LockHolder<QQmlTypeLoader> holder(this); @@ -1713,11 +1726,13 @@ QQmlTypeData *QQmlTypeLoader::getType(const QByteArray &data, const QUrl &url, M /*! Return a QQmlScriptBlob for \a url. The QQmlScriptData may be cached. */ -QQmlScriptBlob *QQmlTypeLoader::getScript(const QUrl &url) +QQmlScriptBlob *QQmlTypeLoader::getScript(const QUrl &unNormalizedUrl) { - Q_ASSERT(!url.isRelative() && - (QQmlFile::urlToLocalFileOrQrc(url).isEmpty() || - !QDir::isRelativePath(QQmlFile::urlToLocalFileOrQrc(url)))); + Q_ASSERT(!unNormalizedUrl.isRelative() && + (QQmlFile::urlToLocalFileOrQrc(unNormalizedUrl).isEmpty() || + !QDir::isRelativePath(QQmlFile::urlToLocalFileOrQrc(unNormalizedUrl)))); + + const QUrl url = normalize(unNormalizedUrl); LockHolder<QQmlTypeLoader> holder(this); @@ -1833,15 +1848,7 @@ QString QQmlTypeLoader::absoluteFilePath(const QString &path) if (*value) absoluteFilePath = path; } else { - bool exists = false; -#ifdef Q_OS_UNIX - struct stat statBuf; - // XXX Avoid encoding entire path. Should store encoded dirpath in cache - if (::stat(QFile::encodeName(path).constData(), &statBuf) == 0) - exists = S_ISREG(statBuf.st_mode); -#else - exists = QFile::exists(path); -#endif + bool exists = QFile::exists(path); fileSet->insert(fileName, new bool(exists)); if (exists) absoluteFilePath = path; @@ -3010,7 +3017,7 @@ void QQmlScriptBlob::dataReceived(const SourceCodeData &data) return; } - QmlIR::ScriptDirectivesCollector collector(&irUnit.jsParserEngine, &irUnit.jsGenerator); + QmlIR::ScriptDirectivesCollector collector(&irUnit); QList<QQmlError> errors; QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = QV4::Script::precompile( @@ -3026,9 +3033,6 @@ void QQmlScriptBlob::dataReceived(const SourceCodeData &data) unit.adopt(new QV4::CompiledData::CompilationUnit); } irUnit.javaScriptCompilationUnit = unit; - irUnit.imports = collector.imports; - if (collector.hasPragmaLibrary) - irUnit.jsModule.unitFlags |= QV4::CompiledData::Unit::IsSharedLibrary; QmlIR::QmlUnitGenerator qmlGenerator; QV4::CompiledData::Unit *unitData = qmlGenerator.generate(irUnit); diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h index 5988632547..e75719866d 100644 --- a/src/qml/qml/qqmltypeloader_p.h +++ b/src/qml/qml/qqmltypeloader_p.h @@ -305,10 +305,12 @@ public: QQmlImportDatabase *importDatabase() const; - QQmlTypeData *getType(const QUrl &url, Mode mode = PreferSynchronous); + static QUrl normalize(const QUrl &unNormalizedUrl); + + QQmlTypeData *getType(const QUrl &unNormalizedUrl, Mode mode = PreferSynchronous); QQmlTypeData *getType(const QByteArray &, const QUrl &url, Mode mode = PreferSynchronous); - QQmlScriptBlob *getScript(const QUrl &); + QQmlScriptBlob *getScript(const QUrl &unNormalizedUrl); QQmlQmldirData *getQmldir(const QUrl &); QString absoluteFilePath(const QString &path); diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index 9e7c84011b..221754a29a 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -1697,7 +1697,7 @@ ReturnedValue ConsoleObject::method_count(const FunctionObject *b, const Value * QString scriptName = frame->source(); - int value = v8engine->consoleCountHelper(scriptName, frame->lineNumber(), -1); + int value = v8engine->consoleCountHelper(scriptName, frame->lineNumber(), 0); QString message = name + QLatin1String(": ") + QString::number(value); QMessageLogger(qPrintable(scriptName), frame->lineNumber(), |