aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4executablecompilationunit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/jsruntime/qv4executablecompilationunit.cpp')
-rw-r--r--src/qml/jsruntime/qv4executablecompilationunit.cpp111
1 files changed, 99 insertions, 12 deletions
diff --git a/src/qml/jsruntime/qv4executablecompilationunit.cpp b/src/qml/jsruntime/qv4executablecompilationunit.cpp
index b1e2879bba..fa4a1f1ce4 100644
--- a/src/qml/jsruntime/qv4executablecompilationunit.cpp
+++ b/src/qml/jsruntime/qv4executablecompilationunit.cpp
@@ -53,6 +53,7 @@
#include <private/qv4compilationunitmapper_p.h>
#include <private/qml_compile_hash_p.h>
#include <private/qqmltypewrapper_p.h>
+#include <private/inlinecomponentutils_p.h>
#include <QtQml/qqmlfile.h>
#include <QtQml/qqmlpropertymap.h>
@@ -62,6 +63,7 @@
#include <QtCore/qfileinfo.h>
#include <QtCore/qscopeguard.h>
#include <QtCore/qcryptographichash.h>
+#include <QtCore/QScopedValueRollback>
#if defined(QML_COMPILE_HASH)
# ifdef Q_OS_LINUX
@@ -387,7 +389,7 @@ IdentifierHash ExecutableCompilationUnit::createNamedObjectsPerComponent(int com
return *namedObjectsPerComponentCache.insert(componentObjectIndex, namedObjectCache);
}
-void ExecutableCompilationUnit::finalizeCompositeType(QQmlEnginePrivate *qmlEngine, QQmlMetaType::CompositeMetaTypeIds typeIds)
+void ExecutableCompilationUnit::finalizeCompositeType(QQmlEnginePrivate *qmlEngine, CompositeMetaTypeIds typeIds)
{
this->qmlEngine = qmlEngine;
@@ -399,6 +401,7 @@ void ExecutableCompilationUnit::finalizeCompositeType(QQmlEnginePrivate *qmlEngi
metaTypeId = typeIds.id;
listMetaTypeId = typeIds.listId;
qmlEngine->registerInternalCompositeType(this);
+
} else {
const QV4::CompiledData::Object *obj = objectAt(/*root object*/0);
auto *typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex);
@@ -413,29 +416,105 @@ void ExecutableCompilationUnit::finalizeCompositeType(QQmlEnginePrivate *qmlEngi
}
// Collect some data for instantiation later.
+ using namespace icutils;
+ std::vector<QV4::CompiledData::InlineComponent> allICs {};
+ for (int i=0; i != objectCount(); ++i) {
+ const CompiledObject *obj = objectAt(i);
+ for (auto it = obj->inlineComponentsBegin(); it != obj->inlineComponentsEnd(); ++it) {
+ allICs.push_back(*it);
+ }
+ }
+ std::vector<Node> nodes;
+ nodes.resize(allICs.size());
+ std::iota(nodes.begin(), nodes.end(), 0);
+ AdjacencyList adjacencyList;
+ adjacencyList.resize(nodes.size());
+ fillAdjacencyListForInlineComponents(this, adjacencyList, nodes, allICs);
+ bool hasCycle = false;
+ auto nodesSorted = topoSort(nodes, adjacencyList, hasCycle);
+ Q_ASSERT(!hasCycle); // would have already been discovered by qqmlpropertycachcecreator
+
+ // We need to first iterate over all inline components, as the containing component might create instances of them
+ // and in that case we need to add its object count
+ for (auto nodeIt = nodesSorted.rbegin(); nodeIt != nodesSorted.rend(); ++nodeIt) {
+ const auto &ic = allICs.at(nodeIt->index);
+ int lastICRoot = ic.objectIndex;
+ for (int i = ic.objectIndex; i<objectCount(); ++i) {
+ const QV4::CompiledData::Object *obj = objectAt(i);
+ bool leftCurrentInlineComponent =
+ (i != lastICRoot && obj->flags & QV4::CompiledData::Object::IsInlineComponentRoot)
+ || !(obj->flags & QV4::CompiledData::Object::InPartOfInlineComponent);
+ if (leftCurrentInlineComponent)
+ break;
+ inlineComponentData[lastICRoot].totalBindingCount += obj->nBindings;
+
+ if (auto *typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex)) {
+ if (typeRef->type.isValid() && typeRef->type.parserStatusCast() != -1)
+ ++inlineComponentData[lastICRoot].totalParserStatusCount;
+
+ ++inlineComponentData[lastICRoot].totalObjectCount;
+ if (typeRef->compilationUnit) {
+ // if the type is an inline component type, we have to extract the information from it
+ // This requires that inline components are visited in the correct order
+ auto icRoot = typeRef->compilationUnit->icRoot;
+ if (typeRef->type.isInlineComponentType()) {
+ icRoot = typeRef->type.inlineComponendId();
+ }
+ QScopedValueRollback<int> rollback {typeRef->compilationUnit->icRoot, icRoot};
+ inlineComponentData[lastICRoot].totalBindingCount += typeRef->compilationUnit->totalBindingsCount();
+ inlineComponentData[lastICRoot].totalParserStatusCount += typeRef->compilationUnit->totalParserStatusCount();
+ inlineComponentData[lastICRoot].totalObjectCount += typeRef->compilationUnit->totalObjectCount();
+ }
+ }
+ }
+ }
int bindingCount = 0;
int parserStatusCount = 0;
int objectCount = 0;
for (quint32 i = 0, count = this->objectCount(); i < count; ++i) {
const QV4::CompiledData::Object *obj = objectAt(i);
+ if (obj->flags & QV4::CompiledData::Object::InPartOfInlineComponent) {
+ continue;
+ }
bindingCount += obj->nBindings;
if (auto *typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex)) {
- if (typeRef->type.isValid()) {
- if (typeRef->type.parserStatusCast() != -1)
- ++parserStatusCount;
- }
+ if (typeRef->type.isValid() && typeRef->type.parserStatusCast() != -1)
+ ++parserStatusCount;
++objectCount;
if (typeRef->compilationUnit) {
- bindingCount += typeRef->compilationUnit->totalBindingsCount;
- parserStatusCount += typeRef->compilationUnit->totalParserStatusCount;
- objectCount += typeRef->compilationUnit->totalObjectCount;
+ auto icRoot = typeRef->compilationUnit->icRoot;
+ if (typeRef->type.isInlineComponentType()) {
+ icRoot = typeRef->type.inlineComponendId();
+ }
+ QScopedValueRollback<int> rollback {typeRef->compilationUnit->icRoot, icRoot};
+ bindingCount += typeRef->compilationUnit->totalBindingsCount();
+ parserStatusCount += typeRef->compilationUnit->totalParserStatusCount();
+ objectCount += typeRef->compilationUnit->totalObjectCount();
}
}
}
- totalBindingsCount = bindingCount;
- totalParserStatusCount = parserStatusCount;
- totalObjectCount = objectCount;
+ m_totalBindingsCount = bindingCount;
+ m_totalParserStatusCount = parserStatusCount;
+ m_totalObjectCount = objectCount;
+}
+
+int ExecutableCompilationUnit::totalBindingsCount() const {
+ if (icRoot == -1)
+ return m_totalBindingsCount;
+ return inlineComponentData[icRoot].totalBindingCount;
+}
+
+int ExecutableCompilationUnit::totalObjectCount() const {
+ if (icRoot == -1)
+ return m_totalObjectCount;
+ return inlineComponentData[icRoot].totalObjectCount;
+}
+
+int ExecutableCompilationUnit::totalParserStatusCount() const {
+ if (icRoot == -1)
+ return m_totalParserStatusCount;
+ return inlineComponentData[icRoot].totalParserStatusCount;
}
bool ExecutableCompilationUnit::verifyChecksum(const CompiledData::DependentTypesHasher &dependencyHasher) const
@@ -453,6 +532,13 @@ bool ExecutableCompilationUnit::verifyChecksum(const CompiledData::DependentType
sizeof(data->dependencyMD5Checksum)) == 0;
}
+CompositeMetaTypeIds ExecutableCompilationUnit::typeIdsForComponent(int objectid) const
+{
+ if (objectid == 0)
+ return {metaTypeId, listMetaTypeId};
+ return inlineComponentData[objectid].typeIds;
+}
+
QStringList ExecutableCompilationUnit::moduleRequests() const
{
QStringList requests;
@@ -734,13 +820,14 @@ QQmlRefPointer<QQmlPropertyCache> ResolvedTypeReference::createPropertyCache(QQm
typePropertyCache = QQmlEnginePrivate::get(engine)->cache(type.metaObject(), minorVersion);
return typePropertyCache;
} else {
+ Q_ASSERT(compilationUnit);
return compilationUnit->rootPropertyCache();
}
}
bool ResolvedTypeReference::addToHash(QCryptographicHash *hash, QQmlEngine *engine)
{
- if (type.isValid()) {
+ if (type.isValid() && !type.isInlineComponentType()) {
bool ok = false;
hash->addData(createPropertyCache(engine)->checksum(&ok));
return ok;