aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2021-06-08 17:27:23 +0200
committerUlf Hermann <ulf.hermann@qt.io>2021-06-08 17:40:40 +0200
commitef7544bb5c6156462d169954c55afd38141e5a74 (patch)
treec88eeace150548cce16a1c46e9aa19a77bdbc671 /src
parent95b448bf89575dfd79ca071ebfeab8960eff6864 (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.cpp8
-rw-r--r--src/qml/qml/qqmljavascriptexpression.cpp26
-rw-r--r--src/qml/qml/qqmlpropertyvalidator.cpp6
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())) {