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
qqmlirloader.cpp
Go to the documentation of this file.
1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant
4
6#include <private/qqmlirbuilder_p.h>
7
9
10QQmlIRLoader::QQmlIRLoader(const QV4::CompiledData::Unit *qmlData, QmlIR::Document *output)
11 : unit(qmlData)
12 , output(output)
13{
14 pool = output->jsParserEngine.pool();
15}
16
17void QQmlIRLoader::load()
18{
19 output->jsGenerator.stringTable.initializeFromBackingUnit(unit);
20
21 const QV4::CompiledData::QmlUnit *qmlUnit = unit->qmlUnit();
22
23 for (quint32 i = 0; i < qmlUnit->nImports; ++i)
24 output->imports << qmlUnit->importAt(i);
25
26 using QmlIR::Pragma;
27 const auto createPragma = [&](Pragma::PragmaType type) {
28 Pragma *p = New<Pragma>();
29 p->location = QV4::CompiledData::Location();
30 p->type = type;
31 output->pragmas << p;
32 return p;
33 };
34
35 const auto createListPragma = [&](
36 Pragma::PragmaType type,
37 Pragma::ListPropertyAssignBehaviorValue value) {
38 createPragma(type)->listPropertyAssignBehavior = value;
39 };
40
41 const auto createComponentPragma = [&](
42 Pragma::PragmaType type,
43 Pragma::ComponentBehaviorValue value) {
44 createPragma(type)->componentBehavior = value;
45 };
46
47 const auto createFunctionSignaturePragma = [&](
48 Pragma::PragmaType type,
49 Pragma::FunctionSignatureBehaviorValue value) {
50 createPragma(type)->functionSignatureBehavior = value;
51 };
52
53 const auto createNativeMethodPragma = [&](
54 Pragma::PragmaType type,
55 Pragma::NativeMethodBehaviorValue value) {
56 createPragma(type)->nativeMethodBehavior = value;
57 };
58
59 const auto createValueTypePragma = [&](
60 Pragma::PragmaType type,
61 Pragma::ValueTypeBehaviorValues value) {
62 createPragma(type)->valueTypeBehavior = value;
63 };
64
65 if (unit->flags & QV4::CompiledData::Unit::IsSingleton)
66 createPragma(Pragma::Singleton);
67 if (unit->flags & QV4::CompiledData::Unit::IsStrict)
68 createPragma(Pragma::Strict);
69
70 if (unit->flags & QV4::CompiledData::Unit::ListPropertyAssignReplace)
71 createListPragma(Pragma::ListPropertyAssignBehavior, Pragma::Replace);
72 else if (unit->flags & QV4::CompiledData::Unit::ListPropertyAssignReplaceIfNotDefault)
73 createListPragma(Pragma::ListPropertyAssignBehavior, Pragma::ReplaceIfNotDefault);
74
75 if (unit->flags & QV4::CompiledData::Unit::ComponentsBound)
76 createComponentPragma(Pragma::ComponentBehavior, Pragma::Bound);
77
78 if (unit->flags & QV4::CompiledData::Unit::FunctionSignaturesIgnored)
79 createFunctionSignaturePragma(Pragma::FunctionSignatureBehavior, Pragma::Ignored);
80
81 if (unit->flags & QV4::CompiledData::Unit::NativeMethodsAcceptThisObject)
82 createNativeMethodPragma(Pragma::NativeMethodBehavior, Pragma::AcceptThisObject);
83
84 Pragma::ValueTypeBehaviorValues valueTypeBehavior = {};
85 if (unit->flags & QV4::CompiledData::Unit::ValueTypesCopied)
86 valueTypeBehavior |= Pragma::Copy;
87 if (unit->flags & QV4::CompiledData::Unit::ValueTypesAddressable)
88 valueTypeBehavior |= Pragma::Addressable;
89 if (unit->flags & QV4::CompiledData::Unit::ValueTypesAssertable)
90 valueTypeBehavior |= Pragma::Assertable;
91 if (valueTypeBehavior)
92 createValueTypePragma(Pragma::ValueTypeBehavior, valueTypeBehavior);
93
94 for (uint i = 0; i < qmlUnit->nObjects; ++i) {
95 const QV4::CompiledData::Object *serializedObject = qmlUnit->objectAt(i);
96 QmlIR::Object *object = loadObject(serializedObject);
97 output->objects.append(object);
98 }
99}
100
102{
103 FakeExpression(int start, int length)
105 {}
106
108 { return location; }
109
111 { return location; }
112
113private:
114 QQmlJS::SourceLocation location;
115};
116
117QmlIR::Object *QQmlIRLoader::loadObject(const QV4::CompiledData::Object *serializedObject)
118{
119 QmlIR::Object *object = pool->New<QmlIR::Object>();
120 object->init(pool, serializedObject->inheritedTypeNameIndex, serializedObject->idNameIndex,
121 serializedObject->location);
122
123 object->indexOfDefaultPropertyOrAlias = serializedObject->indexOfDefaultPropertyOrAlias;
124 object->defaultPropertyIsAlias = serializedObject->hasAliasAsDefaultProperty();
125 object->flags = serializedObject->flags();
126 object->id = serializedObject->objectId();
127 object->locationOfIdProperty = serializedObject->locationOfIdProperty;
128
129 QList<int> functionIndices;
130 functionIndices.reserve(serializedObject->nFunctions + serializedObject->nBindings / 2);
131
132 for (uint i = 0; i < serializedObject->nBindings; ++i) {
133 QmlIR::Binding *b = pool->New<QmlIR::Binding>();
134 *static_cast<QV4::CompiledData::Binding*>(b) = serializedObject->bindingTable()[i];
135 object->bindings->append(b);
136 if (b->type() == QV4::CompiledData::Binding::Type_Script) {
137 functionIndices.append(b->value.compiledScriptIndex);
138 b->value.compiledScriptIndex = functionIndices.size() - 1;
139
140 QmlIR::CompiledFunctionOrExpression *foe = pool->New<QmlIR::CompiledFunctionOrExpression>();
141 foe->nameIndex = 0;
142
143 QQmlJS::AST::ExpressionNode *expr;
144
145 if (b->stringIndex != quint32(0)) {
146 const int start = output->code.size();
147 const QString script = output->stringAt(b->stringIndex);
148 const int length = script.size();
149 output->code.append(script);
150 expr = new (pool) FakeExpression(start, length);
151 } else
152 expr = new (pool) QQmlJS::AST::NullExpression();
153 foe->node = new (pool) QQmlJS::AST::ExpressionStatement(expr); // dummy
154 object->functionsAndExpressions->append(foe);
155 }
156 }
157
158 Q_ASSERT(object->functionsAndExpressions->count == functionIndices.size());
159
160 for (uint i = 0; i < serializedObject->nSignals; ++i) {
161 const QV4::CompiledData::Signal *serializedSignal = serializedObject->signalAt(i);
162 QmlIR::Signal *s = pool->New<QmlIR::Signal>();
163 s->nameIndex = serializedSignal->nameIndex;
164 s->location = serializedSignal->location;
165 s->parameters = pool->New<QmlIR::PoolList<QmlIR::Parameter> >();
166
167 for (uint i = 0; i < serializedSignal->nParameters; ++i) {
168 QmlIR::Parameter *p = pool->New<QmlIR::Parameter>();
169 *static_cast<QV4::CompiledData::Parameter*>(p) = *serializedSignal->parameterAt(i);
170 s->parameters->append(p);
171 }
172
173 object->qmlSignals->append(s);
174 }
175
176 for (uint i = 0; i < serializedObject->nEnums; ++i) {
177 const QV4::CompiledData::Enum *serializedEnum = serializedObject->enumAt(i);
178 QmlIR::Enum *e = pool->New<QmlIR::Enum>();
179 e->nameIndex = serializedEnum->nameIndex;
180 e->location = serializedEnum->location;
181 e->enumValues = pool->New<QmlIR::PoolList<QmlIR::EnumValue> >();
182
183 for (uint i = 0; i < serializedEnum->nEnumValues; ++i) {
184 QmlIR::EnumValue *v = pool->New<QmlIR::EnumValue>();
185 *static_cast<QV4::CompiledData::EnumValue*>(v) = *serializedEnum->enumValueAt(i);
186 e->enumValues->append(v);
187 }
188
189 object->qmlEnums->append(e);
190 }
191
192 const QV4::CompiledData::Property *serializedProperty = serializedObject->propertyTable();
193 for (uint i = 0; i < serializedObject->nProperties; ++i, ++serializedProperty) {
194 QmlIR::Property *p = pool->New<QmlIR::Property>();
195 *static_cast<QV4::CompiledData::Property*>(p) = *serializedProperty;
196 object->properties->append(p);
197 }
198
199 {
200 const QV4::CompiledData::Alias *serializedAlias = serializedObject->aliasTable();
201 for (uint i = 0; i < serializedObject->nAliases; ++i, ++serializedAlias) {
202 QmlIR::Alias *a = pool->New<QmlIR::Alias>();
203 *static_cast<QV4::CompiledData::Alias*>(a) = *serializedAlias;
204 object->aliases->append(a);
205 }
206 }
207
208 const quint32_le *functionIdx = serializedObject->functionOffsetTable();
209 for (uint i = 0; i < serializedObject->nFunctions; ++i, ++functionIdx) {
210 QmlIR::Function *f = pool->New<QmlIR::Function>();
211 const QV4::CompiledData::Function *compiledFunction = unit->functionAt(*functionIdx);
212
213 functionIndices.append(*functionIdx);
214 f->index = functionIndices.size() - 1;
215 f->location = compiledFunction->location;
216 f->nameIndex = compiledFunction->nameIndex;
217 f->returnType = compiledFunction->returnType;
218
219 f->formals.allocate(pool, int(compiledFunction->nFormals));
220 const QV4::CompiledData::Parameter *formalNameIdx = compiledFunction->formalsTable();
221 for (uint i = 0; i < compiledFunction->nFormals; ++i, ++formalNameIdx)
222 *static_cast<QV4::CompiledData::Parameter*>(&f->formals[i]) = *formalNameIdx;
223
224 object->functions->append(f);
225 }
226
227 object->runtimeFunctionIndices.allocate(pool, functionIndices);
228
229 const QV4::CompiledData::InlineComponent *serializedInlineComponent = serializedObject->inlineComponentTable();
230 for (uint i = 0; i < serializedObject->nInlineComponents; ++i, ++serializedInlineComponent) {
231 QmlIR::InlineComponent *ic = pool->New<QmlIR::InlineComponent>();
232 *static_cast<QV4::CompiledData::InlineComponent*>(ic) = *serializedInlineComponent;
233 object->inlineComponents->append(ic);
234 }
235
236 const QV4::CompiledData::RequiredPropertyExtraData *serializedRequiredPropertyExtraData = serializedObject->requiredPropertyExtraDataTable();
237 for (uint i = 0u; i < serializedObject->nRequiredPropertyExtraData; ++i, ++serializedRequiredPropertyExtraData) {
238 QmlIR::RequiredPropertyExtraData *extra = pool->New<QmlIR::RequiredPropertyExtraData>();
239 *static_cast<QV4::CompiledData::RequiredPropertyExtraData *>(extra) = *serializedRequiredPropertyExtraData;
240 object->requiredPropertyExtraDatas->append(extra);
241 }
242
243 return object;
244}
245
246QT_END_NAMESPACE
Combined button and popup list for selecting options.
QQmlJS::SourceLocation firstSourceLocation() const override
QQmlJS::SourceLocation lastSourceLocation() const override
FakeExpression(int start, int length)