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 | |
4 | #ifndef QV4EXECUTABLECOMPILATIONUNIT_P_H |
5 | #define QV4EXECUTABLECOMPILATIONUNIT_P_H |
6 | |
7 | // |
8 | // W A R N I N G |
9 | // ------------- |
10 | // |
11 | // This file is not part of the Qt API. It exists purely as an |
12 | // implementation detail. This header file may change from version to |
13 | // version without notice, or even be removed. |
14 | // |
15 | // We mean it. |
16 | // |
17 | |
18 | #include <private/qintrusivelist_p.h> |
19 | #include <private/qqmlmetatype_p.h> |
20 | #include <private/qqmlnullablevalue_p.h> |
21 | #include <private/qqmlpropertycachevector_p.h> |
22 | #include <private/qqmlrefcount_p.h> |
23 | #include <private/qqmltype_p.h> |
24 | #include <private/qqmltypenamecache_p.h> |
25 | #include <private/qv4compileddata_p.h> |
26 | #include <private/qv4identifierhash_p.h> |
27 | |
28 | #include <memory> |
29 | |
30 | QT_BEGIN_NAMESPACE |
31 | |
32 | class QQmlScriptData; |
33 | class QQmlEnginePrivate; |
34 | |
35 | namespace QV4 { |
36 | |
37 | class CompilationUnitMapper; |
38 | |
39 | struct CompilationUnitRuntimeData |
40 | { |
41 | Heap::String **runtimeStrings = nullptr; // Array |
42 | |
43 | // pointers either to data->constants() or little-endian memory copy. |
44 | // We keep this member twice so that the JIT can access it via standard layout. |
45 | const StaticValue *constants = nullptr; |
46 | |
47 | QV4::StaticValue *runtimeRegularExpressions = nullptr; |
48 | Heap::InternalClass **runtimeClasses = nullptr; |
49 | const StaticValue **imports = nullptr; |
50 | |
51 | QV4::Lookup *runtimeLookups = nullptr; |
52 | QVector<QV4::Function *> runtimeFunctions; |
53 | QVector<QV4::Heap::InternalClass *> runtimeBlocks; |
54 | mutable QVector<QV4::Heap::Object *> templateObjects; |
55 | }; |
56 | |
57 | static_assert(std::is_standard_layout_v<CompilationUnitRuntimeData>); |
58 | static_assert(offsetof(CompilationUnitRuntimeData, runtimeStrings) == 0); |
59 | static_assert(offsetof(CompilationUnitRuntimeData, constants) == sizeof(QV4::Heap::String **)); |
60 | static_assert(offsetof(CompilationUnitRuntimeData, runtimeRegularExpressions) == offsetof(CompilationUnitRuntimeData, constants) + sizeof(const StaticValue *)); |
61 | static_assert(offsetof(CompilationUnitRuntimeData, runtimeClasses) == offsetof(CompilationUnitRuntimeData, runtimeRegularExpressions) + sizeof(const StaticValue *)); |
62 | static_assert(offsetof(CompilationUnitRuntimeData, imports) == offsetof(CompilationUnitRuntimeData, runtimeClasses) + sizeof(const StaticValue *)); |
63 | |
64 | class Q_QML_EXPORT ExecutableCompilationUnit final |
65 | : public CompilationUnitRuntimeData, |
66 | public QQmlRefCounted<ExecutableCompilationUnit> |
67 | { |
68 | Q_DISABLE_COPY_MOVE(ExecutableCompilationUnit) |
69 | public: |
70 | friend class QQmlRefCounted<ExecutableCompilationUnit>; |
71 | friend class QQmlRefPointer<ExecutableCompilationUnit>; |
72 | friend struct ExecutionEngine; |
73 | |
74 | ExecutionEngine *engine = nullptr; |
75 | |
76 | QString finalUrlString() const { return m_compilationUnit->finalUrlString(); } |
77 | QString fileName() const { return m_compilationUnit->fileName(); } |
78 | |
79 | QUrl url() const { return m_compilationUnit->url(); } |
80 | QUrl finalUrl() const { return m_compilationUnit->finalUrl(); } |
81 | |
82 | QQmlRefPointer<QQmlTypeNameCache> typeNameCache() const |
83 | { |
84 | return m_compilationUnit->typeNameCache; |
85 | } |
86 | |
87 | QQmlPropertyCacheVector *propertyCachesPtr() |
88 | { |
89 | return &m_compilationUnit->propertyCaches; |
90 | } |
91 | |
92 | QQmlPropertyCache::ConstPtr rootPropertyCache() const |
93 | { |
94 | return m_compilationUnit->rootPropertyCache(); |
95 | } |
96 | |
97 | // mapping from component object index (CompiledData::Unit object index that points to component) to identifier hash of named objects |
98 | // this is initialized on-demand by QQmlContextData |
99 | QHash<int, IdentifierHash> namedObjectsPerComponentCache; |
100 | inline IdentifierHash namedObjectsPerComponent(int componentObjectIndex); |
101 | |
102 | int totalBindingsCount() const { return m_compilationUnit->totalBindingsCount(); } |
103 | int totalParserStatusCount() const { return m_compilationUnit->totalParserStatusCount(); } |
104 | int totalObjectCount() const { return m_compilationUnit->totalObjectCount(); } |
105 | |
106 | ResolvedTypeReference *resolvedType(int id) const |
107 | { |
108 | return m_compilationUnit->resolvedType(id); |
109 | } |
110 | |
111 | QQmlType qmlTypeForComponent(const QString &inlineComponentName = QString()) const |
112 | { |
113 | return m_compilationUnit->qmlTypeForComponent(inlineComponentName); |
114 | } |
115 | |
116 | QMetaType metaType() const { return m_compilationUnit->qmlType.typeId(); } |
117 | |
118 | int inlineComponentId(const QString &inlineComponentName) const |
119 | { |
120 | return m_compilationUnit->inlineComponentId(inlineComponentName); |
121 | } |
122 | |
123 | // --- interface for QQmlPropertyCacheCreator |
124 | using CompiledObject = CompiledData::CompilationUnit::CompiledObject; |
125 | using CompiledFunction = CompiledData::CompilationUnit::CompiledFunction; |
126 | using CompiledBinding = CompiledData::CompilationUnit::CompiledBinding; |
127 | using IdToObjectMap = CompiledData::CompilationUnit::IdToObjectMap; |
128 | |
129 | bool nativeMethodsAcceptThisObjects() const |
130 | { |
131 | return m_compilationUnit->nativeMethodsAcceptThisObjects(); |
132 | } |
133 | |
134 | bool ignoresFunctionSignature() const { return m_compilationUnit->ignoresFunctionSignature(); } |
135 | bool valueTypesAreCopied() const { return m_compilationUnit->valueTypesAreCopied(); } |
136 | bool valueTypesAreAddressable() const { return m_compilationUnit->valueTypesAreAddressable(); } |
137 | bool valueTypesAreAssertable() const { return m_compilationUnit->valueTypesAreAssertable(); } |
138 | bool componentsAreBound() const { return m_compilationUnit->componentsAreBound(); } |
139 | bool isESModule() const { return m_compilationUnit->isESModule(); } |
140 | |
141 | int objectCount() const { return m_compilationUnit->objectCount(); } |
142 | const CompiledObject *objectAt(int index) const |
143 | { |
144 | return m_compilationUnit->objectAt(index); |
145 | } |
146 | |
147 | Heap::Object *templateObjectAt(int index) const; |
148 | |
149 | Heap::Module *instantiate(); |
150 | const Value *resolveExport(QV4::String *exportName) |
151 | { |
152 | QVector<ResolveSetEntry> resolveSet; |
153 | return resolveExportRecursively(exportName, resolveSet: &resolveSet); |
154 | } |
155 | |
156 | QStringList exportedNames() const |
157 | { |
158 | QStringList names; |
159 | QVector<const ExecutableCompilationUnit*> exportNameSet; |
160 | getExportedNamesRecursively(names: &names, exportNameSet: &exportNameSet); |
161 | names.sort(); |
162 | auto last = std::unique(first: names.begin(), last: names.end()); |
163 | names.erase(abegin: last, aend: names.end()); |
164 | return names; |
165 | } |
166 | |
167 | void evaluate(); |
168 | void evaluateModuleRequests(); |
169 | |
170 | void mark(MarkStack *markStack) const { markObjects(markStack); } |
171 | void markObjects(MarkStack *markStack) const; |
172 | |
173 | QString bindingValueAsString(const CompiledData::Binding *binding) const; |
174 | double bindingValueAsNumber(const CompiledData::Binding *binding) const |
175 | { |
176 | return m_compilationUnit->bindingValueAsNumber(binding); |
177 | } |
178 | QString bindingValueAsScriptString(const CompiledData::Binding *binding) const |
179 | { |
180 | return m_compilationUnit->bindingValueAsScriptString(binding); |
181 | } |
182 | |
183 | struct TranslationDataIndex |
184 | { |
185 | uint index; |
186 | bool byId; |
187 | }; |
188 | |
189 | QString translateFrom(TranslationDataIndex index) const; |
190 | |
191 | Heap::Module *module() const; |
192 | void setModule(Heap::Module *module); |
193 | |
194 | ReturnedValue value() const { return m_valueOrModule.asReturnedValue(); } |
195 | void setValue(const QV4::Value &value) { m_valueOrModule = value; } |
196 | |
197 | const CompiledData::Unit *unitData() const { return m_compilationUnit->data; } |
198 | |
199 | QString stringAt(uint index) const { return m_compilationUnit->stringAt(index); } |
200 | |
201 | const QVector<QQmlRefPointer<QQmlScriptData>> *dependentScriptsPtr() const |
202 | { |
203 | return &m_compilationUnit->dependentScripts; |
204 | } |
205 | |
206 | const CompiledData::BindingPropertyData *bindingPropertyDataPerObjectAt( |
207 | qsizetype objectIndex) const |
208 | { |
209 | return &m_compilationUnit->bindingPropertyDataPerObject.at(i: objectIndex); |
210 | } |
211 | |
212 | const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &baseCompilationUnit() const |
213 | { |
214 | return m_compilationUnit; |
215 | } |
216 | |
217 | QV4::Function *rootFunction() |
218 | { |
219 | if (!runtimeStrings) |
220 | populate(); |
221 | |
222 | const auto *data = unitData(); |
223 | return data->indexOfRootFunction != -1 |
224 | ? runtimeFunctions[data->indexOfRootFunction] |
225 | : nullptr; |
226 | } |
227 | |
228 | void populate(); |
229 | void clear(); |
230 | |
231 | protected: |
232 | quint32 totalStringCount() const |
233 | { return unitData()->stringTableSize; } |
234 | |
235 | private: |
236 | friend struct ExecutionEngine; |
237 | |
238 | QQmlRefPointer<CompiledData::CompilationUnit> m_compilationUnit; |
239 | Value m_valueOrModule = QV4::Value::emptyValue(); |
240 | |
241 | struct ResolveSetEntry |
242 | { |
243 | ResolveSetEntry() {} |
244 | ResolveSetEntry(ExecutableCompilationUnit *module, QV4::String *exportName) |
245 | : module(module), exportName(exportName) {} |
246 | ExecutableCompilationUnit *module = nullptr; |
247 | QV4::String *exportName = nullptr; |
248 | }; |
249 | |
250 | ExecutableCompilationUnit(); |
251 | ExecutableCompilationUnit(QQmlRefPointer<CompiledData::CompilationUnit> &&compilationUnit); |
252 | ~ExecutableCompilationUnit(); |
253 | |
254 | static QQmlRefPointer<ExecutableCompilationUnit> create( |
255 | QQmlRefPointer<CompiledData::CompilationUnit> &&compilationUnit, |
256 | ExecutionEngine *engine); |
257 | |
258 | const Value *resolveExportRecursively(QV4::String *exportName, |
259 | QVector<ResolveSetEntry> *resolveSet); |
260 | |
261 | QUrl urlAt(int index) const { return QUrl(stringAt(index)); } |
262 | |
263 | Q_NEVER_INLINE IdentifierHash createNamedObjectsPerComponent(int componentObjectIndex); |
264 | const CompiledData::ExportEntry *lookupNameInExportTable( |
265 | const CompiledData::ExportEntry *firstExportEntry, int tableSize, |
266 | QV4::String *name) const; |
267 | |
268 | void getExportedNamesRecursively( |
269 | QStringList *names, QVector<const ExecutableCompilationUnit *> *exportNameSet, |
270 | bool includeDefaultExport = true) const; |
271 | }; |
272 | |
273 | IdentifierHash ExecutableCompilationUnit::namedObjectsPerComponent(int componentObjectIndex) |
274 | { |
275 | auto it = namedObjectsPerComponentCache.constFind(key: componentObjectIndex); |
276 | if (Q_UNLIKELY(it == namedObjectsPerComponentCache.cend())) |
277 | return createNamedObjectsPerComponent(componentObjectIndex); |
278 | Q_ASSERT(!it->isEmpty()); |
279 | return *it; |
280 | } |
281 | |
282 | } // namespace QV4 |
283 | |
284 | QT_END_NAMESPACE |
285 | |
286 | #endif // QV4EXECUTABLECOMPILATIONUNIT_P_H |
287 |
Definitions
- CompilationUnitRuntimeData
- ExecutableCompilationUnit
- ExecutableCompilationUnit
- finalUrlString
- fileName
- url
- finalUrl
- typeNameCache
- propertyCachesPtr
- rootPropertyCache
- totalBindingsCount
- totalParserStatusCount
- totalObjectCount
- resolvedType
- qmlTypeForComponent
- metaType
- inlineComponentId
- nativeMethodsAcceptThisObjects
- ignoresFunctionSignature
- valueTypesAreCopied
- valueTypesAreAddressable
- valueTypesAreAssertable
- componentsAreBound
- isESModule
- objectCount
- objectAt
- resolveExport
- exportedNames
- mark
- bindingValueAsNumber
- bindingValueAsScriptString
- TranslationDataIndex
- value
- setValue
- unitData
- stringAt
- dependentScriptsPtr
- bindingPropertyDataPerObjectAt
- baseCompilationUnit
- rootFunction
- totalStringCount
- ResolveSetEntry
- ResolveSetEntry
- ResolveSetEntry
- urlAt
Learn to use CMake with our Intro Training
Find out more