diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2021-06-08 17:27:23 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2021-06-08 17:40:40 +0200 |
commit | ef7544bb5c6156462d169954c55afd38141e5a74 (patch) | |
tree | c88eeace150548cce16a1c46e9aa19a77bdbc671 /src | |
parent | 95b448bf89575dfd79ca071ebfeab8960eff6864 (diff) |
Allow property observers on readonly properties
This makes it necessary to tolerate evaluate() calls after the engine is
gone. With non-QProperty properties this can't happen as the engine
controls the observers.
Change-Id: Ia700a10ad847b8a174b2346a4ad7a4de7afb0c83
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/qml/qqmlboundsignal.cpp | 8 | ||||
-rw-r--r-- | src/qml/qml/qqmljavascriptexpression.cpp | 26 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertyvalidator.cpp | 6 |
3 files changed, 27 insertions, 13 deletions
diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp index 0dfbf1faee..665d4e6c75 100644 --- a/src/qml/qml/qqmlboundsignal.cpp +++ b/src/qml/qml/qqmlboundsignal.cpp @@ -175,12 +175,16 @@ QString QQmlBoundSignalExpression::expression() const // Changes made here may need to be made there and vice versa. void QQmlBoundSignalExpression::evaluate(void **a) { - Q_ASSERT (engine()); - if (!expressionFunctionValid()) return; QQmlEngine *qmlengine = engine(); + + // If there is no engine, we have no way to evaluate anything. + // This can happen on destruction. + if (!qmlengine) + return; + QQmlEnginePrivate *ep = QQmlEnginePrivate::get(qmlengine); QV4::ExecutionEngine *v4 = qmlengine->handle(); QV4::Scope scope(v4); diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp index 95db27019c..75bc944fee 100644 --- a/src/qml/qml/qqmljavascriptexpression.cpp +++ b/src/qml/qml/qqmljavascriptexpression.cpp @@ -178,8 +178,14 @@ void QQmlJavaScriptExpression::refresh() QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(bool *isUndefined) { - QV4::ExecutionEngine *v4 = m_context->engine()->handle(); - QV4::Scope scope(v4); + QQmlEngine *qmlengine = engine(); + if (!qmlengine) { + if (isUndefined) + *isUndefined = true; + return QV4::Encode::undefined(); + } + + QV4::Scope scope(qmlengine->handle()); QV4::JSCallArguments jsCall(scope); return evaluate(jsCall.callData(scope), isUndefined); @@ -256,10 +262,9 @@ static inline QV4::ReturnedValue thisObject(QObject *scopeObject, QV4::Execution QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, bool *isUndefined) { - Q_ASSERT(m_context && m_context->engine()); - + QQmlEngine *qmlEngine = engine(); QV4::Function *v4Function = function(); - if (!v4Function) { + if (!v4Function || !qmlEngine) { if (isUndefined) *isUndefined = true; return QV4::Encode::undefined(); @@ -267,7 +272,6 @@ QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, b // All code that follows must check with watcher before it accesses data members // incase we have been deleted. - QQmlEngine *qmlEngine = m_context->engine(); QQmlJavaScriptExpressionCapture capture(this, qmlEngine); QV4::Scope scope(qmlEngine->handle()); @@ -291,11 +295,15 @@ QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, b bool QQmlJavaScriptExpression::evaluate(void **a, const QMetaType *types, int argc) { - Q_ASSERT(m_context && m_context->engine()); - // All code that follows must check with watcher before it accesses data members // incase we have been deleted. - QQmlEngine *qmlEngine = m_context->engine(); + QQmlEngine *qmlEngine = engine(); + + // If there is no engine, we have no way to evaluate anything. + // This can happen on destruction. + if (!qmlEngine) + return false; + QQmlJavaScriptExpressionCapture capture(this, qmlEngine); QV4::Scope scope(qmlEngine->handle()); diff --git a/src/qml/qml/qqmlpropertyvalidator.cpp b/src/qml/qml/qqmlpropertyvalidator.cpp index deb747fa2f..f1826b2f1c 100644 --- a/src/qml/qml/qqmlpropertyvalidator.cpp +++ b/src/qml/qml/qqmlpropertyvalidator.cpp @@ -241,9 +241,11 @@ QVector<QQmlError> QQmlPropertyValidator::validateObject( } // Signal handlers were resolved and checked earlier in the signal handler conversion pass. - if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression - || binding->flags & QV4::CompiledData::Binding::IsSignalHandlerObject) + if (binding->flags & (QV4::CompiledData::Binding::IsSignalHandlerExpression + | QV4::CompiledData::Binding::IsSignalHandlerObject + | QV4::CompiledData::Binding::IsPropertyObserver)) { continue; + } if (binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) { if (instantiatingBinding && (instantiatingBinding->isAttachedProperty() || instantiatingBinding->isGroupProperty())) { |