diff options
| author | Ulf Hermann <ulf.hermann@qt.io> | 2024-06-10 11:21:15 +0200 |
|---|---|---|
| committer | Ulf Hermann <ulf.hermann@qt.io> | 2024-06-16 00:17:34 +0200 |
| commit | dd731b880b4bfbe7bad7b0b4d1ac3b72503c0071 (patch) | |
| tree | 6a00d633cccc1d3ce0236cfcaa3bd4a1816430e0 /src/qmlcompiler/qqmljsstorageinitializer.cpp | |
| parent | 9542b4b93576dd42cfbfe2dd8692b317fe6f7e3c (diff) | |
QmlCompiler: Create QQmlJSRegisterContent unstored
Add a separate pass to populate the stored types and only run that after
we're done with all the type propagation and optimization.
Task-number: QTBUG-124670
Change-Id: I740063908b22684f5d2c72d6261fad98850d8636
Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qmlcompiler/qqmljsstorageinitializer.cpp')
| -rw-r--r-- | src/qmlcompiler/qqmljsstorageinitializer.cpp | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/src/qmlcompiler/qqmljsstorageinitializer.cpp b/src/qmlcompiler/qqmljsstorageinitializer.cpp new file mode 100644 index 0000000000..b0f7d1a49f --- /dev/null +++ b/src/qmlcompiler/qqmljsstorageinitializer.cpp @@ -0,0 +1,81 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "qqmljsstorageinitializer_p.h" + +QT_BEGIN_NAMESPACE + +/*! + * \internal + * \class QQmlJSStorageInitializer + * + * The QQmlJSStorageInitializer is a compile pass that initializes the storage + * for all register contents. + * + * QQmlJSStorageInitializer does not have to use the byte code at all but + * operates only on the annotations and the function description. + */ + +QQmlJSCompilePass::BlocksAndAnnotations +QQmlJSStorageInitializer::run(Function *function, QQmlJS::DiagnosticMessage *error) +{ + m_function = function; + m_error = error; + + if (QQmlJSRegisterContent &returnType = function->returnType; returnType.isValid()) { + if (const QQmlJSScope::ConstPtr stored + = m_typeResolver->storedType(returnType.containedType())) { + returnType = returnType.storedIn(m_typeResolver->trackedType(stored)); + } else { + setError(QStringLiteral("Cannot store the return type %1.") + .arg(returnType.containedType()->internalName())); + return {}; + } + } + + const auto storeRegister = [&](QQmlJSRegisterContent &content) { + if (!content.isValid()) + return; + + const QQmlJSScope::ConstPtr original + = m_typeResolver->originalType(content.containedType()); + const QQmlJSScope::ConstPtr originalStored = m_typeResolver->storedType(original); + const QQmlJSScope::ConstPtr originalTracked = m_typeResolver->trackedType(originalStored); + content = content.storedIn(originalTracked); + + const QQmlJSScope::ConstPtr adjustedStored + = m_typeResolver->storedType(content.containedType()); + + if (!m_typeResolver->adjustTrackedType(originalTracked, adjustedStored)) { + setError(QStringLiteral("Cannot adjust stored type for %1.") + .arg(content.containedType()->internalName())); + } + }; + + const auto storeRegisters = [&](VirtualRegisters ®isters) { + for (auto j = registers.begin(), jEnd = registers.end(); j != jEnd; ++j) + storeRegister(j.value().content); + }; + + storeRegister(function->qmlScope); + + for (QQmlJSRegisterContent &argument : function->argumentTypes) { + Q_ASSERT(argument.isValid()); + storeRegister(argument); + } + + for (QQmlJSRegisterContent &argument : function->registerTypes) { + Q_ASSERT(argument.isValid()); + storeRegister(argument); + } + + for (auto i = m_annotations.begin(), iEnd = m_annotations.end(); i != iEnd; ++i) { + storeRegister(i->second.changedRegister); + storeRegisters(i->second.typeConversions); + storeRegisters(i->second.readRegisters); + } + + return { std::move(m_basicBlocks), std::move(m_annotations) }; +} + +QT_END_NAMESPACE |
