aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4lookup_p.h
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2021-12-14 16:16:20 +0100
committerUlf Hermann <ulf.hermann@qt.io>2021-12-15 15:35:56 +0100
commite24effdceb3a504182ae271200408750991aa94a (patch)
tree824d4746e63cccb693f6ca3472049b849295370a /src/qml/jsruntime/qv4lookup_p.h
parentb71d8a4ed5c80956b2efc9eb922e02da56e53bdb (diff)
Do not copy lookups
It leads to data corruption. Also, be more careful about releasing the property cache. We can only do that if the qobjectlookup member of the union is active. Unfortunately we have to do a number of checks now, to make sure it is. In order to still keep the checks inline, we move some functions around. Pick-to: 5.15 Fixes: QTBUG-99211 Change-Id: If6dd879e67b172e1a9035e83fbfacbe73c6c7476 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4lookup_p.h')
-rw-r--r--src/qml/jsruntime/qv4lookup_p.h25
1 files changed, 22 insertions, 3 deletions
diff --git a/src/qml/jsruntime/qv4lookup_p.h b/src/qml/jsruntime/qv4lookup_p.h
index deb23d8c58..ce46186827 100644
--- a/src/qml/jsruntime/qv4lookup_p.h
+++ b/src/qml/jsruntime/qv4lookup_p.h
@@ -56,11 +56,17 @@
#include "qv4context_p.h"
#include "qv4object_p.h"
#include "qv4internalclass_p.h"
+#include "qv4qmlcontext_p.h"
+#include <private/qqmltypewrapper_p.h>
+#include <private/qqmlvaluetypewrapper_p.h>
QT_BEGIN_NAMESPACE
namespace QV4 {
+// Note: We cannot hide the copy ctor and assignment operator of this class because it needs to
+// be trivially copyable. But you should never ever copy it. There are refcounted members
+// in there.
struct Q_QML_PRIVATE_EXPORT Lookup {
union {
ReturnedValue (*getter)(Lookup *l, ExecutionEngine *engine, const Value &object);
@@ -187,6 +193,7 @@ struct Q_QML_PRIVATE_EXPORT Lookup {
static ReturnedValue getterProtoAccessor(Lookup *l, ExecutionEngine *engine, const Value &object);
static ReturnedValue getterProtoAccessorTwoClasses(Lookup *l, ExecutionEngine *engine, const Value &object);
static ReturnedValue getterIndexed(Lookup *l, ExecutionEngine *engine, const Value &object);
+ static ReturnedValue getterQObject(Lookup *l, ExecutionEngine *engine, const Value &object);
static ReturnedValue primitiveGetterProto(Lookup *l, ExecutionEngine *engine, const Value &object);
static ReturnedValue primitiveGetterAccessor(Lookup *l, ExecutionEngine *engine, const Value &object);
@@ -216,6 +223,20 @@ struct Q_QML_PRIVATE_EXPORT Lookup {
void clear() {
memset(&markDef, 0, sizeof(markDef));
}
+
+ void releasePropertyCache()
+ {
+ if (getter == getterQObject
+ || getter == QQmlTypeWrapper::lookupSingletonProperty
+ || qmlContextPropertyGetter == QQmlContextWrapper::lookupScopeObjectProperty
+ || qmlContextPropertyGetter == QQmlContextWrapper::lookupContextObjectProperty) {
+ if (QQmlPropertyCache *pc = qobjectLookup.propertyCache)
+ pc->release();
+ } else if (getter == QQmlValueTypeWrapper::lookupGetter) {
+ if (QQmlPropertyCache *pc = qgadgetLookup.propertyCache)
+ pc->release();
+ }
+ }
};
Q_STATIC_ASSERT(std::is_standard_layout<Lookup>::value);
@@ -226,9 +247,7 @@ Q_STATIC_ASSERT(offsetof(Lookup, getter) == 0);
inline void setupQObjectLookup(
Lookup *lookup, const QQmlData *ddata, QQmlPropertyData *propertyData)
{
- if (QQmlPropertyCache *cache = lookup->qobjectLookup.propertyCache)
- cache->release();
-
+ lookup->releasePropertyCache();
Q_ASSERT(ddata->propertyCache != nullptr);
lookup->qobjectLookup.propertyCache = ddata->propertyCache;
lookup->qobjectLookup.propertyCache->addref();