aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4qobjectwrapper.cpp
Commit message (Collapse)AuthorAgeFilesLines
* Port away from QPairZhao Yuhang2025-04-121-11/+11
| | | | | | | | QPair is just an alias of std::pair anyway. Task-number: QTBUG-115841 Change-Id: I26fc90adcc775aac9955ad57304af914dc4ed48f Reviewed-by: Ulf Hermann <[email protected]>
* Improve "could not convert argument" error messageMitch Curtis2025-04-021-1/+2
| | | | | | | | | | | | | | | | | | | | | Add the actual types involved in the attempted conversion, rather than just saying that it couldn't be done. Before: "Could not convert argument 0 at" "expression for onCompleted@qrc:/qt/qml/quick2/Main.qml:34" qrc:/qt/qml/quick2/Main.qml:34: TypeError: Passing incompatible arguments to C++ functions from JavaScript is not allowed. After: "Could not convert argument 0 from QQmlComponent(0x5b72731bd710) to QQuickItem*" "expression for onCompleted@qrc:/qt/qml/quick2/Main.qml:34" qrc:/qt/qml/quick2/Main.qml:34: TypeError: Passing incompatible arguments to C++ functions from JavaScript is not allowed. Pick-to: 6.8 6.9 Change-Id: Ia4144ad61332e53c662a280dd8b68dc99aa09cf8 Reviewed-by: Ulf Hermann <[email protected]>
* QtQml: Don't use bindables for bindings on value type aliasesUlf Hermann2025-03-241-4/+9
| | | | | | | | | | | | | | | | | | | | | | Forwarding the bindability of aliases is a complicated affair because a single alias can encompass two properties (the "core" and the "value type" property). This change adds another flag to discern between "can use the bindable for notifications" and "can install a QBinding on this property". Those are different aspects. Deep aliases can still notify via the bindable of the core property, but they cannot accept a QBinding. Accordingly, when querying the metaobject for a bindable of a value type alias, return the bindable of the core property. This is the one you at least meaningfully install an observer on. The bindable of the value type property would be entirely useless. Amends commit 1f40e12a844ca2939c86f19610590920841efb15. Pick-to: 6.9 6.8 6.5 Task-number: QTBUG-134688 Change-Id: Ib219657bcbd2e263285d54f8736cada74ac594f5 Reviewed-by: Fabian Kosmale <[email protected]>
* QtQml: Add sticky bit to QQmlAbstractBindingUlf Hermann2025-03-111-2/+5
| | | | | | | | | | | QUntypedPropertyBinding has a sticky bit already. We need the same in QQmlAbstractBinding so that we can create bindings that don't break if you write to their targets. Task-number: QTBUG-132420 Change-Id: Ia5fa21120722ce1f8b1088a85b9b57405ab3b57d Reviewed-by: Sami Shalayel <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* QtQml: Fix AOT compiled context for destroy() and toString() methodsUlf Hermann2025-02-261-9/+13
| | | | | | | | | | | | | | | | | | | | Those are not mapped to regular QMetaMethods but rather come with special method indices and need to be resolved separately. Amends commit a741271dd58b21728928684f1ef1efaa91e79ebf This exposes that the override order between JavaScript extensions and their base types was wrong. JavaScript extensions do certainly not override their base types. Fix this, too. We also need to always specialize the lookups for these calls. It doesn't actually matter if there is propertyData or not since we branch off into the special cases anyway when calling them. Pick-to: 6.9 Fixes: QTBUG-132602 Change-Id: Iea83ce94459b0d0a3bf54731898fd62b9ad46c46 Reviewed-by: Fabian Kosmale <[email protected]>
* QObject: Suppress extra arguments on connectionsUlf Hermann2024-12-191-3/+19
| | | | | | | | | | | | If we use connect() to connect signals to other invokables we don't want to see the warnings about extra signal arguments. Amends commit cbe1869fbe7048f34513b201a1d9111a0a64257a. Pick-to: 6.9 6.8 6.5 Fixes: QTBUG-131774 Change-Id: Iedec7b7c9f71cf2493ccdc00841e087bd336e028 Reviewed-by: Semih Yavuz <[email protected]>
* QtQml: Avoid potential gc issuesFabian Kosmale2024-12-181-1/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Implicitly constructing a value from a ReturnedValue muddies the responsibility for ensuring that the gc can find the object. With this change, we disable the implicit conversion. The expectation for lifetime management is now: - If a ReturnedValue is stored on the C++ stack, it must be put into a QV4::Scoped class (or there should be a comment why not doing so is safe). Passing a ReturnedValue to a function should no longer be possible, unless the function takes a ReturnedValue, in which case the expectation is that it stores the value in a place where it can be seen by the gc, before doing anything that could trigger a gc run. Using Value::fromReturnedValue can still be used to pass a Value on, but in that case, the expectation is that there is a comment which explains why this is safe. - If a QV4::Value is obtained from a function call, it ought to be stored in a ScopedValue, too. We currently can't enforce this easily, so this should be checked during code review. A possible way forward would be to disallow returning Values, but that would be a larger change, and is deferred to the future. - If a functions has a QV4::Value parameter, it's the callers' responsibilty to ensure that the gc can find it. Pick-to: 6.9 6.8 6.5 Fixes: QTBUG-131961 Change-Id: Iea055589d35a5f1ac36fe376d4389eb81de87961 Reviewed-by: Ulf Hermann <[email protected]>
* Implement read/write-backs for QVariantMap and QVariantHashLuca Di Sera2024-12-011-0/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When QML receives something from the C++ side, it, sometimes, tries to set up a read/"write-back" mechanism to allow changes on the QML side to be reflected on the C++ side and changes to the original element being synchronized with the QML side. This can happen, for example, when accessing a property of a C++ object that was registered to QML directly from QML. Similarly, it can do so when nesting some of its internal representation of an object with C++ provenance. For example, a `QVariantList` that is passed to the QML side and converted to a `Sequence` type might require some of its stored element to perform a write-back when accessed and modified to ensure that mutations are permanent. For `QVariantMap` and `QVariantHash` this was currently not implemented, with `QVariantMap` being generally converted to a Javascript object and support for `QVariantHash` not necessarily entirely implemented. This can produce surprising results. For example, a `QVariantMap` that is stored in a `QVariantList`, where the list is passed over to the QML side from the C++ side, might incur into its mutations being lost when accessed as a member of the converted `QVariantList`. To ensure that this does not happen, `QVariantMap` and `QVariantHash` will now be converted to a representation that is a `ReferenceObject`, that is, it uses the general read/write-back mechanism in QML. Introduce a new QV4 Object, `VariantAssociationObject`, that can store either a `QVariantMap` or a `QVariantHash` and has read/write-back behavior. The prototype for the object is now registered by the engine and can be accessed through the `variantAssociationPrototype` method. A `QVariantMap`/`QVariantHash` that is being converted to a JS representation will now be converted to the newly introduced object instead of being mapped to a generic JS object. `variantMapToJS` and `variantToJs` in "qv4egnine.cpp", that were used during the conversion of `QVariantMap` to a Javascript object were removed as they are now unused. Some additional cases were added to support conversion from/to `QVariantHash` and conversion from the newly added object. The newly added object supports a small subset of an object functionality and is not intended, at least currently, to support the whole breadth of interactions that a Javascript object would. In particular it aims to support setting properties, retrieving properties, deleting properties, basic iteration and `Object.hasOwnProperty`. It further implements basic read/write-back behavior for those interactions and allows for recursive read/write-backs through the general `virtualMetacall` interface. Additionally, the code `QQmlVMEMetaObject::writeVarProperty` was modified to ensure that the new reference object is detached when assigned to a `var` property, so as to be consistent with the general behavior of the other reference objects. As a drive-by, a comment in the above code that stated that some of the code should be adjusted if a new case was added to it was modified to state that the code should be adjusted with no additional clause, as a new element was added but the adjustment will not be performed as part of this patch. Some general test cases were introduced in `tst_qqmllanguage` for the new object. In particular to test the most basic interactions of the above subset of an object interaction, some of the read/write-back behavior and the behavior of detached when being assigned to a var property. Fixes: QTBUG-129972 Change-Id: Ib655ba6001aef07a74ccf235d2e3223b74d7be59 Reviewed-by: Fabian Kosmale <[email protected]>
* QtQml: Fix calling of method with QML_USING typesUlf Hermann2024-11-131-20/+83
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | On the engine side, types made available with QML_USING are recognizable by their QMetaType conversions. In order to actually call the right methods, we need to slightly prefer methods to whose arguments we can convert over ones we have not idea about. This, however, adds the problem of converting to QString, double, QVariant and QJSValue, which is possible for any type. Since such conversions are less specific than manually added converters, we de-prioritize them a bit. On the compiler side we need to transmit the knowledge about the overload to be called from the compiler (which has already done its own overload selection) to the lookup methods. This is easily done using the relative method index. This way we do not need to do any run time overload selection at all and we do not need to pass any types to the lookup methods. We can do this without further compatibility adaptations because the current version of those lookup methods was only introduced in 6.9. Excluded, of course, are shadowable calls, which are performed with only QVariant arguments. These carry the arguments themselves and trigger the engine's overload selection. Internally nothing changes about them. Passing a list of QMetaType::fromType<QVariant>() to the lookup methods for them has always been a waste. Only the engine changes are relevant for 6.8. In 6.8, the lookup methods defer the overload selection to the engine and take the types on every call. We still cannot separate the engine changes from the compiler changes in dev because the same test is run once in interpreted and once in compiled mode. Pick-to: 6.8 Task-number: QTBUG-127174 Change-Id: I6ab52ddf3be65dcc94547266c5dcc5ac1050c93c Reviewed-by: Olivier De Cannière <[email protected]>
* QtQml: Call lookups based on enums rather than via function pointersUlf Hermann2024-10-241-21/+6
| | | | | | | | | | | | | | | | | While the C++ standard says that different functions need to have unique addresses, some compilers have take substantial liberties with that rule. This means we can't actually rely on the addresses of our different lookup functions to differ and therefore we cannot use them as discriminator. Introduce an enumeration for all the different lookups and use that instead. Now we can also drop all the purely redirecting methods we've introduced just to have different addresses. Change-Id: Ifa68c27c0d2fef4084893a19227dab21bd948dfd Reviewed-by: Fabian Kosmale <[email protected]>
* QtQml: Protect lookupAttached() from identical COMDAT foldingUlf Hermann2024-10-171-0/+10
| | | | | | | | | | | | | | | MSVC thinks it can deviate from the standard and fold separate functions into the same code block even if their addresses are taken. This makes the addresses equal and breaks the lookup mechanism. We set up a dilemma for the compiler by explicitly comparing the function addresses and failing when they are equal. Now the new function has "different" code that will however be optimized away. Pick-to: 6.8 6.5 6.2 Fixes: QTBUG-128843 Change-Id: I42d9f764235b877c5c9e054502ea01a16369d27b Reviewed-by: Sami Shalayel <[email protected]> Reviewed-by: Olivier De Cannière <[email protected]>
* QmlCompiler: Resolve types for calls in init stepUlf Hermann2024-10-141-7/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Now that resolving the types can be more expensive, especially for composite types, we should be careful not to do it too often. Most of the cases where we have to resolve types are for lookups. Most of the lookups only resolve types in their "init" step, which ideally is only performed once in the application life time. However, so far calls had to pass the types of arguments and return values in the actual "lookup" step, which causes the resolution to happen on every call. This change moves those type resolutions to the init step. We can do this because: 1. Regular typed method calls are calls to a specific overload with specific types. The method itself already has the list of types and we can just remember which one that is. Then we don't need to pass the types. 2. Calls to shadowable methods are all-QVariant typed. The only thing we need to know is the number of arguments. Then we can construct the list of types in the lookup itself. We can remember which one of those we're dealing with by adding further "AsVariant" lookup functions. For the case of non-property-cached regular methods we also need a new "Fallback" lookup like we already have it for properties. Change-Id: I74a3729131d6a5ea0ad79e276965a5167cd609be Reviewed-by: Olivier De Cannière <[email protected]>
* QmlEngine: Add support for sequences to CallArgument::fromValueOlivier De Cannière2024-08-081-0/+20
| | | | | | | Fixes: QTBUG-127704 Pick-to: 6.7 6.8 Change-Id: Ifb6aad0feb26fadee2838b74a3a7c29949be05a6 Reviewed-by: Fabian Kosmale <[email protected]>
* QtQml: Improve overload resolution for value type ctorsUlf Hermann2024-07-301-16/+18
| | | | | | | | | | | | | Prefer exact matches where they exist, try all ctors for derived types then, and only if that doesn't help, try conversion. In order to properly compare the types, always retrieve variants from V4 values as their "natural" type rather than pre-coercing them. Pick-to: 6.8 Task-number: QTBUG-125341 Change-Id: Ib3bc45edd6983ca662c556ca8d8c6ed5d2bbaf46 Reviewed-by: Fabian Kosmale <[email protected]>
* QtQml: Straighten out some logging categoriesUlf Hermann2024-06-171-4/+4
| | | | | | | | | | | Either make them static or declare them in a header. We want them to be static wherever possible, in order to reduce the number of visible symbols. If they can't be static, however, they should at least be declared in only one place. Task-number: QTBUG-67692 Change-Id: I91fa641b46510ea8902b478d31dfd60d34b5f580 Reviewed-by: Fabian Kosmale <[email protected]>
* Restructure builtins and QtQml.BaseUlf Hermann2024-06-031-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The QtQml library should hold the builtins and provide no plugin. Move the types currently exposed in QtQml.Base to QtQml where it makes sense. Anonymous object types as well as sequence types and value types can well be exposed as builtins. This makes everybody's life easier since you now can universally depend on their availability. The Qt object, despite being a named object type, also becomes a builtin because you always have the "Qt" member of the JavaScript global object which holds the same thing. So, formally exposing "Qt" as builtin doesn't really add anything new. QQmlLoggingCategory is split up into two classes, not only because we need the base class when printing to the console from QtQml, but also because this paves the way for compile time identification of logging categories as first argument to the console methods. For QQmlLocale we have to refer to a different trick. The value type and the QQmlLocale "namespace" have to be builtins, but the "Locale" name, due to being uppercase and versioned, has to be part of QtQml. We transform QQmlLocale into a struct so that we can inherit the enums from QLocale and extend a namespace with it in QtQml. Pick-to: 6.8 Fixes: QTBUG-119473 Fixes: QTBUG-125765 Change-Id: Ica59390e54c473e33b4315f4384b724c870c1062 Reviewed-by: Fabian Kosmale <[email protected]>
* Clean up some includesUlf Hermann2024-05-301-33/+25
| | | | | | | | | | In particular, don't include qqmllocale_p.h, qqmlbind_p.h and qv4sequenceobject_p.h where we don't need them. Also, don't qualify private includes by their module name so that we can move them to other modules more easily. Change-Id: Ic13592cef574424498ce9e7708d6fbaa681b81f3 Reviewed-by: Sami Shalayel <[email protected]>
* QtQml: Let QQmlTypeWrapper act as a constructor for its typeUlf Hermann2024-05-231-2/+6
| | | | | | | | | | | | | | This calls any invokable ctors and only invokable ctors. Any type that doesn't have an invokable ctor won't even expose a function, since functions are determined by the presence of call methods. QMetaObjectWrapper gains the same functionality since the code is shared. It can now not only create object types but also value types. Task-number: QTBUG-124662 Change-Id: Ib30098666f67aef7a1f464f52d9b0bbd70d896d1 Reviewed-by: Fabian Kosmale <[email protected]>
* Load a QJsonArray property as a SequenceLuca Di Sera2024-05-221-5/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When a property coming from C++ is used in a QML file, the engine might perform some internal conversion to handle the type. When a `QJsonArray` property is loaded, currently, it will be converted to an internal `JsonObject` representation containing an engine-owned array. When the conversion is done, the data from the `QJsonArray` is copied as a part of this process. The performed copy is expected to act like a Javascript array. Nonetheless, due to the way the conversion is implemented, using the property will perform the requested work on the copy without writing back to the original property. This in turn prevents certain operation from working as expected, in particular the mutable methods on the array prototype. For example, if `jsonArray` is a `QJsonArray` property with a C++ provenance, the following will not register the push on the original property, so that it will be lost the following time the property is accessed: ``` ... jsonArray.push(4) ... ``` As a `QJsonArray` property should behave as a Javascript array when used from QML, a `QJsonArray` property will now be converted to a `Sequence`, an internal representation that behaves like a Javascript array but acts as a reference object with property write-backs, to allow in-place mutations to be correctly reflected on the original property. Currently, a `QJsonArray` `Sequence` call to the sort method will not correctly work due to the way the sort method is implemented. This is currently left as non-working and will be fixed separately. A non-exhaustive test-case was added to check that a C++ loaded `QJsonProperty` acts as a Javascript array with regards to the Array prototype methods, taking into consideration the inability of the sort method to currently work. Task-number: QTBUG-111015 Change-Id: Iec48fe4cba9adb9b794e5a568985b86b8da4556c Reviewed-by: Ulf Hermann <[email protected]>
* V4: Slim down FunctionObjectUlf Hermann2024-05-141-22/+16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Most FunctionObjects do not actually need their custom jsCall members. They will only call the functions from the vtable anyway. FunctionObject can therefore be split into a static and a dynamic variant. Only the dyanmic variant needs to carry (and invoke) the extra pointer. The jsCallWithMetaTypes pointer is completely pointless because none of the dynamic functions actually implement it. Furthermore, the QV4::Function and QV4::ExecutionContext pointers in FunctionObject are only needed by actual JavaScript functions. The builtins that like to be dynamic functions never need them. Therefore, split out another class for this. In the generic FunctionObject, we need the capability to decide at run time whether the function shall be a constructor or not. Add a flag to replace the check for jsCallAsConstructor. Also, where we can, avoid the pessimization of checking whether a function is a constructor before trying to call it as constructor. Rather have the default implementation throw the exception. As a side effect, for most functions we don't need an ExecutionContext anymore. The engine is enough. Task-number: QTBUG-124662 Change-Id: Iac657fa71288dd6ec230a33de2986ba3bcf4628c Reviewed-by: Fabian Kosmale <[email protected]>
* QtQml: Move QMetaObjectWrapper into separate header/impl filesUlf Hermann2024-04-281-116/+8
| | | | | | | | | We want to use it from QQmlTypeWrapper and avoid circular includes. Task-number: QTBUG-124662 Change-Id: I4c78a17eb262a303b7239bbdd853ec02d609c330 Reviewed-by: Olivier De Cannière <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* QtQml: do not obtain the stack trace twice in CallPrecise()Vladimir Belyavsky2024-04-221-1/+1
| | | | | | Change-Id: Ieb108a84f5c1fefe813ac0af6c2ca9332fdbefe8 Reviewed-by: Ulf Hermann <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* V4: Handle all array-like containers when converting to QJsonArrayOlivier De Cannière2024-04-221-2/+2
| | | | | | | | | | | | | | | | Commit b9bfdea0e2c6721d2306af0ecc44f88da9988957 removed specialized code for QVariantList conversions by relying on sequences instead. Some checks for sequences and other array-like containers were missed. Add those and perform all calls to QJsonObject::toJsonArray through a common QV4::Object interface. Amends b9bfdea0e2c6721d2306af0ecc44f88da9988957 Pick-to: 6.7 Fixes: QTBUG-123993 Change-Id: Ia671d556af4f2b4d44f652fa93182977d88621f2 Reviewed-by: Ulf Hermann <[email protected]>
* QtQml: Add a wrapper builtin for QQmlV4Function*Ulf Hermann2024-04-121-1/+1
| | | | | | | | | This way qmltyperegistrar can recognize it and refrain from warning about it. Task-number: QTBUG-101143 Change-Id: I598140e7e90dbd3e27a78c26eff3d46f0fd3e989 Reviewed-by: Fabian Kosmale <[email protected]>
* Prepare for white allocations (7/9): QQuick(Window|View)Fabian Kosmale2024-03-051-1/+23
| | | | | | | | | | | | | Prevent QObjectWrapper from being gced - if we use white alloctations, and the weak values have already been marked, then nothing will mark the newly created QObjectWrapper. Use a helper function which takes care of the marking, and call it in the appropriate places. Also mark the normal wrap and wrapConst functions as [[nodiscard]] to avoid this issue from resurfacing in the future, and adjust a few call-sites to also call ensureWrapper. Change-Id: I8d4c73ae62b61d21b1456a3b096fc6a42f302160 Reviewed-by: Ulf Hermann <[email protected]>
* Prepare for white allocations during gc (1/9): Write barrier for LookupsFabian Kosmale2024-03-051-1/+2
| | | | | | | | | | | | | | | | | | | | | | | Lookups can (and do) reference HeapItems. This was safe in a non-incremental gc world, as Lookups are always reachable via their containing CompilationUnits, which are part of the root set. However, when using an incremental gc, an already marked Lookup might reference a new heap item, which then becomes otherwise unreachable. This is alleviated by the fact that Lookups generally either refer to something already existing or a freshly allocated string. The latter however is only safe when we can rely on black allocations during gc, and the former is somewhat reckless. Remedy this by employing the WriteBarrier for Lookups. We wrap all HeapItems in a helper class, which -while trivial itself- can't be used for direct assignments. Intead, it employs a set method which ensures that the WriteBarrier is used. Task-number: QTBUG-121910 Change-Id: I6a0ede66ad044076d2e87f134bc95686cb586aee Reviewed-by: Olivier De Cannière <[email protected]> Reviewed-by: Sami Shalayel <[email protected]> Reviewed-by: Ulf Hermann <[email protected]>
* QtQml: Make QLocale an actual value typeUlf Hermann2024-03-021-7/+0
| | | | | | | | | | | | | | | | | | | | We want to be accessible to qmllint and other QML tooling. To this end, make all legal invocations of its methods properly typed invokables. Keep two QQmlV4Function overloads to produce error messages if the methods are called with the wrong parameters. We have to do this because JavaScript is more liberal in its argument coercion than the methods would like. Un-deprecate QJSNumberCoercion::isInteger() since it's actually quite practical here. Pick-to: 6.7 Fixes: QTBUG-112366 Change-Id: I016e5edc47efaade44461c504c1b3e2b1b829b58 Reviewed-by: Oliver Eftevaag <[email protected]> Reviewed-by: Qt CI Bot <[email protected]> Reviewed-by: Ulf Hermann <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* QtQml: Do not construct strings where we don't need toUlf Hermann2024-02-261-5/+9
| | | | | | | | If we want to know whether the QML.StrictArguments class info is "true", we can just compare the byte array directly. Change-Id: If857f88c0cce7314abaaa6131a2fba3cd459c4b2 Reviewed-by: Fabian Kosmale <[email protected]>
* QtQml: Re-allow manual calling of signal handlersUlf Hermann2024-02-131-0/+22
| | | | | | | | | | | | | | | The fact that you could do this was due to a mistake in the implementation of QQmlPropertyCache. The cache entry for the signal handler looked like the signal itself. Make it possible to call QmlSignalHandler objects, and output a categorized warning when doing so. Also, align the call code between the interpreter and the JIT. Pick-to: 6.7 Fixes: QTBUG-120573 Change-Id: Ic76d37f587d21b68c55d77a08ac2d30950bec133 Reviewed-by: Fabian Kosmale <[email protected]> Reviewed-by: Yifan Zhu <[email protected]> Reviewed-by: Qt CI Bot <[email protected]>
* QtQml: Clear context objects more thoroughly on destructionUlf Hermann2024-02-011-3/+1
| | | | | | | | | | | | The same object can be the context object of a hierarchy of contexts. So far we would only clear one of them, leaving dangling pointers in the others. Clear all the contexts. Pick-to: 6.7 6.6 6.5 6.2 5.15 Fixes: QTBUG-119326 Change-Id: I509f257672813866e3736b51f430f1243a8577f0 Reviewed-by: Qt CI Bot <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* QtQml: Do not call signal handlers on half-deleted objectsUlf Hermann2024-01-171-1/+3
| | | | | | | | Pick-to: 6.7 6.6 Fixes: QTBUG-121022 Change-Id: Icdefd6bef4906700d88eca47c09d0abe54f1eec9 Reviewed-by: Fabian Kosmale <[email protected]> Reviewed-by: Qt CI Bot <[email protected]>
* QtQml: Clear stale compilation units more thoroughlyUlf Hermann2024-01-111-1/+10
| | | | | | | | | There are various places where we can still hold references. Clean them up when asked to do so. Also, free unused types and caches outside the type loader mutex, and only once on engine shutdown. Change-Id: Iae77cd6f50ad847d29a7eae4ac5c7c1c2524065d Reviewed-by: Fabian Kosmale <[email protected]>
* QtQml: Remove QQmlTypeLoader from QQmlImportUlf Hermann2024-01-111-13/+18
| | | | | | | | | The type loader belongs to the engine and we must not store it in engine-independent data structures. We do want the import cache to be stored in the type registry, though (in a separate change). Change-Id: I2828f5098b27bf1fc96852fc2bd160db44b109e7 Reviewed-by: Fabian Kosmale <[email protected]>
* Compiler: Guard against null dereference when ignoring function returnOlivier De Cannière2024-01-091-7/+9
| | | | | | | | | | | | | | | | | | | When a function is called, two arrays with the necessary information are passed to the engine: argv: [return address, prameter 1 address, parameter 2 address, ...] types: [return type, parameter 1 type, parameter 2 type, ...] When the result of the call is ignored, the return type is set to void and the return address to null. A check for this null value was missing leading to a null derefence. Amends: 4f1b9156a48e44cf1f127a4563d0ac69ab436f12 Fixes: QTBUG-120336 Pick-to: 6.7 Change-Id: I4a21779f3276b0143087b41b0d16c0cd3ba0e7db Reviewed-by: Ulf Hermann <[email protected]>
* QQmlConnections: Allow connections to C++-defined methodsUlf Hermann2023-11-291-3/+3
| | | | | | | | | | | | | | | | | | | | With qmltc you can produce classes derived from QQmlConnections with handler methods that should still receive the signals. Introduce a new helper class QQmlConnectionSlotDispatcher that enables connections to a C++ method inside a QQmlConnections, in the same way as QQmlBoundSignal does for Javascript functions. Change QQmlConnectionsPrivate::boundsignals to allow for C++ slots using QQmlConnectionSlotDispatcher. This allows usage of Connections QML elements when they are compiled to C++ via qmltc. Pick-to: 6.6 6.5 Fixes: QTBUG-119084 Change-Id: I05d78a45a703630f43d37337268d0a3df341e7d3 Reviewed-by: Olivier De Cannière <[email protected]> Reviewed-by: Sami Shalayel <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* Fix build with -no-feature-qml-localeTasuku Suzuki2023-11-241-0/+2
| | | | | Change-Id: I01c1005d962a030672f785d8ef752dab62ed5712 Reviewed-by: Ulf Hermann <[email protected]>
* Detect slot object if explicitly providedFabian Kosmale2023-11-151-2/+20
| | | | | | | | | | | If explicitly context is given to function when connecting, it is used as the receiver. Then when the context is destroyed, the connection will also be cleared. Pick-to: 6.6 Fixes: QTBUG-29676 Change-Id: Iec9318132245094603f71e3e6279d65c8021cb7e Reviewed-by: Ulf Hermann <[email protected]>
* QtQml: Optimize reading properties into V4 valuesUlf Hermann2023-11-151-25/+129
| | | | | | | | | | | | | | | We need to be more careful here since the builtins will become proper value types with metaobjects, but we don't want to encode them into QQmlValueTypeWrapper, but rather their specialized representations. Besides, avoiding the code path via QVariant and engine->fromVariant() is also a performance boost. Task-number: QTBUG-101143 Change-Id: I1c570ebcb6c4e129e9bdeef069b8a49e2a1e29d6 Reviewed-by: Qt CI Bot <[email protected]> Reviewed-by: Olivier De Cannière <[email protected]> Reviewed-by: Semih Yavuz <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* QML: Implement QObjectMethod::virtualCallWithMetaTypesUlf Hermann2023-09-281-1/+188
| | | | | | | | | | | | We can use the same mechanism we have in place when calling typed JavaScript functions. The type coercion is generalized and moved to qv4jscall_p.h. We also use the correct JavaScript coercion in the rare fallback case where the types are actually different. Fixes: QTBUG-113258 Change-Id: I30404ee0122433b47227b2fc0dc4b0e3862a99c7 Reviewed-by: Qt CI Bot <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* QtQml: Reset context object when destroying it from QObjectWrapperUlf Hermann2023-08-221-0/+2
| | | | | | | | | | | There may be other objects that still hold on to the context data. We should not leave them with a dangling context obejct. Pick-to: 6.6 6.5 6.2 Fixes: QTBUG-116228 Change-Id: I3dddd20b13956408d0e66c3a46e59377e45d91e5 Reviewed-by: Fabian Kosmale <[email protected]> Reviewed-by: Qt CI Bot <[email protected]>
* QV4::QObjectWrapper: Use the object's actual meta typeKai Uwe Broulik2023-08-221-4/+2
| | | | | | | | | | | | | | | | | | | Otherwise, a derived type's methods will not be found. In our particular case we tried to call a method of 'B*' on a QML attached property declared as 'A*'. This restores the previous behavior of using the object() for the meta type except for when it's a value type wrapper. Amends commit 63b622d5908ec2960ce5dfa301e9d3fd4d92fdb4. Pick-to: 6.6 6.5 6.2 Change-Id: I08b9f4b97a58c15fdc3703dd3c5d927cd1beb3ce Reviewed-by: Sami Shalayel <[email protected]> Reviewed-by: Qt CI Bot <[email protected]> Reviewed-by: Semih Yavuz <[email protected]> Reviewed-by: Ulf Hermann <[email protected]>
* QV4::QObjectWrapper: Remove superfluous loopKai Uwe Broulik2023-08-191-7/+5
| | | | | | | | This caused all overloads to be printed in exponential amounts. Pick-to: 6.6 6.5 Change-Id: I619b5402e9d9f164c4372c30ba28655818b81014 Reviewed-by: Fabian Kosmale <[email protected]>
* QML: Make notify list thread safeUlf Hermann2023-08-101-1/+1
| | | | | | | | | | | | | | | We keep the notifyList itself alive until the QQmlData itself is deleted. This way any isSignalConnected() called while an intermediate dtor runs can safely access it. We use atomics to make the concurrent access to the pointer and the connection mask defined behavior. However, we never need anything but relaxed semantics when accessing it. Pick-to: 5.15 6.2 6.5 6.6 Fixes: QTBUG-105090 Change-Id: I82537be86e5cc33c2a3d76ec639fcbac87eb45ad Reviewed-by: Fabian Kosmale <[email protected]> Reviewed-by: Qt CI Bot <[email protected]>
* QML: Allow conversion from JS Array to QByteArrayUlf Hermann2023-08-081-0/+4
| | | | | | | | | | | | Since QByteArray is sequentially iterable and we allow any sequentially iterable type to be constructed from a JS array, we also need to allow this. Pick-to: 6.6 6.5 Fixes: QTBUG-115733 Change-Id: I6ffd5eaad0e587ea1cafbe0c1b0179202f3f28cf Reviewed-by: Fabian Kosmale <[email protected]> Reviewed-by: Qt CI Bot <[email protected]>
* QML: When marking a QObjectWrapper, also mark its const counterpartUlf Hermann2023-07-261-3/+31
| | | | | | | | | | | | Otherwise the const wrapper will be swept while the object should still be alive (and vice versa). Amends commit d3b3fef5a878d7fd53de6a9f9fff196a273930e3. Pick-to: 6.6 6.5 Fixes: QTBUG-114596 Change-Id: Ib4d8e9f805a229a471ca72f5ff357e3a4c9999a5 Reviewed-by: Fabian Kosmale <[email protected]>
* QML: Unify treatment of wrappers when dealing with QObjectMethodUlf Hermann2023-07-121-88/+91
| | | | | | | | | | | | | | A method can belong to a QObjectWrapper, a QQmlValueTypeWrapper, or a QQmlTypeWrapper. store only one wrapper pointer and allow for all variants. Furthermore, keep a reference to the wrapper so that it doesn't get garbage collected. We still need it to retrieve the metaobject, even if we're calling the method on a different instance. Pick-to: 6.2 6.5 6.6 Fixes: QTBUG-115115 Change-Id: I1759fb687918ff79829fef776e0a93d29373b30f Reviewed-by: Qt CI Bot <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* QtQml: Fix validation when calling methods with different 'this'Ulf Hermann2023-07-071-1/+5
| | | | | | | | | | | We were checking the wrong method offsets and we didn't check for destroy() and toString(). Amends commit 3fd3a2a9d06505d549cc4a7c18819a17c6622dfd. Pick-to: 6.5 6.6 Change-Id: I8ebeb927a7827cc1fd3394fb3ab589c35d31ab70 Reviewed-by: Fabian Kosmale <[email protected]>
* QML: Check result when constructing object from metaobjectUlf Hermann2023-07-061-3/+5
| | | | | | | | | | | If you pass insufficient arguments to call the ctor, the resulting object is null and cannot be used. Pick-to: 6.6 6.5 6.2 Fixes: QTBUG-114910 Change-Id: Ib184684b6a7665bcdc1a3fe8f8a2401a33a8ac1c Reviewed-by: Semih Yavuz <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* QML: Un-specialcase QStringList and QVariantList conversionUlf Hermann2023-06-301-6/+6
| | | | | | | | | | | | | | | | | | Those are just regular sequences these days. They can be written back. Drop some now-dead code and deduplicate the value type conversion code in the process. We should try the (more common) value type conversion before the sequence conversion, but after all the "simple" conversions. [ChangeLog][QtQml][Important Behavior Changes] Converting a QVariantList to a QJSValue via, for example QJSEngine::toScriptValue() does not produce a JavaScript array anymore, but rather a better suited sequence object that behaves almost like a JavaScript array. The only difference is that its QJSValue::isArray() will return false now. Fixes: QTBUG-113690 Change-Id: Ib176c34d59c45a6b5cff68d029c4b1b87d7aa192 Reviewed-by: Qt CI Bot <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* Qml: Better encapsulate QmlListWrapperUlf Hermann2023-06-261-1/+1
| | | | | Change-Id: I00a298f8b5d0473b89c6385e46983ef776a4531b Reviewed-by: Fabian Kosmale <[email protected]>