diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2024-03-19 15:55:12 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2024-03-21 10:41:29 +0100 |
commit | eb79815fbfad7d4e7fb4be856dc0dd43be76fdb9 (patch) | |
tree | 6015c799ae4ddbc2f362322cb0c1bb5f5705d4b2 /src/qml/qml | |
parent | f48ada60c3d6b56881b7355a305ec3e9c00884a5 (diff) |
QmlCompiler: Do not use QQmlEngine from current QML context
We cannot be sure the current context is still alive when a function is
called. We may be left with a skeleton context that doesn't have an
engine anymore.
However, we can always query the QJSEngine given in the AOT context.
That one cannot disappear and is generally the right one for capturing
properties.
Pick-to: 6.7 6.5 6.2
Fixes: QTBUG-123395
Change-Id: I2a6c38baa159fa790f3ba2aba225fdc9cc37001e
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/qml')
-rw-r--r-- | src/qml/qml/qqml.cpp | 70 |
1 files changed, 32 insertions, 38 deletions
diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp index 51bccc2088..82cba4e9d6 100644 --- a/src/qml/qml/qqml.cpp +++ b/src/qml/qml/qqml.cpp @@ -952,7 +952,13 @@ QObject *AOTCompiledContext::thisObject() const QQmlEngine *AOTCompiledContext::qmlEngine() const { - return qmlContext ? qmlContext->engine() : nullptr; + return engine->handle()->qmlEngine(); +} + +static QQmlPropertyCapture *propertyCapture(const AOTCompiledContext *aotContext) +{ + QQmlEngine *engine = aotContext->qmlEngine(); + return engine ? QQmlEnginePrivate::get(aotContext->qmlEngine())->propertyCapture : nullptr; } QJSValue AOTCompiledContext::jsMetaType(int index) const @@ -975,37 +981,25 @@ void AOTCompiledContext::setReturnValueUndefined() const } } -static QQmlPropertyCapture *propertyCapture(const QQmlContextData *qmlContext) -{ - if (!qmlContext) - return nullptr; - - QQmlEngine *engine = qmlContext->engine(); - Q_ASSERT(engine); - QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine); - Q_ASSERT(ep); - return ep->propertyCapture; -} - static void captureFallbackProperty( QObject *object, int coreIndex, int notifyIndex, bool isConstant, - const QQmlContextData *qmlContext) + const AOTCompiledContext *aotContext) { if (isConstant) return; - if (QQmlPropertyCapture *capture = propertyCapture(qmlContext)) + if (QQmlPropertyCapture *capture = propertyCapture(aotContext)) capture->captureProperty(object, coreIndex, notifyIndex); } static void captureObjectProperty( QObject *object, const QQmlPropertyCache *propertyCache, - const QQmlPropertyData *property, QQmlContextData *qmlContext) + const QQmlPropertyData *property, const AOTCompiledContext *aotContext) { if (property->isConstant()) return; - if (QQmlPropertyCapture *capture = propertyCapture(qmlContext)) + if (QQmlPropertyCapture *capture = propertyCapture(aotContext)) capture->captureProperty(object, propertyCache, property); } @@ -1047,7 +1041,7 @@ ObjectPropertyQmlData findObjectPropertyQmlData(QV4::Lookup *l, QObject *object) template<bool StrictType = false> ObjectPropertyResult loadObjectProperty( - QV4::Lookup *l, QObject *object, void *target, QQmlContextData *qmlContext) + QV4::Lookup *l, QObject *object, void *target, const AOTCompiledContext *aotContext) { const ObjectPropertyQmlData data = findObjectPropertyQmlData<StrictType>(l, object); if (data.result != ObjectPropertyResult::OK) @@ -1058,7 +1052,7 @@ ObjectPropertyResult loadObjectProperty( if (data.qmlData->hasPendingBindingBit(coreIndex)) data.qmlData->flushPendingBinding(coreIndex); - captureObjectProperty(object, l->qobjectLookup.propertyCache, propertyData, qmlContext); + captureObjectProperty(object, l->qobjectLookup.propertyCache, propertyData, aotContext); propertyData->readProperty(object, target); return ObjectPropertyResult::OK; } @@ -1098,7 +1092,7 @@ static FallbackPropertyQmlData findFallbackPropertyQmlData(QV4::Lookup *l, QObje } static ObjectPropertyResult loadFallbackProperty( - QV4::Lookup *l, QObject *object, void *target, QQmlContextData *qmlContext) + QV4::Lookup *l, QObject *object, void *target, const AOTCompiledContext *aotContext) { const FallbackPropertyQmlData data = findFallbackPropertyQmlData(l, object); if (data.result != ObjectPropertyResult::OK) @@ -1109,7 +1103,7 @@ static ObjectPropertyResult loadFallbackProperty( data.qmlData->flushPendingBinding(coreIndex); captureFallbackProperty(object, coreIndex, l->qobjectFallbackLookup.notifyIndex, - l->qobjectFallbackLookup.isConstant, qmlContext); + l->qobjectFallbackLookup.isConstant, aotContext); void *a[] = { target, nullptr }; data.metaObject->metacall(object, QMetaObject::ReadProperty, coreIndex, a); @@ -1131,15 +1125,15 @@ static ObjectPropertyResult writeBackFallbackProperty(QV4::Lookup *l, QObject *o } ObjectPropertyResult loadObjectAsVariant( - QV4::Lookup *l, QObject *object, void *target, QQmlContextData *qmlContext) + QV4::Lookup *l, QObject *object, void *target, const AOTCompiledContext *aotContext) { QVariant *variant = static_cast<QVariant *>(target); const QMetaType propType = l->qobjectLookup.propertyData->propType(); if (propType == QMetaType::fromType<QVariant>()) - return loadObjectProperty<true>(l, object, variant, qmlContext); + return loadObjectProperty<true>(l, object, variant, aotContext); *variant = QVariant(propType); - return loadObjectProperty<true>(l, object, variant->data(), qmlContext); + return loadObjectProperty<true>(l, object, variant->data(), aotContext); } ObjectPropertyResult writeBackObjectAsVariant(QV4::Lookup *l, QObject *object, void *source) @@ -1154,7 +1148,7 @@ ObjectPropertyResult writeBackObjectAsVariant(QV4::Lookup *l, QObject *object, v } ObjectPropertyResult loadFallbackAsVariant( - QV4::Lookup *l, QObject *object, void *target, QQmlContextData *qmlContext) + QV4::Lookup *l, QObject *object, void *target, const AOTCompiledContext *aotContext) { const QMetaObject *metaObject = reinterpret_cast<const QMetaObject *>(l->qobjectFallbackLookup.metaObject - 1); @@ -1163,10 +1157,10 @@ ObjectPropertyResult loadFallbackAsVariant( QVariant *variant = static_cast<QVariant *>(target); const QMetaType propType = metaObject->property(l->qobjectFallbackLookup.coreIndex).metaType(); if (propType == QMetaType::fromType<QVariant>()) - return loadFallbackProperty(l, object, variant, qmlContext); + return loadFallbackProperty(l, object, variant, aotContext); *variant = QVariant(propType); - return loadFallbackProperty(l, object, variant->data(), qmlContext); + return loadFallbackProperty(l, object, variant->data(), aotContext); } ObjectPropertyResult writeBackFallbackAsVariant(QV4::Lookup *l, QObject *object, void *source) @@ -1489,7 +1483,7 @@ bool AOTCompiledContext::captureLookup(uint index, QObject *object) const || l->getter == QV4::Lookup::getterQObjectAsVariant) { const QQmlPropertyData *property = l->qobjectLookup.propertyData; QQmlData::flushPendingBinding(object, property->coreIndex()); - captureObjectProperty(object, l->qobjectLookup.propertyCache, property, qmlContext); + captureObjectProperty(object, l->qobjectLookup.propertyCache, property, this); return true; } @@ -1499,7 +1493,7 @@ bool AOTCompiledContext::captureLookup(uint index, QObject *object) const QQmlData::flushPendingBinding(object, coreIndex); captureFallbackProperty( object, coreIndex, l->qobjectFallbackLookup.notifyIndex, - l->qobjectFallbackLookup.isConstant, qmlContext); + l->qobjectFallbackLookup.isConstant, this); return true; } @@ -1513,7 +1507,7 @@ bool AOTCompiledContext::captureQmlContextPropertyLookup(uint index) const && l->qmlContextPropertyGetter == QV4::QQmlContextWrapper::lookupContextObjectProperty) { const QQmlPropertyData *property = l->qobjectLookup.propertyData; QQmlData::flushPendingBinding(qmlScopeObject, property->coreIndex()); - captureObjectProperty(qmlScopeObject, l->qobjectLookup.propertyCache, property, qmlContext); + captureObjectProperty(qmlScopeObject, l->qobjectLookup.propertyCache, property, this); return true; } @@ -1521,7 +1515,7 @@ bool AOTCompiledContext::captureQmlContextPropertyLookup(uint index) const const int coreIndex = l->qobjectFallbackLookup.coreIndex; QQmlData::flushPendingBinding(qmlScopeObject, coreIndex); captureFallbackProperty(qmlScopeObject, coreIndex, l->qobjectFallbackLookup.notifyIndex, - l->qobjectFallbackLookup.isConstant, qmlContext); + l->qobjectFallbackLookup.isConstant, this); return true; } @@ -1530,7 +1524,7 @@ bool AOTCompiledContext::captureQmlContextPropertyLookup(uint index) const void AOTCompiledContext::captureTranslation() const { - if (QQmlPropertyCapture *capture = propertyCapture(qmlContext)) + if (QQmlPropertyCapture *capture = propertyCapture(this)) capture->captureTranslation(); } @@ -1902,9 +1896,9 @@ bool AOTCompiledContext::loadScopeObjectPropertyLookup(uint index, void *target) ObjectPropertyResult result = ObjectPropertyResult::NeedsInit; if (l->qmlContextPropertyGetter == QV4::QQmlContextWrapper::lookupScopeObjectProperty) - result = loadObjectProperty(l, qmlScopeObject, target, qmlContext); + result = loadObjectProperty(l, qmlScopeObject, target, this); else if (l->qmlContextPropertyGetter == QV4::QQmlContextWrapper::lookupScopeFallbackProperty) - result = loadFallbackProperty(l, qmlScopeObject, target, qmlContext); + result = loadFallbackProperty(l, qmlScopeObject, target, this); else return false; @@ -2125,13 +2119,13 @@ bool AOTCompiledContext::getObjectLookup(uint index, QObject *object, void *targ ObjectPropertyResult result = ObjectPropertyResult::NeedsInit; if (l->getter == QV4::Lookup::getterQObject) - result = loadObjectProperty(l, object, target, qmlContext); + result = loadObjectProperty(l, object, target, this); else if (l->getter == QV4::Lookup::getterFallback) - result = loadFallbackProperty(l, object, target, qmlContext); + result = loadFallbackProperty(l, object, target, this); else if (l->getter == QV4::Lookup::getterQObjectAsVariant) - result = loadObjectAsVariant(l, object, target, qmlContext); + result = loadObjectAsVariant(l, object, target, this); else if (l->getter == QV4::Lookup::getterFallbackAsVariant) - result = loadFallbackAsVariant(l, object, target, qmlContext); + result = loadFallbackAsVariant(l, object, target, this); else return false; |