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.h343
1 files changed, 148 insertions, 195 deletions
diff --git a/src/qml/jsruntime/qv4executablecompilationunit_p.h b/src/qml/jsruntime/qv4executablecompilationunit_p.h
index 1b1b9add5c..3f3335ef4e 100644
--- a/src/qml/jsruntime/qv4executablecompilationunit_p.h
+++ b/src/qml/jsruntime/qv4executablecompilationunit_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the tools applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QV4EXECUTABLECOMPILATIONUNIT_P_H
#define QV4EXECUTABLECOMPILATIONUNIT_P_H
@@ -51,202 +15,137 @@
// 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>
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<QQmlPropertyData*> BindingPropertyData;
-
class CompilationUnitMapper;
-class ResolvedTypeReference;
-// map from name index
-// While this could be a hash, a map is chosen here to provide a stable
-// order, which is used to calculating a check-sum on dependent meta-objects.
-struct ResolvedTypeReferenceMap: public QMap<int, ResolvedTypeReference*>
+
+struct CompilationUnitRuntimeData
{
- bool addToHash(QCryptographicHash *hash, QQmlEngine *engine) const;
+ Heap::String **runtimeStrings = nullptr; // Array
+
+ // 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;
+
+ 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;
};
-class Q_QML_PRIVATE_EXPORT ExecutableCompilationUnit final: public CompiledData::CompilationUnit,
- public QQmlRefCount
+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 *));
+
+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;
- static QQmlRefPointer<ExecutableCompilationUnit> create(
- CompiledData::CompilationUnit &&compilationUnit)
+ ExecutionEngine *engine = nullptr;
+
+ QString finalUrlString() const { return m_compilationUnit->finalUrlString(); }
+ QString fileName() const { return m_compilationUnit->fileName(); }
+
+ QUrl url() const { return m_compilationUnit->url(); }
+ QUrl finalUrl() const { return m_compilationUnit->finalUrl(); }
+
+ QQmlRefPointer<QQmlTypeNameCache> typeNameCache() const
{
- return QQmlRefPointer<ExecutableCompilationUnit>(
- new ExecutableCompilationUnit(std::move(compilationUnit)),
- QQmlRefPointer<ExecutableCompilationUnit>::Adopt);
+ return m_compilationUnit->typeNameCache;
}
- static QQmlRefPointer<ExecutableCompilationUnit> create()
+ QQmlPropertyCacheVector *propertyCachesPtr()
{
- return QQmlRefPointer<ExecutableCompilationUnit>(
- new ExecutableCompilationUnit,
- QQmlRefPointer<ExecutableCompilationUnit>::Adopt);
+ return &m_compilationUnit->propertyCaches;
}
- 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
+ QQmlPropertyCache::ConstPtr rootPropertyCache() const
{
- if (m_finalUrl.isNull)
- m_finalUrl = QUrl(finalUrlString());
- return m_finalUrl;
+ return m_compilationUnit->rootPropertyCache();
}
- 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;
- QQmlRefPointer<QQmlPropertyCache> 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;
-
- CompositeMetaTypeIds typeIdsForComponent(int objectid = 0) const;
-
- CompositeMetaTypeIds typeIds;
- bool isRegisteredWithEngine = false;
+ int totalBindingsCount() const { return m_compilationUnit->totalBindingsCount(); }
+ int totalParserStatusCount() const { return m_compilationUnit->totalParserStatusCount(); }
+ int totalObjectCount() const { return m_compilationUnit->totalObjectCount(); }
- QHash<int, InlineComponentData> inlineComponentData;
-
- QScopedPointer<CompilationUnitMapper> backingFile;
-
- // --- interface for QQmlPropertyCacheCreator
- using CompiledObject = CompiledData::Object;
- using CompiledFunction = CompiledData::Function;
-
- int objectCount() const { return qmlData->nObjects; }
- const CompiledObject *objectAt(int index) const
+ 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;
+ QMetaType metaType() const { return m_compilationUnit->qmlType.typeId(); }
- struct FunctionIterator
+ int inlineComponentId(const QString &inlineComponentName) const
{
- 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; }
- };
-
- FunctionIterator objectFunctionsBegin(const CompiledObject *object) 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 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;
@@ -267,25 +166,74 @@ public:
void evaluate();
void evaluateModuleRequests();
- QV4::Function *linkToEngine(QV4::ExecutionEngine *engine);
- void unlink();
+ 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
+ {
+ uint index;
+ bool byId;
+ };
+
+ QString translateFrom(TranslationDataIndex index) const;
- void markObjects(MarkStack *markStack);
+ Heap::Module *module() const { return m_module; }
+ void setModule(Heap::Module *module) { m_module = module; }
- bool loadFromDisk(const QUrl &url, const QDateTime &sourceTimeStamp, QString *errorString);
+ const CompiledData::Unit *unitData() const { return m_compilationUnit->data; }
- static QString localCacheFilePath(const QUrl &url);
- bool saveToDisk(const QUrl &unitUrl, QString *errorString);
+ QString stringAt(uint index) const { return m_compilationUnit->stringAt(index); }
- QString bindingValueAsString(const CompiledData::Binding *binding) const;
+ 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();
- static bool verifyHeader(const CompiledData::Unit *unit, QDateTime expectedSourceTimeStamp,
- QString *errorString);
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() {}
@@ -296,9 +244,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);
@@ -316,9 +268,10 @@ 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;
}