QtQml: Make base CU a member of ExecutableCompilationUnit

We want to re-use the base compilation unit across engines. For that to
work it cannot be a slice of the engine-specific
ExecutableCompilationUnit.

Since CompiledData::CompilationUnit is refcounted on its own now, make
it unmovable.

Change-Id: I8418c9754d7a07e5210c1e7a7fc69355e1d57807
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
Ulf Hermann 2023-12-21 13:25:11 +01:00
parent d85de8da60
commit cfdc612c30
25 changed files with 172 additions and 129 deletions

View File

@ -30,7 +30,9 @@
#endif
#include <private/qendian_p.h>
#include <private/qqmlrefcount_p.h>
#include <private/qv4staticvalue_p.h>
#include <functional>
#include <limits.h>
@ -1421,9 +1423,9 @@ using DependentTypesHasher = std::function<QByteArray()>;
// This is how this hooks into the existing structures:
struct CompilationUnit
struct CompilationUnit final : public QQmlRefCounted<CompilationUnit>
{
Q_DISABLE_COPY(CompilationUnit)
Q_DISABLE_COPY_MOVE(CompilationUnit)
const Unit *data = nullptr;
const QmlUnit *qmlData = nullptr;
@ -1465,32 +1467,6 @@ public:
#endif
}
CompilationUnit(CompilationUnit &&other) noexcept
{
*this = std::move(other);
}
CompilationUnit &operator=(CompilationUnit &&other) noexcept
{
if (this != &other) {
data = other.data;
other.data = nullptr;
qmlData = other.qmlData;
other.qmlData = nullptr;
dynamicStrings = std::move(other.dynamicStrings);
other.dynamicStrings.clear();
aotCompiledFunctions = other.aotCompiledFunctions;
other.aotCompiledFunctions = nullptr;
constants = other.constants;
other.constants = nullptr;
m_fileName = std::move(other.m_fileName);
other.m_fileName.clear();
m_finalUrlString = std::move(other.m_finalUrlString);
other.m_finalUrlString.clear();
}
return *this;
}
const Unit *unitData() const { return data; }
void setUnitData(const Unit *unitData, const QmlUnit *qmlUnit = nullptr,

View File

@ -1645,10 +1645,14 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen
Unit *jsUnit = nullptr;
if (!output.javaScriptCompilationUnit)
output.javaScriptCompilationUnit.adopt(new QV4::CompiledData::CompilationUnit);
// We may already have unit data if we're loading an ahead-of-time generated cache file.
if (output.javaScriptCompilationUnit.data) {
jsUnit = const_cast<Unit *>(output.javaScriptCompilationUnit.data);
output.javaScriptCompilationUnit.dynamicStrings = output.jsGenerator.stringTable.allStrings();
if (output.javaScriptCompilationUnit->unitData()) {
jsUnit = const_cast<Unit *>(output.javaScriptCompilationUnit->unitData());
output.javaScriptCompilationUnit->dynamicStrings
= output.jsGenerator.stringTable.allStrings();
} else {
Unit *createdUnit;
jsUnit = createdUnit = output.jsGenerator.generateUnit();
@ -1921,7 +1925,7 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen
}
}
if (!output.javaScriptCompilationUnit.data) {
if (!output.javaScriptCompilationUnit->unitData()) {
// Combine the qml data into the general unit data.
jsUnit = static_cast<QV4::CompiledData::Unit *>(realloc(jsUnit, jsUnit->unitSize + totalSize));
jsUnit->offsetToQmlUnit = jsUnit->unitSize;
@ -1954,8 +1958,8 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen
qDebug() << " " << totalStringSize << "bytes total strings";
}
output.javaScriptCompilationUnit.setUnitData(jsUnit, qmlUnit, output.jsModule.fileName,
output.jsModule.finalUrl);
output.javaScriptCompilationUnit->setUnitData(
jsUnit, qmlUnit, output.jsModule.fileName, output.jsModule.finalUrl);
}
char *QmlUnitGenerator::writeBindings(char *bindingPtr, const Object *o, BindingFilter filter) const

View File

@ -472,7 +472,7 @@ struct Q_QML_COMPILER_EXPORT Document
QVector<Object*> objects;
QV4::Compiler::JSUnitGenerator jsGenerator;
QV4::CompiledData::CompilationUnit javaScriptCompilationUnit;
QQmlRefPointer<QV4::CompiledData::CompilationUnit> javaScriptCompilationUnit;
bool isSingleton() const {
return std::any_of(pragmas.constBegin(), pragmas.constEnd(), [](const Pragma *pragma) {

View File

@ -4129,14 +4129,16 @@ QQmlJS::DiagnosticMessage Codegen::error() const
return _error;
}
QV4::CompiledData::CompilationUnit Codegen::generateCompilationUnit(
QQmlRefPointer<QV4::CompiledData::CompilationUnit> Codegen::generateCompilationUnit(
bool generateUnitData)
{
return QV4::CompiledData::CompilationUnit(
generateUnitData ? jsUnitGenerator->generateUnit() : nullptr);
return QQmlRefPointer<QV4::CompiledData::CompilationUnit>(
new QV4::CompiledData::CompilationUnit(
generateUnitData ? jsUnitGenerator->generateUnit() : nullptr),
QQmlRefPointer<QV4::CompiledData::CompilationUnit>::Adopt);
}
CompiledData::CompilationUnit Codegen::compileModule(
QQmlRefPointer<QV4::CompiledData::CompilationUnit> Codegen::compileModule(
bool debugMode, const QString &url, const QString &sourceCode,
const QDateTime &sourceTimeStamp, QList<QQmlJS::DiagnosticMessage> *diagnostics)
{
@ -4151,7 +4153,7 @@ CompiledData::CompilationUnit Codegen::compileModule(
*diagnostics = parser.diagnosticMessages();
if (!parsed)
return CompiledData::CompilationUnit();
return QQmlRefPointer<CompiledData::CompilationUnit>();
QQmlJS::AST::ESModule *moduleNode = QQmlJS::AST::cast<QQmlJS::AST::ESModule*>(parser.rootNode());
if (!moduleNode) {
@ -4172,7 +4174,7 @@ CompiledData::CompilationUnit Codegen::compileModule(
if (cg.hasError()) {
if (diagnostics)
*diagnostics << cg.error();
return CompiledData::CompilationUnit();
return QQmlRefPointer<CompiledData::CompilationUnit>();
}
return cg.generateCompilationUnit();

View File

@ -731,8 +731,9 @@ public:
const QString &name, bool lhs,
const QQmlJS::SourceLocation &accessLocation = QQmlJS::SourceLocation());
QV4::CompiledData::CompilationUnit generateCompilationUnit(bool generateUnitData = true);
static QV4::CompiledData::CompilationUnit compileModule(
QQmlRefPointer<QV4::CompiledData::CompilationUnit> generateCompilationUnit(
bool generateUnitData = true);
static QQmlRefPointer<QV4::CompiledData::CompilationUnit> compileModule(
bool debugMode, const QString &url, const QString &sourceCode,
const QDateTime &sourceTimeStamp, QList<QQmlJS::DiagnosticMessage> *diagnostics);

View File

@ -54,7 +54,7 @@ const TranslationBindingInformation TranslationBindingInformation::create(
QQmlTranslation translation;
if (binding->type() == QV4::CompiledData::Binding::Type_TranslationById) {
const QV4::CompiledData::TranslationData data =
compilationUnit->data->translations()[binding->value.translationDataIndex];
compilationUnit->unitData()->translations()[binding->value.translationDataIndex];
const QString id = compilationUnit->stringAt(data.stringIndex);
const int n = data.number;
@ -63,7 +63,7 @@ const TranslationBindingInformation TranslationBindingInformation::create(
Q_ASSERT(binding->type() == QV4::CompiledData::Binding::Type_Translation);
const QV4::CompiledData::TranslationData data =
compilationUnit->data->translations()[binding->value.translationDataIndex];
compilationUnit->unitData()->translations()[binding->value.translationDataIndex];
const QString text = compilationUnit->stringAt(data.stringIndex);
const QString comment = compilationUnit->stringAt(data.commentIndex);
const bool hasContext

View File

@ -2075,9 +2075,11 @@ QQmlRefPointer<ExecutableCompilationUnit> ExecutionEngine::compileModule(const Q
&cacheError)
: nullptr) {
return ExecutableCompilationUnit::create(
QV4::CompiledData::CompilationUnit(
cachedUnit->qmlData, cachedUnit->aotCompiledFunctions,
url.fileName(), url.toString()));
QQmlRefPointer<QV4::CompiledData::CompilationUnit>(
new QV4::CompiledData::CompilationUnit(
cachedUnit->qmlData, cachedUnit->aotCompiledFunctions,
url.fileName(), url.toString()),
QQmlRefPointer<QV4::CompiledData::CompilationUnit>::Adopt));
}
QFile f(QQmlFile::urlToLocalFileOrQrc(url));

View File

@ -55,10 +55,10 @@ namespace QV4 {
ExecutableCompilationUnit::ExecutableCompilationUnit() = default;
ExecutableCompilationUnit::ExecutableCompilationUnit(
CompiledData::CompilationUnit &&compilationUnit)
: CompiledData::CompilationUnit(std::move(compilationUnit))
QQmlRefPointer<CompiledData::CompilationUnit> &&compilationUnit)
: m_compilationUnit(std::move(compilationUnit))
{
CompilationUnitRuntimeData::constants = CompiledData::CompilationUnit::constants;
constants = m_compilationUnit->constants;
}
ExecutableCompilationUnit::~ExecutableCompilationUnit()
@ -112,6 +112,8 @@ QV4::Function *ExecutableCompilationUnit::linkToEngine(ExecutionEngine *engine)
this->engine = engine;
engine->compilationUnits.insert(this);
const CompiledData::Unit *data = m_compilationUnit->data;
Q_ASSERT(!runtimeStrings);
Q_ASSERT(data);
const quint32 stringCount = totalStringCount();
@ -182,7 +184,7 @@ QV4::Function *ExecutableCompilationUnit::linkToEngine(ExecutionEngine *engine)
|| !(engine->diskCacheOptions() & ExecutionEngine::DiskCache::AotNative);
const QQmlPrivate::AOTCompiledFunction *aotFunction
= ignoreAotCompiledFunctions ? nullptr : aotCompiledFunctions;
= ignoreAotCompiledFunctions ? nullptr : m_compilationUnit->aotCompiledFunctions;
auto advanceAotFunction = [&](int i) -> const QQmlPrivate::AOTCompiledFunction * {
if (aotFunction) {
@ -222,7 +224,7 @@ QV4::Function *ExecutableCompilationUnit::linkToEngine(ExecutionEngine *engine)
static const bool showCode = qEnvironmentVariableIsSet("QV4_SHOW_BYTECODE");
if (showCode) {
qDebug() << "=== Constant table";
dumpConstantTable(CompiledData::CompilationUnit::constants, data->constantTableSize);
dumpConstantTable(constants, data->constantTableSize);
qDebug() << "=== String table";
for (uint i = 0, end = totalStringCount(); i < end; ++i)
qDebug() << " " << i << ":" << runtimeStrings[i]->toQString();
@ -242,6 +244,8 @@ QV4::Function *ExecutableCompilationUnit::linkToEngine(ExecutionEngine *engine)
Heap::Object *ExecutableCompilationUnit::templateObjectAt(int index) const
{
const CompiledData::Unit *data = m_compilationUnit->data;
Q_ASSERT(index < int(data->templateObjectTableSize));
if (!templateObjects.size())
templateObjects.resize(data->templateObjectTableSize);
@ -282,7 +286,8 @@ void ExecutableCompilationUnit::unlink()
ic.qmlType = QQmlType();
if (runtimeLookups) {
for (uint i = 0; i < data->lookupTableSize; ++i)
const uint lookupTableSize = unitData()->lookupTableSize;
for (uint i = 0; i < lookupTableSize; ++i)
runtimeLookups[i].releasePropertyCache();
}
@ -312,6 +317,8 @@ void ExecutableCompilationUnit::unlink()
void ExecutableCompilationUnit::markObjects(QV4::MarkStack *markStack)
{
const CompiledData::Unit *data = m_compilationUnit->data;
if (runtimeStrings) {
for (uint i = 0, end = totalStringCount(); i < end; ++i)
if (runtimeStrings[i])
@ -521,6 +528,8 @@ int ExecutableCompilationUnit::totalParserStatusCount() const {
bool ExecutableCompilationUnit::verifyChecksum(const CompiledData::DependentTypesHasher &dependencyHasher) const
{
const CompiledData::Unit *data = m_compilationUnit->data;
if (!dependencyHasher) {
for (size_t i = 0; i < sizeof(data->dependencyMD5Checksum); ++i) {
if (data->dependencyMD5Checksum[i] != 0)
@ -543,6 +552,8 @@ QQmlType ExecutableCompilationUnit::qmlTypeForComponent(const QString &inlineCom
QStringList ExecutableCompilationUnit::moduleRequests() const
{
const CompiledData::Unit *data = m_compilationUnit->data;
QStringList requests;
requests.reserve(data->moduleRequestTableSize);
for (uint i = 0; i < data->moduleRequestTableSize; ++i)
@ -552,6 +563,8 @@ QStringList ExecutableCompilationUnit::moduleRequests() const
Heap::Module *ExecutableCompilationUnit::instantiate(ExecutionEngine *engine)
{
const CompiledData::Unit *data = m_compilationUnit->data;
if (isESModule() && module())
return module();
@ -687,6 +700,7 @@ const Value *ExecutableCompilationUnit::resolveExportRecursively(
if (exportName->toQString() == QLatin1String("*"))
return &module()->self;
const CompiledData::Unit *data = m_compilationUnit->data;
Scope scope(engine);
if (auto localExport = lookupNameInExportTable(
@ -797,6 +811,8 @@ void ExecutableCompilationUnit::getExportedNamesRecursively(
names->append(name);
};
const CompiledData::Unit *data = m_compilationUnit->data;
for (uint i = 0; i < data->localExportEntryTableSize; ++i) {
const CompiledData::ExportEntry &entry = data->localExportEntryTable()[i];
append(stringAt(entry.exportName));
@ -867,21 +883,25 @@ bool ExecutableCompilationUnit::loadFromDisk(const QUrl &url, const QDateTime &s
if (!mappedUnit)
continue;
const CompiledData::Unit *oldData = unitData();
const CompiledData::Unit * const oldDataPtr
= (data && !(data->flags & QV4::CompiledData::Unit::StaticData)) ? data
: nullptr;
const CompiledData::Unit *oldData = data;
auto dataPtrRevert = qScopeGuard([this, oldData](){
setUnitData(oldData);
});
setUnitData(mappedUnit);
= (oldData && !(oldData->flags & QV4::CompiledData::Unit::StaticData))
? oldData
: nullptr;
if (data->sourceFileIndex != 0) {
if (data->sourceFileIndex >= data->stringTableSize + dynamicStrings.size()) {
auto dataPtrRevert = qScopeGuard([this, oldData](){
m_compilationUnit->setUnitData(oldData);
});
m_compilationUnit->setUnitData(mappedUnit);
if (mappedUnit->sourceFileIndex != 0) {
if (mappedUnit->sourceFileIndex >=
mappedUnit->stringTableSize + m_compilationUnit->dynamicStrings.size()) {
*errorString = QStringLiteral("QML source file index is invalid.");
continue;
}
if (sourcePath != QQmlFile::urlToLocalFileOrQrc(stringAt(data->sourceFileIndex))) {
if (sourcePath !=
QQmlFile::urlToLocalFileOrQrc(stringAt(mappedUnit->sourceFileIndex))) {
*errorString = QStringLiteral("QML source file has moved to a different location.");
continue;
}
@ -890,7 +910,7 @@ bool ExecutableCompilationUnit::loadFromDisk(const QUrl &url, const QDateTime &s
dataPtrRevert.dismiss();
free(const_cast<CompiledData::Unit*>(oldDataPtr));
backingFile = std::move(cacheFile);
CompilationUnitRuntimeData::constants = CompiledData::CompilationUnit::constants;
CompilationUnitRuntimeData::constants = m_compilationUnit->constants;
return true;
}
@ -899,7 +919,7 @@ bool ExecutableCompilationUnit::loadFromDisk(const QUrl &url, const QDateTime &s
bool ExecutableCompilationUnit::saveToDisk(const QUrl &unitUrl, QString *errorString)
{
if (data->sourceTimeStamp == 0) {
if (unitData()->sourceTimeStamp == 0) {
*errorString = QStringLiteral("Missing time stamp for source file");
return false;
}
@ -961,7 +981,7 @@ QString ExecutableCompilationUnit::bindingValueAsString(const CompiledData::Bind
break;
}
#endif
return CompilationUnit::bindingValueAsString(binding);
return m_compilationUnit->bindingValueAsString(binding);
}
QString ExecutableCompilationUnit::translateFrom(TranslationDataIndex index) const
@ -969,7 +989,7 @@ QString ExecutableCompilationUnit::translateFrom(TranslationDataIndex index) con
#if !QT_CONFIG(translation)
return QString();
#else
const CompiledData::TranslationData &translation = data->translations()[index.index];
const CompiledData::TranslationData &translation = unitData()->translations()[index.index];
if (index.byId) {
QByteArray id = stringAt(translation.stringIndex).toUtf8();
@ -993,7 +1013,7 @@ QString ExecutableCompilationUnit::translateFrom(TranslationDataIndex index) con
if (hasContext) {
context = stringAt(translation.contextIndex).toUtf8();
} else {
auto pragmaTranslationContext = data->translationContextIndex();
auto pragmaTranslationContext = unitData()->translationContextIndex();
context = stringAt(*pragmaTranslationContext).toUtf8();
context = context.isEmpty() ? fileContext() : context;
}

View File

@ -91,8 +91,7 @@ static_assert(offsetof(CompilationUnitRuntimeData, runtimeClasses) == offsetof(C
static_assert(offsetof(CompilationUnitRuntimeData, imports) == offsetof(CompilationUnitRuntimeData, runtimeClasses) + sizeof(const StaticValue *));
class Q_QML_PRIVATE_EXPORT ExecutableCompilationUnit final
: public CompiledData::CompilationUnit,
public CompilationUnitRuntimeData,
: public CompilationUnitRuntimeData,
public QQmlRefCounted<ExecutableCompilationUnit>
{
Q_DISABLE_COPY_MOVE(ExecutableCompilationUnit)
@ -101,7 +100,7 @@ public:
friend class QQmlRefPointer<ExecutableCompilationUnit>;
static QQmlRefPointer<ExecutableCompilationUnit> create(
CompiledData::CompilationUnit &&compilationUnit)
QQmlRefPointer<CompiledData::CompilationUnit> &&compilationUnit)
{
return QQmlRefPointer<ExecutableCompilationUnit>(
new ExecutableCompilationUnit(std::move(compilationUnit)),
@ -111,13 +110,19 @@ public:
static QQmlRefPointer<ExecutableCompilationUnit> create()
{
return QQmlRefPointer<ExecutableCompilationUnit>(
new ExecutableCompilationUnit,
new ExecutableCompilationUnit(
QQmlRefPointer<CompiledData::CompilationUnit>(
new CompiledData::CompilationUnit,
QQmlRefPointer<CompiledData::CompilationUnit>::Adopt)),
QQmlRefPointer<ExecutableCompilationUnit>::Adopt);
}
QIntrusiveListNode nextCompilationUnit;
ExecutionEngine *engine = nullptr;
QString finalUrlString() const { return m_compilationUnit->finalUrlString(); }
QString fileName() const { return m_compilationUnit->fileName(); }
// 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.
@ -128,14 +133,14 @@ public:
QUrl url() const
{
if (!m_url.isValid())
m_url = QUrl(fileName());
m_url = QUrl(m_compilationUnit->fileName());
return m_url;
}
QUrl finalUrl() const
{
if (!m_finalUrl.isValid())
m_finalUrl = QUrl(finalUrlString());
m_finalUrl = QUrl(m_compilationUnit->finalUrlString());
return m_finalUrl;
}
@ -216,48 +221,48 @@ public:
ListPropertyAssignBehavior listPropertyAssignBehavior() const
{
if (data->flags & CompiledData::Unit::ListPropertyAssignReplace)
if (unitData()->flags & CompiledData::Unit::ListPropertyAssignReplace)
return ListPropertyAssignBehavior::Replace;
if (data->flags & CompiledData::Unit::ListPropertyAssignReplaceIfNotDefault)
if (unitData()->flags & CompiledData::Unit::ListPropertyAssignReplaceIfNotDefault)
return ListPropertyAssignBehavior::ReplaceIfNotDefault;
return ListPropertyAssignBehavior::Append;
}
bool ignoresFunctionSignature() const
{
return data->flags & CompiledData::Unit::FunctionSignaturesIgnored;
return unitData()->flags & CompiledData::Unit::FunctionSignaturesIgnored;
}
bool nativeMethodsAcceptThisObjects() const
{
return data->flags & CompiledData::Unit::NativeMethodsAcceptThisObject;
return unitData()->flags & CompiledData::Unit::NativeMethodsAcceptThisObject;
}
bool valueTypesAreCopied() const
{
return data->flags & CompiledData::Unit::ValueTypesCopied;
return unitData()->flags & CompiledData::Unit::ValueTypesCopied;
}
bool valueTypesAreAddressable() const
{
return data->flags & CompiledData::Unit::ValueTypesAddressable;
return unitData()->flags & CompiledData::Unit::ValueTypesAddressable;
}
bool componentsAreBound() const
{
return data->flags & CompiledData::Unit::ComponentsBound;
return unitData()->flags & CompiledData::Unit::ComponentsBound;
}
int objectCount() const { return qmlData->nObjects; }
int objectCount() const { return qmlData()->nObjects; }
const CompiledObject *objectAt(int index) const
{
return qmlData->objectAt(index);
return qmlData()->objectAt(index);
}
int importCount() const { return qmlData->nImports; }
int importCount() const { return qmlData()->nImports; }
const CompiledData::Import *importAt(int index) const
{
return qmlData->importAt(index);
return qmlData()->importAt(index);
}
Heap::Object *templateObjectAt(int index) const;
@ -282,22 +287,22 @@ public:
FunctionIterator objectFunctionsBegin(const CompiledObject *object) const
{
return FunctionIterator(data, object, 0);
return FunctionIterator(unitData(), object, 0);
}
FunctionIterator objectFunctionsEnd(const CompiledObject *object) const
{
return FunctionIterator(data, object, object->nFunctions);
return FunctionIterator(unitData(), object, object->nFunctions);
}
bool isESModule() const
{
return data->flags & CompiledData::Unit::IsESModule;
return unitData()->flags & CompiledData::Unit::IsESModule;
}
bool isSharedLibrary() const
{
return data->flags & CompiledData::Unit::IsSharedLibrary;
return unitData()->flags & CompiledData::Unit::IsSharedLibrary;
}
QStringList moduleRequests() const;
@ -333,6 +338,14 @@ public:
bool saveToDisk(const QUrl &unitUrl, QString *errorString);
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
{
@ -348,11 +361,22 @@ public:
Heap::Module *module() const { return m_module; }
void setModule(Heap::Module *module) { m_module = module; }
const CompiledData::Unit *unitData() const { return m_compilationUnit->data; }
const CompiledData::QmlUnit *qmlData() const { return m_compilationUnit->qmlData; }
QString stringAt(uint index) const { return m_compilationUnit->stringAt(index); }
QQmlRefPointer<QV4::CompiledData::CompilationUnit> baseCompilationUnit() const
{
return m_compilationUnit;
}
protected:
quint32 totalStringCount() const
{ return data->stringTableSize; }
{ return unitData()->stringTableSize; }
private:
QQmlRefPointer<CompiledData::CompilationUnit> m_compilationUnit;
Heap::Module *m_module = nullptr;
struct ResolveSetEntry
@ -365,7 +389,7 @@ private:
};
ExecutableCompilationUnit();
ExecutableCompilationUnit(CompiledData::CompilationUnit &&compilationUnit);
ExecutableCompilationUnit(QQmlRefPointer<CompiledData::CompilationUnit> &&compilationUnit);
~ExecutableCompilationUnit();
const Value *resolveExportRecursively(QV4::String *exportName,

View File

@ -51,8 +51,8 @@ void Heap::Module::init(ExecutionEngine *engine, ExecutableCompilationUnit *modu
{
Scoped<QV4::InternalClass> ic(valueScope, scope->internalClass);
for (uint i = 0; i < unit->data->importEntryTableSize; ++i) {
const CompiledData::ImportEntry &import = unit->data->importEntryTable()[i];
for (uint i = 0; i < unit->unitData()->importEntryTableSize; ++i) {
const CompiledData::ImportEntry &import = unit->unitData()->importEntryTable()[i];
ic = ic->addMember(engine->identifierTable->asPropertyKey(unit->runtimeStrings[import.localName]), Attr_NotConfigurable);
}
scope->internalClass.set(engine, ic->d());
@ -76,7 +76,7 @@ void Module::evaluate()
unit->evaluateModuleRequests();
ExecutionEngine *v4 = engine();
Function *moduleFunction = unit->runtimeFunctions[unit->data->indexOfRootFunction];
Function *moduleFunction = unit->runtimeFunctions[unit->unitData()->indexOfRootFunction];
JSTypesStackFrame frame;
frame.init(moduleFunction, nullptr, 0);
frame.setupJSFrame(v4->jsStackTop, Value::undefinedValue(), d()->scope,

View File

@ -88,8 +88,8 @@ bool ResolvedTypeReference::addToHash(
}
if (!m_compilationUnit)
return false;
hash->addData({m_compilationUnit->data->md5Checksum,
sizeof(m_compilationUnit->data->md5Checksum)});
hash->addData({m_compilationUnit->unitData()->md5Checksum,
sizeof(m_compilationUnit->unitData()->md5Checksum)});
return true;
}

View File

@ -133,7 +133,7 @@ Function *Script::function()
return vmFunction;
}
QV4::CompiledData::CompilationUnit Script::precompile(
QQmlRefPointer<QV4::CompiledData::CompilationUnit> Script::precompile(
QV4::Compiler::Module *module, QQmlJS::Engine *jsEngine,
Compiler::JSUnitGenerator *unitGenerator, const QString &fileName, const QString &finalUrl,
const QString &source, QList<QQmlError> *reportedErrors,
@ -198,7 +198,10 @@ Script *Script::createFromFileOrCache(ExecutionEngine *engine, QmlContext *qmlCo
: nullptr) {
QQmlRefPointer<QV4::ExecutableCompilationUnit> jsUnit
= QV4::ExecutableCompilationUnit::create(
QV4::CompiledData::CompilationUnit(cachedUnit->qmlData, cachedUnit->aotCompiledFunctions));
QQmlRefPointer<QV4::CompiledData::CompilationUnit>(
new QV4::CompiledData::CompilationUnit(
cachedUnit->qmlData, cachedUnit->aotCompiledFunctions),
QQmlRefPointer<QV4::CompiledData::CompilationUnit>::Adopt));
return new QV4::Script(engine, qmlContext, jsUnit);
}

View File

@ -65,7 +65,7 @@ struct Q_QML_EXPORT Script {
Function *function();
static QV4::CompiledData::CompilationUnit precompile(
static QQmlRefPointer<QV4::CompiledData::CompilationUnit> precompile(
QV4::Compiler::Module *module, QQmlJS::Engine *jsEngine,
Compiler::JSUnitGenerator *unitGenerator, const QString &fileName,
const QString &finalUrl, const QString &source,

View File

@ -2174,7 +2174,7 @@ QString GlobalExtensions::currentTranslationContext(ExecutionEngine *engine)
// The first non-empty source URL in the call stack determines the translation context.
while (frame && context.isEmpty()) {
if (ExecutableCompilationUnit *unit = frame->v4Function->executableCompilationUnit()) {
auto translationContextIndex = unit->data->translationContextIndex();
auto translationContextIndex = unit->unitData()->translationContextIndex();
if (translationContextIndex)
context = unit->stringAt(*translationContextIndex);
if (!context.isEmpty())

View File

@ -61,7 +61,7 @@ void QQmlScriptBlob::dataReceived(const SourceCodeData &data)
return;
}
QV4::CompiledData::CompilationUnit unit;
QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit;
if (m_isModule) {
QList<QQmlJS::DiagnosticMessage> diagnostics;
@ -117,7 +117,11 @@ void QQmlScriptBlob::dataReceived(const SourceCodeData &data)
void QQmlScriptBlob::initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *unit)
{
initializeFromCompilationUnit(QV4::ExecutableCompilationUnit::create(
QV4::CompiledData::CompilationUnit(unit->qmlData, unit->aotCompiledFunctions, urlString(), finalUrlString())));
QQmlRefPointer<QV4::CompiledData::CompilationUnit>(
new QV4::CompiledData::CompilationUnit(
unit->qmlData, unit->aotCompiledFunctions,
urlString(), finalUrlString()),
QQmlRefPointer<QV4::CompiledData::CompilationUnit>::Adopt)));
}
void QQmlScriptBlob::done()

View File

@ -112,7 +112,7 @@ QQmlRefPointer<QV4::ExecutableCompilationUnit> QQmlTypeCompiler::compile()
return nullptr;
}
if (!document->javaScriptCompilationUnit.unitData()) {
if (!document->javaScriptCompilationUnit || !document->javaScriptCompilationUnit->unitData()) {
// Compile JS binding expressions and signal handlers if necessary
{
// We can compile script strings ahead of time, but they must be compiled
@ -196,7 +196,7 @@ int QQmlTypeCompiler::registerConstant(QV4::ReturnedValue v)
const QV4::CompiledData::Unit *QQmlTypeCompiler::qmlUnit() const
{
return document->javaScriptCompilationUnit.unitData();
return document->javaScriptCompilationUnit->unitData();
}
const QQmlImports *QQmlTypeCompiler::imports() const

View File

@ -100,7 +100,7 @@ bool QQmlTypeData::tryLoadFromDiskCache()
}
if (unit->unitData()->flags & QV4::CompiledData::Unit::PendingTypeCompilation) {
restoreIR(std::move(*unit));
restoreIR(unit->baseCompilationUnit());
return true;
}
@ -651,7 +651,10 @@ void QQmlTypeData::initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *un
loader.load();
m_document->jsModule.fileName = urlString();
m_document->jsModule.finalUrl = finalUrlString();
m_document->javaScriptCompilationUnit = QV4::CompiledData::CompilationUnit(unit->qmlData, unit->aotCompiledFunctions);
m_document->javaScriptCompilationUnit
= QQmlRefPointer<QV4::CompiledData::CompilationUnit>(
new QV4::CompiledData::CompilationUnit(unit->qmlData, unit->aotCompiledFunctions),
QQmlRefPointer<QV4::CompiledData::CompilationUnit>::Adopt);
continueLoadFromIR();
}
@ -686,14 +689,14 @@ bool QQmlTypeData::loadFromSource()
return true;
}
void QQmlTypeData::restoreIR(QV4::CompiledData::CompilationUnit &&unit)
void QQmlTypeData::restoreIR(const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &unit)
{
m_document.reset(new QmlIR::Document(isDebugging()));
QQmlIRLoader loader(unit.unitData(), m_document.data());
QQmlIRLoader loader(unit->unitData(), m_document.data());
loader.load();
m_document->jsModule.fileName = urlString();
m_document->jsModule.finalUrl = finalUrlString();
m_document->javaScriptCompilationUnit = std::move(unit);
m_document->javaScriptCompilationUnit = unit;
continueLoadFromIR();
}
@ -809,8 +812,11 @@ void QQmlTypeData::compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCach
{
Q_ASSERT(m_compiledData.isNull());
const bool typeRecompilation = m_document && m_document->javaScriptCompilationUnit.unitData()
&& (m_document->javaScriptCompilationUnit.unitData()->flags & QV4::CompiledData::Unit::PendingTypeCompilation);
const bool typeRecompilation = m_document
&& m_document->javaScriptCompilationUnit
&& m_document->javaScriptCompilationUnit->unitData()
&& (m_document->javaScriptCompilationUnit->unitData()->flags
& QV4::CompiledData::Unit::PendingTypeCompilation);
QQmlEnginePrivate * const enginePrivate = QQmlEnginePrivate::get(typeLoader()->engine());
QQmlTypeCompiler compiler(enginePrivate, this, m_document.data(), typeNameCache, resolvedTypeCache, dependencyHasher);

View File

@ -85,7 +85,7 @@ protected:
private:
bool tryLoadFromDiskCache();
bool loadFromSource();
void restoreIR(QV4::CompiledData::CompilationUnit &&unit);
void restoreIR(const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &unit);
void continueLoadFromIR();
void resolveTypes();
QQmlError buildTypeResolutionCaches(

View File

@ -363,8 +363,8 @@ bool qCompileQmlFile(QmlIR::Document &irDocument, const QString &inputFileName,
const quint32 saveFlags
= QV4::CompiledData::Unit::StaticData
| QV4::CompiledData::Unit::PendingTypeCompilation;
QV4::CompiledData::SaveableUnitPointer saveable(irDocument.javaScriptCompilationUnit.data,
saveFlags);
QV4::CompiledData::SaveableUnitPointer saveable(
irDocument.javaScriptCompilationUnit->unitData(), saveFlags);
if (!saveFunction(saveable, aotFunctionsByIndex, &error->message))
return false;
}
@ -373,7 +373,7 @@ bool qCompileQmlFile(QmlIR::Document &irDocument, const QString &inputFileName,
bool qCompileJSFile(const QString &inputFileName, const QString &inputFileUrl, QQmlJSSaveFunction saveFunction, QQmlJSCompileError *error)
{
QV4::CompiledData::CompilationUnit unit;
QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit;
QString sourceCode;
{
@ -397,7 +397,7 @@ bool qCompileJSFile(const QString &inputFileName, const QString &inputFileUrl, Q
unit = QV4::Compiler::Codegen::compileModule(/*debugMode*/false, url, sourceCode,
QDateTime(), &diagnostics);
error->appendDiagnostics(inputFileName, diagnostics);
if (!unit.unitData())
if (!unit || !unit->unitData())
return false;
} else {
QmlIR::Document irDocument(/*debugMode*/false);
@ -455,7 +455,8 @@ bool qCompileJSFile(const QString &inputFileName, const QString &inputFileUrl, Q
}
QQmlJSAotFunctionMap empty;
return saveFunction(QV4::CompiledData::SaveableUnitPointer(unit.data), empty, &error->message);
return saveFunction(
QV4::CompiledData::SaveableUnitPointer(unit->unitData()), empty, &error->message);
}
static const char *wrapCallCode = R"(

View File

@ -351,7 +351,7 @@ void tst_qmlcachegen::signalHandlerParameters()
};
QVERIFY(isStringIndexInStringTable(compilationUnit->objectAt(0)->signalAt(0)->parameterAt(0)->nameIndex));
QVERIFY(!compilationUnit->dynamicStrings.isEmpty());
QVERIFY(!compilationUnit->baseCompilationUnit()->dynamicStrings.isEmpty());
}
}

View File

@ -1432,7 +1432,7 @@ void tst_qqmlcomponent::loadFromQrc()
QQmlComponentPrivate *p = QQmlComponentPrivate::get(&component);
QVERIFY(p);
QVERIFY(p->compilationUnit);
QVERIFY(p->compilationUnit->aotCompiledFunctions);
QVERIFY(p->compilationUnit->baseCompilationUnit()->aotCompiledFunctions);
}
void tst_qqmlcomponent::removeBinding()

View File

@ -509,7 +509,7 @@ void tst_qqmljsscope::scriptIndices()
QmlIR::Document document(false); // we need QmlIR information here
QQmlJSScope::ConstPtr root = run(u"functionAndBindingIndices.qml"_s, &document);
QVERIFY(root);
QVERIFY(document.javaScriptCompilationUnit.unitData());
QVERIFY(document.javaScriptCompilationUnit->unitData());
// compare QQmlJSScope and QmlIR:
@ -756,8 +756,8 @@ void tst_qqmljsscope::compilationUnitsAreCompatible()
QmlIR::Document document(false); // we need QmlIR information here
QVERIFY(run(url, &document));
QVERIFY(document.javaScriptCompilationUnit.unitData());
getRuntimeInfoFromCompilationUnit(document.javaScriptCompilationUnit.unitData(),
QVERIFY(document.javaScriptCompilationUnit->unitData());
getRuntimeInfoFromCompilationUnit(document.javaScriptCompilationUnit->unitData(),
cachegenFunctions);
if (QTest::currentTestFailed())
return;

View File

@ -2624,7 +2624,7 @@ void tst_qqmllanguage::scriptStringWithoutSourceCode()
memcpy(qmlUnit, readOnlyQmlUnit.data(), readOnlyQmlUnit->unitSize);
qmlUnit->flags &= ~QV4::CompiledData::Unit::StaticData;
compilationUnit->setUnitData(qmlUnit);
compilationUnit->baseCompilationUnit()->setUnitData(qmlUnit);
const QV4::CompiledData::Object *rootObject = compilationUnit->objectAt(/*root object*/0);
QCOMPARE(compilationUnit->stringAt(rootObject->inheritedTypeNameIndex), QString("MyTypeObject"));

View File

@ -60,7 +60,7 @@ void tst_qqmltranslation::translation()
QQmlEnginePrivate *engine = QQmlEnginePrivate::get(context->engine());
QQmlRefPointer<QQmlTypeData> typeData = engine->typeLoader.getType(context->baseUrl());
QVERIFY(!typeData->backupSourceCode().isValid());
QV4::CompiledData::CompilationUnit *compilationUnit = typeData->compilationUnit();
QV4::ExecutableCompilationUnit *compilationUnit = typeData->compilationUnit();
QVERIFY(compilationUnit);
QSet<QString> compiledTranslations;
@ -73,7 +73,7 @@ void tst_qqmltranslation::translation()
<< QStringLiteral("emptyContext");
const QV4::CompiledData::Object *rootObject
= compilationUnit->qmlData->objectAt(/*root object*/0);
= compilationUnit->qmlData()->objectAt(/*root object*/0);
const QV4::CompiledData::Binding *binding = rootObject->bindingTable();
for (quint32 i = 0; i < rootObject->nBindings; ++i, ++binding) {
const QString propertyName = compilationUnit->stringAt(binding->propertyNameIndex);
@ -125,11 +125,11 @@ void tst_qqmltranslation::idTranslation()
QQmlEnginePrivate *engine = QQmlEnginePrivate::get(context->engine());
QQmlRefPointer<QQmlTypeData> typeData = engine->typeLoader.getType(context->baseUrl());
QVERIFY(!typeData->backupSourceCode().isValid());
QV4::CompiledData::CompilationUnit *compilationUnit = typeData->compilationUnit();
QV4::ExecutableCompilationUnit *compilationUnit = typeData->compilationUnit();
QVERIFY(compilationUnit);
const QV4::CompiledData::Object *rootObject
= compilationUnit->qmlData->objectAt(/*root object*/0);
= compilationUnit->qmlData()->objectAt(/*root object*/0);
const QV4::CompiledData::Binding *binding = rootObject->bindingTable();
for (quint32 i = 0; i < rootObject->nBindings; ++i, ++binding) {
const QString propertyName = compilationUnit->stringAt(binding->propertyNameIndex);

View File

@ -78,7 +78,7 @@ void tst_toolsupport::offsets_data()
= QTest::newRow("CompiledData::CompilationUnit::data")
<< pmm_to_offsetof(&QV4::CompiledData::CompilationUnit::data);
data << 0 << 0;
data << 4 << 8;
}
{