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
30QT_BEGIN_NAMESPACE
31
32class QQmlScriptData;
33class QQmlEnginePrivate;
34
35namespace QV4 {
36
37class CompilationUnitMapper;
38
39struct 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
57static_assert(std::is_standard_layout_v<CompilationUnitRuntimeData>);
58static_assert(offsetof(CompilationUnitRuntimeData, runtimeStrings) == 0);
59static_assert(offsetof(CompilationUnitRuntimeData, constants) == sizeof(QV4::Heap::String **));
60static_assert(offsetof(CompilationUnitRuntimeData, runtimeRegularExpressions) == offsetof(CompilationUnitRuntimeData, constants) + sizeof(const StaticValue *));
61static_assert(offsetof(CompilationUnitRuntimeData, runtimeClasses) == offsetof(CompilationUnitRuntimeData, runtimeRegularExpressions) + sizeof(const StaticValue *));
62static_assert(offsetof(CompilationUnitRuntimeData, imports) == offsetof(CompilationUnitRuntimeData, runtimeClasses) + sizeof(const StaticValue *));
63
64class Q_QML_EXPORT ExecutableCompilationUnit final
65 : public CompilationUnitRuntimeData,
66 public QQmlRefCounted<ExecutableCompilationUnit>
67{
68 Q_DISABLE_COPY_MOVE(ExecutableCompilationUnit)
69public:
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
231protected:
232 quint32 totalStringCount() const
233 { return unitData()->stringTableSize; }
234
235private:
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
273IdentifierHash 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
284QT_END_NAMESPACE
285
286#endif // QV4EXECUTABLECOMPILATIONUNIT_P_H
287

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of qtdeclarative/src/qml/jsruntime/qv4executablecompilationunit_p.h