aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4sequenceobject.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2025-08-27 14:51:16 +0200
committerUlf Hermann <ulf.hermann@qt.io>2025-09-01 19:25:21 +0200
commit706e479e3b7a71f070ef6c05f00143e1842f2ec8 (patch)
treeee9fcad1f4cf94bc32ed0438ce272705a6e28e9b /src/qml/jsruntime/qv4sequenceobject.cpp
parentc9d95333468b5aedb7d83089df40208946164c00 (diff)
QtQml: Extract method to create the inline storage for Sequence
We will get a different kind of storage in addition. The unification of the different init() methods uncovers a bug: The storage can indeed be nullptr when querying the size later. If you construct a detached sequence from a null container, there is no reason to create the internal storage. The size is evidently 0 in that case. Fix sizeInline() to tell us as much. Pick-to: 6.10 6.9 6.8 Task-number: QTBUG-129972 Task-number: QTBUG-139025 Change-Id: I33347805fc79f81c69c3191a76ff9167186b43f0 Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4sequenceobject.cpp')
-rw-r--r--src/qml/jsruntime/qv4sequenceobject.cpp28
1 files changed, 19 insertions, 9 deletions
diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp
index e30b2d8ac2..d893973b03 100644
--- a/src/qml/jsruntime/qv4sequenceobject.cpp
+++ b/src/qml/jsruntime/qv4sequenceobject.cpp
@@ -80,8 +80,13 @@ static void generateWarning(QV4::ExecutionEngine *v4, const QString& description
static qsizetype sizeInline(const Heap::Sequence *p)
{
- Q_ASSERT(p->storagePointer()); // Must readReference() before
- return p->metaSequence().size(p->storagePointer());
+ if (const void *container = p->storagePointer())
+ return p->metaSequence().size(container);
+
+ // It can be stored inline, and the container can still be nullptr.
+ // This happens if we construct it from a nullptr in the first place and never update it.
+ // It means it's empty.
+ return 0;
}
struct SequenceOwnPropertyKeyIterator : ObjectOwnPropertyKeyIterator
@@ -121,16 +126,13 @@ void Heap::Sequence::initTypes(QMetaType listType, QMetaSequence metaSequence)
Q_ASSERT(m_listType);
m_metaSequence = metaSequence.iface();
Q_ASSERT(m_metaSequence);
- QV4::Scope scope(internalClass->engine);
- QV4::Scoped<QV4::Sequence> o(scope, this);
- o->setArrayType(Heap::ArrayData::Custom);
}
void Heap::Sequence::init(QMetaType listType, QMetaSequence metaSequence, const void *container)
{
ReferenceObject::init(nullptr, -1, NoFlag);
initTypes(listType, metaSequence);
- m_container = listType.create(container);
+ createInlineStorage(container);
}
void Heap::Sequence::init(
@@ -142,12 +144,20 @@ void Heap::Sequence::init(
if (CppStackFrame *frame = internalClass->engine->currentStackFrame)
setLocation(frame->v4Function, frame->statementNumber());
- if (container)
- m_container = listType.create(container);
- else if (flags & EnforcesLocation)
+ createInlineStorage(container);
+ if (!container && (flags & EnforcesLocation))
QV4::ReferenceObject::readReference(this);
}
+void Heap::Sequence::createInlineStorage(const void *container)
+{
+ QV4::Scope scope(internalClass->engine);
+ QV4::Scoped<QV4::Sequence> o(scope, this);
+ o->setArrayType(Heap::ArrayData::Custom);
+ if (container)
+ m_container = listType().create(container);
+}
+
Heap::Sequence *Heap::Sequence::detached() const
{
return internalClass->engine->memoryManager->allocate<QV4::Sequence>(