diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2021-06-15 09:38:17 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2021-06-15 14:03:48 +0200 |
commit | 31ab6b81060abb0db0a68c88c61ea93c7d6bdc60 (patch) | |
tree | 4bbf8f7d7ab63348417bb9faae4530288f3f482c | |
parent | 719e7daab06d10c9cec0059d73096435a1589e00 (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.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4stackframe_p.h | 5 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 4 | ||||
-rw-r--r-- | src/qml/qml/qqml.cpp | 7 | ||||
-rw-r--r-- | src/qml/qml/qqmlprivate.h | 1 |
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; |