aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmlcompiler/qqmljsbasicblocks.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2022-02-24 08:57:44 +0100
committerUlf Hermann <ulf.hermann@qt.io>2022-03-14 20:53:52 +0100
commit6eff3465b5192e40343f0486ef7076da2ed28bed (patch)
tree5b1b4f65b2396ebd7152ab8f13300e5f5dd33421 /src/qmlcompiler/qqmljsbasicblocks.cpp
parent9de2b11a7033a1969156277bafa848b5c178baa1 (diff)
QmlCompiler: Implement generate_DefineArray
Using the type cloning and adaption mechanism we can now determine what kind of list we have to create in order to avoid a later conversion. We can even propagate the type adjustment into the element types we read. Fixes: QTBUG-100157 Change-Id: Ia2f160ebae56f39ee5946f49d2f8c5b4986a6b77 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qmlcompiler/qqmljsbasicblocks.cpp')
-rw-r--r--src/qmlcompiler/qqmljsbasicblocks.cpp41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/qmlcompiler/qqmljsbasicblocks.cpp b/src/qmlcompiler/qqmljsbasicblocks.cpp
index cce7e141eb..6c3a0d71ab 100644
--- a/src/qmlcompiler/qqmljsbasicblocks.cpp
+++ b/src/qmlcompiler/qqmljsbasicblocks.cpp
@@ -140,6 +140,14 @@ void QQmlJSBasicBlocks::generate_ThrowException()
m_skipUntilNextLabel = true;
}
+void QQmlJSBasicBlocks::generate_DefineArray(int argc, int)
+{
+ if (argc == 0)
+ return; // empty array/list, nothing to do
+
+ m_arrayDefinitions.append(currentInstructionOffset());
+}
+
void QQmlJSBasicBlocks::processJump(int offset, JumpMode mode)
{
if (offset < 0)
@@ -377,6 +385,39 @@ void QQmlJSBasicBlocks::adjustTypes()
using NewVirtualRegisters = NewFlatMap<int, QQmlJSRegisterContent>;
QHash<int, QList<int>> liveConversions;
+
+ // Handle the array definitions first.
+ // Changing the array type changes the expected element types.
+ for (int instructionOffset : m_arrayDefinitions) {
+ auto it = m_readerLocations.find(instructionOffset);
+ if (it == m_readerLocations.end())
+ continue;
+
+ const InstructionAnnotation &annotation = m_annotations[instructionOffset];
+
+ Q_ASSERT(it->trackedTypes.length() == 1);
+ Q_ASSERT(it->trackedTypes[0] == m_typeResolver->containedType(annotation.changedRegister));
+ Q_ASSERT(!annotation.readRegisters.isEmpty());
+
+ m_typeResolver->adjustTrackedType(it->trackedTypes[0], it->typeReaders.values());
+
+ // Now we don't adjust the type we store, but rather the type we expect to read. We
+ // can do this because we've tracked the read type when we defined the array in
+ // QQmlJSTypePropagator.
+ if (QQmlJSScope::ConstPtr valueType = it->trackedTypes[0]->valueType()) {
+ m_typeResolver->adjustTrackedType(
+ m_typeResolver->containedType(annotation.readRegisters.begin().value()),
+ valueType);
+ }
+
+ for (const QList<int> &conversions : qAsConst(it->registerReadersAndConversions)) {
+ for (int conversion : conversions)
+ liveConversions[conversion].append(it->trackedRegister);
+ }
+
+ m_readerLocations.erase(it);
+ }
+
for (auto it = m_readerLocations.begin(), end = m_readerLocations.end(); it != end; ++it) {
for (const QList<int> &conversions : qAsConst(it->registerReadersAndConversions)) {
for (int conversion : conversions)