diff options
| author | Ulf Hermann <ulf.hermann@qt.io> | 2025-08-27 14:51:16 +0200 |
|---|---|---|
| committer | Ulf Hermann <ulf.hermann@qt.io> | 2025-09-01 19:25:21 +0200 |
| commit | 706e479e3b7a71f070ef6c05f00143e1842f2ec8 (patch) | |
| tree | ee9fcad1f4cf94bc32ed0438ce272705a6e28e9b /src/qml/jsruntime/qv4sequenceobject.cpp | |
| parent | c9d95333468b5aedb7d83089df40208946164c00 (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.cpp | 28 |
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>( |
