diff options
author | Ivan Solovev <ivan.solovev@qt.io> | 2021-05-25 10:45:51 +0200 |
---|---|---|
committer | Ivan Solovev <ivan.solovev@qt.io> | 2021-05-25 11:26:15 +0200 |
commit | 8ac705247430ff6fbbc25a9db20c0e7dc572abe7 (patch) | |
tree | b62681e21db563a605f785e8a12f2ead3c958c5b /src/qml | |
parent | 9184f6c1de2c315cc66eb6cd3886c3daea90516f (diff) |
Revert "Do QMetaType-style call in QQmlPropertyBinding::evaluate"
This reverts commit 3a4e013f0058952c94ed3414aafbf96216efff8d.
The patch seems to break the tests in QtPositioning
(see QTBUG-93983 for some more details)
Task-number: QTBUG-93983
Change-Id: Ie2caa8418f06add1c24d9f3d3d137e51e94908c2
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/jsruntime/qv4function.cpp | 9 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4function_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4jscall_p.h | 12 | ||||
-rw-r--r-- | src/qml/qml/qqmljavascriptexpression.cpp | 6 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertybinding.cpp | 83 |
5 files changed, 30 insertions, 82 deletions
diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp index f6001da1f8..348837c3a5 100644 --- a/src/qml/jsruntime/qv4function.cpp +++ b/src/qml/jsruntime/qv4function.cpp @@ -57,15 +57,15 @@ QT_BEGIN_NAMESPACE using namespace QV4; -bool Function::call(const Value *thisObject, void **a, const QMetaType *types, int argc, +void Function::call(const Value *thisObject, void **a, const QMetaType *types, int argc, const ExecutionContext *context) { if (!aotFunction) { - return QV4::convertAndCall( - context->engine(), thisObject, a, types, argc, - [this, context](const Value *thisObject, const Value *argv, int argc) { + QV4::convertAndCall(context->engine(), thisObject, a, types, argc, + [this, context](const Value *thisObject, const Value *argv, int argc) { return call(thisObject, argv, argc, context); }); + return; } ExecutionEngine *engine = context->engine(); @@ -77,7 +77,6 @@ bool Function::call(const Value *thisObject, void **a, const QMetaType *types, i engine->jsStackTop += frame.requiredJSStackFrameSize(); Moth::VME::exec(&frame, engine); frame.pop(engine); - return true; } ReturnedValue Function::call(const Value *thisObject, const Value *argv, int argc, const ExecutionContext *context) { diff --git a/src/qml/jsruntime/qv4function_p.h b/src/qml/jsruntime/qv4function_p.h index 7577161c01..a15344dacd 100644 --- a/src/qml/jsruntime/qv4function_p.h +++ b/src/qml/jsruntime/qv4function_p.h @@ -100,7 +100,7 @@ public: return compilationUnit->runtimeStrings[i]; } - bool call(const Value *thisObject, void **a, const QMetaType *types, int argc, + void call(const Value *thisObject, void **a, const QMetaType *types, int argc, const ExecutionContext *context); ReturnedValue call(const Value *thisObject, const Value *argv, int argc, const ExecutionContext *context); diff --git a/src/qml/jsruntime/qv4jscall_p.h b/src/qml/jsruntime/qv4jscall_p.h index c6d320ac20..3f0c8ee06d 100644 --- a/src/qml/jsruntime/qv4jscall_p.h +++ b/src/qml/jsruntime/qv4jscall_p.h @@ -206,7 +206,7 @@ ReturnedValue convertAndCall( } template<typename Callable> -bool convertAndCall(ExecutionEngine *engine, const Value *thisObject, +void convertAndCall(ExecutionEngine *engine, const Value *thisObject, void **a, const QMetaType *types, int argc, Callable call) { Scope scope(engine); @@ -215,10 +215,13 @@ bool convertAndCall(ExecutionEngine *engine, const Value *thisObject, for (int ii = 0; ii < argc; ++ii) jsCallData.args[ii] = engine->metaTypeToJS(types[ii + 1], a[ii + 1]); - ScopedValue jsResult(scope, call(thisObject, jsCallData.args, argc)); void *result = a[0]; - if (!result) - return !jsResult->isUndefined(); + if (!result) { + call(thisObject, jsCallData.args, argc); + return; + } + + ScopedValue jsResult(scope, call(thisObject, jsCallData.args, argc)); const QMetaType resultType = types[0]; if (scope.hasException()) { @@ -234,7 +237,6 @@ bool convertAndCall(ExecutionEngine *engine, const Value *thisObject, scope.engine->metaTypeFromJS(jsResult, resultType, result); } } - return !jsResult->isUndefined(); } } diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp index 95db27019c..95d7d89c99 100644 --- a/src/qml/qml/qqmljavascriptexpression.cpp +++ b/src/qml/qml/qqmljavascriptexpression.cpp @@ -303,10 +303,10 @@ bool QQmlJavaScriptExpression::evaluate(void **a, const QMetaType *types, int ar Q_ASSERT(m_qmlScope.valueRef()); Q_ASSERT(function()); - const bool isUndefined = !function()->call( - self, a, types, argc, static_cast<QV4::ExecutionContext *>(m_qmlScope.valueRef())); + function()->call(self, a, types, argc, + static_cast<QV4::ExecutionContext *>(m_qmlScope.valueRef())); - return !capture.catchException(scope) && !isUndefined; + return !capture.catchException(scope); } void QQmlPropertyCapture::captureProperty(QQmlNotifier *n) diff --git a/src/qml/qml/qqmlpropertybinding.cpp b/src/qml/qml/qqmlpropertybinding.cpp index 7729198146..647b0f7b59 100644 --- a/src/qml/qml/qqmlpropertybinding.cpp +++ b/src/qml/qml/qqmlpropertybinding.cpp @@ -146,15 +146,6 @@ QQmlPropertyBinding::QQmlPropertyBinding(QMetaType mt, QObject *target, QQmlProp errorCallBack = bindingErrorCallback; } -template<typename T> -bool compareAndAssign(void *dataPtr, const void *result) -{ - if (*static_cast<const T *>(result) == *static_cast<const T *>(dataPtr)) - return false; - *static_cast<T *>(dataPtr) = *static_cast<const T *>(result); - return true; -} - bool QQmlPropertyBinding::evaluate(QMetaType metaType, void *dataPtr) { const auto ctxt = jsExpression()->context(); @@ -168,16 +159,17 @@ bool QQmlPropertyBinding::evaluate(QMetaType metaType, void *dataPtr) QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine); ep->referenceScarceResources(); - const auto handleErrorAndUndefined = [&](bool evaluatedToUndefined) { - ep->dereferenceScarceResources(); - if (jsExpression()->hasError()) { - QPropertyBindingError error(QPropertyBindingError::UnknownError, - jsExpression()->delayedError()->error().description()); - QPropertyBindingPrivate::currentlyEvaluatingBinding()->setError(std::move(error)); - bindingErrorCallback(this); - return false; - } + bool evaluatedToUndefined = false; + + QV4::Scope scope(engine->handle()); + QV4::ScopedValue result(scope, hasBoundFunction() + ? static_cast<QQmlPropertyBindingJSForBoundFunction *>(jsExpression())->evaluate(&evaluatedToUndefined) + : jsExpression()->evaluate(&evaluatedToUndefined)); + + ep->dereferenceScarceResources(); + bool hadError = jsExpression()->hasError(); + if (!hadError) { if (evaluatedToUndefined) { handleUndefinedAssignment(ep, dataPtr); // if property has been changed due to reset, reset is responsible for @@ -186,57 +178,12 @@ bool QQmlPropertyBinding::evaluate(QMetaType metaType, void *dataPtr) } else if (isUndefined()) { setIsUndefined(false); } - - return true; - }; - - if (!hasBoundFunction()) { - Q_ASSERT(metaType.sizeOf() > 0); - - // No need to construct here. evaluate() expects uninitialized memory. - Q_ALLOCA_VAR(void, result, metaType.sizeOf()); - - const bool evaluatedToUndefined = !jsExpression()->evaluate(&result, &metaType, 0); - if (!handleErrorAndUndefined(evaluatedToUndefined)) - return false; - - if (metaType.flags() & QMetaType::PointerToQObject) - return compareAndAssign<QObject *>(dataPtr, result); - - switch (metaType.id()) { - case QMetaType::Bool: - return compareAndAssign<bool>(dataPtr, result); - case QMetaType::Int: - return compareAndAssign<int>(dataPtr, result); - case QMetaType::Double: - return compareAndAssign<double>(dataPtr, result); - case QMetaType::Float: - return compareAndAssign<float>(dataPtr, result); - case QMetaType::QString: { - const bool hasChanged = compareAndAssign<QString>(dataPtr, result); - static_cast<QString *>(result)->~QString(); - return hasChanged; - } - default: - break; - } - - const bool hasChanged = !metaType.equals(result, dataPtr); - if (hasChanged) { - metaType.destruct(dataPtr); - metaType.construct(dataPtr, result); - } - metaType.destruct(result); - return hasChanged; - } - - bool evaluatedToUndefined = false; - QV4::Scope scope(engine->handle()); - QV4::ScopedValue result(scope, static_cast<QQmlPropertyBindingJSForBoundFunction *>( - jsExpression())->evaluate(&evaluatedToUndefined)); - - if (!handleErrorAndUndefined(evaluatedToUndefined)) + } else { + QPropertyBindingError error(QPropertyBindingError::UnknownError, jsExpression()->delayedError()->error().description()); + QPropertyBindingPrivate::currentlyEvaluatingBinding()->setError(std::move(error)); + bindingErrorCallback(this); return false; + } int propertyType = metaType.id(); |