aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4executablecompilationunit_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/jsruntime/qv4executablecompilationunit_p.h')
-rw-r--r--src/qml/jsruntime/qv4executablecompilationunit_p.h315
1 files changed, 136 insertions, 179 deletions
diff --git a/src/qml/jsruntime/qv4executablecompilationunit_p.h b/src/qml/jsruntime/qv4executablecompilationunit_p.h
index e6472f3f83..930e138732 100644
--- a/src/qml/jsruntime/qv4executablecompilationunit_p.h
+++ b/src/qml/jsruntime/qv4executablecompilationunit_p.h
@@ -15,14 +15,15 @@
// We mean it.
//
-#include <private/qv4compileddata_p.h>
-#include <private/qv4identifierhash_p.h>
-#include <private/qqmlrefcount_p.h>
#include <private/qintrusivelist_p.h>
+#include <private/qqmlmetatype_p.h>
+#include <private/qqmlnullablevalue_p.h>
#include <private/qqmlpropertycachevector_p.h>
+#include <private/qqmlrefcount_p.h>
#include <private/qqmltype_p.h>
-#include <private/qqmlnullablevalue_p.h>
-#include <private/qqmlmetatype_p.h>
+#include <private/qqmltypenamecache_p.h>
+#include <private/qv4compileddata_p.h>
+#include <private/qv4identifierhash_p.h>
#include <memory>
@@ -31,210 +32,121 @@ QT_BEGIN_NAMESPACE
class QQmlScriptData;
class QQmlEnginePrivate;
-struct InlineComponentData {
-
- InlineComponentData() = default;
- InlineComponentData(const CompositeMetaTypeIds &typeIds, int objectIndex, int nameIndex, int totalObjectCount, int totalBindingCount, int totalParserStatusCount)
- : typeIds(typeIds)
- , objectIndex(objectIndex)
- , nameIndex(nameIndex)
- , totalObjectCount(totalObjectCount)
- , totalBindingCount(totalBindingCount)
- , totalParserStatusCount(totalParserStatusCount) {}
-
- CompositeMetaTypeIds typeIds;
- int objectIndex = -1;
- int nameIndex = -1;
- int totalObjectCount = 0;
- int totalBindingCount = 0;
- int totalParserStatusCount = 0;
-};
-
namespace QV4 {
-// index is per-object binding index
-typedef QVector<const QQmlPropertyData *> BindingPropertyData;
-
class CompilationUnitMapper;
-class ResolvedTypeReference;
-// map from name index
-struct ResolvedTypeReferenceMap: public QHash<int, ResolvedTypeReference*>
-{
- bool addToHash(QCryptographicHash *hash, QHash<quintptr, QByteArray> *checksums) const;
-};
-class Q_QML_PRIVATE_EXPORT ExecutableCompilationUnit final: public CompiledData::CompilationUnit,
- public QQmlRefCount
+struct CompilationUnitRuntimeData
{
- Q_DISABLE_COPY_MOVE(ExecutableCompilationUnit)
-public:
- friend class QQmlRefPointer<ExecutableCompilationUnit>;
-
- static QQmlRefPointer<ExecutableCompilationUnit> create(
- CompiledData::CompilationUnit &&compilationUnit)
- {
- return QQmlRefPointer<ExecutableCompilationUnit>(
- new ExecutableCompilationUnit(std::move(compilationUnit)),
- QQmlRefPointer<ExecutableCompilationUnit>::Adopt);
- }
+ Heap::String **runtimeStrings = nullptr; // Array
- static QQmlRefPointer<ExecutableCompilationUnit> create()
- {
- return QQmlRefPointer<ExecutableCompilationUnit>(
- new ExecutableCompilationUnit,
- QQmlRefPointer<ExecutableCompilationUnit>::Adopt);
- }
+ // pointers either to data->constants() or little-endian memory copy.
+ // We keep this member twice so that the JIT can access it via standard layout.
+ const StaticValue *constants = nullptr;
- QIntrusiveListNode nextCompilationUnit;
- ExecutionEngine *engine = nullptr;
- QQmlEnginePrivate *qmlEngine = nullptr; // only used in QML environment for composite types, not in plain QJSEngine case.
-
- // url() and fileName() shall be used to load the actual QML/JS code or to show errors or
- // warnings about that code. They include any potential URL interceptions and thus represent the
- // "physical" location of the code.
- //
- // finalUrl() and finalUrlString() shall be used to resolve further URLs referred to in the code
- // They are _not_ intercepted and thus represent the "logical" name for the code.
-
- QUrl url() const { if (m_url.isNull) m_url = QUrl(fileName()); return m_url; }
- QUrl finalUrl() const
- {
- if (m_finalUrl.isNull)
- m_finalUrl = QUrl(finalUrlString());
- return m_finalUrl;
- }
+ QV4::StaticValue *runtimeRegularExpressions = nullptr;
+ Heap::InternalClass **runtimeClasses = nullptr;
+ const StaticValue **imports = nullptr;
QV4::Lookup *runtimeLookups = nullptr;
QVector<QV4::Function *> runtimeFunctions;
QVector<QV4::Heap::InternalClass *> runtimeBlocks;
mutable QVector<QV4::Heap::Object *> templateObjects;
- mutable QQmlNullableValue<QUrl> m_url;
- mutable QQmlNullableValue<QUrl> m_finalUrl;
-
- // QML specific fields
- QQmlPropertyCacheVector propertyCaches;
- QQmlPropertyCache::ConstPtr rootPropertyCache() const { return propertyCaches.at(/*root object*/0); }
-
- QQmlRefPointer<QQmlTypeNameCache> typeNameCache;
-
- // index is object index. This allows fast access to the
- // property data when initializing bindings, avoiding expensive
- // lookups by string (property name).
- QVector<BindingPropertyData> bindingPropertyDataPerObject;
-
- // mapping from component object index (CompiledData::Unit object index that points to component) to identifier hash of named objects
- // this is initialized on-demand by QQmlContextData
- QHash<int, IdentifierHash> namedObjectsPerComponentCache;
- inline IdentifierHash namedObjectsPerComponent(int componentObjectIndex);
-
- void finalizeCompositeType(QQmlEnginePrivate *qmlEngine, CompositeMetaTypeIds typeIdsForComponent);
-
- int m_totalBindingsCount = 0; // Number of bindings used in this type
- int m_totalParserStatusCount = 0; // Number of instantiated types that are QQmlParserStatus subclasses
- int m_totalObjectCount = 0; // Number of objects explicitly instantiated
- int icRoot = -1;
-
- int totalBindingsCount() const;
- int totalParserStatusCount() const;
- int totalObjectCount() const;
-
- QVector<QQmlRefPointer<QQmlScriptData>> dependentScripts;
- ResolvedTypeReferenceMap resolvedTypes;
- ResolvedTypeReference *resolvedType(int id) const { return resolvedTypes.value(id); }
+};
- bool verifyChecksum(const CompiledData::DependentTypesHasher &dependencyHasher) const;
+static_assert(std::is_standard_layout_v<CompilationUnitRuntimeData>);
+static_assert(offsetof(CompilationUnitRuntimeData, runtimeStrings) == 0);
+static_assert(offsetof(CompilationUnitRuntimeData, constants) == sizeof(QV4::Heap::String **));
+static_assert(offsetof(CompilationUnitRuntimeData, runtimeRegularExpressions) == offsetof(CompilationUnitRuntimeData, constants) + sizeof(const StaticValue *));
+static_assert(offsetof(CompilationUnitRuntimeData, runtimeClasses) == offsetof(CompilationUnitRuntimeData, runtimeRegularExpressions) + sizeof(const StaticValue *));
+static_assert(offsetof(CompilationUnitRuntimeData, imports) == offsetof(CompilationUnitRuntimeData, runtimeClasses) + sizeof(const StaticValue *));
- CompositeMetaTypeIds typeIdsForComponent(int objectid = 0) const;
+class Q_QML_EXPORT ExecutableCompilationUnit final
+ : public CompilationUnitRuntimeData,
+ public QQmlRefCounted<ExecutableCompilationUnit>
+{
+ Q_DISABLE_COPY_MOVE(ExecutableCompilationUnit)
+public:
+ friend class QQmlRefCounted<ExecutableCompilationUnit>;
+ friend class QQmlRefPointer<ExecutableCompilationUnit>;
+ friend struct ExecutionEngine;
- CompositeMetaTypeIds typeIds;
- bool isRegistered = false;
+ ExecutionEngine *engine = nullptr;
- QHash<int, InlineComponentData> inlineComponentData;
+ QString finalUrlString() const { return m_compilationUnit->finalUrlString(); }
+ QString fileName() const { return m_compilationUnit->fileName(); }
- std::unique_ptr<CompilationUnitMapper> backingFile;
+ QUrl url() const { return m_compilationUnit->url(); }
+ QUrl finalUrl() const { return m_compilationUnit->finalUrl(); }
- // --- interface for QQmlPropertyCacheCreator
- using CompiledObject = CompiledData::Object;
- using CompiledFunction = CompiledData::Function;
- enum class ListPropertyAssignBehavior { Append, Replace, ReplaceIfNotDefault };
- ListPropertyAssignBehavior listPropertyAssignBehavior() const
+ QQmlRefPointer<QQmlTypeNameCache> typeNameCache() const
{
- if (data->flags & CompiledData::Unit::ListPropertyAssignReplace)
- return ListPropertyAssignBehavior::Replace;
- if (data->flags & CompiledData::Unit::ListPropertyAssignReplaceIfNotDefault)
- return ListPropertyAssignBehavior::ReplaceIfNotDefault;
- return ListPropertyAssignBehavior::Append;
+ return m_compilationUnit->typeNameCache;
}
- bool enforcesFunctionSignature() const
+ QQmlPropertyCacheVector *propertyCachesPtr()
{
- return data->flags & CompiledData::Unit::FunctionSignaturesEnforced;
+ return &m_compilationUnit->propertyCaches;
}
- bool nativeMethodsAcceptThisObjects() const
+ QQmlPropertyCache::ConstPtr rootPropertyCache() const
{
- return data->flags & CompiledData::Unit::NativeMethodsAcceptThisObject;
+ return m_compilationUnit->rootPropertyCache();
}
- bool valueTypesAreCopied() const
- {
- return data->flags & CompiledData::Unit::ValueTypesCopied;
- }
+ // mapping from component object index (CompiledData::Unit object index that points to component) to identifier hash of named objects
+ // this is initialized on-demand by QQmlContextData
+ QHash<int, IdentifierHash> namedObjectsPerComponentCache;
+ inline IdentifierHash namedObjectsPerComponent(int componentObjectIndex);
- int objectCount() const { return qmlData->nObjects; }
- const CompiledObject *objectAt(int index) const
+ int totalBindingsCount() const { return m_compilationUnit->totalBindingsCount(); }
+ int totalParserStatusCount() const { return m_compilationUnit->totalParserStatusCount(); }
+ int totalObjectCount() const { return m_compilationUnit->totalObjectCount(); }
+
+ ResolvedTypeReference *resolvedType(int id) const
{
- return qmlData->objectAt(index);
+ return m_compilationUnit->resolvedType(id);
}
- int importCount() const { return qmlData->nImports; }
- const CompiledData::Import *importAt(int index) const
+ QQmlType qmlTypeForComponent(const QString &inlineComponentName = QString()) const
{
- return qmlData->importAt(index);
+ return m_compilationUnit->qmlTypeForComponent(inlineComponentName);
}
- Heap::Object *templateObjectAt(int index) const;
-
- struct FunctionIterator
- {
- FunctionIterator(const CompiledData::Unit *unit, const CompiledObject *object, int index)
- : unit(unit), object(object), index(index) {}
- const CompiledData::Unit *unit;
- const CompiledObject *object;
- int index;
-
- const CompiledFunction *operator->() const
- {
- return unit->functionAt(object->functionOffsetTable()[index]);
- }
-
- void operator++() { ++index; }
- bool operator==(const FunctionIterator &rhs) const { return index == rhs.index; }
- bool operator!=(const FunctionIterator &rhs) const { return index != rhs.index; }
- };
+ QMetaType metaType() const { return m_compilationUnit->qmlType.typeId(); }
- FunctionIterator objectFunctionsBegin(const CompiledObject *object) const
+ int inlineComponentId(const QString &inlineComponentName) const
{
- return FunctionIterator(data, object, 0);
+ return m_compilationUnit->inlineComponentId(inlineComponentName);
}
- FunctionIterator objectFunctionsEnd(const CompiledObject *object) const
- {
- return FunctionIterator(data, object, object->nFunctions);
- }
+ // --- interface for QQmlPropertyCacheCreator
+ using CompiledObject = CompiledData::CompilationUnit::CompiledObject;
+ using CompiledFunction = CompiledData::CompilationUnit::CompiledFunction;
+ using CompiledBinding = CompiledData::CompilationUnit::CompiledBinding;
+ using IdToObjectMap = CompiledData::CompilationUnit::IdToObjectMap;
- bool isESModule() const
+ bool nativeMethodsAcceptThisObjects() const
{
- return data->flags & CompiledData::Unit::IsESModule;
+ return m_compilationUnit->nativeMethodsAcceptThisObjects();
}
- bool isSharedLibrary() const
+ bool ignoresFunctionSignature() const { return m_compilationUnit->ignoresFunctionSignature(); }
+ bool valueTypesAreCopied() const { return m_compilationUnit->valueTypesAreCopied(); }
+ bool valueTypesAreAddressable() const { return m_compilationUnit->valueTypesAreAddressable(); }
+ bool valueTypesAreAssertable() const { return m_compilationUnit->valueTypesAreAssertable(); }
+ bool componentsAreBound() const { return m_compilationUnit->componentsAreBound(); }
+ bool isESModule() const { return m_compilationUnit->isESModule(); }
+
+ int objectCount() const { return m_compilationUnit->objectCount(); }
+ const CompiledObject *objectAt(int index) const
{
- return data->flags & CompiledData::Unit::IsSharedLibrary;
+ return m_compilationUnit->objectAt(index);
}
- QStringList moduleRequests() const;
- Heap::Module *instantiate(ExecutionEngine *engine);
+ Heap::Object *templateObjectAt(int index) const;
+
+ Heap::Module *instantiate();
const Value *resolveExport(QV4::String *exportName)
{
QVector<ResolveSetEntry> resolveSet;
@@ -255,17 +167,18 @@ public:
void evaluate();
void evaluateModuleRequests();
- QV4::Function *linkToEngine(QV4::ExecutionEngine *engine);
- void unlink();
-
- void markObjects(MarkStack *markStack);
-
- bool loadFromDisk(const QUrl &url, const QDateTime &sourceTimeStamp, QString *errorString);
-
- static QString localCacheFilePath(const QUrl &url);
- bool saveToDisk(const QUrl &unitUrl, QString *errorString);
+ void mark(MarkStack *markStack) const { markObjects(markStack); }
+ void markObjects(MarkStack *markStack) const;
QString bindingValueAsString(const CompiledData::Binding *binding) const;
+ double bindingValueAsNumber(const CompiledData::Binding *binding) const
+ {
+ return m_compilationUnit->bindingValueAsNumber(binding);
+ }
+ QString bindingValueAsScriptString(const CompiledData::Binding *binding) const
+ {
+ return m_compilationUnit->bindingValueAsScriptString(binding);
+ }
struct TranslationDataIndex
{
@@ -275,13 +188,53 @@ public:
QString translateFrom(TranslationDataIndex index) const;
- static bool verifyHeader(const CompiledData::Unit *unit, QDateTime expectedSourceTimeStamp,
- QString *errorString);
+ Heap::Module *module() const { return m_module; }
+ void setModule(Heap::Module *module) { m_module = module; }
+
+ const CompiledData::Unit *unitData() const { return m_compilationUnit->data; }
+
+ QString stringAt(uint index) const { return m_compilationUnit->stringAt(index); }
+
+ const QVector<QQmlRefPointer<QQmlScriptData>> *dependentScriptsPtr() const
+ {
+ return &m_compilationUnit->dependentScripts;
+ }
+
+ const CompiledData::BindingPropertyData *bindingPropertyDataPerObjectAt(
+ qsizetype objectIndex) const
+ {
+ return &m_compilationUnit->bindingPropertyDataPerObject.at(objectIndex);
+ }
+
+ const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &baseCompilationUnit() const
+ {
+ return m_compilationUnit;
+ }
+
+ QV4::Function *rootFunction()
+ {
+ if (!runtimeStrings)
+ populate();
+
+ const auto *data = unitData();
+ return data->indexOfRootFunction != -1
+ ? runtimeFunctions[data->indexOfRootFunction]
+ : nullptr;
+ }
+
+ void populate();
+ void clear();
+
protected:
quint32 totalStringCount() const
- { return data->stringTableSize; }
+ { return unitData()->stringTableSize; }
private:
+ friend struct ExecutionEngine;
+
+ QQmlRefPointer<CompiledData::CompilationUnit> m_compilationUnit;
+ Heap::Module *m_module = nullptr;
+
struct ResolveSetEntry
{
ResolveSetEntry() {}
@@ -292,9 +245,13 @@ private:
};
ExecutableCompilationUnit();
- ExecutableCompilationUnit(CompiledData::CompilationUnit &&compilationUnit);
+ ExecutableCompilationUnit(QQmlRefPointer<CompiledData::CompilationUnit> &&compilationUnit);
~ExecutableCompilationUnit();
+ static QQmlRefPointer<ExecutableCompilationUnit> create(
+ QQmlRefPointer<CompiledData::CompilationUnit> &&compilationUnit,
+ ExecutionEngine *engine);
+
const Value *resolveExportRecursively(QV4::String *exportName,
QVector<ResolveSetEntry> *resolveSet);
@@ -312,8 +269,8 @@ private:
IdentifierHash ExecutableCompilationUnit::namedObjectsPerComponent(int componentObjectIndex)
{
- auto it = namedObjectsPerComponentCache.find(componentObjectIndex);
- if (Q_UNLIKELY(it == namedObjectsPerComponentCache.end()))
+ auto it = namedObjectsPerComponentCache.constFind(componentObjectIndex);
+ if (Q_UNLIKELY(it == namedObjectsPerComponentCache.cend()))
return createNamedObjectsPerComponent(componentObjectIndex);
Q_ASSERT(!it->isEmpty());
return *it;