aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2021-06-15 09:38:17 +0200
committerUlf Hermann <ulf.hermann@qt.io>2021-06-15 14:03:48 +0200
commit31ab6b81060abb0db0a68c88c61ea93c7d6bdc60 (patch)
tree4bbf8f7d7ab63348417bb9faae4530288f3f482c
parent719e7daab06d10c9cec0059d73096435a1589e00 (diff)
Allow AOT functions to signal an undefined result via the context
undefined as value returned from bindings has the special meaning of resetting the binding. As AOT-compiled functions return the actual type of the binding rather than a QV4::Value, we cannot always encode undefined. Therefore, add a flag that tells us whether the result was supposed to be undefined. Pick-to: 6.2 Change-Id: Iac2298869dde80f6d889240dd8200b2ad83e5dc5 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
-rw-r--r--src/qml/jsruntime/qv4function.cpp2
-rw-r--r--src/qml/jsruntime/qv4stackframe_p.h5
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp4
-rw-r--r--src/qml/qml/qqml.cpp7
-rw-r--r--src/qml/qml/qqmlprivate.h1
5 files changed, 17 insertions, 2 deletions
diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp
index 7b5685a2a0..95a7506c80 100644
--- a/src/qml/jsruntime/qv4function.cpp
+++ b/src/qml/jsruntime/qv4function.cpp
@@ -74,7 +74,7 @@ bool Function::call(QObject *thisObject, void **a, const QMetaType *types, int a
frame.push(engine);
Moth::VME::exec(&frame, engine);
frame.pop(engine);
- return true;
+ return !frame.isReturnValueUndefined();
}
ReturnedValue Function::call(
diff --git a/src/qml/jsruntime/qv4stackframe_p.h b/src/qml/jsruntime/qv4stackframe_p.h
index 1439e9f677..9a121b48cd 100644
--- a/src/qml/jsruntime/qv4stackframe_p.h
+++ b/src/qml/jsruntime/qv4stackframe_p.h
@@ -90,6 +90,7 @@ struct Q_QML_PRIVATE_EXPORT CppStackFrameBase
QObject *thisObject;
const QMetaType *metaTypes;
void **returnAndArgs;
+ bool returnValueIsUndefined;
};
};
@@ -163,11 +164,15 @@ struct Q_QML_PRIVATE_EXPORT MetaTypesStackFrame : public CppStackFrame
CppStackFrameBase::context = context;
CppStackFrameBase::metaTypes = metaTypes;
CppStackFrameBase::returnAndArgs = returnAndArgs;
+ CppStackFrameBase::returnValueIsUndefined = false;
}
QMetaType returnType() const { return metaTypes[0]; }
void *returnValue() const { return returnAndArgs[0]; }
+ bool isReturnValueUndefined() const { return CppStackFrameBase::returnValueIsUndefined; }
+ void setReturnValueUndefined() { CppStackFrameBase::returnValueIsUndefined = true; }
+
const QMetaType *argTypes() const { return metaTypes + 1; }
void **argv() const { return returnAndArgs + 1; }
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index 009cff067a..94860f0521 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -432,8 +432,10 @@ static bool compareEqualInt(QV4::Value &accumulator, QV4::Value lhs, int rhs)
void VME::exec(MetaTypesStackFrame *frame, ExecutionEngine *engine)
{
qt_v4ResolvePendingBreakpointsHook();
- if (engine->checkStackLimits())
+ if (engine->checkStackLimits()) {
+ frame->setReturnValueUndefined();
return;
+ }
ExecutionEngineCallDepthRecorder executionEngineCallDepthRecorder(engine);
Function *function = frame->v4Function;
diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp
index 2144893c2d..3b0000ab02 100644
--- a/src/qml/qml/qqml.cpp
+++ b/src/qml/qml/qqml.cpp
@@ -712,6 +712,13 @@ void AOTCompiledContext::setInstructionPointer(int offset) const
frame->instructionPointer = offset;
}
+void AOTCompiledContext::setReturnValueUndefined() const
+{
+ if (auto *frame = engine->handle()->currentStackFrame) {
+ Q_ASSERT(frame->isMetaTypesFrame());
+ static_cast<QV4::MetaTypesStackFrame *>(frame)->setReturnValueUndefined();
+ }
+}
static void captureObjectProperty(
QObject *object, const QQmlPropertyCache *propertyCache,
diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h
index 71855df966..11c948445f 100644
--- a/src/qml/qml/qqmlprivate.h
+++ b/src/qml/qml/qqmlprivate.h
@@ -612,6 +612,7 @@ namespace QQmlPrivate
QJSValue jsMetaType(int index) const;
void setInstructionPointer(int offset) const;
+ void setReturnValueUndefined() const;
// Run QQmlPropertyCapture::captureProperty() without retrieving the value.
bool captureLookup(uint index, QObject *object) const;