aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorIvan Solovev <ivan.solovev@qt.io>2021-05-25 10:45:51 +0200
committerIvan Solovev <ivan.solovev@qt.io>2021-05-25 11:26:15 +0200
commit8ac705247430ff6fbbc25a9db20c0e7dc572abe7 (patch)
treeb62681e21db563a605f785e8a12f2ead3c958c5b /src/qml
parent9184f6c1de2c315cc66eb6cd3886c3daea90516f (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.cpp9
-rw-r--r--src/qml/jsruntime/qv4function_p.h2
-rw-r--r--src/qml/jsruntime/qv4jscall_p.h12
-rw-r--r--src/qml/qml/qqmljavascriptexpression.cpp6
-rw-r--r--src/qml/qml/qqmlpropertybinding.cpp83
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();