aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2021-05-04 17:00:16 +0200
committerUlf Hermann <ulf.hermann@qt.io>2021-05-05 22:15:44 +0200
commit1dc4bdbabfed1eb73b563a77810ceb00a8fd6fca (patch)
tree160c2cce24848faf2bce1e464bcef2111ce3f9d1 /src/qml/qml
parent21463aa204bea6c92f2864156fc133c44e8d5d6f (diff)
V4: Write back value type references after function calls
If we call a function on a value type reference we have to assume that the value has changed. Therefore, we need to write back, just like we do when writing a property on the reference. Fixes: QTBUG-91783 Pick-to: 6.1 5.15 Change-Id: I6d2e957997d64e40e42eb5210350b6592a92ee26 Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/qml')
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper.cpp49
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper_p.h40
2 files changed, 42 insertions, 47 deletions
diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp
index b3c073a3f0..5d34a593a5 100644
--- a/src/qml/qml/qqmlvaluetypewrapper.cpp
+++ b/src/qml/qml/qqmlvaluetypewrapper.cpp
@@ -64,36 +64,6 @@ QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcBindingRemoval)
DEFINE_OBJECT_VTABLE(QV4::QQmlValueTypeWrapper);
-
-namespace QV4 {
-namespace Heap {
-
-struct QQmlValueTypeReference : QQmlValueTypeWrapper
-{
- void init() {
- QQmlValueTypeWrapper::init();
- object.init();
- }
- void destroy() {
- object.destroy();
- QQmlValueTypeWrapper::destroy();
- }
- QV4QPointer<QObject> object;
- int property;
-};
-
-}
-
-struct QQmlValueTypeReference : public QQmlValueTypeWrapper
-{
- V4_OBJECT2(QQmlValueTypeReference, QQmlValueTypeWrapper)
- V4_NEEDS_DESTROY
-
- bool readReferenceValue() const;
-};
-
-}
-
DEFINE_OBJECT_VTABLE(QV4::QQmlValueTypeReference);
using namespace QV4;
@@ -693,23 +663,8 @@ bool QQmlValueTypeWrapper::virtualPut(Managed *m, PropertyKey id, const Value &v
void *gadget = r->d()->gadgetPtr();
property.writeOnGadget(gadget, v);
-
- if (reference) {
- if (writeBackPropertyType == QMetaType::fromType<QVariant>()) {
- QVariant variantReferenceValue = r->d()->toVariant();
-
- int flags = 0;
- int status = -1;
- void *a[] = { &variantReferenceValue, nullptr, &status, &flags };
- QMetaObject::metacall(reference->d()->object, QMetaObject::WriteProperty, reference->d()->property, a);
-
- } else {
- int flags = 0;
- int status = -1;
- void *a[] = { r->d()->gadgetPtr(), nullptr, &status, &flags };
- QMetaObject::metacall(reference->d()->object, QMetaObject::WriteProperty, reference->d()->property, a);
- }
- }
+ if (reference)
+ reference->d()->writeBack();
return true;
}
diff --git a/src/qml/qml/qqmlvaluetypewrapper_p.h b/src/qml/qml/qqmlvaluetypewrapper_p.h
index 0eb1088a64..ed58157c26 100644
--- a/src/qml/qml/qqmlvaluetypewrapper_p.h
+++ b/src/qml/qml/qqmlvaluetypewrapper_p.h
@@ -111,6 +111,38 @@ private:
const QMetaObject *m_metaObject;
};
+struct QQmlValueTypeReference : QQmlValueTypeWrapper
+{
+ void init() {
+ QQmlValueTypeWrapper::init();
+ object.init();
+ }
+ void destroy() {
+ object.destroy();
+ QQmlValueTypeWrapper::destroy();
+ }
+
+ void writeBack() {
+ const QMetaProperty writebackProperty = object->metaObject()->property(property);
+ if (!writebackProperty.isWritable())
+ return;
+
+ int flags = 0;
+ int status = -1;
+ if (writebackProperty.metaType() == QMetaType::fromType<QVariant>()) {
+ QVariant variantReferenceValue = toVariant();
+ void *a[] = { &variantReferenceValue, nullptr, &status, &flags };
+ QMetaObject::metacall(object, QMetaObject::WriteProperty, property, a);
+ } else {
+ void *a[] = { gadgetPtr(), nullptr, &status, &flags };
+ QMetaObject::metacall(object, QMetaObject::WriteProperty, property, a);
+ }
+ }
+
+ QV4QPointer<QObject> object;
+ int property;
+};
+
}
struct Q_QML_EXPORT QQmlValueTypeWrapper : Object
@@ -149,6 +181,14 @@ public:
static void initProto(ExecutionEngine *v4);
};
+struct QQmlValueTypeReference : public QQmlValueTypeWrapper
+{
+ V4_OBJECT2(QQmlValueTypeReference, QQmlValueTypeWrapper)
+ V4_NEEDS_DESTROY
+
+ bool readReferenceValue() const;
+};
+
}
QT_END_NAMESPACE