QtQml: Move ResolvedTypeReference into base CU
Change-Id: I25063457aad3a6d29a8c2a5b236f9a51b56a2f51 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
parent
21cf487816
commit
c225e23e00
|
@ -3,9 +3,10 @@
|
|||
|
||||
#include "qv4compileddata_p.h"
|
||||
|
||||
#include <private/qv4resolvedtypereference_p.h>
|
||||
|
||||
#include <QtQml/qqmlfile.h>
|
||||
|
||||
#include <QtCore/qcryptographichash.h>
|
||||
#include <QtCore/qdir.h>
|
||||
#include <QtCore/qscopeguard.h>
|
||||
#include <QtCore/qstandardpaths.h>
|
||||
|
@ -15,6 +16,48 @@ QT_BEGIN_NAMESPACE
|
|||
namespace QV4 {
|
||||
namespace CompiledData {
|
||||
|
||||
/*!
|
||||
\internal
|
||||
This function creates a temporary key vector and sorts it to guarantuee a stable
|
||||
hash. This is used to calculate a check-sum on dependent meta-objects.
|
||||
*/
|
||||
bool ResolvedTypeReferenceMap::addToHash(
|
||||
QCryptographicHash *hash, QHash<quintptr, QByteArray> *checksums) const
|
||||
{
|
||||
std::vector<int> keys (size());
|
||||
int i = 0;
|
||||
for (auto it = constBegin(), end = constEnd(); it != end; ++it) {
|
||||
keys[i] = it.key();
|
||||
++i;
|
||||
}
|
||||
std::sort(keys.begin(), keys.end());
|
||||
for (int key: keys) {
|
||||
if (!this->operator[](key)->addToHash(hash, checksums))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CompilationUnit::~CompilationUnit()
|
||||
{
|
||||
qDeleteAll(resolvedTypes);
|
||||
|
||||
if (data) {
|
||||
if (data->qmlUnit() != qmlData)
|
||||
free(const_cast<QmlUnit *>(qmlData));
|
||||
qmlData = nullptr;
|
||||
|
||||
if (!(data->flags & QV4::CompiledData::Unit::StaticData))
|
||||
free(const_cast<Unit *>(data));
|
||||
}
|
||||
data = nullptr;
|
||||
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
|
||||
delete [] constants;
|
||||
constants = nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
QString CompilationUnit::localCacheFilePath(const QUrl &url)
|
||||
{
|
||||
static const QByteArray envCachePath = qgetenv("QML_DISK_CACHE_PATH");
|
||||
|
@ -117,6 +160,16 @@ QStringList CompilationUnit::moduleRequests() const
|
|||
return requests;
|
||||
}
|
||||
|
||||
ResolvedTypeReference *CompilationUnit::resolvedType(QMetaType type) const
|
||||
{
|
||||
for (ResolvedTypeReference *ref : std::as_const(resolvedTypes)) {
|
||||
if (ref->type().typeId() == type)
|
||||
return ref;
|
||||
}
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
|
||||
} // namespace CompiledData
|
||||
} // namespace QV4
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include <functional>
|
||||
|
||||
#include <QtCore/qcryptographichash.h>
|
||||
#include <QtCore/qhash.h>
|
||||
#include <QtCore/qhashfunctions.h>
|
||||
#include <QtCore/qlocale.h>
|
||||
|
@ -74,12 +75,19 @@ struct InternalClass;
|
|||
|
||||
struct Function;
|
||||
class EvalISelFactory;
|
||||
class ResolvedTypeReference;
|
||||
|
||||
namespace CompiledData {
|
||||
|
||||
// index is per-object binding index
|
||||
using BindingPropertyData = QVector<const QQmlPropertyData *>;
|
||||
|
||||
// map from name index
|
||||
struct ResolvedTypeReferenceMap: public QHash<int, ResolvedTypeReference*>
|
||||
{
|
||||
bool addToHash(QCryptographicHash *hash, QHash<quintptr, QByteArray> *checksums) const;
|
||||
};
|
||||
|
||||
struct String;
|
||||
struct Function;
|
||||
struct Lookup;
|
||||
|
@ -1473,6 +1481,8 @@ struct CompilationUnit final : public QQmlRefCounted<CompilationUnit>
|
|||
// lookups by string (property name).
|
||||
QVector<BindingPropertyData> bindingPropertyDataPerObject;
|
||||
|
||||
ResolvedTypeReferenceMap resolvedTypes;
|
||||
|
||||
public:
|
||||
using CompiledObject = CompiledData::Object;
|
||||
|
||||
|
@ -1489,22 +1499,7 @@ public:
|
|||
this->aotCompiledFunctions = aotCompiledFunctions;
|
||||
}
|
||||
|
||||
~CompilationUnit()
|
||||
{
|
||||
if (data) {
|
||||
if (data->qmlUnit() != qmlData)
|
||||
free(const_cast<QmlUnit *>(qmlData));
|
||||
qmlData = nullptr;
|
||||
|
||||
if (!(data->flags & QV4::CompiledData::Unit::StaticData))
|
||||
free(const_cast<Unit *>(data));
|
||||
}
|
||||
data = nullptr;
|
||||
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
|
||||
delete [] constants;
|
||||
constants = nullptr;
|
||||
#endif
|
||||
}
|
||||
Q_QML_EXPORT ~CompilationUnit();
|
||||
|
||||
const Unit *unitData() const { return data; }
|
||||
|
||||
|
@ -1620,6 +1615,9 @@ public:
|
|||
return m_finalUrl;
|
||||
}
|
||||
|
||||
ResolvedTypeReference *resolvedType(int id) const { return resolvedTypes.value(id); }
|
||||
ResolvedTypeReference *resolvedType(QMetaType type) const;
|
||||
|
||||
private:
|
||||
QString m_fileName; // initialized from data->sourceFileIndex
|
||||
QString m_finalUrlString; // initialized from data->finalUrlIndex
|
||||
|
|
|
@ -268,9 +268,6 @@ void ExecutableCompilationUnit::clear()
|
|||
|
||||
typeNameCache.reset();
|
||||
|
||||
qDeleteAll(resolvedTypes);
|
||||
resolvedTypes.clear();
|
||||
|
||||
delete [] runtimeLookups;
|
||||
runtimeLookups = nullptr;
|
||||
|
||||
|
@ -391,7 +388,7 @@ void ExecutableCompilationUnit::finalizeCompositeType(const QQmlType &type)
|
|||
QQmlMetaType::registerInternalCompositeType(this);
|
||||
} else {
|
||||
const QV4::CompiledData::Object *obj = objectAt(/*root object*/0);
|
||||
auto *typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex);
|
||||
auto *typeRef = m_compilationUnit->resolvedTypes.value(obj->inheritedTypeNameIndex);
|
||||
Q_ASSERT(typeRef);
|
||||
if (const auto compilationUnit = typeRef->compilationUnit())
|
||||
qmlType = compilationUnit->qmlType;
|
||||
|
@ -435,7 +432,7 @@ void ExecutableCompilationUnit::finalizeCompositeType(const QQmlType &type)
|
|||
m_compilationUnit->inlineComponentData[lastICRootName].totalBindingCount
|
||||
+= obj->nBindings;
|
||||
|
||||
if (auto *typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex)) {
|
||||
if (auto *typeRef = m_compilationUnit->resolvedTypes.value(obj->inheritedTypeNameIndex)) {
|
||||
const auto type = typeRef->type();
|
||||
if (type.isValid() && type.parserStatusCast() != -1)
|
||||
++m_compilationUnit->inlineComponentData[lastICRootName].totalParserStatusCount;
|
||||
|
@ -463,7 +460,7 @@ void ExecutableCompilationUnit::finalizeCompositeType(const QQmlType &type)
|
|||
continue;
|
||||
|
||||
bindingCount += obj->nBindings;
|
||||
if (auto *typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex)) {
|
||||
if (auto *typeRef = m_compilationUnit->resolvedTypes.value(obj->inheritedTypeNameIndex)) {
|
||||
const auto type = typeRef->type();
|
||||
if (type.isValid() && type.parserStatusCast() != -1)
|
||||
++parserStatusCount;
|
||||
|
@ -495,15 +492,6 @@ int ExecutableCompilationUnit::totalObjectCount() const {
|
|||
return m_compilationUnit->inlineComponentData[*icRootName()].totalObjectCount;
|
||||
}
|
||||
|
||||
ResolvedTypeReference *ExecutableCompilationUnit::resolvedType(QMetaType type) const
|
||||
{
|
||||
for (ResolvedTypeReference *ref : std::as_const(resolvedTypes)) {
|
||||
if (ref->type().typeId() == type)
|
||||
return ref;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int ExecutableCompilationUnit::totalParserStatusCount() const {
|
||||
if (!m_compilationUnit->icRootName)
|
||||
return m_totalParserStatusCount;
|
||||
|
@ -854,29 +842,6 @@ void ExecutableCompilationUnit::evaluateModuleRequests()
|
|||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
This function creates a temporary key vector and sorts it to guarantuee a stable
|
||||
hash. This is used to calculate a check-sum on dependent meta-objects.
|
||||
*/
|
||||
bool ResolvedTypeReferenceMap::addToHash(
|
||||
QCryptographicHash *hash, QHash<quintptr, QByteArray> *checksums) const
|
||||
{
|
||||
std::vector<int> keys (size());
|
||||
int i = 0;
|
||||
for (auto it = constBegin(), end = constEnd(); it != end; ++it) {
|
||||
keys[i] = it.key();
|
||||
++i;
|
||||
}
|
||||
std::sort(keys.begin(), keys.end());
|
||||
for (int key: keys) {
|
||||
if (!this->operator[](key)->addToHash(hash, checksums))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QString ExecutableCompilationUnit::bindingValueAsString(const CompiledData::Binding *binding) const
|
||||
{
|
||||
#if QT_CONFIG(translation)
|
||||
|
|
|
@ -34,12 +34,6 @@ class QQmlEnginePrivate;
|
|||
namespace QV4 {
|
||||
|
||||
class CompilationUnitMapper;
|
||||
class ResolvedTypeReference;
|
||||
// map from name index
|
||||
struct ResolvedTypeReferenceMap: public QHash<int, ResolvedTypeReference*>
|
||||
{
|
||||
bool addToHash(QCryptographicHash *hash, QHash<quintptr, QByteArray> *checksums) const;
|
||||
};
|
||||
|
||||
struct CompilationUnitRuntimeData
|
||||
{
|
||||
|
@ -113,9 +107,21 @@ public:
|
|||
int totalObjectCount() const;
|
||||
|
||||
QVector<QQmlRefPointer<QQmlScriptData>> dependentScripts;
|
||||
ResolvedTypeReferenceMap resolvedTypes;
|
||||
ResolvedTypeReference *resolvedType(int id) const { return resolvedTypes.value(id); }
|
||||
ResolvedTypeReference *resolvedType(QMetaType type) const;
|
||||
|
||||
ResolvedTypeReference *resolvedType(int id) const
|
||||
{
|
||||
return m_compilationUnit->resolvedType(id);
|
||||
}
|
||||
|
||||
ResolvedTypeReference *resolvedType(QMetaType type) const
|
||||
{
|
||||
return m_compilationUnit->resolvedType(type);
|
||||
}
|
||||
|
||||
void setResolvedTypes(const CompiledData::ResolvedTypeReferenceMap &resolvedTypes)
|
||||
{
|
||||
m_compilationUnit->resolvedTypes = resolvedTypes;
|
||||
}
|
||||
|
||||
bool verifyChecksum(const CompiledData::DependentTypesHasher &dependencyHasher) const;
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ Q_LOGGING_CATEGORY(lcQmlTypeCompiler, "qt.qml.typecompiler");
|
|||
|
||||
QQmlTypeCompiler::QQmlTypeCompiler(
|
||||
QQmlEnginePrivate *engine, QQmlTypeData *typeData, QmlIR::Document *parsedQML,
|
||||
QV4::ResolvedTypeReferenceMap *resolvedTypeCache,
|
||||
QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache,
|
||||
const QV4::CompiledData::DependentTypesHasher &dependencyHasher)
|
||||
: resolvedTypes(resolvedTypeCache)
|
||||
, engine(engine)
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
QQmlTypeCompiler(QQmlEnginePrivate *engine,
|
||||
QQmlTypeData *typeData,
|
||||
QmlIR::Document *document,
|
||||
QV4::ResolvedTypeReferenceMap *resolvedTypeCache,
|
||||
QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache,
|
||||
const QV4::CompiledData::DependentTypesHasher &dependencyHasher);
|
||||
|
||||
// --- interface used by QQmlPropertyCacheCreator
|
||||
|
@ -63,7 +63,7 @@ public:
|
|||
QString stringAt(int idx) const;
|
||||
QmlIR::PoolList<QmlIR::Function>::Iterator objectFunctionsBegin(const QmlIR::Object *object) const { return object->functionsBegin(); }
|
||||
QmlIR::PoolList<QmlIR::Function>::Iterator objectFunctionsEnd(const QmlIR::Object *object) const { return object->functionsEnd(); }
|
||||
QV4::ResolvedTypeReferenceMap *resolvedTypes = nullptr;
|
||||
QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypes = nullptr;
|
||||
ListPropertyAssignBehavior listPropertyAssignBehavior() const
|
||||
{
|
||||
for (const QmlIR::Pragma *pragma: document->pragmas) {
|
||||
|
|
|
@ -236,11 +236,11 @@ bool QQmlComponentAndAliasResolver<QV4::ExecutableCompilationUnit>::wrapImplicit
|
|||
|
||||
QQmlError QQmlTypeData::createTypeAndPropertyCaches(
|
||||
const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache,
|
||||
const QV4::ResolvedTypeReferenceMap &resolvedTypeCache)
|
||||
const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache)
|
||||
{
|
||||
Q_ASSERT(m_compiledData);
|
||||
m_compiledData->typeNameCache = typeNameCache;
|
||||
m_compiledData->resolvedTypes = resolvedTypeCache;
|
||||
m_compiledData->setResolvedTypes(resolvedTypeCache);
|
||||
m_compiledData->setInlineComponentData(m_inlineComponentData);
|
||||
|
||||
QQmlEnginePrivate * const engine = QQmlEnginePrivate::get(typeLoader()->engine());
|
||||
|
@ -440,7 +440,7 @@ void QQmlTypeData::done()
|
|||
else
|
||||
setupICs(m_compiledData, &m_inlineComponentData, finalUrl(), m_compiledData);
|
||||
|
||||
QV4::ResolvedTypeReferenceMap resolvedTypeCache;
|
||||
QV4::CompiledData::ResolvedTypeReferenceMap resolvedTypeCache;
|
||||
QQmlRefPointer<QQmlTypeNameCache> typeNameCache;
|
||||
{
|
||||
QQmlError error = buildTypeResolutionCaches(&typeNameCache, &resolvedTypeCache);
|
||||
|
@ -482,7 +482,7 @@ void QQmlTypeData::done()
|
|||
return;
|
||||
|
||||
// We want to keep our resolve types ...
|
||||
m_compiledData->resolvedTypes.clear();
|
||||
m_compiledData->setResolvedTypes({});
|
||||
// ... but we don't want the property caches we've created for the broken CU.
|
||||
for (QV4::ResolvedTypeReference *ref: std::as_const(resolvedTypeCache)) {
|
||||
const auto compilationUnit = ref->compilationUnit();
|
||||
|
@ -808,7 +808,7 @@ QString QQmlTypeData::stringAt(int index) const
|
|||
}
|
||||
|
||||
void QQmlTypeData::compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache,
|
||||
QV4::ResolvedTypeReferenceMap *resolvedTypeCache,
|
||||
QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache,
|
||||
const QV4::CompiledData::DependentTypesHasher &dependencyHasher)
|
||||
{
|
||||
Q_ASSERT(m_compiledData.isNull());
|
||||
|
@ -847,7 +847,7 @@ void QQmlTypeData::compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCach
|
|||
m_compiledData = enginePrivate->v4engine()->executableCompilationUnit(
|
||||
std::move(compilationUnit));
|
||||
m_compiledData->typeNameCache = typeNameCache;
|
||||
m_compiledData->resolvedTypes = *resolvedTypeCache;
|
||||
m_compiledData->setResolvedTypes(*resolvedTypeCache);
|
||||
m_compiledData->propertyCaches = std::move(*compiler.propertyCaches());
|
||||
Q_ASSERT(m_compiledData->propertyCaches.count()
|
||||
== static_cast<int>(m_compiledData->objectCount()));
|
||||
|
@ -958,7 +958,7 @@ void QQmlTypeData::resolveTypes()
|
|||
|
||||
QQmlError QQmlTypeData::buildTypeResolutionCaches(
|
||||
QQmlRefPointer<QQmlTypeNameCache> *typeNameCache,
|
||||
QV4::ResolvedTypeReferenceMap *resolvedTypeCache) const
|
||||
QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache) const
|
||||
{
|
||||
typeNameCache->adopt(new QQmlTypeNameCache(m_importCache));
|
||||
|
||||
|
|
|
@ -92,13 +92,14 @@ private:
|
|||
void resolveTypes();
|
||||
QQmlError buildTypeResolutionCaches(
|
||||
QQmlRefPointer<QQmlTypeNameCache> *typeNameCache,
|
||||
QV4::ResolvedTypeReferenceMap *resolvedTypeCache
|
||||
QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache
|
||||
) const;
|
||||
void compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache,
|
||||
QV4::ResolvedTypeReferenceMap *resolvedTypeCache,
|
||||
QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache,
|
||||
const QV4::CompiledData::DependentTypesHasher &dependencyHasher);
|
||||
QQmlError createTypeAndPropertyCaches(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache,
|
||||
const QV4::ResolvedTypeReferenceMap &resolvedTypeCache);
|
||||
QQmlError createTypeAndPropertyCaches(
|
||||
const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache,
|
||||
const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache);
|
||||
bool resolveType(const QString &typeName, QTypeRevision &version,
|
||||
TypeReference &ref, int lineNumber = -1, int columnNumber = -1,
|
||||
bool reportErrors = true,
|
||||
|
|
|
@ -367,8 +367,8 @@ private:
|
|||
if (object->hasFlag(Object::IsInlineComponentRoot))
|
||||
return result;
|
||||
|
||||
if (const auto superTypeUnit = compilationUnit->resolvedTypes.value(
|
||||
object->inheritedTypeNameIndex)->compilationUnit()) {
|
||||
if (const auto superTypeUnit = compilationUnit->resolvedType(object->inheritedTypeNameIndex)
|
||||
->compilationUnit()) {
|
||||
// We have a non-C++ super type, which could indicate we're a subtype of a TestCase
|
||||
if (testCaseType.isValid() && superTypeUnit->url() == testCaseType.sourceUrl())
|
||||
result.isTestCase = true;
|
||||
|
|
Loading…
Reference in New Issue