aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmltype_p_p.h
Commit message (Collapse)AuthorAgeFilesLines
* QtQml: Properly enforce signatures of AOT-compiled functionsUlf Hermann12 days1-0/+24
| | | | | | | | | | | | | Pass the metatypes of the contained types rather than the stored types. [ChangeLog][QtQml][Important Behavior Changes] The AOT compiled code for type-annotated JavaScript functions does not let you pass or return values of the wrong type anymore. Fixes: QTBUG-119885 Change-Id: I685d398c0745d32a999a3abd76c622a2c0d6651f Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QtQml: Consider value types when looking for metaobjectsUlf Hermann2024-02-151-0/+39
| | | | | | | | | | | We have quite a few types with only extension metaobjects now. Move the functionality to retrieve the metaobject into QQmlType where it belongs. Pick-to: 6.7 6.6 Fixes: QTBUG-119829 Change-Id: I2b99b1a305d8726547ae0512d3c832799a4e4b04 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
* QtQml: Do not poison the type registry with unfinished enumsUlf Hermann2023-12-201-3/+70
| | | | | | | | | | | | If a composite type is not ready, yet, and we request its enums, we should not cache the result. To facilitate this, deduplicate the surrounding code and centralize the call to initEnums(). Pick-to: 6.7 Fixes: QTBUG-120084 Change-Id: I8386a3b44010a39470e886e93c5c64bfedac0b95 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QtQml: Key singletons by singleton instance infoUlf Hermann2023-08-301-1/+1
| | | | | | | | | | | | | | | | | | | | We can keep the singleton instance info the same across multiple types created in a single registration call. The result is that we only get one singleton instance per engine, rather than separate ones for each version. If you invoke qmlRegisterSingletonType separately, you still get separate instances, though. [ChangeLog][QtQml][Important Behavior Changes] The QML engine will now refrain from creating separate instances of a singleton type for each version it is registered for if the singleton is registered declaratively (using QML_SINGLETON). The behavior of procedurally registered singletons (using the qmlRegisterSingletonType() family of functions) remains the same: For each registration call, a separate singleton instance is created. Task-number: QTBUG-116432 Change-Id: Ic8a5de0f88ef530670cfd81b192201a8ab49b2f7 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QtQml: Clean up lazy-loading of parts of QQmlTypePrivateUlf Hermann2023-07-111-16/+32
| | | | | | | | | | | | | | | | | The meta objects and the enums are lazily loaded semi-independently from each other. Their data structures take up a lot of space. We only want to incur that cost if they are actually needed. Furthermore, the lazy-loading needs to be thread-safe. The easiest way to make a thread safe lazy loading structure is via a mutable atomic pointer to an immutable object. Refactor QQmlTypePrivate to do just that. This reduces the memory usage of the base structure by about 50%, cuts down on the locking required to set up the extra aspects, and generally makes the code more readable. Change-Id: I815338d3e4de02b2f535ab2fee748bba47719efc Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* QQmlType: Re-organize QQmlTypePrivate to reduce memory usageUlf Hermann2023-07-061-25/+16
| | | | | | | | | | | | The iid is only used for interfaces, and re-ordering the members saves some padding. Also, avoid extra indirection where possible. QUrl is only one pointer to begin with, just like QMetaSequence. We can store them directly in the union. Finally, rename the extraData members so that we can easily recognize them. Change-Id: Ia9c524ea65f8137b264a7dfd9459369c90ce1670 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QQmlRefCount: de-virtualize dtorMarc Mutz2023-06-251-2/+3
| | | | | | | | | | | | | | | | | | | | | | Now that QQmlRefCounted ensures no-one uses ~QQmlRefCount() directly anymore, we can make it non-virtual, shrinking the sizeof(QQmlRefCount) from 8/16 to 4/4 bytes (32/64 bit platforms). This requires moving the release() function from QQmlRefCount down into QQmlRefCounted<T>, and static_cast'ing *this to T before calling delete. We need to be careful, of course, that no derived class relied on the implied virtualness of ~QQmlRefCount() making their dtors virtual, so require that all classes that use QQmlRefCounted are either final or have a virtual destructor. Update the toolsupport test and the TypeInformationVersion, as sizeof(QQmlRefCount) was one the items checked. Fixes: QTBUG-114817 Change-Id: I69afd36ec5b63313842c1438e0244503603ed96f Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QQmlRefCount: break all users that attempt to access the dtorMarc Mutz2023-06-251-1/+1
| | | | | | | | | | | | | | | | | | | | | ... by making the dtor private, accessible only via an auxiliary friend class QQmlRefCounted<T>. There are no users of QQmlRefCount outside of qtdeclarative, but we cannot rule out that users use this private API. Since we develop this patch as part of our own due diligence, we might as well put it into the 6.6 release so as to alert any potential users outside the qt5.git tree. Once this change is released as part of 6.6, we know we have no users of ~QQmlRefCount() (anymore), and can, in the next step, drop the virtual from the dtor, saving sizeof(void*) on each object in the hierarchy that isn't virtual of its own volition. Task-number: QTBUG-114817 Pick-to: 6.6 Change-Id: I16ea02dc57f9555e302d9415f3e573d8765cf7a3 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QQmlType: Drop dead membersUlf Hermann2023-06-231-2/+0
| | | | | | | We don't actually store the "superType". It just wastes space. Change-Id: I000303d7f1a61ace71fc41a04fc603ca4909940b Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QML: Use QQmlType as container for composite types (inline or not)Ulf Hermann2023-06-221-6/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This gives us a unified interface to all kinds of QML types at run time and reduces the effort of finding corresponding type attributes. QQmlType is much larger than CompositeMetaTypeIds. Most composite types, however, are initially referenced by URL, and we call typeForUrl anyway. typeForUrl already creates a mostly functional QQmlType; we only need to add the dynamic metatypes. The same type can be retrieved later and associated with the actual CU using the compositeTypes hash. That way, we don't need any extra type. We do, however, incur the cost of creating the QMetaTypePrivate instances when first referencing a type. This could be optimized, like many things in this area, by using thread safe lazy initialization. Now some QQmlTypes implicitly depend on the CUs they were created for. This creates problems if the CUs are removed but the types still persist. Such a situation can arise if you create and delete engines. In order to avoid it, we: 1. Make the compositeTypes hold a strong reference to the CUs 2. When unlinking, avoid dropping the property caches (as those are used to hold the metaobjects) Now, however we got a cyclic reference between the CU and its QQmlType(s). To resolve this, we clear the QQmlTypes on unlinking. Finally, to avoid deletion recursion when clearing the last CUs on destruction of the QQmlMetaTypeData, we move the compilation units out of the way first. All of this still doesn't work if multiple CUs hold the same QQmlType, since compositeTypes can only hold one CU per type and that may be the one that gets removed first. Therefore, we cannot allow such a situation to happen and have to create a new QQmlType if it arises. It can only arise if you have multiple engines loading the same QML components, which should be fairly rare. For inline components, we apply a similar trick: You can either find an inline component by Url, and receive any type that matches, no matter what CU it belongs to. Or you can request an inline component type that belongs to a specific CU. It turns out we don't have to store the containing type of an IC at all. Also, we slightly change the naming of internal components' "class names" since we want to use the inline components' element names for them. Change-Id: I0ef89bd4b0a02cc927aed2525e72f6bff56df626 Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
* QtQml: Move inline component registry to QQmlMetaTypeDataUlf Hermann2023-05-301-1/+0
| | | | | | | | | | | | QQmlTypePrivate is supposed to be immutable. "Amending" an existing QQmlTypePrivate with inline components after the fact is risky. It's hard to guarantee that no other thread accesses the data in between. Also, this way we need one lookup table for all the inline components rather than a separate (mostly empty) one for each type. Change-Id: I7a06c0faca1f8244dd2bdc7aa775abd8e2f92125 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QtQml: Eliminate inlineComponentNameUlf Hermann2023-05-301-2/+1
| | | | | | | | | It's always the same as elementName, and the lack of a containing type can be detected by asking for the containing type. Change-Id: I57e8ac89913563c3bd0c7c5824faa22bf34bb3c4 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* QtQml: Index inline components by name rather than IDUlf Hermann2023-05-301-3/+1
| | | | | | | | | | | The ID can only be determined once the compilation unit is present. It depends on the order of objects in the compiled data. The name is always available. Indexing by name increases the overhead. However, since we don't have to "amend" the ID later on and since we only need one lookup table rather than two per type now, it's probably worth it. Change-Id: I478de505a1934b5b6ab340b4be4fa5da4e95aeb3 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Allow more options for creating value types from JS objectsUlf Hermann2022-09-241-0/+2
| | | | | | | | | | | | | | | | | | | | We allow value types to be created 1. by calling Q_INVOKABLE constructors 2. by setting their values from properties of a JS object Both have to be opted into by setting a class info. If opted into, these options override the existing methods. When a a type can be created by setting its properties, that implies you can also initialize it using an invokable constructor. However, when given a JS object, the properties method is used. We keep this internal and undocumented for now. As the last try (the create(QJSValue) methods and QJSValue ctors) was not that stellar, let's first wait a bit and see if we're getting it right this time around. Fixes: QTBUG-106480 Change-Id: I767230924afcba032d501846cc3263dad57b7bf0 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Use SPDX license identifiersLucie Gérard2022-06-111-38/+2
| | | | | | | | | | | | Replace the current license disclaimer in files by a SPDX-License-Identifier. Files that have to be modified by hand are modified. License files are organized under LICENSES directory. Pick-to: 6.4 Task-number: QTBUG-67283 Change-Id: I63563bbeb6f60f89d2c99660400dca7fab78a294 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* Use const QQmlPropertyCache wherever possibleUlf Hermann2022-03-141-2/+2
| | | | | | | | We're not supposed to modify property caches after they've been created. Task-number: QTBUG-73271 Change-Id: I0ab8ed6750508fa4e28931995142f56cd5fa3061 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Clean up PropertyCache life cycleUlf Hermann2021-11-091-2/+2
| | | | | | | | | | | | | We generally want to use QQmlRefPointer for it, rather than manually calling addref() and release() all over the place. Also, we can completely inline its ctor and drop an unused member. Also, do not keep property caches of dynamic meta objects in type registry. The dynamic metaobjects will change, and the outdated property caches will eventually be retrieved. Change-Id: I8042c85b32f3031b554f97a35c1545a3412d2acb Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
* Long live (the internal) QQmlFinalizerHook!Fabian Kosmale2021-09-291-0/+1
| | | | | | | | | | | | | | | | | | | | | | | QQmlFinalizerHook is meant to replace registerFinalizeCallback. The latter is more powerful: It allows you to register multiple functions, depending on various conditions. Moreover, if the component is already finalized, it directly runs the function. However, that power is not used anywhere: All we currently use and need is the ability to run a function after the component is finalized. By using an inerface instead of some generic registration framework, we can make finalizers visible to tooling. This is especially important for qmltc, which needs to instantiate the compiled components and still must ensure that finalizers do run. We also use this chance to document the existence of finalizers, as well as the difference between componentComplete and finalizers. The interface is kept internal, as asynchronus component instantiation is still an underdocumented corner of the QML engine, and the implications of making the interface public are unclear. Task-number: QTBUG-96054 Change-Id: I876bf9650faac20598cfd6aaea7c6da9bf65d73f Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Allow registration of enums from related types to be switched offUlf Hermann2021-06-161-0/+1
| | | | | | | | | | | | | | This was a terrible misfeature. It registers random enums from all over the place into a type. See the test for an example. [ChangeLog][QtQml] You can now suppress the registration of enums of "related" C++ types in a QML type. Such registration is often unintended and rather unpredictable. Set the "RegisterEnumsFromRelatedTypes" Q_CLASSINFO to "false" in order to suppress the registration. Task-number: QTBUG-83703 Change-Id: Ic9046daa7a3c833ce65396a8731dfa28d269317c Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
* QML: Allow singleton types to be extendedUlf Hermann2020-11-021-0/+2
| | | | | | | | | It seems we never stated that singletons can not be extended in our documentation. Therefore this is technically a bug fix and doesn't need separate documentation. Change-Id: I7877289bd5a52ecf709f80ba1975137981ec65f0 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Use factory functions and ctors for creating value typesUlf Hermann2020-10-021-0/+1
| | | | | | | | | | As you can extend value types with QML_EXTENDED we may as well allow a factory function in the extended type. Furthermore, if the original type allows construction from QJSValue, we may just use that. In turn, we can get rid of the value type providers now. Change-Id: I9124ea47537eab6c33d7451080ab2fff942eaa7b Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* V4: Rewrite qv4sequenceobject based on QMetaSequenceUlf Hermann2020-10-021-0/+3
| | | | | | | | | | This avoids the template explosion and makes the mechanism extendable. You can now register additional anonymous sequential containers. Fixes: QTBUG-71574 Task-number: QTBUG-82443 Change-Id: I5b9ed9af1533a3b7df8fc5bb37bbb73b8304e592 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Add userdata callback to qml registrationMaximilian Goldstein2020-07-101-1/+2
| | | | | | | This is needed in order to remove PySide2's qml type limit. Change-Id: I331d9e31574a744eb9085222d58ea8a8789e0e31 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QQmlTypePrivate: do not abuse volatile for atomicFabian Kosmale2020-06-091-4/+6
| | | | | | | | | | Instead of using volatile, use proper atomics for thread safe access. Moreover, we don't gain anything by using bitfields here, as we have space for 4 bools due to alignment reasons anyway. Therefore using bools does not create any overhead. Change-Id: I390acd935656efcb20265ddb67fa0059f3f18118 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Adapt to the the new QMetaType changeOlivier Goffart2020-03-091-2/+2
| | | | | | Fixes: QTBUG-82453 Change-Id: I7e5682945a07c3af183becd3947a69568f139d16 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Use QTypeRevision for all versions and revisionsUlf Hermann2020-02-031-3/+2
| | | | | | | | | | | | | | In many places we carry major and minor versions or revisions that are loosely coupled to minor versions. As the Qt minor version resets now, we need to handle these things more systematically. In particular, we need to add a "major" part to revisions. QTypeRevision can express the current major/minor pairs more efficiently and can also be used to add a major version to revisions. This change does not change the semantics, yet, but only replaces the types. Change-Id: Ie58ba8114d7e4c6427f0f28716deee71995c0d24 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Long live QML inline componentsFabian Kosmale2020-01-231-0/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | [ChangeLog][QtQml] It is now possible to declare new QML components in a QML file via the component keyword. They can be used just as if they were declared in another file, with the only difference that the type name needs to be prefixed with the name of the containing type outside of the file were the inline component has been declared. Notably, inline components are not closures: In the following example, the output would be 42 // MyItem.qml Item { property int i: 33 component IC: Item { Component.onCompleted: console.log(i) } } // user.qml Item { property int i: 42 MyItem.IC {} } Fixes: QTBUG-79382 Change-Id: I6a5ffc43f093a76323f435cfee9bab217781b8f5 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Retrieve the attached properties base type without recursionUlf Hermann2019-11-181-0/+12
| | | | | | | | | This is probably faster and avoids the deprecation warnings stemming from deprecated functions calling themselves recursively. Task-number: QTBUG-80040 Change-Id: I2f65aad3bc7f85b7a7de66d3e76dac1233a58db8 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Optimize enum setupUlf Hermann2019-09-101-1/+21
| | | | | | | | | | If we have already set up the enums from a property cache or a metaobject, respectively, we can see that from the flags. Retrieving the composite property cache is expensive and we can skip it in that case. Task-number: QTBUG-77237 Change-Id: I63f5e1ca0fc166ec927754bdf5d166b2ce8ff0f6 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* Merge remote-tracking branch 'origin/5.13' into devQt Forward Merge Bot2019-04-231-1/+0
| | | | | | | Conflicts: src/qml/qml/qqmlmetatype.cpp Change-Id: Ieff61c076e46eb50a059c8b0210f7f4d7ce0cbcf
* Move propertyCache-by-minor-version into QQmlMetaTypeDataUlf Hermann2019-04-181-11/+0
| | | | | | | | | | | | Ths data structure should only be accessed when protected by the metatype data lock. In fact we don't access it from anywhere else. To make that more obvious, move it to the right place. This allows us to eliminate some const_cast and poking around in QQmlTypePrivate from the outside. Change-Id: I16ffd240b9504b9c00010bdb2d17b05c8196fe8a Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
* Merge remote-tracking branch 'origin/5.13' into devQt Forward Merge Bot2019-04-101-1/+2
| | | | | | | | Conflicts: src/qml/qml/qqmlmetatype.cpp src/qml/types/qqmlmodelsmodule.cpp Change-Id: Idc63689ba98d83a455283674f4b5cf3014473605
* Use QQmlRefCount for QQmlType(Private)Ulf Hermann2019-03-191-4/+4
| | | | | | | | | | | | | As we already have an implementation of refcounting, we can just use that intead of inventing another one. This also gives us nice move ctors and operators. Also, use const pointers to QQmlTypePrivate where possible. This exposes quite some nastiness that needs to be fixed in follow-up commits: All the mutable members of QQmlTypePrivate are unsafe for multithreaded use. Change-Id: I3be8f2c53d86e06ffa80c8df8830473fe6d1d91d Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* Make QQmlTypePrivate::name safe for usage from different threadsUlf Hermann2019-02-111-0/+3
| | | | | | | | There is hardly a point in setting this lazily. We always set uri and elementName together anyway. Change-Id: I5f9f00ee72d78fd8cf66413e81c8d88db1f8a436 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
* Eliminate excessive friendlyness of QQmlTypeUlf Hermann2019-02-081-2/+0
| | | | | | | | | | | | QQmlMetaTypeData does need to be exposed to the QQmlType ctors. Rather, we can use factory functions to create the QQmlTypePrivate objects. The static attachedPropertyIds should really be part of QQmlMetaTypeData and access to them should be protected by the lock. Task-number: QTBUG-73271 Change-Id: I154a3842fab03a02c710901a20afd1652364808d Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* Move QStringHash into its own fileUlf Hermann2019-02-061-1/+1
| | | | | | | QHashedString and QStringHash are different things. Change-Id: Ifcac58ef41bf15dd6172fa0c42b86eca385c2ce0 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* QML: Split qqmlmetatype{_p.h|.cpp} into multiple filesUlf Hermann2019-02-061-0/+160
Having all those classes in one big file promotes spaghetti code and makes the code unreadable. Change-Id: I3b6df93b9cfe1d97228771049b3054e78b868ea3 Reviewed-by: Lars Knoll <lars.knoll@qt.io>