aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime
diff options
context:
space:
mode:
authorTarja Sundqvist <[email protected]>2024-07-23 13:25:53 +0300
committerTarja Sundqvist <[email protected]>2024-07-23 13:25:53 +0300
commit7c32569ad27b743b6cb50e2bcb67c9ca1674f238 (patch)
tree15b39c35a96707029dbd352e0e74cb78c59b3952 /src/qml/jsruntime
parent5f4570b5164a828b20514b938957ce06b105ff3e (diff)
parente6e266221555bf3c5554427f7402f6e7e3087fa5 (diff)
Merge tag 'v5.15.15-lts' into tqtc/lts-5.15-opensourcev5.15.15-lts-lgpl
Qt 5.15.15-lts release Change-Id: I0272e1ec4b55be362e13e36cd48f532fe4b7c770
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r--src/qml/jsruntime/qv4arraydata.cpp38
1 files changed, 33 insertions, 5 deletions
diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp
index 0eea3345c5..9816a646de 100644
--- a/src/qml/jsruntime/qv4arraydata.cpp
+++ b/src/qml/jsruntime/qv4arraydata.cpp
@@ -670,8 +670,8 @@ bool ArrayElementLessThan::operator()(Value v1, Value v2) const
return p1s->toQString() < p2s->toQString();
}
-template <typename RandomAccessIterator, typename T, typename LessThan>
-void sortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan)
+template <typename RandomAccessIterator, typename LessThan>
+void sortHelper(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
{
top:
int span = int(end - start);
@@ -716,7 +716,7 @@ top:
++low;
qSwap(*end, *low);
- sortHelper(start, low, t, lessThan);
+ sortHelper(start, low, lessThan);
start = low + 1;
++end;
@@ -816,8 +816,36 @@ void ArrayData::sort(ExecutionEngine *engine, Object *thisObject, const Value &c
ArrayElementLessThan lessThan(engine, static_cast<const FunctionObject &>(comparefn));
- Value *begin = thisObject->arrayData()->values.values;
- sortHelper(begin, begin + len, *begin, lessThan);
+ const auto thisArrayData = thisObject->arrayData();
+ uint startIndex = thisArrayData->mappedIndex(0);
+ uint endIndex = thisArrayData->mappedIndex(len - 1) + 1;
+ if (startIndex < endIndex) {
+ // Values are contiguous. Sort right away.
+ sortHelper(
+ thisArrayData->values.values + startIndex,
+ thisArrayData->values.values + endIndex,
+ lessThan);
+ } else {
+ // Values wrap around the end of the allocation. Close the gap to form a contiguous array.
+ // We're going to sort anyway. So we don't need to care about order.
+
+ // ArrayElementLessThan sorts empty and undefined to the end of the array anyway, but we
+ // probably shouldn't rely on the unused slots to be actually undefined or empty.
+
+ const uint gap = startIndex - endIndex;
+ const uint allocEnd = thisArrayData->values.alloc - 1;
+ for (uint i = 0; i < gap; ++i) {
+ const uint from = allocEnd - i;
+ const uint to = endIndex + i;
+ if (from < startIndex)
+ break;
+
+ std::swap(thisArrayData->values.values[from], thisArrayData->values.values[to]);
+ }
+
+ thisArrayData->offset = 0;
+ sortHelper(thisArrayData->values.values, thisArrayData->values.values + len, lessThan);
+ }
#ifdef CHECK_SPARSE_ARRAYS
thisObject->initSparseArray();