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-16 10:24:26 +0200 |
commit | 3248c0242c43f8e4251013a7a7c2fe39687553e9 (patch) | |
tree | 7ec3e53acce2c67bf3553f5a22fdd1b01009b147 | |
parent | 6578629fd23a98b02b7b208d36ecb7304b5080a5 (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.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 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; |