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-16 10:24:26 +0200
commit3248c0242c43f8e4251013a7a7c2fe39687553e9 (patch)
tree7ec3e53acce2c67bf3553f5a22fdd1b01009b147
parent6578629fd23a98b02b7b208d36ecb7304b5080a5 (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. Change-Id: Iac2298869dde80f6d889240dd8200b2ad83e5dc5 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> (cherry picked from commit 31ab6b81060abb0db0a68c88c61ea93c7d6bdc60)
-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 f6001da1f8..6ab9a87ec0 100644
--- a/src/qml/jsruntime/qv4function.cpp
+++ b/src/qml/jsruntime/qv4function.cpp
@@ -77,7 +77,7 @@ 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;
+ return !frame.isReturnValueUndefined();
}
ReturnedValue Function::call(const Value *thisObject, const Value *argv, int argc, const ExecutionContext *context) {
diff --git a/src/qml/jsruntime/qv4stackframe_p.h b/src/qml/jsruntime/qv4stackframe_p.h
index ebe3b762af..be6ec550b6 100644
--- a/src/qml/jsruntime/qv4stackframe_p.h
+++ b/src/qml/jsruntime/qv4stackframe_p.h
@@ -88,6 +88,7 @@ struct Q_QML_PRIVATE_EXPORT CppStackFrameBase
struct {
const QMetaType *metaTypes;
void **returnAndArgs;
+ bool returnValueIsUndefined;
};
};
@@ -182,11 +183,15 @@ struct Q_QML_PRIVATE_EXPORT MetaTypesStackFrame : public CppStackFrame
CppStackFrame::init(v4Function, argc, Kind::Meta);
metaTypes = types;
returnAndArgs = a;
+ 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 88bb309b7d..94225ff0c7 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 66991ad994..ccc90cabbf 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;