diff options
Diffstat (limited to 'src/qml')
45 files changed, 766 insertions, 134 deletions
diff --git a/src/qml/animations/qanimationgroupjob_p.h b/src/qml/animations/qanimationgroupjob_p.h index b01b2f3b36..a27c9195dd 100644 --- a/src/qml/animations/qanimationgroupjob_p.h +++ b/src/qml/animations/qanimationgroupjob_p.h @@ -72,7 +72,7 @@ public: QAbstractAnimationJob *firstChild() const { return m_firstChild; } QAbstractAnimationJob *lastChild() const { return m_lastChild; } - void clear(); + virtual void clear(); //called by QAbstractAnimationJob virtual void uncontrolledAnimationFinished(QAbstractAnimationJob *animation); diff --git a/src/qml/animations/qsequentialanimationgroupjob.cpp b/src/qml/animations/qsequentialanimationgroupjob.cpp index 22e20d9268..0595141d60 100644 --- a/src/qml/animations/qsequentialanimationgroupjob.cpp +++ b/src/qml/animations/qsequentialanimationgroupjob.cpp @@ -204,6 +204,13 @@ int QSequentialAnimationGroupJob::duration() const return ret; } +void QSequentialAnimationGroupJob::clear() +{ + m_currentAnimation = nullptr; + m_previousLoop = 0; + QAnimationGroupJob::clear(); +} + void QSequentialAnimationGroupJob::updateCurrentTime(int currentTime) { if (!m_currentAnimation) diff --git a/src/qml/animations/qsequentialanimationgroupjob_p.h b/src/qml/animations/qsequentialanimationgroupjob_p.h index 13f9806be1..34e8fe1e08 100644 --- a/src/qml/animations/qsequentialanimationgroupjob_p.h +++ b/src/qml/animations/qsequentialanimationgroupjob_p.h @@ -68,6 +68,7 @@ public: int duration() const override; QAbstractAnimationJob *currentAnimation() const { return m_currentAnimation; } + void clear() override; protected: void updateCurrentTime(int) override; diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index 2421e8c1ea..84fd66b114 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -2510,8 +2510,6 @@ QmlIR::Object *IRLoader::loadObject(const QV4::CompiledData::Object *serializedO f->location = compiledFunction->location; f->nameIndex = compiledFunction->nameIndex; - const QString name = unit->stringAtInternal(compiledFunction->nameIndex); - f->formals.allocate(pool, int(compiledFunction->nFormals)); const quint32_le *formalNameIdx = compiledFunction->formalsTable(); for (uint i = 0; i < compiledFunction->nFormals; ++i, ++formalNameIdx) diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index f570af4819..cdba21604d 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -2563,9 +2563,6 @@ bool Codegen::visit(ObjectPattern *ast) TailCallBlocker blockTailCalls(this); - QVector<QPair<Reference, ObjectPropertyValue>> computedProperties; - QMap<QString, ObjectPropertyValue> valueMap; - RegisterScope scope(this); QStringList members; diff --git a/src/qml/configure.json b/src/qml/configure.json index 878ec0119b..c7b145f46f 100644 --- a/src/qml/configure.json +++ b/src/qml/configure.json @@ -8,6 +8,7 @@ "commandline": { "options": { "qml-network": "boolean", + "qml-tracing": "boolean", "qml-debug": "boolean" } }, @@ -38,6 +39,13 @@ "condition": "features.network", "output": [ "publicFeature" ] }, + "qml-tracing": { + "label": "QML tracing JIT support", + "purpose": "Provides a JIT that uses trace information generated by the interpreter.", + "section": "QML", + "output": [ "publicFeature" ], + "autoDetect": false + }, "qml-debug": { "label": "QML debugging and profiling support", "purpose": "Provides infrastructure and plugins for debugging and profiling.", @@ -131,6 +139,7 @@ "entries": [ "qml-network", "qml-debug", + "qml-tracing", "qml-sequence-object", "qml-list-model", "qml-xml-http-request", diff --git a/src/qml/doc/src/cppintegration/data.qdoc b/src/qml/doc/src/cppintegration/data.qdoc index 8ebbd28737..171b2b6a11 100644 --- a/src/qml/doc/src/cppintegration/data.qdoc +++ b/src/qml/doc/src/cppintegration/data.qdoc @@ -284,6 +284,9 @@ In particular, QML currently supports: \li \c {std::vector<bool>} \endlist +and all registered QList, QVector, QQueue, QStack, QSet, QLinkedList, std::list, +std::vector that contain a type marked with \l Q_DECLARE_METATYPE. + These sequence types are implemented directly in terms of the underlying C++ sequence. There are two ways in which such sequences can be exposed to QML: as a Q_PROPERTY of the given sequence type; or as the return type of a diff --git a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc index 2bb1fcac61..15e8e4c52c 100644 --- a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc +++ b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc @@ -540,6 +540,58 @@ Internally, however, the rectangle can correctly set its \c color property and refer to the actual defined property rather than the alias. +\section4 Property Aliases and Types + +Property aliases cannot have explicit type specifications. The type of a +property alias is the \e declared type of the property or object it refers to. +Therefore, if you create an alias to an object referenced via id with extra +properties declared inline, the extra properties won't be accessible through +the alias: + +\code +// MyItem.qml +Item { + property alias inner: innerItem + + Item { + id: innerItem + property int extraProperty + } +} +\code + +You cannot initialize \a inner.extraProperty from outside of this component, as +inner is only an \a Item: + +\code +// main.qml +MyItem { + inner.extraProperty: 5 // fails +} +\code + +However, if you extract the inner object into a separate component with a +dedicated .qml file, you can instantiate that component instead and have all +its properties available through the alias: + +\code +// MainItem.qml +Item { + // Now you can access inner.extraProperty, as inner is now an ExtraItem + property alias inner: innerItem + + ExtraItem { + id: innerItem + } +} + +// ExtraItem.qml +Item { + property int extraProperty +} +\code + + \section3 Default Properties An object definition can have a single \e default property. A default property diff --git a/src/qml/jit/qv4assemblercommon.cpp b/src/qml/jit/qv4assemblercommon.cpp index b302ac6403..bc17be229d 100644 --- a/src/qml/jit/qv4assemblercommon.cpp +++ b/src/qml/jit/qv4assemblercommon.cpp @@ -43,6 +43,7 @@ #include "qv4engine_p.h" #include "qv4assemblercommon_p.h" #include <private/qv4function_p.h> +#include <private/qv4functiontable_p.h> #include <private/qv4runtime_p.h> #include <assembler/MacroAssemblerCodeRef.h> @@ -112,17 +113,6 @@ static void printDisassembledOutputWithCalls(QByteArray processedOutput, qDebug("%s", processedOutput.constData()); } -static QByteArray functionName(Function *function) -{ - QByteArray name = function->name()->toQString().toUtf8(); - if (name.isEmpty()) { - name = QByteArray::number(reinterpret_cast<quintptr>(function), 16); - name.prepend("QV4::Function(0x"); - name.append(')'); - } - return name; -} - JIT::PlatformAssemblerCommon::~PlatformAssemblerCommon() {} @@ -147,7 +137,9 @@ void PlatformAssemblerCommon::link(Function *function, const char *jitKind) buf.open(QIODevice::WriteOnly); WTF::setDataFile(new QIODevicePrintStream(&buf)); - QByteArray name = functionName(function); + // We use debugAddress here because it's actually for debugging and hidden behind an + // environment variable. + const QByteArray name = Function::prettyName(function, linkBuffer.debugAddress()).toUtf8(); codeRef = linkBuffer.finalizeCodeWithDisassembly(jitKind, "function %s", name.constData()); WTF::setDataFile(stderr); @@ -159,31 +151,9 @@ void PlatformAssemblerCommon::link(Function *function, const char *jitKind) function->codeRef = new JSC::MacroAssemblerCodeRef(codeRef); function->jittedCode = reinterpret_cast<Function::JittedCode>(function->codeRef->code().executableAddress()); - // This implements writing of JIT'd addresses so that perf can find the - // symbol names. - // - // Perf expects the mapping to be in a certain place and have certain - // content, for more information, see: - // https://github.com/torvalds/linux/blob/master/tools/perf/Documentation/jit-interface.txt - static bool doProfile = !qEnvironmentVariableIsEmpty("QV4_PROFILE_WRITE_PERF_MAP"); - if (Q_UNLIKELY(doProfile)) { - static QFile perfMapFile(QString::fromLatin1("/tmp/perf-%1.map") - .arg(QCoreApplication::applicationPid())); - static const bool isOpen = perfMapFile.open(QIODevice::WriteOnly); - if (!isOpen) { - qWarning("QV4::JIT::Assembler: Cannot write perf map file."); - doProfile = false; - } else { - perfMapFile.write(QByteArray::number(reinterpret_cast<quintptr>( - codeRef.code().executableAddress()), 16)); - perfMapFile.putChar(' '); - perfMapFile.write(QByteArray::number(static_cast<qsizetype>(codeRef.size()), 16)); - perfMapFile.putChar(' '); - perfMapFile.write(functionName(function)); - perfMapFile.putChar('\n'); - perfMapFile.flush(); - } - } + generateFunctionTable(function, &codeRef); + + linkBuffer.makeExecutable(); } void PlatformAssemblerCommon::prepareCallWithArgCount(int argc) diff --git a/src/qml/jsruntime/jsruntime.pri b/src/qml/jsruntime/jsruntime.pri index 5ec55b960b..a24ee0a188 100644 --- a/src/qml/jsruntime/jsruntime.pri +++ b/src/qml/jsruntime/jsruntime.pri @@ -147,7 +147,8 @@ HEADERS += \ $$PWD/qv4value_p.h \ $$PWD/qv4string_p.h \ $$PWD/qv4util_p.h \ - $$PWD/qv4value_p.h + $$PWD/qv4value_p.h \ + $$PWD/qv4functiontable_p.h SOURCES += \ $$PWD/qv4engine.cpp \ @@ -156,6 +157,23 @@ SOURCES += \ $$PWD/qv4value.cpp \ $$PWD/qv4executableallocator.cpp +qmldevtools_build { + SOURCES += \ + $$PWD/qv4functiontable_noop.cpp +} else:win32 { + !winrt:equals(QT_ARCH, x86_64) { + SOURCES += \ + $$PWD/qv4functiontable_win64.cpp + } else { + SOURCES += \ + $$PWD/qv4functiontable_noop.cpp + } +} else { + SOURCES += \ + $$PWD/qv4functiontable_unix.cpp +} + + valgrind { DEFINES += V4_USE_VALGRIND } diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp index a13fb37a52..21c6a5d06b 100644 --- a/src/qml/jsruntime/qv4dateobject.cpp +++ b/src/qml/jsruntime/qv4dateobject.cpp @@ -670,17 +670,17 @@ static inline QString ToTimeString(double t) static inline QString ToLocaleString(double t) { - return ToDateTime(t, Qt::LocalTime).toString(Qt::LocaleDate); + return ToDateTime(t, Qt::LocalTime).toString(Qt::DefaultLocaleShortDate); } static inline QString ToLocaleDateString(double t) { - return ToDateTime(t, Qt::LocalTime).date().toString(Qt::LocaleDate); + return ToDateTime(t, Qt::LocalTime).date().toString(Qt::DefaultLocaleShortDate); } static inline QString ToLocaleTimeString(double t) { - return ToDateTime(t, Qt::LocalTime).time().toString(Qt::LocaleDate); + return ToDateTime(t, Qt::LocalTime).time().toString(Qt::DefaultLocaleShortDate); } static double getLocalTZA() diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 57a364b205..ff7bcb63fa 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -1597,6 +1597,22 @@ static QV4::ReturnedValue variantListToJS(QV4::ExecutionEngine *v4, const QVaria return a.asReturnedValue(); } +// Converts a QSequentialIterable to JS. +// The result is a new Array object with length equal to the length +// of the QSequentialIterable, and the elements being the QSequentialIterable's +// elements converted to JS, recursively. +static QV4::ReturnedValue sequentialIterableToJS(QV4::ExecutionEngine *v4, const QSequentialIterable &lst) +{ + QV4::Scope scope(v4); + QV4::ScopedArrayObject a(scope, v4->newArrayObject()); + a->arrayReserve(lst.size()); + QV4::ScopedValue v(scope); + for (int i = 0; i < lst.size(); i++) + a->arrayPut(i, (v = variantToJS(v4, lst.at(i)))); + a->setArrayLengthUnchecked(lst.size()); + return a.asReturnedValue(); +} + // Converts a QVariantMap to JS. // The result is a new Object object with property names being // the keys of the QVariantMap, and values being the values of @@ -1701,9 +1717,18 @@ QV4::ReturnedValue ExecutionEngine::metaTypeToJS(int type, const void *data) return QV4::Encode::null(); } QMetaType mt(type); - if (mt.flags() & QMetaType::IsGadget) { - Q_ASSERT(mt.metaObject()); - return QV4::QQmlValueTypeWrapper::create(this, QVariant(type, data), mt.metaObject(), type); + if (auto metaObject = mt.metaObject()) { + auto flags = mt.flags(); + if (flags & QMetaType::IsGadget) { + return QV4::QQmlValueTypeWrapper::create(this, QVariant(type, data), metaObject, type); + } else if (flags & QMetaType::PointerToQObject) { + return QV4::QObjectWrapper::wrap(this, *reinterpret_cast<QObject* const *>(data)); + } + } + if (QMetaType::hasRegisteredConverterFunction(type, qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>())) { + auto v = QVariant(type, data); + QSequentialIterable lst = v.value<QSequentialIterable>(); + return sequentialIterableToJS(this, lst); } // Fall back to wrapping in a QVariant. return QV4::Encode(newVariantObject(QVariant(type, data))); diff --git a/src/qml/jsruntime/qv4executableallocator.cpp b/src/qml/jsruntime/qv4executableallocator.cpp index 6f04a712e6..c836d121e3 100644 --- a/src/qml/jsruntime/qv4executableallocator.cpp +++ b/src/qml/jsruntime/qv4executableallocator.cpp @@ -38,17 +38,23 @@ ****************************************************************************/ #include "qv4executableallocator_p.h" +#include "qv4functiontable_p.h" #include <wtf/StdLibExtras.h> #include <wtf/PageAllocation.h> using namespace QV4; -void *ExecutableAllocator::Allocation::start() const +void *ExecutableAllocator::Allocation::exceptionHandler() const { return reinterpret_cast<void*>(addr); } +void *ExecutableAllocator::Allocation::start() const +{ + return reinterpret_cast<void*>(addr + exceptionHandlerSize()); +} + void ExecutableAllocator::Allocation::deallocate(ExecutableAllocator *allocator) { if (isValid()) @@ -162,7 +168,7 @@ ExecutableAllocator::Allocation *ExecutableAllocator::allocate(size_t size) Allocation *allocation = nullptr; // Code is best aligned to 16-byte boundaries. - size = WTF::roundUpToMultipleOf(16, size); + size = WTF::roundUpToMultipleOf(16, size + exceptionHandlerSize()); QMultiMap<size_t, Allocation*>::Iterator it = freeAllocations.lowerBound(size); if (it != freeAllocations.end()) { diff --git a/src/qml/jsruntime/qv4executableallocator_p.h b/src/qml/jsruntime/qv4executableallocator_p.h index 375c9a365f..013c6d7120 100644 --- a/src/qml/jsruntime/qv4executableallocator_p.h +++ b/src/qml/jsruntime/qv4executableallocator_p.h @@ -86,6 +86,7 @@ public: , free(true) {} + void *exceptionHandler() const; void *start() const; void invalidate() { addr = 0; } bool isValid() const { return addr != 0; } diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp index 941c37de5b..2a82d96f1d 100644 --- a/src/qml/jsruntime/qv4function.cpp +++ b/src/qml/jsruntime/qv4function.cpp @@ -46,6 +46,7 @@ #include "qv4lookup_p.h" #include <private/qv4mm_p.h> #include <private/qv4identifiertable_p.h> +#include <private/qv4functiontable_p.h> #include <assembler/MacroAssemblerCodeRef.h> #include <private/qv4vme_moth_p.h> #include <private/qqmlglobal_p.h> @@ -98,7 +99,10 @@ Function::Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit, Function::~Function() { - delete codeRef; + if (codeRef) { + destroyFunctionTable(this, codeRef); + delete codeRef; + } } void Function::updateInternalClass(ExecutionEngine *engine, const QList<QByteArray> ¶meters) @@ -145,6 +149,17 @@ void Function::updateInternalClass(ExecutionEngine *engine, const QList<QByteArr nFormals = parameters.size(); } +QString Function::prettyName(const Function *function, const void *code) +{ + QString prettyName = function ? function->name()->toQString() : QString(); + if (prettyName.isEmpty()) { + prettyName = QString::number(reinterpret_cast<quintptr>(code), 16); + prettyName.prepend(QLatin1String("QV4::Function(0x")); + prettyName.append(QLatin1Char(')')); + } + return prettyName; +} + QQmlSourceLocation Function::sourceLocation() const { return QQmlSourceLocation(sourceFile(), compiledFunction->location.line, compiledFunction->location.column); diff --git a/src/qml/jsruntime/qv4function_p.h b/src/qml/jsruntime/qv4function_p.h index 029dd7786b..86343ea061 100644 --- a/src/qml/jsruntime/qv4function_p.h +++ b/src/qml/jsruntime/qv4function_p.h @@ -89,9 +89,12 @@ struct Q_QML_EXPORT Function { // used when dynamically assigning signal handlers (QQmlConnection) void updateInternalClass(ExecutionEngine *engine, const QList<QByteArray> ¶meters); - inline Heap::String *name() { + inline Heap::String *name() const { return compilationUnit->runtimeStrings[compiledFunction->nameIndex]; } + + static QString prettyName(const Function *function, const void *address); + inline QString sourceFile() const { return compilationUnit->fileName(); } inline QUrl finalUrl() const { return compilationUnit->finalUrl(); } diff --git a/src/qml/jsruntime/qv4functiontable_noop.cpp b/src/qml/jsruntime/qv4functiontable_noop.cpp new file mode 100644 index 0000000000..31c198eb00 --- /dev/null +++ b/src/qml/jsruntime/qv4functiontable_noop.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** 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-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qv4functiontable_p.h" + +QT_BEGIN_NAMESPACE + +namespace QV4 { + +void generateFunctionTable(Function *function, JSC::MacroAssemblerCodeRef *codeRef) +{ + Q_UNUSED(function); + Q_UNUSED(codeRef); +} + +void destroyFunctionTable(Function *function, JSC::MacroAssemblerCodeRef *codeRef) +{ + Q_UNUSED(function); + Q_UNUSED(codeRef); +} + +size_t exceptionHandlerSize() +{ + return 0; +} + +} // QV4 + +QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4functiontable_p.h b/src/qml/jsruntime/qv4functiontable_p.h new file mode 100644 index 0000000000..69e3d2bdd5 --- /dev/null +++ b/src/qml/jsruntime/qv4functiontable_p.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** 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-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QV4FUNCTIONTABLE_P_H +#define QV4FUNCTIONTABLE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qv4global_p.h" + +namespace JSC { +class MacroAssemblerCodeRef; +} + +QT_BEGIN_NAMESPACE + +namespace QV4 { + +struct Function; + +void generateFunctionTable(Function *function, JSC::MacroAssemblerCodeRef *codeRef); +void destroyFunctionTable(Function *function, JSC::MacroAssemblerCodeRef *codeRef); + +size_t exceptionHandlerSize(); + +} + +QT_END_NAMESPACE + +#endif // QV4FUNCTIONTABLE_P_H diff --git a/src/qml/jsruntime/qv4functiontable_unix.cpp b/src/qml/jsruntime/qv4functiontable_unix.cpp new file mode 100644 index 0000000000..25b5c27161 --- /dev/null +++ b/src/qml/jsruntime/qv4functiontable_unix.cpp @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** 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-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qv4functiontable_p.h" +#include "qv4function_p.h" + +#include <assembler/MacroAssemblerCodeRef.h> + +#include <QtCore/qfile.h> +#include <QtCore/qcoreapplication.h> + +QT_BEGIN_NAMESPACE + +namespace QV4 { + +void generateFunctionTable(Function *function, JSC::MacroAssemblerCodeRef *codeRef) +{ + // This implements writing of JIT'd addresses so that perf can find the + // symbol names. + // + // Perf expects the mapping to be in a certain place and have certain + // content, for more information, see: + // https://github.com/torvalds/linux/blob/master/tools/perf/Documentation/jit-interface.txt + static bool doProfile = !qEnvironmentVariableIsEmpty("QV4_PROFILE_WRITE_PERF_MAP"); + if (Q_UNLIKELY(doProfile)) { + static QFile perfMapFile(QString::fromLatin1("/tmp/perf-%1.map") + .arg(QCoreApplication::applicationPid())); + static const bool isOpen = perfMapFile.open(QIODevice::WriteOnly); + if (!isOpen) { + qWarning("QV4::JIT::Assembler: Cannot write perf map file."); + doProfile = false; + } else { + const void *address = codeRef->code().executableAddress(); + perfMapFile.write(QByteArray::number(reinterpret_cast<quintptr>(address), 16)); + perfMapFile.putChar(' '); + perfMapFile.write(QByteArray::number(static_cast<qsizetype>(codeRef->size()), 16)); + perfMapFile.putChar(' '); + perfMapFile.write(Function::prettyName(function, address).toUtf8()); + perfMapFile.putChar('\n'); + perfMapFile.flush(); + } + } +} + +void destroyFunctionTable(Function *function, JSC::MacroAssemblerCodeRef *codeRef) +{ + Q_UNUSED(function); + Q_UNUSED(codeRef); + + // It's not advisable to remove things from the perf map file, as it's primarily used to analyze + // a trace after the application has terminated. We want to know about all functions that were + // ever jitted then. If the memory ranges overlap, we will have a problem when analyzing the + // trace. The JIT should try to avoid this. +} + +size_t exceptionHandlerSize() +{ + return 0; +} + +} // QV4 + +QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4functiontable_win64.cpp b/src/qml/jsruntime/qv4functiontable_win64.cpp new file mode 100644 index 0000000000..bc5b24f6cd --- /dev/null +++ b/src/qml/jsruntime/qv4functiontable_win64.cpp @@ -0,0 +1,153 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** 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-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qv4functiontable_p.h" + +#include <assembler/MacroAssemblerCodeRef.h> + +#include <QtCore/qdebug.h> + +#include <Windows.h> + +QT_BEGIN_NAMESPACE + +namespace QV4 { + +enum UnwindOpcode: UINT8 +{ + UWOP_PUSH_NONVOL = 0, /* info == register number */ + UWOP_ALLOC_LARGE, /* no info, alloc size in next 2 slots */ + UWOP_ALLOC_SMALL, /* info == size of allocation / 8 - 1 */ + UWOP_SET_FPREG, /* no info, FP = RSP + UNWIND_INFO.FPRegOffset*16 */ + UWOP_SAVE_NONVOL, /* info == register number, offset in next slot */ + UWOP_SAVE_NONVOL_FAR, /* info == register number, offset in next 2 slots */ + UWOP_SAVE_XMM128 = 8, /* info == XMM reg number, offset in next slot */ + UWOP_SAVE_XMM128_FAR, /* info == XMM reg number, offset in next 2 slots */ + UWOP_PUSH_MACHFRAME /* info == 0: no error-code, 1: error-code */ +}; + +enum Register : UINT8 +{ + RAX = 0, + RCX, + RDX, + RBX, + RSP, + RBP, + RSI, + RDI, + NONE = 15 +}; + +struct UnwindCode +{ + UnwindCode(UINT8 offset, UnwindOpcode operation, Register info) + : offset(offset), operation(operation), info(info) + {} + + UINT8 offset; + UINT8 operation: 4; + UINT8 info: 4; +}; + +struct UnwindInfo +{ + UINT8 Version : 3; + UINT8 Flags : 5; + UINT8 SizeOfProlog; + UINT8 CountOfUnwindCodes; + UINT8 FrameRegister : 4; + UINT8 FrameRegisterOffset : 4; + UnwindCode UnwindCodes[2]; +}; + +struct ExceptionHandlerRecord +{ + RUNTIME_FUNCTION handler; + UnwindInfo info; +}; + +void generateFunctionTable(Function *, JSC::MacroAssemblerCodeRef *codeRef) +{ + ExceptionHandlerRecord *record = reinterpret_cast<ExceptionHandlerRecord *>( + codeRef->executableMemory()->exceptionHandler()); + + record->info.Version = 1; + record->info.Flags = 0; + record->info.SizeOfProlog = 4; + record->info.CountOfUnwindCodes = 2; + record->info.FrameRegister = RBP; + record->info.FrameRegisterOffset = 0; + + // Push frame pointer + record->info.UnwindCodes[1] = UnwindCode(1, UWOP_PUSH_NONVOL, RBP); + // Set frame pointer from stack pointer + record->info.UnwindCodes[0] = UnwindCode(4, UWOP_SET_FPREG, NONE); + + const quintptr codeStart = quintptr(codeRef->code().executableAddress()); + const quintptr codeSize = codeRef->size(); + + record->handler.BeginAddress = DWORD(codeStart - quintptr(record)); + record->handler.EndAddress = DWORD(codeStart + codeSize - quintptr(record)); + record->handler.UnwindData = offsetof(ExceptionHandlerRecord, info); + + if (!RtlAddFunctionTable(&record->handler, 1, DWORD64(record))) { + const unsigned int errorCode = GetLastError(); + qWarning() << "Failed to install win64 unwind hook. Error code:" << errorCode; + } +} + +void destroyFunctionTable(Function *, JSC::MacroAssemblerCodeRef *codeRef) +{ + ExceptionHandlerRecord *record = reinterpret_cast<ExceptionHandlerRecord *>( + codeRef->executableMemory()->exceptionHandler()); + if (!RtlDeleteFunctionTable(&record->handler)) { + const unsigned int errorCode = GetLastError(); + qWarning() << "Failed to remove win64 unwind hook. Error code:" << errorCode; + } +} + +size_t exceptionHandlerSize() +{ + return sizeof(ExceptionHandlerRecord); +} + +} // QV4 + +QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4variantobject.cpp b/src/qml/jsruntime/qv4variantobject.cpp index ef0877dbd0..e4d8bcaafc 100644 --- a/src/qml/jsruntime/qv4variantobject.cpp +++ b/src/qml/jsruntime/qv4variantobject.cpp @@ -138,11 +138,14 @@ ReturnedValue VariantPrototype::method_toString(const FunctionObject *b, const V const VariantObject *o = thisObject->as<QV4::VariantObject>(); if (!o) RETURN_UNDEFINED(); - QString result = o->d()->data().toString(); - if (result.isEmpty() && !o->d()->data().canConvert(QVariant::String)) { - result = QLatin1String("QVariant(") - + QLatin1String(o->d()->data().typeName()) - + QLatin1Char(')'); + const QVariant variant = o->d()->data(); + QString result = variant.toString(); + if (result.isEmpty() && !variant.canConvert(QVariant::String)) { + QDebug dbg(&result); + dbg << variant; + // QDebug appends a space, we're not interested in continuing the stream so we chop it off. + // Can't use nospace() because it would affect the debug-stream operator of the variant. + result.chop(1); } return Encode(v4->newString(result)); } diff --git a/src/qml/parser/parser.pri b/src/qml/parser/parser.pri index adab4ef9a2..2c0175c94b 100644 --- a/src/qml/parser/parser.pri +++ b/src/qml/parser/parser.pri @@ -8,7 +8,8 @@ HEADERS += \ $$PWD/qqmljsglobal_p.h \ $$PWD/qqmljskeywords_p.h \ $$PWD/qqmljsengine_p.h \ - $$PWD/qqmljsglobal_p.h + $$PWD/qqmljsglobal_p.h \ + $$PWD/qqmljssourcelocation_p.h SOURCES += \ $$PWD/qqmljsast.cpp \ diff --git a/src/qml/parser/qqmljsastfwd_p.h b/src/qml/parser/qqmljsastfwd_p.h index 996264db59..7795e0ce71 100644 --- a/src/qml/parser/qqmljsastfwd_p.h +++ b/src/qml/parser/qqmljsastfwd_p.h @@ -41,6 +41,7 @@ #define QQMLJSAST_FWD_P_H #include "qqmljsglobal_p.h" +#include "qqmljssourcelocation_p.h" #include <QtCore/qglobal.h> @@ -59,27 +60,6 @@ QT_QML_BEGIN_NAMESPACE namespace QQmlJS { namespace AST { -class SourceLocation -{ -public: - explicit SourceLocation(quint32 offset = 0, quint32 length = 0, quint32 line = 0, quint32 column = 0) - : offset(offset), length(length), - startLine(line), startColumn(column) - { } - - bool isValid() const { return length != 0; } - - quint32 begin() const { return offset; } - quint32 end() const { return offset + length; } - -// attributes - // ### encode - quint32 offset; - quint32 length; - quint32 startLine; - quint32 startColumn; -}; - class Visitor; class Node; class ExpressionNode; diff --git a/src/qml/parser/qqmljsengine_p.h b/src/qml/parser/qqmljsengine_p.h index 1de907d296..07b5026eb9 100644 --- a/src/qml/parser/qqmljsengine_p.h +++ b/src/qml/parser/qqmljsengine_p.h @@ -52,8 +52,8 @@ // #include "qqmljsglobal_p.h" -#include "qqmljsastfwd_p.h" #include "qqmljsmemorypool_p.h" +#include "qqmljssourcelocation_p.h" #include <QtCore/qstring.h> #include <QtCore/qset.h> @@ -95,7 +95,7 @@ public: class QML_PARSER_EXPORT DiagnosticMessage { public: - enum Kind { Warning, Error }; + enum Kind { Hint, Warning, Error }; DiagnosticMessage() {} diff --git a/src/qml/parser/qqmljssourcelocation_p.h b/src/qml/parser/qqmljssourcelocation_p.h new file mode 100644 index 0000000000..dc307ba168 --- /dev/null +++ b/src/qml/parser/qqmljssourcelocation_p.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** 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-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQMLJSSOURCELOCATION_P_H +#define QQMLJSSOURCELOCATION_P_H + +#include "qqmljsglobal_p.h" + +#include <QtCore/qglobal.h> + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_QML_BEGIN_NAMESPACE + +namespace QQmlJS { namespace AST { + +class SourceLocation +{ +public: + explicit SourceLocation(quint32 offset = 0, quint32 length = 0, quint32 line = 0, quint32 column = 0) + : offset(offset), length(length), + startLine(line), startColumn(column) + { } + + bool isValid() const { return length != 0; } + + quint32 begin() const { return offset; } + quint32 end() const { return offset + length; } + +// attributes + // ### encode + quint32 offset; + quint32 length; + quint32 startLine; + quint32 startColumn; +}; + +} } // namespace AST + +QT_QML_END_NAMESPACE + +#endif diff --git a/src/qml/qml.pro b/src/qml/qml.pro index db59140f06..94717a8f43 100644 --- a/src/qml/qml.pro +++ b/src/qml/qml.pro @@ -73,6 +73,7 @@ include(jsruntime/jsruntime.pri) include(jit/jit.pri) include(qml/qml.pri) include(debugger/debugger.pri) +include(qmldirparser/qmldirparser.pri) qtConfig(qml-animation) { include(animations/animations.pri) } diff --git a/src/qml/qml/qml.pri b/src/qml/qml/qml.pri index 6d69294c17..ca13ce9211 100644 --- a/src/qml/qml/qml.pri +++ b/src/qml/qml/qml.pri @@ -18,7 +18,6 @@ SOURCES += \ $$PWD/qqmlparserstatus.cpp \ $$PWD/qqmltypeloader.cpp \ $$PWD/qqmlinfo.cpp \ - $$PWD/qqmlerror.cpp \ $$PWD/qqmlvaluetype.cpp \ $$PWD/qqmlcleanup.cpp \ $$PWD/qqmlpropertycache.cpp \ @@ -44,7 +43,6 @@ SOURCES += \ $$PWD/qqmltypewrapper.cpp \ $$PWD/qqmlfileselector.cpp \ $$PWD/qqmlobjectcreator.cpp \ - $$PWD/qqmldirparser.cpp \ $$PWD/qqmldelayedcallqueue.cpp \ $$PWD/qqmlloggingcategory.cpp @@ -81,7 +79,6 @@ HEADERS += \ $$PWD/qqmllist.h \ $$PWD/qqmllist_p.h \ $$PWD/qqmldata_p.h \ - $$PWD/qqmlerror.h \ $$PWD/qqmlvaluetype_p.h \ $$PWD/qqmlcleanup_p.h \ $$PWD/qqmlpropertycache_p.h \ @@ -112,7 +109,6 @@ HEADERS += \ $$PWD/qqmlfileselector_p.h \ $$PWD/qqmlfileselector.h \ $$PWD/qqmlobjectcreator_p.h \ - $$PWD/qqmldirparser_p.h \ $$PWD/qqmldelayedcallqueue_p.h \ $$PWD/qqmlloggingcategory_p.h diff --git a/src/qml/qml/qqmlabstracturlinterceptor.h b/src/qml/qml/qqmlabstracturlinterceptor.h index 665b37fb3a..af231f51b2 100644 --- a/src/qml/qml/qqmlabstracturlinterceptor.h +++ b/src/qml/qml/qqmlabstracturlinterceptor.h @@ -55,8 +55,8 @@ public: UrlString = 0x1000 }; - QQmlAbstractUrlInterceptor() {} - virtual ~QQmlAbstractUrlInterceptor() {} + QQmlAbstractUrlInterceptor() = default; + virtual ~QQmlAbstractUrlInterceptor() = default; virtual QUrl intercept(const QUrl &path, DataType type) = 0; }; diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index e38f379eb0..024ec29a56 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -316,7 +316,7 @@ protected: break; default: if (const QV4::QQmlValueTypeWrapper *vtw = result.as<const QV4::QQmlValueTypeWrapper>()) { - if (vtw->d()->valueType->typeId == pd->propType()) { + if (vtw->d()->valueType->metaType.id() == pd->propType()) { return vtw->write(m_target.data(), pd->coreIndex()); } } diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h index 3caa6ec138..70e188dc1c 100644 --- a/src/qml/qml/qqmlengine_p.h +++ b/src/qml/qml/qqmlengine_p.h @@ -64,7 +64,6 @@ #include "qqmlproperty_p.h" #include "qqmlpropertycache_p.h" #include "qqmlmetatype_p.h" -#include "qqmldirparser_p.h" #include <private/qintrusivelist_p.h> #include <private/qrecyclepool_p.h> #include <private/qfieldlist_p.h> @@ -80,6 +79,7 @@ #include <private/qv8engine_p.h> #include <private/qjsengine_p.h> +#include <private/qqmldirparser_p.h> QT_BEGIN_NAMESPACE diff --git a/src/qml/qml/qqmlexpression.cpp b/src/qml/qml/qqmlexpression.cpp index 0c1ffbf3a0..ac2629979f 100644 --- a/src/qml/qml/qqmlexpression.cpp +++ b/src/qml/qml/qqmlexpression.cpp @@ -46,6 +46,7 @@ #include "qqmlscriptstring_p.h" #include "qqmlbinding_p.h" #include <private/qv8engine_p.h> +#include <private/qqmlsourcecoordinate_p.h> #include <QtCore/qdebug.h> diff --git a/src/qml/qml/qqmlextensioninterface.h b/src/qml/qml/qqmlextensioninterface.h index c2d20ef0a3..d2eb79c5c9 100644 --- a/src/qml/qml/qqmlextensioninterface.h +++ b/src/qml/qml/qqmlextensioninterface.h @@ -51,14 +51,14 @@ class QQmlEngine; class Q_QML_EXPORT QQmlTypesExtensionInterface { public: - virtual ~QQmlTypesExtensionInterface() {} + virtual ~QQmlTypesExtensionInterface() = default; virtual void registerTypes(const char *uri) = 0; }; class Q_QML_EXPORT QQmlExtensionInterface : public QQmlTypesExtensionInterface { public: - ~QQmlExtensionInterface() override {} + ~QQmlExtensionInterface() override = default; virtual void initializeEngine(QQmlEngine *engine, const char *uri) = 0; }; diff --git a/src/qml/qml/qqmlglobal_p.h b/src/qml/qml/qqmlglobal_p.h index 302fdd56c4..818537560c 100644 --- a/src/qml/qml/qqmlglobal_p.h +++ b/src/qml/qml/qqmlglobal_p.h @@ -174,16 +174,6 @@ T qmlobject_cast(QObject *object) return 0; } -inline quint16 qmlSourceCoordinate(int n) -{ - return (n > 0 && n <= static_cast<int>(USHRT_MAX)) ? static_cast<quint16>(n) : 0; -} - -inline int qmlSourceCoordinate(quint16 n) -{ - return (n == 0) ? -1 : static_cast<int>(n); -} - #define IS_SIGNAL_CONNECTED(Sender, SenderType, Name, Arguments) \ do { \ QObject *sender = (Sender); \ diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index 11806a89a0..083917d20f 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -1087,13 +1087,6 @@ QString QQmlType::noCreationReason() const return d->extraData.cd->noCreationReason; } -int QQmlType::createSize() const -{ - if (!d || d->regType != CppType) - return 0; - return d->extraData.cd->allocationSize; -} - bool QQmlType::isCreatable() const { return d && d->regType == CppType && d->extraData.cd->newFunc; diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index b3ca6acd64..2a45ddb4bb 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -196,8 +196,6 @@ public: typedef void (*CreateFunc)(void *); CreateFunc createFunction() const; - int createSize() const; - QQmlCustomParser *customParser() const; bool isCreatable() const; diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 9df502f778..fc48957bcb 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -1891,8 +1891,6 @@ bool QQmlTypeLoader::fileExists(const QString &path, const QString &file) if (!fileSet) return false; - QString absoluteFilePath; - bool *value = fileSet->object(file); if (value) { return *value; diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp index 2b21591017..e92488f9f6 100644 --- a/src/qml/qml/qqmlvaluetype.cpp +++ b/src/qml/qml/qqmlvaluetype.cpp @@ -191,7 +191,6 @@ void QQmlValueTypeFactory::registerValueTypes(const char *uri, int versionMajor, QQmlValueType::QQmlValueType(int typeId, const QMetaObject *gadgetMetaObject) : gadgetPtr(QMetaType::create(typeId)) - , typeId(typeId) , metaType(typeId) { QObjectPrivate *op = QObjectPrivate::get(this); @@ -230,12 +229,12 @@ void QQmlValueType::write(QObject *obj, int idx, QQmlPropertyData::WriteFlags fl QVariant QQmlValueType::value() { Q_ASSERT(gadgetPtr); - return QVariant(typeId, gadgetPtr); + return QVariant(metaType.id(), gadgetPtr); } void QQmlValueType::setValue(const QVariant &value) { - Q_ASSERT(typeId == value.userType()); + Q_ASSERT(metaType.id() == value.userType()); metaType.destruct(gadgetPtr); metaType.construct(gadgetPtr, value.constData()); } diff --git a/src/qml/qml/qqmlvaluetype_p.h b/src/qml/qml/qqmlvaluetype_p.h index 4ea71e8955..89f1b71d61 100644 --- a/src/qml/qml/qqmlvaluetype_p.h +++ b/src/qml/qml/qqmlvaluetype_p.h @@ -84,7 +84,6 @@ private: void *gadgetPtr; public: - int typeId; QMetaType metaType; }; diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp index b503d75a47..9ce1c82f09 100644 --- a/src/qml/qml/qqmlvaluetypewrapper.cpp +++ b/src/qml/qml/qqmlvaluetypewrapper.cpp @@ -105,7 +105,7 @@ void Heap::QQmlValueTypeWrapper::destroy() void Heap::QQmlValueTypeWrapper::setValue(const QVariant &value) const { - Q_ASSERT(valueType->typeId == value.userType()); + Q_ASSERT(valueType->metaType.id() == value.userType()); if (gadgetPtr) valueType->metaType.destruct(gadgetPtr); if (!gadgetPtr) @@ -116,7 +116,7 @@ void Heap::QQmlValueTypeWrapper::setValue(const QVariant &value) const QVariant Heap::QQmlValueTypeWrapper::toVariant() const { Q_ASSERT(gadgetPtr); - return QVariant(valueType->typeId, gadgetPtr); + return QVariant(valueType->metaType.id(), gadgetPtr); } @@ -221,7 +221,7 @@ bool QQmlValueTypeWrapper::toGadget(void *data) const if (const QQmlValueTypeReference *ref = as<const QQmlValueTypeReference>()) if (!ref->readReferenceValue()) return false; - const int typeId = d()->valueType->typeId; + const int typeId = d()->valueType->metaType.id(); QMetaType::destruct(typeId, data); QMetaType::construct(typeId, data, d()->gadgetPtr); return true; @@ -305,7 +305,7 @@ bool QQmlValueTypeWrapper::isEqual(const QVariant& value) const int QQmlValueTypeWrapper::typeId() const { - return d()->valueType->typeId; + return d()->valueType->metaType.id(); } bool QQmlValueTypeWrapper::write(QObject *target, int propertyIndex) const @@ -352,10 +352,10 @@ ReturnedValue QQmlValueTypeWrapper::method_toString(const FunctionObject *b, con // Prepare a buffer to pass to QMetaType::convert() QString convertResult; convertResult.~QString(); - if (QMetaType::convert(w->d()->gadgetPtr, w->d()->valueType->typeId, &convertResult, QMetaType::QString)) { + if (QMetaType::convert(w->d()->gadgetPtr, w->d()->valueType->metaType.id(), &convertResult, QMetaType::QString)) { result = convertResult; } else { - result += QString::fromUtf8(QMetaType::typeName(w->d()->valueType->typeId)) + result += QString::fromUtf8(QMetaType::typeName(w->d()->valueType->metaType.id())) + QLatin1Char('('); const QMetaObject *mo = w->d()->propertyCache()->metaObject(); const int propCount = mo->propertyCount(); diff --git a/src/qml/qmldirparser/qmldirparser.pri b/src/qml/qmldirparser/qmldirparser.pri new file mode 100644 index 0000000000..660e7b395a --- /dev/null +++ b/src/qml/qmldirparser/qmldirparser.pri @@ -0,0 +1,11 @@ +INCLUDEPATH += $$PWD +INCLUDEPATH += $$OUT_PWD + +HEADERS += \ + $$PWD/qqmldirparser_p.h \ + $$PWD/qqmlerror.h \ + $$PWD/qqmlsourcecoordinate_p.h + +SOURCES += \ + $$PWD/qqmldirparser.cpp \ + $$PWD/qqmlerror.cpp diff --git a/src/qml/qml/qqmldirparser.cpp b/src/qml/qmldirparser/qqmldirparser.cpp index d87bf433b8..e944b52e47 100644 --- a/src/qml/qml/qqmldirparser.cpp +++ b/src/qml/qmldirparser/qqmldirparser.cpp @@ -367,12 +367,10 @@ QList<QQmlDirParser::Script> QQmlDirParser::scripts() const return _scripts; } -#ifdef QT_CREATOR QList<QQmlDirParser::TypeInfo> QQmlDirParser::typeInfos() const { return _typeInfos; } -#endif bool QQmlDirParser::designerSupported() const { diff --git a/src/qml/qml/qqmldirparser_p.h b/src/qml/qmldirparser/qqmldirparser_p.h index d7e29813d1..cff9cb11a4 100644 --- a/src/qml/qml/qqmldirparser_p.h +++ b/src/qml/qmldirparser/qqmldirparser_p.h @@ -122,7 +122,6 @@ public: QList<Plugin> plugins() const; bool designerSupported() const; -#ifdef QT_CREATOR struct TypeInfo { TypeInfo() {} @@ -133,7 +132,6 @@ public: }; QList<TypeInfo> typeInfos() const; -#endif QString className() const; @@ -149,9 +147,7 @@ private: QList<Script> _scripts; QList<Plugin> _plugins; bool _designerSupported; -#ifdef QT_CREATOR QList<TypeInfo> _typeInfos; -#endif QString _className; }; diff --git a/src/qml/qml/qqmlerror.cpp b/src/qml/qmldirparser/qqmlerror.cpp index 61e9a3f37e..5e181f7e27 100644 --- a/src/qml/qml/qqmlerror.cpp +++ b/src/qml/qmldirparser/qqmlerror.cpp @@ -38,15 +38,17 @@ ****************************************************************************/ #include "qqmlerror.h" -#include "qqmlglobal_p.h" +#include "qqmlsourcecoordinate_p.h" #include <QtCore/qdebug.h> #include <QtCore/qfile.h> #include <QtCore/qstringlist.h> #include <QtCore/qvector.h> -#include <QtCore/qpointer.h> -#include <private/qv4errorobject_p.h> +#ifndef QT_NO_QOBJECT +#include <QtCore/qobject.h> +#include <QtCore/qpointer.h> +#endif QT_BEGIN_NAMESPACE @@ -85,11 +87,13 @@ public: quint16 line; quint16 column; QtMsgType messageType; +#ifndef QT_NO_QOBJECT QPointer<QObject> object; +#endif }; QQmlErrorPrivate::QQmlErrorPrivate() -: line(0), column(0), messageType(QtMsgType::QtWarningMsg), object() +: line(0), column(0), messageType(QtMsgType::QtWarningMsg) { } @@ -125,7 +129,9 @@ QQmlError &QQmlError::operator=(const QQmlError &other) d->description = other.d->description; d->line = other.d->line; d->column = other.d->column; +#ifndef QT_NO_QOBJECT d->object = other.d->object; +#endif d->messageType = other.d->messageType; } return *this; @@ -227,6 +233,7 @@ void QQmlError::setColumn(int column) d->column = qmlSourceCoordinate(column); } +#ifndef QT_NO_QOBJECT /*! Returns the nearest object where this error occurred. Exceptions in bound property expressions set this to the object @@ -249,6 +256,7 @@ void QQmlError::setObject(QObject *object) d = new QQmlErrorPrivate; d->object = object; } +#endif // QT_NO_QOBJECT /*! \since 5.9 diff --git a/src/qml/qml/qqmlerror.h b/src/qml/qmldirparser/qqmlerror.h index ef529e3828..f4221358e9 100644 --- a/src/qml/qml/qqmlerror.h +++ b/src/qml/qmldirparser/qqmlerror.h @@ -68,8 +68,12 @@ public: void setLine(int); int column() const; void setColumn(int); + +#ifndef QT_NO_QOBJECT QObject *object() const; void setObject(QObject *); +#endif + QtMsgType messageType() const; void setMessageType(QtMsgType messageType); diff --git a/src/qml/qmldirparser/qqmlsourcecoordinate_p.h b/src/qml/qmldirparser/qqmlsourcecoordinate_p.h new file mode 100644 index 0000000000..76ac741ae8 --- /dev/null +++ b/src/qml/qmldirparser/qqmlsourcecoordinate_p.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** 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-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQMLSOURCECOORDINATE_P_H +#define QQMLSOURCECOORDINATE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qglobal.h> + +#include <climits> + +QT_BEGIN_NAMESPACE + +inline quint16 qmlSourceCoordinate(int n) +{ + return (n > 0 && n <= static_cast<int>(USHRT_MAX)) ? static_cast<quint16>(n) : 0; +} + +inline int qmlSourceCoordinate(quint16 n) +{ + return (n == 0) ? -1 : static_cast<int>(n); +} + +QT_END_NAMESPACE + +#endif // QQMLSOURCECOORDINATE_P_H |