Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qv4executablecompilationunit_p.h
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
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/qv4compileddata_p.h>
19#include <private/qv4identifierhash_p.h>
20#include <private/qqmlrefcount_p.h>
21#include <private/qintrusivelist_p.h>
22#include <private/qqmlpropertycachevector_p.h>
23#include <private/qqmltype_p.h>
24#include <private/qqmlnullablevalue_p.h>
25#include <private/qqmlmetatype_p.h>
26
27#include <memory>
28
30
31class QQmlScriptData;
33
35
46
48 int objectIndex = -1;
49 int nameIndex = -1;
53};
54
55namespace QV4 {
56
57// index is per-object binding index
59
62// map from name index
63struct ResolvedTypeReferenceMap: public QHash<int, ResolvedTypeReference*>
64{
66};
67
68class Q_QML_PRIVATE_EXPORT ExecutableCompilationUnit final
70 public QQmlRefCounted<ExecutableCompilationUnit>
71{
72 Q_DISABLE_COPY_MOVE(ExecutableCompilationUnit)
73public:
76
78 CompiledData::CompilationUnit &&compilationUnit)
79 {
81 new ExecutableCompilationUnit(std::move(compilationUnit)),
83 }
84
86 {
90 }
91
94
95 // url() and fileName() shall be used to load the actual QML/JS code or to show errors or
96 // warnings about that code. They include any potential URL interceptions and thus represent the
97 // "physical" location of the code.
98 //
99 // finalUrl() and finalUrlString() shall be used to resolve further URLs referred to in the code
100 // They are _not_ intercepted and thus represent the "logical" name for the code.
101
102 QUrl url() const { if (m_url.isNull) m_url = QUrl(fileName()); return m_url; }
104 {
105 if (m_finalUrl.isNull)
106 m_finalUrl = QUrl(finalUrlString());
107 return m_finalUrl;
108 }
109
110 QV4::Lookup *runtimeLookups = nullptr;
116
117 // QML specific fields
119 QQmlPropertyCache::ConstPtr rootPropertyCache() const { return propertyCaches.at(/*root object*/0); }
120
122
123 // index is object index. This allows fast access to the
124 // property data when initializing bindings, avoiding expensive
125 // lookups by string (property name).
127
128 // mapping from component object index (CompiledData::Unit object index that points to component) to identifier hash of named objects
129 // this is initialized on-demand by QQmlContextData
131 inline IdentifierHash namedObjectsPerComponent(int componentObjectIndex);
132
133 void finalizeCompositeType(const QQmlType &type);
134
135 int m_totalBindingsCount = 0; // Number of bindings used in this type
136 int m_totalParserStatusCount = 0; // Number of instantiated types that are QQmlParserStatus subclasses
137 int m_totalObjectCount = 0; // Number of objects explicitly instantiated
138 std::unique_ptr<QString> icRootName;
139
140 int totalBindingsCount() const;
141 int totalParserStatusCount() const;
142 int totalObjectCount() const;
143
146 ResolvedTypeReference *resolvedType(int id) const { return resolvedTypes.value(id); }
147
148 bool verifyChecksum(const CompiledData::DependentTypesHasher &dependencyHasher) const;
149
150 QQmlType qmlTypeForComponent(const QString &inlineComponentName = QString()) const;
151
153
155
156 int inlineComponentId(const QString &inlineComponentName) const
157 {
158 for (int i = 0; i < objectCount(); ++i) {
159 auto *object = objectAt(i);
160 for (auto it = object->inlineComponentsBegin(), end = object->inlineComponentsEnd();
161 it != end; ++it) {
162 if (stringAt(it->nameIndex) == inlineComponentName)
163 return it->objectIndex;
164 }
165 }
166 return -1;
167 }
168
169 std::unique_ptr<CompilationUnitMapper> backingFile;
170
171 // --- interface for QQmlPropertyCacheCreator
175 enum class ListPropertyAssignBehavior { Append, Replace, ReplaceIfNotDefault };
176
177 // Empty dummy. We don't need to do this when loading from cache.
179 {
180 public:
181 void insert(int, int) {}
182 void clear() {}
183
184 // We have already checked uniqueness of IDs when creating the CU
185 bool contains(int) { return false; }
186 };
187
189 {
190 if (data->flags & CompiledData::Unit::ListPropertyAssignReplace)
191 return ListPropertyAssignBehavior::Replace;
192 if (data->flags & CompiledData::Unit::ListPropertyAssignReplaceIfNotDefault)
193 return ListPropertyAssignBehavior::ReplaceIfNotDefault;
194 return ListPropertyAssignBehavior::Append;
195 }
196
198 {
199 return data->flags & CompiledData::Unit::FunctionSignaturesIgnored;
200 }
201
203 {
204 return data->flags & CompiledData::Unit::NativeMethodsAcceptThisObject;
205 }
206
208 {
209 return data->flags & CompiledData::Unit::ValueTypesCopied;
210 }
211
213 {
214 return data->flags & CompiledData::Unit::ValueTypesAddressable;
215 }
216
217 int objectCount() const { return qmlData->nObjects; }
218 const CompiledObject *objectAt(int index) const
219 {
220 return qmlData->objectAt(index);
221 }
222
223 int importCount() const { return qmlData->nImports; }
225 {
226 return qmlData->importAt(index);
227 }
228
229 Heap::Object *templateObjectAt(int index) const;
230
232 {
234 : unit(unit), object(object), index(index) {}
237 int index;
238
240 {
241 return unit->functionAt(object->functionOffsetTable()[index]);
242 }
243
244 void operator++() { ++index; }
245 bool operator==(const FunctionIterator &rhs) const { return index == rhs.index; }
246 bool operator!=(const FunctionIterator &rhs) const { return index != rhs.index; }
247 };
248
250 {
251 return FunctionIterator(data, object, 0);
252 }
253
255 {
256 return FunctionIterator(data, object, object->nFunctions);
257 }
258
259 bool isESModule() const
260 {
261 return data->flags & CompiledData::Unit::IsESModule;
262 }
263
264 bool isSharedLibrary() const
265 {
266 return data->flags & CompiledData::Unit::IsSharedLibrary;
267 }
268
269 QStringList moduleRequests() const;
270 Heap::Module *instantiate(ExecutionEngine *engine);
271 const Value *resolveExport(QV4::String *exportName)
272 {
273 QVector<ResolveSetEntry> resolveSet;
274 return resolveExportRecursively(exportName, &resolveSet);
275 }
276
278 {
281 getExportedNamesRecursively(&names, &exportNameSet);
282 names.sort();
283 auto last = std::unique(names.begin(), names.end());
284 names.erase(last, names.end());
285 return names;
286 }
287
288 void evaluate();
289 void evaluateModuleRequests();
290
292 void unlink();
293
294 void markObjects(MarkStack *markStack);
295
296 bool loadFromDisk(const QUrl &url, const QDateTime &sourceTimeStamp, QString *errorString);
297
298 static QString localCacheFilePath(const QUrl &url);
299 bool saveToDisk(const QUrl &unitUrl, QString *errorString);
300
301 QString bindingValueAsString(const CompiledData::Binding *binding) const;
302
304 {
306 bool byId;
307 };
308
309 QString translateFrom(TranslationDataIndex index) const;
310
311 static bool verifyHeader(const CompiledData::Unit *unit, QDateTime expectedSourceTimeStamp,
312 QString *errorString);
313protected:
315 { return data->stringTableSize; }
316
317private:
318 struct ResolveSetEntry
319 {
320 ResolveSetEntry() {}
321 ResolveSetEntry(ExecutableCompilationUnit *module, QV4::String *exportName)
322 : module(module), exportName(exportName) {}
323 ExecutableCompilationUnit *module = nullptr;
324 QV4::String *exportName = nullptr;
325 };
326
327 ExecutableCompilationUnit();
328 ExecutableCompilationUnit(CompiledData::CompilationUnit &&compilationUnit);
329 ~ExecutableCompilationUnit();
330
331 const Value *resolveExportRecursively(QV4::String *exportName,
332 QVector<ResolveSetEntry> *resolveSet);
333
334 QUrl urlAt(int index) const { return QUrl(stringAt(index)); }
335
336 Q_NEVER_INLINE IdentifierHash createNamedObjectsPerComponent(int componentObjectIndex);
337 const CompiledData::ExportEntry *lookupNameInExportTable(
338 const CompiledData::ExportEntry *firstExportEntry, int tableSize,
339 QV4::String *name) const;
340
341 void getExportedNamesRecursively(
343 bool includeDefaultExport = true) const;
344};
345
347{
348 auto it = namedObjectsPerComponentCache.find(componentObjectIndex);
350 return createNamedObjectsPerComponent(componentObjectIndex);
351 Q_ASSERT(!it->isEmpty());
352 return *it;
353}
354
355} // namespace QV4
356
358
359#endif // QV4EXECUTABLECOMPILATIONUNIT_P_H
\inmodule QtCore\reentrant
Definition qdatetime.h:257
\inmodule QtCore
Definition qhash.h:818
T value(const Key &key) const noexcept
Definition qhash.h:1044
Definition qlist.h:74
QQmlPropertyCache::ConstPtr at(int index) const
bool isEmpty() const
Definition qset.h:52
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
\inmodule QtCore
Definition qurl.h:94
static QQmlRefPointer< ExecutableCompilationUnit > create(CompiledData::CompilationUnit &&compilationUnit)
std::unique_ptr< CompilationUnitMapper > backingFile
const CompiledObject * objectAt(int index) const
QVector< QV4::Heap::Object * > templateObjects
const CompiledData::Import * importAt(int index) const
FunctionIterator objectFunctionsBegin(const CompiledObject *object) const
QHash< int, IdentifierHash > namedObjectsPerComponentCache
FunctionIterator objectFunctionsEnd(const CompiledObject *object) const
ResolvedTypeReference * resolvedType(int id) const
const Value * resolveExport(QV4::String *exportName)
QQmlPropertyCache::ConstPtr rootPropertyCache() const
QVector< QQmlRefPointer< QQmlScriptData > > dependentScripts
IdentifierHash namedObjectsPerComponent(int componentObjectIndex)
int inlineComponentId(const QString &inlineComponentName) const
QHash< QString, InlineComponentData > inlineComponentData
QVector< QV4::Heap::InternalClass * > runtimeBlocks
QQmlRefPointer< QQmlTypeNameCache > typeNameCache
ListPropertyAssignBehavior listPropertyAssignBehavior() const
QVector< BindingPropertyData > bindingPropertyDataPerObject
static QQmlRefPointer< ExecutableCompilationUnit > create()
QHash< int, QWidget * > hash
[35multi]
QSet< QString >::iterator it
Combined button and popup list for selecting options.
std::function< QByteArray()> DependentTypesHasher
\qmltype Particle \inqmlmodule QtQuick.Particles
QVector< const QQmlPropertyData * > BindingPropertyData
#define Q_UNLIKELY(x)
#define Q_NEVER_INLINE
GLuint index
[2]
GLuint GLuint end
GLuint object
[3]
GLenum type
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint name
GLuint GLuint * names
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
unsigned int quint32
Definition qtypes.h:45
unsigned int uint
Definition qtypes.h:29
QUrl url("example.com")
[constructor-url-reference]
engine evaluate("var myObject = new MyObject()")
[8]
QJSEngine engine
[0]
InlineComponentData(const QQmlType &qmlType, int objectIndex, int nameIndex, int totalObjectCount, int totalBindingCount, int totalParserStatusCount)
InlineComponentData()=default
const Function * functionAt(int idx) const
FunctionIterator(const CompiledData::Unit *unit, const CompiledObject *object, int index)
bool addToHash(QCryptographicHash *hash, QHash< quintptr, QByteArray > *checksums) const