diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2017-03-23 14:37:05 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2017-03-23 14:43:46 +0100 |
commit | 24d0266ee45cf6a3c5b9142453966199702fbf90 (patch) | |
tree | 3484070112f5d4cbd1da4683398d0b41d748be65 /src/qml/qml | |
parent | 12569460e765ea01935ab60e06b5a5acf770ebe7 (diff) | |
parent | 8f5366aed675ce7928448be2f6d739d0548b350e (diff) |
Merge remote-tracking branch 'origin/5.9' into HEAD
Conflicts:
src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
src/qml/jit/qv4assembler.cpp
src/qml/jit/qv4assembler_p.h
src/qml/jit/qv4isel_masm.cpp
src/qml/jsruntime/qv4context.cpp
src/qml/jsruntime/qv4context_p.h
src/qml/jsruntime/qv4engine.cpp
src/qml/jsruntime/qv4vme_moth.cpp
src/qml/memory/qv4mmdefs_p.h
Change-Id: I9966750b7cd9106b78e4c4779f12b95a481cca40
Diffstat (limited to 'src/qml/qml')
-rw-r--r-- | src/qml/qml/qqmlengine.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetatype.cpp | 12 | ||||
-rw-r--r-- | src/qml/qml/qqmlnotifier.cpp | 4 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader.cpp | 114 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader_p.h | 31 | ||||
-rw-r--r-- | src/qml/qml/v8/qqmlbuiltinfunctions.cpp | 2 |
6 files changed, 92 insertions, 73 deletions
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index af94ece496..d4d21583ba 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -791,7 +791,7 @@ void QQmlData::signalEmitted(QAbstractDeclarativeData *, QObject *object, int in // marshalled back onto the QObject's thread and handled by QML from there. This is tested // by the qqmlecmascript::threadSignal() autotest. if (ddata->notifyList && - QThread::currentThreadId() != QObjectPrivate::get(object)->threadData->threadId) { + QThread::currentThreadId() != QObjectPrivate::get(object)->threadData->threadId.load()) { if (!QObjectPrivate::get(object)->threadData->thread) return; diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index bd6b9a1599..bb9b69c479 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -1971,7 +1971,9 @@ QString QQmlMetaType::prettyTypeName(const QObject *object) const int lastSlash = typeName.lastIndexOf(QLatin1Char('/')); if (lastSlash != -1) typeName = typeName.mid(lastSlash + 1); - } else { + } + + if (typeName.isEmpty()) { typeName = QString::fromUtf8(object->metaObject()->className()); int marker = typeName.indexOf(QLatin1String("_QMLTYPE_")); if (marker != -1) @@ -1982,10 +1984,12 @@ QString QQmlMetaType::prettyTypeName(const QObject *object) typeName = typeName.leftRef(marker) + QLatin1Char('*'); type = QQmlMetaType::qmlType(QMetaType::type(typeName.toLatin1())); if (type) { - typeName = type->qmlTypeName(); - const int lastSlash = typeName.lastIndexOf(QLatin1Char('/')); + QString qmlTypeName = type->qmlTypeName(); + const int lastSlash = qmlTypeName.lastIndexOf(QLatin1Char('/')); if (lastSlash != -1) - typeName = typeName.mid(lastSlash + 1); + qmlTypeName = qmlTypeName.mid(lastSlash + 1); + if (!qmlTypeName.isEmpty()) + typeName = qmlTypeName; } } } diff --git a/src/qml/qml/qqmlnotifier.cpp b/src/qml/qml/qqmlnotifier.cpp index 185f9687fb..538ca822ee 100644 --- a/src/qml/qml/qqmlnotifier.cpp +++ b/src/qml/qml/qqmlnotifier.cpp @@ -122,8 +122,8 @@ void QQmlNotifierEndpoint::connect(QObject *source, int sourceSignal, QQmlEngine disconnect(); Q_ASSERT(engine); - if (QObjectPrivate::get(source)->threadData->threadId != - QObjectPrivate::get(engine)->threadData->threadId) { + if (QObjectPrivate::get(source)->threadData->threadId.load() != + QObjectPrivate::get(engine)->threadData->threadId.load()) { QString sourceName; QDebug(&sourceName) << source; diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 68eb989c70..eedb649ef6 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -80,10 +80,6 @@ # define NAME_MAX _POSIX_SYMLINK_MAX #endif -// LSB has a broken version of qOffsetOf that can't be used at compile time -// https://lsbbugs.linuxfoundation.org/show_bug.cgi?id=3462 -#undef qOffsetOf -#define qOffsetOf(TYPE, MEMBER) __builtin_qOffsetOf (TYPE, MEMBER) #endif // #define DATABLOB_DEBUG @@ -1249,20 +1245,20 @@ void QQmlTypeLoader::initializeEngine(QQmlExtensionInterface *iface, void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QByteArray &data) { QML_MEMORY_SCOPE_URL(blob->url()); - QQmlDataBlob::Data d; - d.d = &data; + QQmlDataBlob::SourceCodeData d; + d.inlineSourceCode = QString::fromUtf8(data); setData(blob, d); } void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QString &fileName) { QML_MEMORY_SCOPE_URL(blob->url()); - QQmlDataBlob::Data d; - d.d = &fileName; + QQmlDataBlob::SourceCodeData d; + d.fileInfo = QFileInfo(fileName); setData(blob, d); } -void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QQmlDataBlob::Data &d) +void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QQmlDataBlob::SourceCodeData &d) { QML_MEMORY_SCOPE_URL(blob->url()); QQmlCompilingProfiler prof(QQmlEnginePrivate::get(engine())->profiler, blob); @@ -2069,7 +2065,7 @@ bool QQmlTypeData::tryLoadFromDiskCache() QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = v4->iselFactory->createUnitForLoading(); { QString error; - if (!unit->loadFromDisk(url(), v4->iselFactory.data(), &error)) { + if (!unit->loadFromDisk(url(), m_backupSourceCode.sourceTimeStamp(), v4->iselFactory.data(), &error)) { qCDebug(DBG_DISK_CACHE) << "Error loading" << url().toString() << "from disk cache:" << error; return false; } @@ -2239,7 +2235,7 @@ void QQmlTypeData::done() qCDebug(DBG_DISK_CACHE) << "Checksum mismatch for cached version of" << m_compiledData->url().toString(); if (!loadFromSource()) return; - m_backupSourceCode.clear(); + m_backupSourceCode = SourceCodeData(); m_compiledData = nullptr; } @@ -2346,13 +2342,9 @@ bool QQmlTypeData::loadImplicitImport() return true; } -void QQmlTypeData::dataReceived(const Data &data) +void QQmlTypeData::dataReceived(const SourceCodeData &data) { - QString error; - m_backupSourceCode = data.readAll(&error, &m_sourceTimeStamp); - // if we failed to read the source code, process it _after_ we've tried - // to use the disk cache, in order to support scenarios where the source - // was removed deliberately. + m_backupSourceCode = data; if (tryLoadFromDiskCache()) return; @@ -2360,8 +2352,8 @@ void QQmlTypeData::dataReceived(const Data &data) if (isError()) return; - if (!error.isEmpty()) { - setError(error); + if (!m_backupSourceCode.exists()) { + setError(QQmlTypeLoader::tr("No such file or directory")); return; } @@ -2380,12 +2372,19 @@ void QQmlTypeData::initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *un bool QQmlTypeData::loadFromSource() { - QString code = QString::fromUtf8(m_backupSourceCode); m_document.reset(new QmlIR::Document(isDebugging())); - m_document->jsModule.sourceTimeStamp = m_sourceTimeStamp; + m_document->jsModule.sourceTimeStamp = m_backupSourceCode.sourceTimeStamp(); QQmlEngine *qmlEngine = typeLoader()->engine(); QmlIR::IRBuilder compiler(QV8Engine::get(qmlEngine)->illegalNames()); - if (!compiler.generateFromQml(code, finalUrlString(), m_document.data())) { + + QString sourceError; + const QString source = m_backupSourceCode.readAll(&sourceError); + if (!sourceError.isEmpty()) { + setError(sourceError); + return false; + } + + if (!compiler.generateFromQml(source, finalUrlString(), m_document.data())) { QList<QQmlError> errors; errors.reserve(compiler.errors.count()); for (const QQmlJS::DiagnosticMessage &msg : qAsConst(compiler.errors)) { @@ -2523,7 +2522,7 @@ void QQmlTypeData::compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCach QString errorString; if (m_compiledData->saveToDisk(url(), &errorString)) { QString error; - if (!m_compiledData->loadFromDisk(url(), enginePrivate->v4engine()->iselFactory.data(), &error)) { + if (!m_compiledData->loadFromDisk(url(), m_backupSourceCode.sourceTimeStamp(), enginePrivate->v4engine()->iselFactory.data(), &error)) { // ignore error, keep using the in-memory compilation unit. } } else { @@ -2876,14 +2875,14 @@ struct EmptyCompilationUnit : public QV4::CompiledData::CompilationUnit void linkBackendToEngine(QV4::ExecutionEngine *) override {} }; -void QQmlScriptBlob::dataReceived(const Data &data) +void QQmlScriptBlob::dataReceived(const SourceCodeData &data) { QV4::ExecutionEngine *v4 = QV8Engine::getV4(m_typeLoader->engine()); if (!disableDiskCache() || forceDiskCache()) { QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = v4->iselFactory->createUnitForLoading(); QString error; - if (unit->loadFromDisk(url(), v4->iselFactory.data(), &error)) { + if (unit->loadFromDisk(url(), data.sourceTimeStamp(), v4->iselFactory.data(), &error)) { initializeFromCompilationUnit(unit); return; } else { @@ -2894,8 +2893,9 @@ void QQmlScriptBlob::dataReceived(const Data &data) QmlIR::Document irUnit(isDebugging()); + irUnit.jsModule.sourceTimeStamp = data.sourceTimeStamp(); QString error; - QString source = QString::fromUtf8(data.readAll(&error, &irUnit.jsModule.sourceTimeStamp)); + QString source = data.readAll(&error); if (!error.isEmpty()) { setError(error); return; @@ -3059,10 +3059,10 @@ void QQmlQmldirData::setPriority(int priority) m_priority = priority; } -void QQmlQmldirData::dataReceived(const Data &data) +void QQmlQmldirData::dataReceived(const SourceCodeData &data) { QString error; - m_content = QString::fromUtf8(data.readAll(&error)); + m_content = data.readAll(&error); if (!error.isEmpty()) { setError(error); return; @@ -3074,34 +3074,54 @@ void QQmlQmldirData::initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit * Q_UNIMPLEMENTED(); } -QByteArray QQmlDataBlob::Data::readAll(QString *error, qint64 *sourceTimeStamp) const +QString QQmlDataBlob::SourceCodeData::readAll(QString *error) const { - Q_ASSERT(!d.isNull()); error->clear(); - if (d.isT1()) { - if (sourceTimeStamp) - *sourceTimeStamp = 0; - return *d.asT1(); - } - QFile f(*d.asT2()); + if (!inlineSourceCode.isEmpty()) + return inlineSourceCode; + + QFile f(fileInfo.absoluteFilePath()); if (!f.open(QIODevice::ReadOnly)) { *error = f.errorString(); - return QByteArray(); + return QString(); } - if (sourceTimeStamp) { - QDateTime timeStamp = QFileInfo(f).lastModified(); - // Files from the resource system do not have any time stamps, so fall back to the application - // executable. - if (!timeStamp.isValid()) - timeStamp = QFileInfo(QCoreApplication::applicationFilePath()).lastModified(); - *sourceTimeStamp = timeStamp.toMSecsSinceEpoch(); + + const qint64 fileSize = fileInfo.size(); + + if (uchar *mappedData = f.map(0, fileSize)) { + QString source = QString::fromUtf8(reinterpret_cast<const char *>(mappedData), fileSize); + f.unmap(mappedData); + return source; } - QByteArray data(f.size(), Qt::Uninitialized); + + QByteArray data(fileSize, Qt::Uninitialized); if (f.read(data.data(), data.length()) != data.length()) { *error = f.errorString(); - return QByteArray(); + return QString(); } - return data; + return QString::fromUtf8(data); +} + +QDateTime QQmlDataBlob::SourceCodeData::sourceTimeStamp() const +{ + if (!inlineSourceCode.isEmpty()) + return QDateTime(); + + QDateTime timeStamp = fileInfo.lastModified(); + if (timeStamp.isValid()) + return timeStamp; + + static QDateTime appTimeStamp; + if (!appTimeStamp.isValid()) + appTimeStamp = QFileInfo(QCoreApplication::applicationFilePath()).lastModified(); + return appTimeStamp; +} + +bool QQmlDataBlob::SourceCodeData::exists() const +{ + if (!inlineSourceCode.isEmpty()) + return true; + return fileInfo.exists(); } QT_END_NAMESPACE diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h index 915b1bcc4c..1bd2c7f1e1 100644 --- a/src/qml/qml/qqmltypeloader_p.h +++ b/src/qml/qml/qqmltypeloader_p.h @@ -54,6 +54,7 @@ #include <QtQml/qtqmlglobal.h> #include <QtCore/qobject.h> #include <QtCore/qatomic.h> +#include <QtCore/qfileinfo.h> #if QT_CONFIG(qml_network) #include <QtNetwork/qnetworkreply.h> #endif @@ -130,16 +131,16 @@ public: QList<QQmlError> errors() const; - class Data { + class SourceCodeData { public: - QByteArray readAll(QString *error, qint64 *sourceTimeStamp = 0) const; + QString readAll(QString *error) const; + QDateTime sourceTimeStamp() const; + bool exists() const; private: friend class QQmlDataBlob; friend class QQmlTypeLoader; - inline Data(); - Data(const Data &); - Data &operator=(const Data &); - QBiPointer<const QByteArray, const QString> d; + QString inlineSourceCode; + QFileInfo fileInfo; }; protected: @@ -152,7 +153,7 @@ protected: void addDependency(QQmlDataBlob *); // Callbacks made in load thread - virtual void dataReceived(const Data &) = 0; + virtual void dataReceived(const SourceCodeData &) = 0; virtual void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit*) = 0; virtual void done(); #if QT_CONFIG(qml_network) @@ -339,7 +340,7 @@ private: void setData(QQmlDataBlob *, const QByteArray &); void setData(QQmlDataBlob *, const QString &fileName); - void setData(QQmlDataBlob *, const QQmlDataBlob::Data &); + void setData(QQmlDataBlob *, const QQmlDataBlob::SourceCodeData &); void setCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit); template<typename T> @@ -436,7 +437,7 @@ public: protected: void done() override; void completed() override; - void dataReceived(const Data &) override; + void dataReceived(const SourceCodeData &) override; void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *unit) override; void allDependenciesDone() override; void downloadProgressChanged(qreal) override; @@ -462,8 +463,7 @@ private: void scriptImported(QQmlScriptBlob *blob, const QV4::CompiledData::Location &location, const QString &qualifier, const QString &nameSpace) override; - qint64 m_sourceTimeStamp = 0; - QByteArray m_backupSourceCode; // used when cache verification fails. + SourceCodeData m_backupSourceCode; // used when cache verification fails. QScopedPointer<QmlIR::Document> m_document; QV4::CompiledData::TypeReferenceMap m_typeReferences; @@ -547,7 +547,7 @@ public: QQmlScriptData *scriptData() const; protected: - void dataReceived(const Data &) override; + void dataReceived(const SourceCodeData &) override; void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *unit) override; void done() override; @@ -578,7 +578,7 @@ public: void setPriority(int); protected: - void dataReceived(const Data &) override; + void dataReceived(const SourceCodeData &) override; void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit*) override; private: @@ -587,11 +587,6 @@ private: int m_priority; }; -QQmlDataBlob::Data::Data() -{ -} - - QT_END_NAMESPACE diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index ec40c7846d..68a64a28f0 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -1885,7 +1885,7 @@ void GlobalExtensions::method_qsTr(const BuiltinFunction *, Scope &scope, CallDa ExecutionContext *parentCtx = scope.engine->currentContext; // The first non-empty source URL in the call stack determines the translation context. while (!!parentCtx && context.isEmpty()) { - if (QV4::CompiledData::CompilationUnit *unit = parentCtx->d()->compilationUnit) { + if (CompiledData::CompilationUnit *unit = static_cast<CompiledData::CompilationUnit*>(parentCtx->d()->compilationUnit)) { QString fileName = unit->fileName(); QUrl url(unit->fileName()); if (url.isValid() && url.isRelative()) { |