aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2017-03-23 14:37:05 +0100
committerSimon Hausmann <simon.hausmann@qt.io>2017-03-23 14:43:46 +0100
commit24d0266ee45cf6a3c5b9142453966199702fbf90 (patch)
tree3484070112f5d4cbd1da4683398d0b41d748be65 /src/qml/qml
parent12569460e765ea01935ab60e06b5a5acf770ebe7 (diff)
parent8f5366aed675ce7928448be2f6d739d0548b350e (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.cpp2
-rw-r--r--src/qml/qml/qqmlmetatype.cpp12
-rw-r--r--src/qml/qml/qqmlnotifier.cpp4
-rw-r--r--src/qml/qml/qqmltypeloader.cpp114
-rw-r--r--src/qml/qml/qqmltypeloader_p.h31
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp2
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()) {