summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2021-01-14 16:50:39 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-02-03 08:28:30 +0000
commit2951c124d3ff58abe1f84175e512ba26977f13d8 (patch)
tree681b5483e7a7be7c37924a31b6160fdf34e766cd
parent167f01e4be56440cb58e97510bc408f3476eb307 (diff)
Mark dynamic state machines' metaobjects as fully dynamic
The memory is allocated using malloc() and will be free()'d eventually. Client code cannot expect to keep string data from those metaobjects around. The QML engine will avoid the creation of property caches (which hold string data from the metaobject) if the metaobject is fully dynamic. Therefore, just create a QAbstractDynamicMetaObject that wraps the original metaobject and pass that to QObjectPrivate in order to signal the fully dynamic nature of the metaobject to QML. Fixes: QTBUG-89521 Change-Id: I349dcb689be5674679237a551ed8595bd6b5b672 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> (cherry picked from commit 0e4c91654abff279b51238b46f880dd624ab9ec8) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/scxml/qscxmlcompiler.cpp32
1 files changed, 27 insertions, 5 deletions
diff --git a/src/scxml/qscxmlcompiler.cpp b/src/scxml/qscxmlcompiler.cpp
index 8583233..9bf3a92 100644
--- a/src/scxml/qscxmlcompiler.cpp
+++ b/src/scxml/qscxmlcompiler.cpp
@@ -485,9 +485,31 @@ private:
class DynamicStateMachinePrivate : public QScxmlStateMachinePrivate
{
+ struct DynamicMetaObject : public QAbstractDynamicMetaObject
+ {
+ QAbstractDynamicMetaObject *toDynamicMetaObject(QObject *) override
+ {
+ return this;
+ }
+
+ int metaCall(QObject *o, QMetaObject::Call c, int id, void **a) override
+ {
+ return o->qt_metacall(c, id, a);
+ }
+ };
+
public:
DynamicStateMachinePrivate() :
- QScxmlStateMachinePrivate(&QScxmlStateMachine::staticMetaObject) {}
+ QScxmlStateMachinePrivate(&QScxmlStateMachine::staticMetaObject)
+ {
+ metaObject = new DynamicMetaObject;
+ }
+
+ void setDynamicMetaObject(const QMetaObject *m) {
+ // Prevent the QML engine from creating a property cache for this thing.
+ static_cast<DynamicMetaObject *>(metaObject)->d = m->d;
+ m_metaObject = m;
+ }
};
class DynamicStateMachine: public QScxmlStateMachine, public QScxmlInternal::GeneratedTableData
@@ -544,7 +566,7 @@ private:
b.setClassName("DynamicStateMachine");
b.setSuperClass(&QScxmlStateMachine::staticMetaObject);
b.setStaticMetacallFunction(qt_static_metacall);
- d->m_metaObject = b.toMetaObject();
+ d->setDynamicMetaObject(b.toMetaObject());
}
void initDynamicParts(const MetaDataInfo &info)
@@ -553,7 +575,7 @@ private:
// Release the temporary QMetaObject.
Q_ASSERT(d->m_metaObject != &QScxmlStateMachine::staticMetaObject);
free(const_cast<QMetaObject *>(d->m_metaObject));
- d->m_metaObject = &QScxmlStateMachine::staticMetaObject;
+ d->setDynamicMetaObject(&QScxmlStateMachine::staticMetaObject);
// Build the real one.
QMetaObjectBuilder b;
@@ -579,7 +601,7 @@ private:
}
// And we're done
- d->m_metaObject = b.toMetaObject();
+ d->setDynamicMetaObject(b.toMetaObject());
}
public:
@@ -588,7 +610,7 @@ public:
Q_D(DynamicStateMachine);
if (d->m_metaObject != &QScxmlStateMachine::staticMetaObject) {
free(const_cast<QMetaObject *>(d->m_metaObject));
- d->m_metaObject = &QScxmlStateMachine::staticMetaObject;
+ d->setDynamicMetaObject(&QScxmlStateMachine::staticMetaObject);
}
}