1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#include "qqmljsstorageinitializer_p.h"
5
6QT_BEGIN_NAMESPACE
7
8/*!
9 * \internal
10 * \class QQmlJSStorageInitializer
11 *
12 * The QQmlJSStorageInitializer is a compile pass that initializes the storage
13 * for all register contents.
14 *
15 * QQmlJSStorageInitializer does not have to use the byte code at all but
16 * operates only on the annotations and the function description.
17 */
18
19QQmlJSCompilePass::BlocksAndAnnotations QQmlJSStorageInitializer::run(Function *function)
20{
21 m_function = function;
22
23 if (QQmlJSRegisterContent &returnType = function->returnType; returnType.isValid()) {
24 if (const QQmlJSScope::ConstPtr stored
25 = m_typeResolver->storedType(type: returnType.containedType())) {
26 m_pool->storeType(content: returnType, stored);
27 } else {
28 addError(QStringLiteral("Cannot store the return type %1.")
29 .arg(a: returnType.containedType()->internalName()));
30 return {};
31 }
32 }
33
34 const auto storeRegister = [&](QQmlJSRegisterContent &content) {
35 if (!content.isValid() || !content.storage().isNull())
36 return;
37
38 const QQmlJSScope::ConstPtr original = m_typeResolver->originalContainedType(container: content);
39 if (const QQmlJSScope::ConstPtr originalStored = m_typeResolver->storedType(type: original)) {
40 m_pool->storeType(content, stored: originalStored);
41 } else {
42 addError(QStringLiteral("Cannot store type %1.").arg(a: original->internalName()));
43 return;
44 }
45
46 const QQmlJSScope::ConstPtr contentContained = content.containedType();
47 const QQmlJSScope::ConstPtr adjustedStored = m_typeResolver->storedType(type: contentContained);
48 if (!adjustedStored) {
49 addError(QStringLiteral("Cannot store type %1.")
50 .arg(a: contentContained->internalName()));
51 return;
52 }
53
54 if (!m_typeResolver->adjustTrackedType(tracked: content.storage(), conversion: adjustedStored)) {
55 addError(QStringLiteral("Cannot adjust stored type for %1 to %2.")
56 .arg(args: contentContained->internalName(), args: adjustedStored->internalName()));
57 }
58 };
59
60 const auto storeRegisters = [&](VirtualRegisters &registers) {
61 for (auto j = registers.begin(), jEnd = registers.end(); j != jEnd; ++j)
62 storeRegister(j.value().content);
63 };
64
65 storeRegister(function->qmlScope);
66
67 for (QQmlJSRegisterContent &argument : function->argumentTypes) {
68 Q_ASSERT(argument.isValid());
69 storeRegister(argument);
70 }
71
72 for (QQmlJSRegisterContent &argument : function->registerTypes) {
73 Q_ASSERT(argument.isValid());
74 storeRegister(argument);
75 }
76
77 for (auto i = m_annotations.begin(), iEnd = m_annotations.end(); i != iEnd; ++i) {
78 storeRegister(i->second.changedRegister);
79 storeRegisters(i->second.typeConversions);
80 storeRegisters(i->second.readRegisters);
81 }
82
83 return { .basicBlocks: std::move(m_basicBlocks), .annotations: std::move(m_annotations) };
84}
85
86QT_END_NAMESPACE
87

source code of qtdeclarative/src/qmlcompiler/qqmljsstorageinitializer.cpp