diff options
author | Liang Qi <liang.qi@qt.io> | 2018-03-28 08:27:57 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2018-03-28 08:27:57 +0200 |
commit | 198409ba76e18587526e9e1ec84fdb432c671937 (patch) | |
tree | 2d06c052272ddfd1c9b34b863e342826a31d20b9 | |
parent | 9a98d16d9e49395a24cd733ca8f65b2f82ebba94 (diff) | |
parent | e696a6b7bff04d1581cf59b4d96ecb5508f54169 (diff) |
Merge remote-tracking branch 'origin/5.11' into dev
Conflicts:
src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp
tests/auto/qml/qjsengine/tst_qjsengine.cpp
Change-Id: I8276669e257f35a76768ef7f8795a8605cf4c9bc
33 files changed, 281 insertions, 102 deletions
diff --git a/src/3rdparty/masm/yarr/YarrInterpreter.cpp b/src/3rdparty/masm/yarr/YarrInterpreter.cpp index 4a789f6f28..16fc183cad 100644 --- a/src/3rdparty/masm/yarr/YarrInterpreter.cpp +++ b/src/3rdparty/masm/yarr/YarrInterpreter.cpp @@ -731,6 +731,7 @@ public: context->term -= term.atom.parenthesesWidth; return false; } + Q_FALLTHROUGH(); case QuantifierNonGreedy: if (backTrack->begin == notFound) { backTrack->begin = input.getPos(); diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp index 92e93a053a..22c515adf9 100644 --- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp +++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp @@ -59,7 +59,7 @@ Q_QML_DEBUG_PLUGIN_LOADER(QQmlAbstractProfilerAdapter) QQmlProfilerServiceImpl::QQmlProfilerServiceImpl(QObject *parent) : QQmlConfigurableDebugService<QQmlProfilerService>(1, parent), - m_waitingForStop(false) + m_waitingForStop(false), m_globalEnabled(false), m_globalFeatures(0) { m_timer.start(); QQmlAbstractProfilerAdapter *quickAdapter = @@ -137,6 +137,10 @@ void QQmlProfilerServiceImpl::engineAdded(QJSEngine *engine) "QML profilers have to be added from the engine thread"); QMutexLocker lock(&m_configMutex); + + if (m_globalEnabled) + startProfiling(engine, m_globalFeatures); + const auto range = qAsConst(m_engineProfilers).equal_range(engine); for (auto it = range.first; it != range.second; ++it) (*it)->stopWaiting(); @@ -254,6 +258,9 @@ void QQmlProfilerServiceImpl::startProfiling(QJSEngine *engine, quint64 features if (startedAny) d << idForObject(engine); } else { + m_globalEnabled = true; + m_globalFeatures = features; + QSet<QJSEngine *> engines; for (QMultiHash<QJSEngine *, QQmlAbstractProfilerAdapter *>::iterator i(m_engineProfilers.begin()); i != m_engineProfilers.end(); ++i) { @@ -274,9 +281,8 @@ void QQmlProfilerServiceImpl::startProfiling(QJSEngine *engine, quint64 features } emit startFlushTimer(); + emit messageToClient(name(), d.data()); } - - emit messageToClient(name(), d.data()); } /*! @@ -292,6 +298,9 @@ void QQmlProfilerServiceImpl::stopProfiling(QJSEngine *engine) QList<QQmlAbstractProfilerAdapter *> stopping; QList<QQmlAbstractProfilerAdapter *> reporting; + if (engine == nullptr) + m_globalEnabled = false; + bool stillRunning = false; for (QMultiHash<QJSEngine *, QQmlAbstractProfilerAdapter *>::iterator i(m_engineProfilers.begin()); i != m_engineProfilers.end(); ++i) { diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h index e86c8df4ac..ce0101f4d4 100644 --- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h +++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h @@ -115,6 +115,9 @@ private: QTimer m_flushTimer; bool m_waitingForStop; + bool m_globalEnabled; + quint64 m_globalFeatures; + QList<QQmlAbstractProfilerAdapter *> m_globalProfilers; QMultiHash<QJSEngine *, QQmlAbstractProfilerAdapter *> m_engineProfilers; QList<QJSEngine *> m_stoppingEngines; diff --git a/src/qml/debugger/qqmlprofiler_p.h b/src/qml/debugger/qqmlprofiler_p.h index 44d208db41..d01e2bc429 100644 --- a/src/qml/debugger/qqmlprofiler_p.h +++ b/src/qml/debugger/qqmlprofiler_p.h @@ -190,7 +190,7 @@ public: } RefLocation(QQmlDataBlob *ref) - : Location(QQmlSourceLocation()), locationType(Compiling), sent(false) + : Location(QQmlSourceLocation(), ref->url()), locationType(Compiling), sent(false) { blob = ref; blob->addref(); diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h index 7f82a02ae0..9b13d4e341 100644 --- a/src/qml/jsruntime/qv4global_p.h +++ b/src/qml/jsruntime/qv4global_p.h @@ -108,6 +108,11 @@ inline double trunc(double d) { return d > 0 ? floor(d) : ceil(d); } //# define V4_ENABLE_JIT #endif +// check FPU with double precision on ARM platform +#if (defined(Q_PROCESSOR_ARM_64) || defined(Q_PROCESSOR_ARM_32)) && defined(V4_ENABLE_JIT) && defined(__ARM_FP) && (__ARM_FP <= 0x04) +# undef V4_ENABLE_JIT +#endif + // Black list some platforms #if defined(V4_ENABLE_JIT) #if defined(Q_OS_IOS) || defined(Q_OS_TVOS) diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h index 97ed13cd91..a5ee6b5373 100644 --- a/src/qml/jsruntime/qv4value_p.h +++ b/src/qml/jsruntime/qv4value_p.h @@ -339,7 +339,7 @@ public: if (isDouble()) { double d = doubleValue(); int i = (int)d; - if (i == d) { + if (i == d && !(d == 0 && std::signbit(d))) { setInt_32(i); return true; } diff --git a/src/qml/qml/qqmlexpression.cpp b/src/qml/qml/qqmlexpression.cpp index 59cc9bb09f..27d3acb9b7 100644 --- a/src/qml/qml/qqmlexpression.cpp +++ b/src/qml/qml/qqmlexpression.cpp @@ -252,6 +252,11 @@ QV4::ReturnedValue QQmlExpressionPrivate::v4value(bool *isUndefined) if (!expressionFunctionValid) { createQmlBinding(context(), scopeObject(), expression, url, line); expressionFunctionValid = true; + if (hasError()) { + if (isUndefined) + *isUndefined = true; + return QV4::Encode::undefined(); + } } return evaluate(isUndefined); diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp index 74148e3ca4..3daa107b64 100644 --- a/src/qml/qml/qqmljavascriptexpression.cpp +++ b/src/qml/qml/qqmljavascriptexpression.cpp @@ -451,15 +451,11 @@ void QQmlJavaScriptExpression::createQmlBinding(QQmlContextData *ctxt, QObject * QV4::Script script(v4, qmlContext, code, filename, line); script.parse(); if (v4->hasException) { - QQmlError error = v4->catchExceptionAsQmlError(); - if (error.description().isEmpty()) - error.setDescription(QLatin1String("Exception occurred during function evaluation")); - if (error.line() == -1) - error.setLine(line); - if (error.url().isEmpty()) - error.setUrl(QUrl::fromLocalFile(filename)); - error.setObject(qmlScope); - ep->warning(error); + QQmlDelayedError *error = delayedError(); + error->catchJavaScriptException(v4); + error->setErrorObject(qmlScope); + if (!error->addError(ep)) + ep->warning(error); return; } setupFunction(qmlContext, script.vmFunction); diff --git a/src/quick/designer/qquickdesignercustomobjectdata.cpp b/src/quick/designer/qquickdesignercustomobjectdata.cpp index daa9486f02..8989de711e 100644 --- a/src/quick/designer/qquickdesignercustomobjectdata.cpp +++ b/src/quick/designer/qquickdesignercustomobjectdata.cpp @@ -149,11 +149,11 @@ void QQuickDesignerCustomObjectData::populateResetHashes() QQuickDesignerSupportProperties::propertyNameListForWritableProperties(object()); const QMetaObject *mo = object()->metaObject(); - QStringList deferredPropertyNames; + QByteArrayList deferredPropertyNames; const int namesIndex = mo->indexOfClassInfo("DeferredPropertyNames"); if (namesIndex != -1) { QMetaClassInfo classInfo = mo->classInfo(namesIndex); - deferredPropertyNames = QString::fromUtf8(classInfo.value()).split(QLatin1Char(',')); + deferredPropertyNames = QByteArray(classInfo.value()).split(','); } for (const QQuickDesignerSupport::PropertyName &propertyName : propertyNameList) { diff --git a/src/quick/designer/qquickdesignersupportitems.cpp b/src/quick/designer/qquickdesignersupportitems.cpp index 82474827aa..1c338fa79d 100644 --- a/src/quick/designer/qquickdesignersupportitems.cpp +++ b/src/quick/designer/qquickdesignersupportitems.cpp @@ -96,11 +96,11 @@ static void allSubObjects(QObject *object, QObjectList &objectList) const QMetaObject *mo = object->metaObject(); - QStringList deferredPropertyNames; + QByteArrayList deferredPropertyNames; const int namesIndex = mo->indexOfClassInfo("DeferredPropertyNames"); if (namesIndex != -1) { QMetaClassInfo classInfo = mo->classInfo(namesIndex); - deferredPropertyNames = QString::fromUtf8(classInfo.value()).split(QLatin1Char(',')); + deferredPropertyNames = QByteArray(classInfo.value()).split(','); } for (int index = QObject::staticMetaObject.propertyOffset(); diff --git a/src/quick/doc/QtQuickDoc b/src/quick/doc/QtQuickDoc new file mode 100644 index 0000000000..6c151f2ebd --- /dev/null +++ b/src/quick/doc/QtQuickDoc @@ -0,0 +1,2 @@ +#include <QtQuick/QtQuick> +#include <QtQuickWidgets/QtQuickWidgets> diff --git a/src/quick/doc/qtquick.qdocconf b/src/quick/doc/qtquick.qdocconf index 7ce0dfcf09..c137d1d2c8 100644 --- a/src/quick/doc/qtquick.qdocconf +++ b/src/quick/doc/qtquick.qdocconf @@ -6,6 +6,10 @@ version = $QT_VERSION examplesinstallpath = quick +# Custom module header that pulls in also QtQuickWidgets +moduleheader = QtQuickDoc +includepaths = -I . + qhp.projects = QtQuick qhp.QtQuick.file = qtquick.qhp diff --git a/src/quick/handlers/qquickpointerhandler.cpp b/src/quick/handlers/qquickpointerhandler.cpp index 959030b8fe..e5b1dc8985 100644 --- a/src/quick/handlers/qquickpointerhandler.cpp +++ b/src/quick/handlers/qquickpointerhandler.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtQuick module of the Qt Toolkit. @@ -245,6 +245,14 @@ void QQuickPointerHandler::setGrabPermissions(GrabPermissions grabPermission) emit grabPermissionChanged(); } +void QQuickPointerHandler::classBegin() +{ +} + +void QQuickPointerHandler::componentComplete() +{ +} + /*! \internal Acquire or give up the exclusive grab of the given \a point, according to diff --git a/src/quick/handlers/qquickpointerhandler_p.h b/src/quick/handlers/qquickpointerhandler_p.h index 9ea6a8b5e2..e2bcce8fc9 100644 --- a/src/quick/handlers/qquickpointerhandler_p.h +++ b/src/quick/handlers/qquickpointerhandler_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtQuick module of the Qt Toolkit. @@ -106,9 +106,6 @@ public: GrabPermissions grabPermissions() const { return static_cast<GrabPermissions>(m_grabPermissions); } void setGrabPermissions(GrabPermissions grabPermissions); - void classBegin() override { } - void componentComplete() override { } - Q_SIGNALS: void enabledChanged(); void activeChanged(); @@ -118,6 +115,9 @@ Q_SIGNALS: void canceled(QQuickEventPoint *point); protected: + void classBegin() override; + void componentComplete() override; + QQuickPointerEvent *currentEvent() { return m_currentEvent; } virtual bool wantsPointerEvent(QQuickPointerEvent *event); virtual void handlePointerEventImpl(QQuickPointerEvent *event); diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp index 423f5f7321..b400473128 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp @@ -195,7 +195,7 @@ void QSGSoftwareRenderLoop::renderWindow(QQuickWindow *window, bool isNewExpose) int(polishTime / 1000000), int((syncTime - polishTime) / 1000000), int((renderTime - syncTime) / 1000000), - int((swapTime - renderTime) / 10000000), + int((swapTime - renderTime) / 1000000), int(lastFrameTime.msecsTo(QTime::currentTime()))); lastFrameTime = QTime::currentTime(); } diff --git a/tests/auto/cmake/CMakeLists.txt b/tests/auto/cmake/CMakeLists.txt index 4d4d8e3db7..f304a99705 100644 --- a/tests/auto/cmake/CMakeLists.txt +++ b/tests/auto/cmake/CMakeLists.txt @@ -25,4 +25,5 @@ add_test(qtquickcompiler ${CMAKE_CTEST_COMMAND} --build-makeprogram ${CMAKE_MAKE_PROGRAM} --build-project qqc_test --build-options "-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}" ${BUILD_OPTIONS_LIST} + --test-command qqc_test ) diff --git a/tests/auto/cmake/qtquickcompiler/CMakeLists.txt b/tests/auto/cmake/qtquickcompiler/CMakeLists.txt index 6dee1e25dc..4e46544767 100644 --- a/tests/auto/cmake/qtquickcompiler/CMakeLists.txt +++ b/tests/auto/cmake/qtquickcompiler/CMakeLists.txt @@ -4,11 +4,14 @@ project(qqc_test) find_package(Qt5Qml 5.0.0 REQUIRED) find_package(Qt5Gui 5.0.0 REQUIRED) +find_package(Qt5Test 5.0.0 REQUIRED) find_package(Qt5QuickCompiler) set(CMAKE_CXXFLAGS "${CMAKE_CXXFLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}") -qtquick_compiler_add_resources(RESOURCES qqc_test.qrc) +qtquick_compiler_add_resources(RESOURCES "resources with space/qqc_test.qrc") + +set(CMAKE_AUTOMOC ON) add_executable(qqc_test "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" ${RESOURCES}) -target_link_libraries(qqc_test Qt5::Gui Qt5::Qml) +target_link_libraries(qqc_test Qt5::Gui Qt5::Qml Qt5::Test) diff --git a/tests/auto/cmake/qtquickcompiler/main.cpp b/tests/auto/cmake/qtquickcompiler/main.cpp index 47fc709c0a..c357ef60e6 100644 --- a/tests/auto/cmake/qtquickcompiler/main.cpp +++ b/tests/auto/cmake/qtquickcompiler/main.cpp @@ -1,9 +1,30 @@ -#include <QtGui> +#include <QtCore> #include <QtQml> +#include <QtTest> -int main(int argc, char **argv) +class tst_QQC : public QObject { - QGuiApplication app(argc, argv); - return app.exec(); + Q_OBJECT +private slots: + void packaging(); +}; + +void tst_QQC::packaging() +{ + QVERIFY(QFile::exists(":/main.qml")); + QCOMPARE(QFileInfo(":/main.qml").size(), 0); + QVERIFY(QFile::exists(":/main.cpp")); + QVERIFY(QFileInfo(":/main.cpp").size() > 0); + + + QQmlEngine engine; + QQmlComponent component(&engine, QUrl("qrc:/main.qml")); + QScopedPointer<QObject> obj(component.create()); + QVERIFY(!obj.isNull()); + QCOMPARE(obj->property("success").toInt(), 42); } + +QTEST_MAIN(tst_QQC) + +#include "main.moc" diff --git a/tests/auto/cmake/qtquickcompiler/main.qml b/tests/auto/cmake/qtquickcompiler/resources with space/main.qml index 1f146d89c3..0836808dc2 100644 --- a/tests/auto/cmake/qtquickcompiler/main.qml +++ b/tests/auto/cmake/qtquickcompiler/resources with space/main.qml @@ -1,4 +1,4 @@ import QtQml 2.0 QtObject { - property bool success: 42 + property int success: 42 } diff --git a/tests/auto/cmake/qtquickcompiler/qqc_test.qrc b/tests/auto/cmake/qtquickcompiler/resources with space/qqc_test.qrc index f128b7004b..63d8d1f37e 100644 --- a/tests/auto/cmake/qtquickcompiler/qqc_test.qrc +++ b/tests/auto/cmake/qtquickcompiler/resources with space/qqc_test.qrc @@ -1,6 +1,6 @@ <!DOCTYPE RCC><RCC version="1.0"> <qresource> <file>./main.qml</file> -<file>./main.cpp</file> +<file alias="main.cpp">../main.cpp</file> </qresource> </RCC> diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp index cd8e4216f3..f2b44a4d95 100644 --- a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp +++ b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp @@ -221,6 +221,7 @@ private slots: void flushInterval(); void translationBinding(); void memory(); + void compile(); private: bool m_recordFromStart = true; @@ -525,6 +526,8 @@ void tst_QQmlProfilerService::connect() if (!traceEnabled) m_client->client->setRecording(true); + + QTRY_VERIFY(m_client->numLoadedEventTypes() > 0); m_client->client->setRecording(false); checkTraceReceived(); checkJsHeap(); @@ -643,6 +646,7 @@ void tst_QQmlProfilerService::controlFromJS() { QCOMPARE(connect(true, "controlFromJS.qml", false), ConnectSuccess); + QTRY_VERIFY(m_client->numLoadedEventTypes() > 0); m_client->client->setRecording(false); checkTraceReceived(); checkJsHeap(); @@ -749,6 +753,41 @@ void tst_QQmlProfilerService::memory() QVERIFY(smallItems > 5); } +void tst_QQmlProfilerService::compile() +{ + connect(true, "test.qml"); + + QTRY_VERIFY(m_client->numLoadedEventTypes() > 0); + m_client->client->setRecording(false); + + checkTraceReceived(); + checkJsHeap(); + + QQmlProfilerDefinitions::Message rangeStage = QQmlProfilerDefinitions::MaximumMessage; + for (auto message : m_client->qmlMessages) { + const QQmlProfilerEventType &type = m_client->types[message.typeIndex()]; + if (type.rangeType() == QQmlProfilerDefinitions::Compiling) { + switch (rangeStage) { + case QQmlProfilerDefinitions::MaximumMessage: + QCOMPARE(message.rangeStage(), QQmlProfilerDefinitions::RangeStart); + break; + case QQmlProfilerDefinitions::RangeStart: + QCOMPARE(message.rangeStage(), QQmlProfilerDefinitions::RangeEnd); + break; + default: + QFAIL("Wrong range stage"); + } + rangeStage = message.rangeStage(); + QCOMPARE(type.message(), QQmlProfilerDefinitions::MaximumMessage); + QCOMPARE(type.location().filename(), testFileUrl("test.qml").toString()); + QCOMPARE(type.location().line(), 0); + QCOMPARE(type.location().column(), 0); + } + } + + QCOMPARE(rangeStage, QQmlProfilerDefinitions::RangeEnd); +} + QTEST_MAIN(tst_QQmlProfilerService) #include "tst_qqmlprofilerservice.moc" diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp index 1eff5739b8..cc0a1e9a93 100644 --- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp +++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp @@ -203,7 +203,6 @@ private slots: void malformedExpression(); void scriptScopes(); - void perfMapFile(); void binaryNumbers(); void octalNumbers(); @@ -4180,73 +4179,6 @@ void tst_QJSEngine::octalNumbers() QVERIFY(result.isError()); } -static const char *perfMapKey = "QV4_PROFILE_WRITE_PERF_MAP"; -static const char *jitCallKey = "QV4_JIT_CALL_THRESHOLD"; - -struct EnvironmentModifier { - const bool hasPerfMap = false; - const bool hasJitCall = false; - const QByteArray perfMap; - const QByteArray jitCall; - - EnvironmentModifier() : - hasPerfMap(qEnvironmentVariableIsSet(perfMapKey)), - hasJitCall(qEnvironmentVariableIsSet(jitCallKey)), - perfMap(qgetenv(perfMapKey)), - jitCall(qgetenv(jitCallKey)) - { - qputenv(perfMapKey, "1"); - qputenv(jitCallKey, "0"); - } - - ~EnvironmentModifier() - { - if (hasPerfMap) - qputenv(perfMapKey, perfMap); - else - qunsetenv(perfMapKey); - - if (hasJitCall) - qputenv(jitCallKey, jitCall); - else - qunsetenv(jitCallKey); - } -}; - -void tst_QJSEngine::perfMapFile() -{ -#if !defined(Q_OS_LINUX) - QSKIP("perf map files are only generated on linux"); -#else - EnvironmentModifier modifier; - Q_UNUSED(modifier); - QJSEngine engine; - QJSValue def = engine.evaluate("'use strict'; function foo() { return 42 }"); - QVERIFY(!def.isError()); - QJSValue use = engine.evaluate("'use strict'; foo()"); - QVERIFY(use.isNumber()); - QFile file(QString::fromLatin1("/tmp/perf-%1.map").arg(QCoreApplication::applicationPid())); - QVERIFY(file.exists()); - QVERIFY(file.open(QIODevice::ReadOnly)); - QList<QByteArray> functions; - while (!file.atEnd()) { - const QByteArray contents = file.readLine(); - QVERIFY(contents.endsWith('\n')); - QList<QByteArray> fields = contents.split(' '); - QCOMPARE(fields.length(), 3); - bool ok = false; - const qulonglong address = fields[0].toULongLong(&ok, 16); - QVERIFY(ok); - QVERIFY(address > 0); - const ulong size = fields[1].toULong(&ok, 16); - QVERIFY(ok); - QVERIFY(size > 0); - functions.append(fields[2]); - } - QVERIFY(functions.contains("foo\n")); -#endif -} - QTEST_MAIN(tst_QJSEngine) #include "tst_qjsengine.moc" diff --git a/tests/auto/qml/qml.pro b/tests/auto/qml/qml.pro index 9557393a2e..3433b56864 100644 --- a/tests/auto/qml/qml.pro +++ b/tests/auto/qml/qml.pro @@ -69,6 +69,7 @@ PRIVATETESTS += \ qqmltranslation \ qqmlimport \ qqmlobjectmodel \ + qv4assembler \ qv4mm \ ecmascripttests \ bindingdependencyapi diff --git a/tests/auto/qml/qmlcachegen/qmlcachegen.pro b/tests/auto/qml/qmlcachegen/qmlcachegen.pro index bad912c781..a2f963e8c3 100644 --- a/tests/auto/qml/qmlcachegen/qmlcachegen.pro +++ b/tests/auto/qml/qmlcachegen/qmlcachegen.pro @@ -10,4 +10,6 @@ RESOURCES += workerscripts_test RESOURCES += versionchecks.qml +RESOURCES += trickypaths.qrc + QT += core-private qml-private testlib diff --git a/tests/auto/qml/qmlcachegen/trickypaths.qml b/tests/auto/qml/qmlcachegen/trickypaths.qml new file mode 100644 index 0000000000..0836808dc2 --- /dev/null +++ b/tests/auto/qml/qmlcachegen/trickypaths.qml @@ -0,0 +1,4 @@ +import QtQml 2.0 +QtObject { + property int success: 42 +} diff --git a/tests/auto/qml/qmlcachegen/trickypaths.qrc b/tests/auto/qml/qmlcachegen/trickypaths.qrc new file mode 100644 index 0000000000..271cf6571e --- /dev/null +++ b/tests/auto/qml/qmlcachegen/trickypaths.qrc @@ -0,0 +1,5 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource prefix="/directory with spaces"> +<file alias="file name with spaces.qml">trickypaths.qml</file> +</qresource> +</RCC> diff --git a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp index 1c05005c90..5c1692f086 100644 --- a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp +++ b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp @@ -52,6 +52,8 @@ private slots: void versionChecksForAheadOfTimeUnits(); void workerScripts(); + + void trickyPaths(); }; // A wrapper around QQmlComponent to ensure the temporary reference counts @@ -402,6 +404,18 @@ void tst_qmlcachegen::functionExpressions() QCOMPARE(obj->property("h_connections_handler_called").toBool(), true); } +void tst_qmlcachegen::trickyPaths() +{ + QString pathWithSpaces(QStringLiteral(":/directory with spaces/file name with spaces.qml")); + QVERIFY2(QFile::exists(pathWithSpaces), qPrintable(pathWithSpaces)); + QCOMPARE(QFileInfo(pathWithSpaces).size(), 0); + QQmlEngine engine; + QQmlComponent component(&engine, QUrl("qrc" + pathWithSpaces)); + QScopedPointer<QObject> obj(component.create()); + QVERIFY(!obj.isNull()); + QCOMPARE(obj->property("success").toInt(), 42); +} + QTEST_GUILESS_MAIN(tst_qmlcachegen) #include "tst_qmlcachegen.moc" diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 31cf40be16..e0b8127dfb 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -351,6 +351,7 @@ private slots: void shadowedFunctionName(); void anotherNaN(); void callPropertyOnUndefined(); + void jumpStrictNotEqualUndefined(); private: // static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter); @@ -8479,6 +8480,26 @@ void tst_qqmlecmascript::callPropertyOnUndefined() QVERIFY(!v.isError()); // well, more importantly: this shouldn't fail on an assert. } +void tst_qqmlecmascript::jumpStrictNotEqualUndefined() +{ + QJSEngine engine; + QJSValue v = engine.evaluate(QString::fromLatin1( + "var ok = 0\n" + "var foo = 0\n" + "if (foo !== void 1)\n" + " ++ok;\n" + "else\n" + " --ok;\n" + "if (foo === void 1)\n" + " --ok;\n" + "else\n" + " ++ok;\n" + "ok\n" + )); + QVERIFY(!v.isError()); + QCOMPARE(v.toInt(), 2); +} + QTEST_MAIN(tst_qqmlecmascript) #include "tst_qqmlecmascript.moc" diff --git a/tests/auto/qml/qqmlexpression/tst_qqmlexpression.cpp b/tests/auto/qml/qqmlexpression/tst_qqmlexpression.cpp index e1ad1e8c5f..1decc04ad2 100644 --- a/tests/auto/qml/qqmlexpression/tst_qqmlexpression.cpp +++ b/tests/auto/qml/qqmlexpression/tst_qqmlexpression.cpp @@ -101,8 +101,12 @@ void tst_qqmlexpression::syntaxError() { QQmlEngine engine; QQmlExpression expression(engine.rootContext(), nullptr, "asd asd"); - QVariant v = expression.evaluate(); + bool isUndefined = false; + QVariant v = expression.evaluate(&isUndefined); QCOMPARE(v, QVariant()); + QVERIFY(expression.hasError()); + QCOMPARE(expression.error().description(), "SyntaxError: Expected token `;'"); + QVERIFY(isUndefined); } void tst_qqmlexpression::exception() diff --git a/tests/auto/qml/qv4assembler/qv4assembler.pro b/tests/auto/qml/qv4assembler/qv4assembler.pro new file mode 100644 index 0000000000..afd7586ac7 --- /dev/null +++ b/tests/auto/qml/qv4assembler/qv4assembler.pro @@ -0,0 +1,7 @@ +CONFIG += testcase +TARGET = tst_qv4assembler +macos:CONFIG -= app_bundle + +SOURCES += tst_qv4assembler.cpp + +QT += qml-private testlib diff --git a/tests/auto/qml/qv4assembler/tst_qv4assembler.cpp b/tests/auto/qml/qv4assembler/tst_qv4assembler.cpp new file mode 100644 index 0000000000..9bd1afa256 --- /dev/null +++ b/tests/auto/qml/qv4assembler/tst_qv4assembler.cpp @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <QtCore/qprocess.h> +#include <QtCore/qtemporaryfile.h> + +class tst_QV4Assembler : public QObject +{ + Q_OBJECT + +private slots: + void perfMapFile(); +}; + +void tst_QV4Assembler::perfMapFile() +{ +#if !defined(Q_OS_LINUX) + QSKIP("perf map files are only generated on linux"); +#else + const QString qmljs = QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmljs"; + QProcess process; + + QTemporaryFile infile; + QVERIFY(infile.open()); + infile.write("'use strict'; function foo() { return 42 }; foo();"); + infile.close(); + + QProcessEnvironment environment = QProcessEnvironment::systemEnvironment(); + environment.insert("QV4_PROFILE_WRITE_PERF_MAP", "1"); + environment.insert("QV4_JIT_CALL_THRESHOLD", "0"); + + process.setProcessEnvironment(environment); + process.start(qmljs, QStringList({infile.fileName()})); + QVERIFY(process.waitForStarted()); + const qint64 pid = process.processId(); + QVERIFY(pid != 0); + QVERIFY(process.waitForFinished()); + QCOMPARE(process.exitCode(), 0); + + QFile file(QString::fromLatin1("/tmp/perf-%1.map").arg(pid)); + QVERIFY(file.exists()); + QVERIFY(file.open(QIODevice::ReadOnly)); + QList<QByteArray> functions; + while (!file.atEnd()) { + const QByteArray contents = file.readLine(); + QVERIFY(contents.endsWith('\n')); + QList<QByteArray> fields = contents.split(' '); + QCOMPARE(fields.length(), 3); + bool ok = false; + const qulonglong address = fields[0].toULongLong(&ok, 16); + QVERIFY(ok); + QVERIFY(address > 0); + const ulong size = fields[1].toULong(&ok, 16); + QVERIFY(ok); + QVERIFY(size > 0); + functions.append(fields[2]); + } + QVERIFY(functions.contains("foo\n")); +#endif +} + +QTEST_MAIN(tst_QV4Assembler) + +#include "tst_qv4assembler.moc" + diff --git a/tools/qmlcachegen/Qt5QuickCompilerConfig.cmake b/tools/qmlcachegen/Qt5QuickCompilerConfig.cmake index 6fe1662995..56cb3fb55e 100644 --- a/tools/qmlcachegen/Qt5QuickCompilerConfig.cmake +++ b/tools/qmlcachegen/Qt5QuickCompilerConfig.cmake @@ -44,7 +44,7 @@ function(QTQUICK_COMPILER_ADD_RESOURCES outfiles) set(rcc_file_with_compilation_units) - exec_program(${rcc_path} ARGS -list ${input_resource} OUTPUT_VARIABLE rcc_contents) + exec_program(${rcc_path} ARGS -list \"${input_resource}\" OUTPUT_VARIABLE rcc_contents) string(REGEX REPLACE "[\r\n]+" ";" rcc_contents ${rcc_contents}) foreach(it ${rcc_contents}) get_filename_component(extension ${it} EXT) diff --git a/tools/qmlcachegen/generateloader.cpp b/tools/qmlcachegen/generateloader.cpp index a2e673d15a..96528a9477 100644 --- a/tools/qmlcachegen/generateloader.cpp +++ b/tools/qmlcachegen/generateloader.cpp @@ -51,6 +51,7 @@ QString symbolNamespaceForPath(const QString &relativePath) symbol.replace(QLatin1Char('.'), QLatin1Char('_')); symbol.replace(QLatin1Char('+'), QLatin1Char('_')); symbol.replace(QLatin1Char('-'), QLatin1Char('_')); + symbol.replace(QLatin1Char(' '), QLatin1Char('_')); return symbol; } |