aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmlcompiler/qqmljsstorageinitializer.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2024-06-10 11:21:15 +0200
committerUlf Hermann <ulf.hermann@qt.io>2024-06-16 00:17:34 +0200
commitdd731b880b4bfbe7bad7b0b4d1ac3b72503c0071 (patch)
tree6a00d633cccc1d3ce0236cfcaa3bd4a1816430e0 /src/qmlcompiler/qqmljsstorageinitializer.cpp
parent9542b4b93576dd42cfbfe2dd8692b317fe6f7e3c (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.cpp81
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 &registers) {
+ 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