diff options
| author | Ulf Hermann <ulf.hermann@qt.io> | 2022-02-24 08:57:44 +0100 |
|---|---|---|
| committer | Ulf Hermann <ulf.hermann@qt.io> | 2022-03-14 20:53:52 +0100 |
| commit | 6eff3465b5192e40343f0486ef7076da2ed28bed (patch) | |
| tree | 5b1b4f65b2396ebd7152ab8f13300e5f5dd33421 /src/qmlcompiler/qqmljsbasicblocks.cpp | |
| parent | 9de2b11a7033a1969156277bafa848b5c178baa1 (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.cpp | 41 |
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) |
