diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2021-05-04 17:00:16 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2021-05-05 22:15:44 +0200 |
commit | 1dc4bdbabfed1eb73b563a77810ceb00a8fd6fca (patch) | |
tree | 160c2cce24848faf2bce1e464bcef2111ce3f9d1 /src/qml/qml | |
parent | 21463aa204bea6c92f2864156fc133c44e8d5d6f (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.cpp | 49 | ||||
-rw-r--r-- | src/qml/qml/qqmlvaluetypewrapper_p.h | 40 |
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 |