diff options
| author | Ulf Hermann <ulf.hermann@qt.io> | 2024-05-22 14:21:11 +0200 |
|---|---|---|
| committer | Ulf Hermann <ulf.hermann@qt.io> | 2024-05-28 15:22:14 +0200 |
| commit | 87cf75dd28e24c85a5cf8a606bcee4c89176a314 (patch) | |
| tree | 8e333c915136c8efd4044a802c59bc79121c6aff /src/qml/jsruntime/qv4sequenceobject.cpp | |
| parent | c16a3e5adb59f6da5e39e51ca15a4d5324d68d1c (diff) | |
QtQml: Optimize QV4::Sequence's shift() method
Most of the time we have a native shift() operation.
Fixes: QTBUG-123882
Change-Id: I1bc50f98f29918a56b5fc70d1644eb99542a3073
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4sequenceobject.cpp')
| -rw-r--r-- | src/qml/jsruntime/qv4sequenceobject.cpp | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp index cc899428c2..cc05e030c5 100644 --- a/src/qml/jsruntime/qv4sequenceobject.cpp +++ b/src/qml/jsruntime/qv4sequenceobject.cpp @@ -250,6 +250,42 @@ QVariant Sequence::at(qsizetype index) const return result; } +QVariant Sequence::shift() +{ + auto *p = d(); + void *storage = p->storagePointer(); + Q_ASSERT(storage); // Must readReference() before + const QMetaType v = p->valueMetaType(); + const QMetaSequence m = p->metaSequence(); + + const auto variantData = [&](QVariant *variant) -> void *{ + if (v == QMetaType::fromType<QVariant>()) + return variant; + + *variant = QVariant(v); + return variant->data(); + }; + + QVariant result; + void *resultData = variantData(&result); + m.valueAtIndex(storage, 0, resultData); + + if (m.canRemoveValueAtBegin()) { + m.removeValueAtBegin(storage); + return result; + } + + QVariant t; + void *tData = variantData(&t); + for (qsizetype i = 1, end = m.size(storage); i < end; ++i) { + m.valueAtIndex(storage, i, tData); + m.setValueAtIndex(storage, i - 1, tData); + } + m.removeValueAtEnd(storage); + + return result; +} + template<typename Action> void convertAndDo(const QVariant &item, const QMetaType v, Action action) @@ -602,6 +638,7 @@ void SequencePrototype::init() defineDefaultProperty(QStringLiteral("sort"), method_sort, 1); defineDefaultProperty(engine()->id_valueOf(), method_valueOf, 0); defineAccessorProperty(QStringLiteral("length"), method_get_length, method_set_length); + defineDefaultProperty(QStringLiteral("shift"), method_shift, 0); } ReturnedValue SequencePrototype::method_valueOf(const FunctionObject *f, const Value *thisObject, const Value *, int) @@ -627,6 +664,29 @@ ReturnedValue SequencePrototype::method_sort(const FunctionObject *b, const Valu return o.asReturnedValue(); } +ReturnedValue SequencePrototype::method_shift( + const FunctionObject *b, const Value *thisObject, const Value *argv, int argc) +{ + Scope scope(b); + Scoped<Sequence> s(scope, thisObject); + if (!s) + return ArrayPrototype::method_shift(b, thisObject, argv, argc); + + if (s->d()->isReference() && !s->loadReference()) + RETURN_UNDEFINED(); + + const qsizetype len = s->size(); + if (!len) + RETURN_UNDEFINED(); + + ScopedValue result(scope, scope.engine->fromVariant(s->shift())); + + if (s->d()->object()) + s->storeReference(); + + return result->asReturnedValue(); +} + ReturnedValue SequencePrototype::newSequence( QV4::ExecutionEngine *engine, QMetaType type, QMetaSequence metaSequence, const void *data, Heap::Object *object, int propertyIndex, Heap::ReferenceObject::Flags flags) |
