aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlprivate.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/qml/qqmlprivate.h')
-rw-r--r--src/qml/qml/qqmlprivate.h889
1 files changed, 706 insertions, 183 deletions
diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h
index 9504fc37dc..92c9765509 100644
--- a/src/qml/qml/qqmlprivate.h
+++ b/src/qml/qml/qqmlprivate.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QQMLPRIVATE_H
#define QQMLPRIVATE_H
@@ -51,39 +15,32 @@
// We mean it.
//
-#include <functional>
-#include <type_traits>
-
-#include <QtQml/qtqmlglobal.h>
-#include <QtQml/qqmlparserstatus.h>
+#include <QtQml/qjsprimitivevalue.h>
+#include <QtQml/qjsvalue.h>
#include <QtQml/qqmllist.h>
+#include <QtQml/qqmlparserstatus.h>
#include <QtQml/qqmlpropertyvaluesource.h>
+#include <QtQml/qtqmlglobal.h>
+#include <QtCore/qdatetime.h>
+#include <QtCore/qdebug.h>
#include <QtCore/qglobal.h>
-#include <QtCore/qvariant.h>
-#include <QtCore/qurl.h>
-#include <QtCore/qpointer.h>
-
+#include <QtCore/qmetacontainer.h>
#include <QtCore/qmetaobject.h>
-#include <QtCore/qdebug.h>
+#include <QtCore/qpointer.h>
+#include <QtCore/qurl.h>
+#include <QtCore/qvariant.h>
+#include <QtCore/qversionnumber.h>
-#define QML_GETTYPENAMES \
- const char *className = T::staticMetaObject.className(); \
- const int nameLen = int(strlen(className)); \
- QVarLengthArray<char,48> pointerName(nameLen+2); \
- memcpy(pointerName.data(), className, size_t(nameLen)); \
- pointerName[nameLen] = '*'; \
- pointerName[nameLen+1] = '\0'; \
- const int listLen = int(strlen("QQmlListProperty<")); \
- QVarLengthArray<char,64> listName(listLen + nameLen + 2); \
- memcpy(listName.data(), "QQmlListProperty<", size_t(listLen)); \
- memcpy(listName.data()+listLen, className, size_t(nameLen)); \
- listName[listLen+nameLen] = '>'; \
- listName[listLen+nameLen+1] = '\0';
+#include <functional>
+#include <limits>
+#include <type_traits>
QT_BEGIN_NAMESPACE
class QQmlPropertyValueInterceptor;
+class QQmlContextData;
+class QQmlFinalizerHook;
namespace QQmlPrivate {
struct CachedQmlUnit;
@@ -93,9 +50,9 @@ using QQmlAttachedPropertiesFunc = A *(*)(QObject *);
namespace QV4 {
struct ExecutionEngine;
+class ExecutableCompilationUnit;
namespace CompiledData {
struct Unit;
-struct CompilationUnit;
}
}
namespace QmlIR {
@@ -105,7 +62,7 @@ typedef void (*IRLoaderFunction)(Document *, const QQmlPrivate::CachedQmlUnit *)
using QQmlAttachedPropertiesFunc = QQmlPrivate::QQmlAttachedPropertiesFunc<QObject>;
-inline uint qHash(QQmlAttachedPropertiesFunc func, uint seed = 0)
+inline size_t qHash(QQmlAttachedPropertiesFunc func, size_t seed = 0)
{
return qHash(quintptr(func), seed);
}
@@ -120,10 +77,14 @@ public:
};
-class QJSValue;
class QJSEngine;
class QQmlEngine;
class QQmlCustomParser;
+class QQmlTypeNotAvailable;
+
+class QQmlV4Function;
+using QQmlV4FunctionPtr = QQmlV4Function *;
+using QQmlV4ExecutionEnginePtr = QV4::ExecutionEngine *;
template<class T>
QQmlCustomParser *qmlCreateCustomParser()
@@ -149,67 +110,202 @@ namespace QQmlPrivate
// the size that was allocated.
::operator delete (ptr);
}
+#ifdef Q_CC_MSVC
static void operator delete(void *, void *) {
// Deliberately empty placement delete operator.
// Silences MSVC warning C4291: no matching operator delete found
+ // On MinGW it causes -Wmismatched-new-delete, though.
}
+#endif
};
- template<typename T>
- constexpr bool isConstructible()
+ enum class SingletonConstructionMode
{
- return std::is_default_constructible<T>::value && std::is_base_of<QObject, T>::value;
+ None,
+ Constructor,
+ Factory,
+ FactoryWrapper
+ };
+
+ template<typename T, typename WrapperT = T, typename = std::void_t<>>
+ struct HasSingletonFactory
+ {
+ static constexpr bool value = false;
+ };
+
+ template<typename T, typename WrapperT>
+ struct HasSingletonFactory<T, WrapperT, std::void_t<decltype(WrapperT::create(
+ static_cast<QQmlEngine *>(nullptr),
+ static_cast<QJSEngine *>(nullptr)))>>
+ {
+ static constexpr bool value = std::is_same_v<
+ decltype(WrapperT::create(static_cast<QQmlEngine *>(nullptr),
+ static_cast<QJSEngine *>(nullptr))), T *>;
+ };
+
+ template<typename T, typename WrapperT>
+ constexpr SingletonConstructionMode singletonConstructionMode()
+ {
+ if constexpr (!std::is_base_of<QObject, T>::value)
+ return SingletonConstructionMode::None;
+ if constexpr (!std::is_same_v<T, WrapperT> && HasSingletonFactory<T, WrapperT>::value)
+ return SingletonConstructionMode::FactoryWrapper;
+ if constexpr (std::is_default_constructible<T>::value)
+ return SingletonConstructionMode::Constructor;
+ if constexpr (HasSingletonFactory<T>::value)
+ return SingletonConstructionMode::Factory;
+
+ return SingletonConstructionMode::None;
}
- template<typename T>
- void createInto(void *memory) { new (memory) QQmlElement<T>; }
+ template<typename>
+ struct QmlMarkerFunction;
+
+ template<typename Ret, typename Class>
+ struct QmlMarkerFunction<Ret (Class::*)()>
+ {
+ using ClassType = Class;
+ };
+
+ template<typename T, typename Marker>
+ using QmlTypeHasMarker = std::is_same<T, typename QmlMarkerFunction<Marker>::ClassType>;
template<typename T>
- QObject *createSingletonInstance(QQmlEngine *, QJSEngine *) { return new T; }
+ void createInto(void *memory, void *) { new (memory) QQmlElement<T>; }
+
+ template<typename T, typename WrapperT, SingletonConstructionMode Mode>
+ QObject *createSingletonInstance(QQmlEngine *q, QJSEngine *j)
+ {
+ Q_UNUSED(q);
+ Q_UNUSED(j);
+ if constexpr (Mode == SingletonConstructionMode::Constructor)
+ return new T;
+ else if constexpr (Mode == SingletonConstructionMode::Factory)
+ return T::create(q, j);
+ else if constexpr (Mode == SingletonConstructionMode::FactoryWrapper)
+ return WrapperT::create(q, j);
+ else
+ return nullptr;
+ }
template<typename T>
QObject *createParent(QObject *p) { return new T(p); }
- using CreateIntoFunction = void (*)(void *);
+ using CreateIntoFunction = void (*)(void *, void *);
using CreateSingletonFunction = QObject *(*)(QQmlEngine *, QJSEngine *);
using CreateParentFunction = QObject *(*)(QObject *);
+ using CreateValueTypeFunction = QVariant (*)(const QJSValue &);
- template<typename T, bool Constructible = isConstructible<T>()>
+ template<typename T, typename WrapperT = T,
+ SingletonConstructionMode Mode = singletonConstructionMode<T, WrapperT>()>
struct Constructors;
- template<typename T>
- struct Constructors<T, true>
+ template<typename T, typename WrapperT>
+ struct Constructors<T, WrapperT, SingletonConstructionMode::Constructor>
{
static constexpr CreateIntoFunction createInto
= QQmlPrivate::createInto<T>;
static constexpr CreateSingletonFunction createSingletonInstance
- = QQmlPrivate::createSingletonInstance<T>;
+ = QQmlPrivate::createSingletonInstance<
+ T, WrapperT, SingletonConstructionMode::Constructor>;
};
- template<typename T>
- struct Constructors<T, false>
+ template<typename T, typename WrapperT>
+ struct Constructors<T, WrapperT, SingletonConstructionMode::None>
{
static constexpr CreateIntoFunction createInto = nullptr;
static constexpr CreateSingletonFunction createSingletonInstance = nullptr;
};
- template<typename T, bool IsVoid = std::is_void<T>::value>
+ template<typename T, typename WrapperT>
+ struct Constructors<T, WrapperT, SingletonConstructionMode::Factory>
+ {
+ static constexpr CreateIntoFunction createInto = nullptr;
+ static constexpr CreateSingletonFunction createSingletonInstance
+ = QQmlPrivate::createSingletonInstance<
+ T, WrapperT, SingletonConstructionMode::Factory>;
+ };
+
+ template<typename T, typename WrapperT>
+ struct Constructors<T, WrapperT, SingletonConstructionMode::FactoryWrapper>
+ {
+ static constexpr CreateIntoFunction createInto = nullptr;
+ static constexpr CreateSingletonFunction createSingletonInstance
+ = QQmlPrivate::createSingletonInstance<
+ T, WrapperT, SingletonConstructionMode::FactoryWrapper>;
+ };
+
+ template<typename T,
+ bool IsObject = std::is_base_of<QObject, T>::value,
+ bool IsGadget = QtPrivate::IsGadgetHelper<T>::IsRealGadget>
struct ExtendedType;
- // void means "not an extended type"
template<typename T>
- struct ExtendedType<T, true>
+ struct ExtendedType<T, false, false>
{
static constexpr const CreateParentFunction createParent = nullptr;
- static constexpr const QMetaObject *staticMetaObject = nullptr;
+ static const QMetaObject *staticMetaObject() { return nullptr; }
};
- // If it's not void, we actually want an error if the ctor or the metaobject is missing.
+ // If it's a QObject, we actually want an error if the ctor or the metaobject is missing.
template<typename T>
- struct ExtendedType<T, false>
+ struct ExtendedType<T, true, false>
{
static constexpr const CreateParentFunction createParent = QQmlPrivate::createParent<T>;
- static constexpr const QMetaObject *staticMetaObject = &T::staticMetaObject;
+ static const QMetaObject *staticMetaObject() { return &T::staticMetaObject; }
+ };
+
+ // If it's a Q_GADGET, we don't want the ctor.
+ template<typename T>
+ struct ExtendedType<T, false, true>
+ {
+ static constexpr const CreateParentFunction createParent = nullptr;
+ static const QMetaObject *staticMetaObject() { return &T::staticMetaObject; }
+ };
+
+ template<typename F, typename Result = void>
+ struct ValueTypeFactory
+ {
+ static constexpr const Result (*create)(const QJSValue &) = nullptr;
+ };
+
+ template<typename F>
+ struct ValueTypeFactory<F, std::void_t<decltype(F::create(QJSValue()))>>
+ {
+ static decltype(F::create(QJSValue())) create(const QJSValue &params)
+ {
+ return F::create(params);
+ }
+ };
+
+ template<typename T, typename F,
+ bool HasCtor = std::is_constructible_v<T, QJSValue>,
+ bool HasFactory = std::is_constructible_v<
+ QVariant, decltype(ValueTypeFactory<F>::create(QJSValue()))>>
+ struct ValueType;
+
+ template<typename T, typename F>
+ struct ValueType<T, F, false, false>
+ {
+ static constexpr const CreateValueTypeFunction create = nullptr;
+ };
+
+ template<typename T, typename F, bool HasCtor>
+ struct ValueType<T, F, HasCtor, true>
+ {
+ static QVariant create(const QJSValue &params)
+ {
+ return F::create(params);
+ }
+ };
+
+ template<typename T, typename F>
+ struct ValueType<T, F, true, false>
+ {
+ static QVariant create(const QJSValue &params)
+ {
+ return QVariant::fromValue(T(params));
+ }
};
template<class From, class To, int N>
@@ -239,9 +335,6 @@ namespace QQmlPrivate
}
};
- template<typename...>
- using QmlVoidT = void;
-
// You can prevent subclasses from using the same attached type by specialzing this.
// This is reserved for internal types, though.
template<class T, class A>
@@ -250,7 +343,7 @@ namespace QQmlPrivate
using Type = A;
};
- template<class T, class = QmlVoidT<>, bool OldStyle = QQmlTypeInfo<T>::hasAttachedProperties>
+ template<class T, class = std::void_t<>, bool OldStyle = QQmlTypeInfo<T>::hasAttachedProperties>
struct QmlAttached
{
using Type = void;
@@ -261,7 +354,7 @@ namespace QQmlPrivate
// Defined inline via QML_ATTACHED
template<class T>
- struct QmlAttached<T, QmlVoidT<typename OverridableAttachedType<T, typename T::QmlAttachedType>::Type>, false>
+ struct QmlAttached<T, std::void_t<typename OverridableAttachedType<T, typename T::QmlAttachedType>::Type>, false>
{
// Normal attached properties
template <typename Parent, typename Attached>
@@ -277,11 +370,13 @@ namespace QQmlPrivate
struct Properties<Parent, void>
{
using Func = QQmlAttachedPropertiesFunc<QObject>;
- static const QMetaObject *staticMetaObject() { return nullptr; };
- static Func attachedPropertiesFunc() { return nullptr; };
+ static const QMetaObject *staticMetaObject() { return nullptr; }
+ static Func attachedPropertiesFunc() { return nullptr; }
};
- using Type = typename OverridableAttachedType<T, typename T::QmlAttachedType>::Type;
+ using Type = typename std::conditional<
+ QmlTypeHasMarker<T, decltype(&T::qt_qmlMarker_attached)>::value,
+ typename OverridableAttachedType<T, typename T::QmlAttachedType>::Type, void>::type;
using Func = typename Properties<T, Type>::Func;
static const QMetaObject *staticMetaObject()
@@ -297,7 +392,7 @@ namespace QQmlPrivate
// Separately defined via QQmlTypeInfo
template<class T>
- struct QmlAttached<T, QmlVoidT<decltype(T::qmlAttachedProperties)>, true>
+ struct QmlAttached<T, std::void_t<decltype(T::qmlAttachedProperties)>, true>
{
using Type = typename std::remove_pointer<decltype(T::qmlAttachedProperties(nullptr))>::type;
using Func = QQmlAttachedPropertiesFunc<Type>;
@@ -341,18 +436,33 @@ namespace QQmlPrivate
enum AutoParentResult { Parented, IncompatibleObject, IncompatibleParent };
typedef AutoParentResult (*AutoParentFunction)(QObject *object, QObject *parent);
+ enum class ValueTypeCreationMethod { None, Construct, Structured };
+
struct RegisterType {
- int version;
+ enum StructVersion: int {
+ Base = 0,
+ FinalizerCast = 1,
+ CreationMethod = 2,
+ CurrentVersion = CreationMethod,
+ };
+
+ bool has(StructVersion v) const { return structVersion >= int(v); }
- int typeId;
- int listId;
+ int structVersion;
+
+ QMetaType typeId;
+ QMetaType listId;
int objectSize;
- void (*create)(void *);
+ // The second parameter of create is for userdata
+ void (*create)(void *, void *);
+ void *userdata;
QString noCreationReason;
+ // ### Qt7: Get rid of this. It can be covered by creationMethod below.
+ QVariant (*createValueType)(const QJSValue &);
+
const char *uri;
- int versionMajor;
- int versionMinor;
+ QTypeRevision version;
const char *elementName;
const QMetaObject *metaObject;
@@ -368,20 +478,26 @@ namespace QQmlPrivate
QQmlCustomParser *customParser;
- int revision;
+ QTypeRevision revision;
+ int finalizerCast;
+
+ ValueTypeCreationMethod creationMethod;
// If this is extended ensure "version" is bumped!!!
};
struct RegisterTypeAndRevisions {
- int version;
+ int structVersion;
- int typeId;
- int listId;
+ QMetaType typeId;
+ QMetaType listId;
int objectSize;
- void (*create)(void *);
+ void (*create)(void *, void *);
+ void *userdata;
+
+ QVariant (*createValueType)(const QJSValue &);
const char *uri;
- int versionMajor;
+ QTypeRevision version;
const QMetaObject *metaObject;
const QMetaObject *classInfoMetaObject;
@@ -397,78 +513,253 @@ namespace QQmlPrivate
const QMetaObject *extensionMetaObject;
QQmlCustomParser *(*customParserFactory)();
+ QVector<int> *qmlTypeIds;
+ int finalizerCast;
+
+ bool forceAnonymous;
+ QMetaSequence listMetaSequence;
};
struct RegisterInterface {
- int version;
+ int structVersion;
- int typeId;
- int listId;
+ QMetaType typeId;
+ QMetaType listId;
const char *iid;
+
+ const char *uri;
+ QTypeRevision version;
};
struct RegisterAutoParent {
- int version;
+ int structVersion;
AutoParentFunction function;
};
struct RegisterSingletonType {
- int version;
+ int structVersion;
const char *uri;
- int versionMajor;
- int versionMinor;
+ QTypeRevision version;
const char *typeName;
- QJSValue (*scriptApi)(QQmlEngine *, QJSEngine *);
- QObject *(*qobjectApi)(QQmlEngine *, QJSEngine *);
- const QMetaObject *instanceMetaObject; // new in version 1
- int typeId; // new in version 2
- int revision; // new in version 2
- std::function<QObject*(QQmlEngine *, QJSEngine *)> generalizedQobjectApi; // new in version 3
- // If this is extended ensure "version" is bumped!!!
+ std::function<QJSValue(QQmlEngine *, QJSEngine *)> scriptApi;
+ std::function<QObject*(QQmlEngine *, QJSEngine *)> qObjectApi;
+
+ const QMetaObject *instanceMetaObject;
+ QMetaType typeId;
+
+ QObject *(*extensionObjectCreate)(QObject *);
+ const QMetaObject *extensionMetaObject;
+
+ QTypeRevision revision;
};
struct RegisterSingletonTypeAndRevisions {
- int version;
+ int structVersion;
const char *uri;
- int versionMajor;
+ QTypeRevision version;
+
+ std::function<QObject*(QQmlEngine *, QJSEngine *)> qObjectApi;
- QJSValue (*scriptApi)(QQmlEngine *, QJSEngine *);
const QMetaObject *instanceMetaObject;
const QMetaObject *classInfoMetaObject;
- int typeId;
- std::function<QObject*(QQmlEngine *, QJSEngine *)> generalizedQobjectApi; // new in version 3
+ QMetaType typeId;
+
+ QObject *(*extensionObjectCreate)(QObject *);
+ const QMetaObject *extensionMetaObject;
+
+ QVector<int> *qmlTypeIds;
};
struct RegisterCompositeType {
+ int structVersion;
QUrl url;
const char *uri;
- int versionMajor;
- int versionMinor;
+ QTypeRevision version;
const char *typeName;
};
struct RegisterCompositeSingletonType {
+ int structVersion;
QUrl url;
const char *uri;
- int versionMajor;
- int versionMinor;
+ QTypeRevision version;
const char *typeName;
};
+ struct RegisterSequentialContainer {
+ int structVersion;
+ const char *uri;
+ QTypeRevision version;
+
+ // ### Qt7: Remove typeName. It's ignored because the only valid name is "list",
+ // and that's automatic.
+ const char *typeName;
+
+ QMetaType typeId;
+ QMetaSequence metaSequence;
+ QTypeRevision revision;
+ };
+
+ struct RegisterSequentialContainerAndRevisions {
+ int structVersion;
+ const char *uri;
+ QTypeRevision version;
+
+ const QMetaObject *classInfoMetaObject;
+ QMetaType typeId;
+ QMetaSequence metaSequence;
+
+ QVector<int> *qmlTypeIds;
+ };
+
+ struct Q_QML_EXPORT AOTCompiledContext {
+ enum: uint { InvalidStringId = (std::numeric_limits<uint>::max)() };
+
+ QQmlContextData *qmlContext;
+ QObject *qmlScopeObject;
+ QJSEngine *engine;
+ union {
+ QV4::ExecutableCompilationUnit *compilationUnit;
+ qintptr extraData;
+ };
+
+ QObject *thisObject() const;
+ QQmlEngine *qmlEngine() const;
+
+ QJSValue jsMetaType(int index) const;
+ void setInstructionPointer(int offset) const;
+ void setReturnValueUndefined() const;
+
+ // Run QQmlPropertyCapture::captureProperty() without retrieving the value.
+ bool captureLookup(uint index, QObject *object) const;
+ bool captureQmlContextPropertyLookup(uint index) const;
+ void captureTranslation() const;
+ QString translationContext() const;
+ QMetaType lookupResultMetaType(uint index) const;
+ void storeNameSloppy(uint nameIndex, void *value, QMetaType type) const;
+ QJSValue javaScriptGlobalProperty(uint nameIndex) const;
+
+ const QLoggingCategory *resolveLoggingCategory(QObject *wrapper, bool *ok) const;
+
+ void writeToConsole(
+ QtMsgType type, const QString &message,
+ const QLoggingCategory *loggingCategory) const;
+
+ QVariant constructValueType(
+ QMetaType resultMetaType, const QMetaObject *resultMetaObject,
+ int ctorIndex, void *ctorArg) const;
+
+ // Those are explicit arguments to the Date() ctor, not implicit coercions.
+ QDateTime constructDateTime(double timestamp) const;
+ QDateTime constructDateTime(const QString &string) const;
+ QDateTime constructDateTime(const QJSPrimitiveValue &arg) const
+ {
+ return arg.type() == QJSPrimitiveValue::String
+ ? constructDateTime(arg.toString())
+ : constructDateTime(arg.toDouble());
+ }
+
+ QDateTime constructDateTime(
+ double year, double month, double day = 1,
+ double hours = 0, double minutes = 0, double seconds = 0, double msecs = 0) const;
+
+ // All of these lookup functions should be used as follows:
+ //
+ // while (!fooBarLookup(...)) {
+ // setInstructionPointer(...);
+ // initFooBarLookup(...);
+ // if (engine->hasException()) {
+ // ...
+ // break;
+ // }
+ // }
+ //
+ // The bool-returning *Lookup functions exclusively run the happy path and return false if
+ // that fails in any way. The failure may either be in the lookup structs not being
+ // initialized or an exception being thrown.
+ // The init*Lookup functions initialize the lookup structs and amend any exceptions
+ // previously thrown with line numbers. They might also throw their own exceptions. If an
+ // exception is present after the initialization there is no way to carry out the lookup and
+ // the exception should be propagated. If not, the original lookup can be tried again.
+
+ bool callQmlContextPropertyLookup(
+ uint index, void **args, const QMetaType *types, int argc) const;
+ void initCallQmlContextPropertyLookup(uint index) const;
+
+ bool loadContextIdLookup(uint index, void *target) const;
+ void initLoadContextIdLookup(uint index) const;
+
+ bool callObjectPropertyLookup(uint index, QObject *object,
+ void **args, const QMetaType *types, int argc) const;
+ void initCallObjectPropertyLookup(uint index) const;
+
+ bool callGlobalLookup(uint index, void **args, const QMetaType *types, int argc) const;
+ void initCallGlobalLookup(uint index) const;
+
+ bool loadGlobalLookup(uint index, void *target, QMetaType type) const;
+ void initLoadGlobalLookup(uint index) const;
+
+ bool loadScopeObjectPropertyLookup(uint index, void *target) const;
+ bool writeBackScopeObjectPropertyLookup(uint index, void *source) const;
+ void initLoadScopeObjectPropertyLookup(uint index, QMetaType type) const;
+
+ bool loadSingletonLookup(uint index, void *target) const;
+ void initLoadSingletonLookup(uint index, uint importNamespace) const;
+
+ bool loadAttachedLookup(uint index, QObject *object, void *target) const;
+ void initLoadAttachedLookup(uint index, uint importNamespace, QObject *object) const;
+
+ bool loadTypeLookup(uint index, void *target) const;
+ void initLoadTypeLookup(uint index, uint importNamespace) const;
+
+ bool getObjectLookup(uint index, QObject *object, void *target) const;
+ bool writeBackObjectLookup(uint index, QObject *object, void *source) const;
+ void initGetObjectLookup(uint index, QObject *object, QMetaType type) const;
+
+ bool getValueLookup(uint index, void *value, void *target) const;
+ bool writeBackValueLookup(uint index, void *value, void *source) const;
+ void initGetValueLookup(uint index, const QMetaObject *metaObject, QMetaType type) const;
+
+ bool getEnumLookup(uint index, void *target) const;
+#if QT_QML_REMOVED_SINCE(6, 6)
+ bool getEnumLookup(uint index, int *target) const;
+#endif
+ void initGetEnumLookup(uint index, const QMetaObject *metaObject,
+ const char *enumerator, const char *enumValue) const;
+
+ bool setObjectLookup(uint index, QObject *object, void *value) const;
+ void initSetObjectLookup(uint index, QObject *object, QMetaType type) const;
+
+ bool setValueLookup(uint index, void *target, void *value) const;
+ void initSetValueLookup(uint index, const QMetaObject *metaObject, QMetaType type) const;
+ };
+
+ struct AOTCompiledFunction {
+ int functionIndex;
+ int numArguments;
+ void (*signature)(QV4::ExecutableCompilationUnit *unit, QMetaType *argTypes);
+ void (*functionPtr)(const AOTCompiledContext *context, void **argv);
+ };
+
+#if QT_DEPRECATED_SINCE(6, 6)
+ QT_DEPRECATED_VERSION_X(6, 6, "Use AOTCompiledFunction instead")
+ typedef AOTCompiledFunction TypedFunction;
+#endif
+
struct CachedQmlUnit {
const QV4::CompiledData::Unit *qmlData;
- void *unused1;
+ const AOTCompiledFunction *aotCompiledFunctions;
void *unused2;
};
typedef const CachedQmlUnit *(*QmlUnitCacheLookupFunction)(const QUrl &url);
struct RegisterQmlUnitCacheHook {
- int version;
+ int structVersion;
QmlUnitCacheLookupFunction lookupCachedQmlUnit;
};
@@ -481,26 +772,45 @@ namespace QQmlPrivate
CompositeSingletonRegistration = 5,
QmlUnitCacheHookRegistration = 6,
TypeAndRevisionsRegistration = 7,
- SingletonAndRevisionsRegistration = 8
+ SingletonAndRevisionsRegistration = 8,
+ SequentialContainerRegistration = 9,
+ SequentialContainerAndRevisionsRegistration = 10,
};
int Q_QML_EXPORT qmlregister(RegistrationType, void *);
void Q_QML_EXPORT qmlunregister(RegistrationType, quintptr);
- struct Q_QML_EXPORT RegisterSingletonFunctor
+
+#if QT_DEPRECATED_SINCE(6, 3)
+ struct Q_QML_EXPORT SingletonFunctor
+ {
+ QT_DEPRECATED QObject *operator()(QQmlEngine *, QJSEngine *);
+ QPointer<QObject> m_object;
+ bool alreadyCalled = false;
+ };
+#endif
+
+ struct Q_QML_EXPORT SingletonInstanceFunctor
{
QObject *operator()(QQmlEngine *, QJSEngine *);
QPointer<QObject> m_object;
- bool alreadyCalled = false;
+
+ // Not a QPointer, so that you cannot assign it to a different
+ // engine when the first one is deleted.
+ // That would mess up the QML contexts.
+ QQmlEngine *m_engine = nullptr;
};
- static int indexOfOwnClassInfo(const QMetaObject *metaObject, const char *key)
+ static int indexOfOwnClassInfo(const QMetaObject *metaObject, const char *key, int startOffset = -1)
{
if (!metaObject || !key)
return -1;
const int offset = metaObject->classInfoOffset();
- for (int i = metaObject->classInfoCount() + offset - 1; i >= offset; --i)
+ const int start = (startOffset == -1)
+ ? (metaObject->classInfoCount() + offset - 1)
+ : startOffset;
+ for (int i = start; i >= offset; --i)
if (qstrcmp(key, metaObject->classInfo(i).name()) == 0) {
return i;
}
@@ -512,92 +822,229 @@ namespace QQmlPrivate
return metaObject->classInfo(indexOfOwnClassInfo(metaObject, key)).value();
}
- inline int intClassInfo(const QMetaObject *metaObject, const char *key, int defaultValue = 0)
+ inline QTypeRevision revisionClassInfo(const QMetaObject *metaObject, const char *key,
+ QTypeRevision defaultValue = QTypeRevision())
{
const int index = indexOfOwnClassInfo(metaObject, key);
return (index == -1) ? defaultValue
- : QByteArray(metaObject->classInfo(index).value()).toInt();
+ : QTypeRevision::fromEncodedVersion(
+ QLatin1StringView(metaObject->classInfo(index).value()).toInt());
}
+ Q_QML_EXPORT QList<QTypeRevision> revisionClassInfos(const QMetaObject *metaObject, const char *key);
+
inline bool boolClassInfo(const QMetaObject *metaObject, const char *key,
bool defaultValue = false)
{
const int index = indexOfOwnClassInfo(metaObject, key);
- return (index == -1) ? defaultValue
- : (QByteArray(metaObject->classInfo(index).value()) == "true");
+ if (index == -1)
+ return defaultValue;
+ return qstrcmp(metaObject->classInfo(index).value(), "true") == 0;
}
- inline const char *classElementName(const QMetaObject *metaObject)
+ template<class T, class = std::void_t<>>
+ struct QmlExtended
{
- const char *elementName = classInfo(metaObject, "QML.Element");
- if (qstrcmp(elementName, "auto") == 0)
- return metaObject->className();
- if (qstrcmp(elementName, "anonymous") == 0)
- return nullptr;
-
- if (!elementName || elementName[0] < 'A' || elementName[0] > 'Z') {
- qWarning() << "Missing or unusable QML.Element class info \"" << elementName << "\""
- << "for" << metaObject->className();
- }
+ using Type = void;
+ };
- return elementName;
- }
+ template<class T>
+ struct QmlExtended<T, std::void_t<typename T::QmlExtendedType>>
+ {
+ using Type = typename std::conditional<
+ QmlTypeHasMarker<T, decltype(&T::qt_qmlMarker_extended)>::value,
+ typename T::QmlExtendedType, void>::type;
+ };
- template<class T, class = QmlVoidT<>>
- struct QmlExtended
+ template<class T, class = std::void_t<>>
+ struct QmlExtendedNamespace
{
- using Type = void;
+ static constexpr const QMetaObject *metaObject() { return nullptr; }
};
template<class T>
- struct QmlExtended<T, QmlVoidT<typename T::QmlExtendedType>>
+ struct QmlExtendedNamespace<T, std::void_t<decltype(T::qmlExtendedNamespace())>>
{
- using Type = typename T::QmlExtendedType;
+ static constexpr const QMetaObject *metaObject()
+ {
+ if constexpr (QmlTypeHasMarker<T, decltype(&T::qt_qmlMarker_extendedNamespace)>::value)
+ return T::qmlExtendedNamespace();
+ else
+ return nullptr;
+ }
};
- template<class T, class = QmlVoidT<>>
+ template<class T, class = std::void_t<>>
struct QmlResolved
{
using Type = T;
};
template<class T>
- struct QmlResolved<T, QmlVoidT<typename T::QmlForeignType>>
+ struct QmlResolved<T, std::void_t<typename T::QmlForeignType>>
+ {
+ using Type = typename std::conditional<
+ QmlTypeHasMarker<T, decltype(&T::qt_qmlMarker_foreign)>::value,
+ typename T::QmlForeignType, T>::type;
+ };
+
+ template<class T, class = std::void_t<>>
+ struct QmlUncreatable
+ {
+ static constexpr bool Value = false;
+ };
+
+ template<class T>
+ struct QmlUncreatable<T, std::void_t<typename T::QmlIsUncreatable>>
+ {
+ static constexpr bool Value =
+ QmlTypeHasMarker<T, decltype(&T::qt_qmlMarker_uncreatable)>::value
+ && bool(T::QmlIsUncreatable::yes);
+ };
+
+ template<class T, class = std::void_t<>>
+ struct QmlAnonymous
+ {
+ static constexpr bool Value = false;
+ };
+
+ template<class T>
+ struct QmlAnonymous<T, std::void_t<typename T::QmlIsAnonymous>>
{
- using Type = typename T::QmlForeignType;
+ static constexpr bool Value =
+ QmlTypeHasMarker<T, decltype(&T::qt_qmlMarker_anonymous)>::value
+ && bool(T::QmlIsAnonymous::yes);
};
- template<class T, class = QmlVoidT<>>
+
+ template<class T, class = std::void_t<>>
struct QmlSingleton
{
static constexpr bool Value = false;
};
template<class T>
- struct QmlSingleton<T, QmlVoidT<typename T::QmlIsSingleton>>
+ struct QmlSingleton<T, std::void_t<typename T::QmlIsSingleton>>
{
- static constexpr bool Value = bool(T::QmlIsSingleton::yes);
+ static constexpr bool Value =
+ QmlTypeHasMarker<T, decltype(&T::qt_qmlMarker_singleton)>::value
+ && bool(T::QmlIsSingleton::yes);
};
- template<typename T>
- void qmlRegisterSingletonAndRevisions(const char *uri, int versionMajor,
- const QMetaObject *classInfoMetaObject)
+ template<class T, class = std::void_t<>>
+ struct QmlSequence
+ {
+ static constexpr bool Value = false;
+ };
+
+ template<class T>
+ struct QmlSequence<T, std::void_t<typename T::QmlIsSequence>>
+ {
+ Q_STATIC_ASSERT((std::is_same_v<typename T::QmlSequenceValueType,
+ typename QmlResolved<T>::Type::value_type>));
+ static constexpr bool Value = bool(T::QmlIsSequence::yes);
+ };
+
+ template<class T, class = std::void_t<>>
+ struct QmlInterface
+ {
+ static constexpr bool Value = false;
+ };
+
+ template<class T>
+ struct QmlInterface<T, std::void_t<typename T::QmlIsInterface, decltype(qobject_interface_iid<T *>())>>
{
- QML_GETTYPENAMES
+ static constexpr bool Value = bool(T::QmlIsInterface::yes);
+ };
+
+ template<class T, typename = std::void_t<>>
+ struct StaticMetaObject
+ {
+ static const QMetaObject *staticMetaObject() { return nullptr; }
+ };
+
+ template<class T>
+ struct StaticMetaObject<T, std::void_t<decltype(T::staticMetaObject)>>
+ {
+ static const QMetaObject *staticMetaObject() { return &T::staticMetaObject; }
+ };
+
+ template<class T>
+ struct QmlMetaType
+ {
+ static constexpr bool hasAcceptableCtors()
+ {
+ if constexpr (!std::is_default_constructible_v<T>)
+ return false;
+ else if constexpr (std::is_base_of_v<QObject, T>)
+ return true;
+ else
+ return std::is_copy_constructible_v<T>;
+ }
+ static constexpr QMetaType self()
+ {
+ if constexpr (std::is_base_of_v<QObject, T>)
+ return QMetaType::fromType<T*>();
+ else
+ return QMetaType::fromType<T>();
+ }
+
+ static constexpr QMetaType list()
+ {
+ if constexpr (std::is_base_of_v<QObject, T>)
+ return QMetaType::fromType<QQmlListProperty<T>>();
+ else
+ return QMetaType::fromType<QList<T>>();
+ }
+
+ static constexpr QMetaSequence sequence()
+ {
+ if constexpr (std::is_base_of_v<QObject, T>)
+ return QMetaSequence();
+ else
+ return QMetaSequence::fromContainer<QList<T>>();
+ }
+
+ static constexpr int size()
+ {
+ return sizeof(T);
+ }
+ };
+
+ template<>
+ struct QmlMetaType<void>
+ {
+ static constexpr bool hasAcceptableCtors() { return true; }
+ static constexpr QMetaType self() { return QMetaType(); }
+ static constexpr QMetaType list() { return QMetaType(); }
+ static constexpr QMetaSequence sequence() { return QMetaSequence(); }
+ static constexpr int size() { return 0; }
+ };
+
+ template<typename T, typename E, typename WrapperT = T>
+ void qmlRegisterSingletonAndRevisions(const char *uri, int versionMajor,
+ const QMetaObject *classInfoMetaObject,
+ QVector<int> *qmlTypeIds, const QMetaObject *extension)
+ {
+ static_assert(std::is_base_of_v<QObject, T>);
RegisterSingletonTypeAndRevisions api = {
0,
uri,
- versionMajor,
+ QTypeRevision::fromMajorVersion(versionMajor),
- nullptr,
+ Constructors<T, WrapperT>::createSingletonInstance,
- &T::staticMetaObject,
+ StaticMetaObject<T>::staticMetaObject(),
classInfoMetaObject,
- qRegisterNormalizedMetaType<T *>(pointerName.constData()),
- Constructors<T>::createSingletonInstance
+ QmlMetaType<T>::self(),
+
+ ExtendedType<E>::createParent,
+ extension ? extension : ExtendedType<E>::staticMetaObject(),
+
+ qmlTypeIds
};
qmlregister(SingletonAndRevisionsRegistration, &api);
@@ -605,21 +1052,23 @@ namespace QQmlPrivate
template<typename T, typename E>
void qmlRegisterTypeAndRevisions(const char *uri, int versionMajor,
- const QMetaObject *classInfoMetaObject)
+ const QMetaObject *classInfoMetaObject,
+ QVector<int> *qmlTypeIds, const QMetaObject *extension,
+ bool forceAnonymous = false)
{
- QML_GETTYPENAMES
-
RegisterTypeAndRevisions type = {
- 0,
- qRegisterNormalizedMetaType<T *>(pointerName.constData()),
- qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
- int(sizeof(T)),
+ 3,
+ QmlMetaType<T>::self(),
+ QmlMetaType<T>::list(),
+ QmlMetaType<T>::size(),
Constructors<T>::createInto,
+ nullptr,
+ ValueType<T, E>::create,
uri,
- versionMajor,
+ QTypeRevision::fromMajorVersion(versionMajor),
- &T::staticMetaObject,
+ StaticMetaObject<T>::staticMetaObject(),
classInfoMetaObject,
attachedPropertiesFunc<T>(),
@@ -630,15 +1079,89 @@ namespace QQmlPrivate
StaticCastSelector<T, QQmlPropertyValueInterceptor>::cast(),
ExtendedType<E>::createParent,
- ExtendedType<E>::staticMetaObject,
+ extension ? extension : ExtendedType<E>::staticMetaObject(),
- &qmlCreateCustomParser<T>
+ &qmlCreateCustomParser<T>,
+ qmlTypeIds,
+ StaticCastSelector<T, QQmlFinalizerHook>::cast(),
+
+ forceAnonymous,
+ QmlMetaType<T>::sequence(),
};
+ // Initialize the extension so that we can find it by name or ID.
+ qMetaTypeId<E>();
+
qmlregister(TypeAndRevisionsRegistration, &type);
}
+
+ template<typename T>
+ void qmlRegisterSequenceAndRevisions(const char *uri, int versionMajor,
+ const QMetaObject *classInfoMetaObject,
+ QVector<int> *qmlTypeIds)
+ {
+ RegisterSequentialContainerAndRevisions type = {
+ 0,
+ uri,
+ QTypeRevision::fromMajorVersion(versionMajor),
+ classInfoMetaObject,
+ QMetaType::fromType<T>(),
+ QMetaSequence::fromContainer<T>(),
+ qmlTypeIds
+ };
+
+ qmlregister(SequentialContainerAndRevisionsRegistration, &type);
+ }
+
+ template<>
+ void Q_QML_EXPORT qmlRegisterTypeAndRevisions<QQmlTypeNotAvailable, void>(
+ const char *uri, int versionMajor, const QMetaObject *classInfoMetaObject,
+ QVector<int> *qmlTypeIds, const QMetaObject *, bool);
+
+ constexpr QtPrivate::QMetaTypeInterface metaTypeForNamespace(
+ const QtPrivate::QMetaTypeInterface::MetaObjectFn &metaObjectFunction, const char *name)
+ {
+ return {
+ /*.revision=*/ 0,
+ /*.alignment=*/ 0,
+ /*.size=*/ 0,
+ /*.flags=*/ 0,
+ /*.typeId=*/ {},
+ /*.metaObject=*/ metaObjectFunction,
+ /*.name=*/ name,
+ /*.defaultCtr=*/ nullptr,
+ /*.copyCtr=*/ nullptr,
+ /*.moveCtr=*/ nullptr,
+ /*.dtor=*/ nullptr,
+ /*.equals*/ nullptr,
+ /*.lessThan*/ nullptr,
+ /*.debugStream=*/ nullptr,
+ /*.dataStreamOut=*/ nullptr,
+ /*.dataStreamIn=*/ nullptr,
+ /*.legacyRegisterOp=*/ nullptr
+ };
+ }
+
+ Q_QML_EXPORT QObject *qmlExtendedObject(QObject *, int);
+
+ enum QmlRegistrationWarning {
+ UnconstructibleType,
+ UnconstructibleSingleton,
+ NonQObjectWithAtached,
+ };
+
+ Q_QML_EXPORT void qmlRegistrationWarning(QmlRegistrationWarning warning, QMetaType type);
+
+ Q_QML_EXPORT QMetaType compositeMetaType(
+ QV4::ExecutableCompilationUnit *unit, const QString &elementName);
+ Q_QML_EXPORT QMetaType compositeListMetaType(
+ QV4::ExecutableCompilationUnit *unit, const QString &elementName);
+
} // namespace QQmlPrivate
QT_END_NAMESPACE
+Q_DECLARE_OPAQUE_POINTER(QQmlV4FunctionPtr)
+Q_DECLARE_OPAQUE_POINTER(QQmlV4ExecutionEnginePtr)
+
#endif // QQMLPRIVATE_H