Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qqmljsstoragegeneralizer.cpp
Go to the documentation of this file.
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// Qt-Security score:significant
4
6
8
9/*!
10 * \internal
11 * \class QQmlJSStorageGeneralizer
12 *
13 * The QQmlJSStorageGeneralizer is a compile pass that changes all type
14 * annotations and the function signature to use a generic storage type like
15 * QVariant or QObject*. This is necessary if we cannot rely on the original
16 * type to be immediately accessible, for example because we cannot include its
17 * header.
18 *
19 * QQmlJSStorageGeneralizer does not have to use the byte code at all but
20 * operates only on the annotations and the function description.
21 */
22
23QQmlJSCompilePass::BlocksAndAnnotations QQmlJSStorageGeneralizer::run(Function *function)
24{
25 m_function = function;
26
27 if (QQmlJSRegisterContent &returnType = function->returnType; returnType.isValid()) {
28 if (QQmlJSScope::ConstPtr stored = m_typeResolver->genericType(
29 returnType.storedType(), QQmlJSTypeResolver::ComponentIsGeneric::Yes)) {
30 m_pool->generalizeType(returnType.storage(), stored);
31 } else {
32 addError(QStringLiteral("Cannot store the return type %1.")
33 .arg(returnType.storedType()->internalName()));
34 return {};
35 }
36 }
37
38 const auto transformRegister = [&](QQmlJSRegisterContent &content) {
39 QQmlJSRegisterContent specific = content.storage();
40 if (specific.isValid())
41 m_typeResolver->generalizeType(specific);
42 };
43
44 const auto transformRegisters = [&](VirtualRegisters &registers) {
45 for (auto j = registers.begin(), jEnd = registers.end(); j != jEnd; ++j) {
46 QQmlJSRegisterContent &content = j.value().content;
47 transformRegister(content);
48 }
49 };
50
51 for (QQmlJSRegisterContent &argument : function->argumentTypes) {
52 Q_ASSERT(argument.isValid());
53 transformRegister(argument);
54 }
55
56 for (auto i = m_annotations.begin(), iEnd = m_annotations.end(); i != iEnd; ++i) {
57 transformRegister(i->second.changedRegister);
58 transformRegisters(i->second.typeConversions);
59 transformRegisters(i->second.readRegisters);
60 }
61
62 return { std::move(m_basicBlocks), std::move(m_annotations) };
63}
64
65QT_END_NAMESPACE