diff options
-rw-r--r-- | src/qml/compiler/qqmlirbuilder.cpp | 81 | ||||
-rw-r--r-- | src/qml/compiler/qqmlirbuilder_p.h | 13 | ||||
-rw-r--r-- | src/qml/qml/qqmltypecompiler.cpp | 78 | ||||
-rw-r--r-- | src/qml/qml/qqmltypecompiler_p.h | 18 | ||||
-rw-r--r-- | tools/qmlcachegen/qmlcachegen.cpp | 9 |
5 files changed, 76 insertions, 123 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index 6dc6f191ab..3bad0d6a10 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -1746,19 +1746,11 @@ char *QmlUnitGenerator::writeBindings(char *bindingPtr, const Object *o, Binding return bindingPtr; } -JSCodeGen::JSCodeGen(const QString &sourceCode, QV4::Compiler::JSUnitGenerator *jsUnitGenerator, - QV4::Compiler::Module *jsModule, QQmlJS::Engine *jsEngine, - QQmlJS::AST::UiProgram *qmlRoot, - const QV4::Compiler::StringTableGenerator *stringPool, const QSet<QString> &globalNames) - : QV4::Compiler::Codegen(jsUnitGenerator, /*strict mode*/false) - , sourceCode(sourceCode) - , jsEngine(jsEngine) - , qmlRoot(qmlRoot) - , stringPool(stringPool) +JSCodeGen::JSCodeGen(Document *document, const QSet<QString> &globalNames) + : QV4::Compiler::Codegen(&document->jsGenerator, /*strict mode*/false), document(document) { m_globalNames = globalNames; - - _module = jsModule; + _module = &document->jsModule; _fileNameIsUrl = true; } @@ -1766,17 +1758,17 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil { auto qmlName = [&](const CompiledFunctionOrExpression &c) { if (c.nameIndex != 0) - return stringPool->stringForIndex(c.nameIndex); + return document->stringAt(c.nameIndex); else return QStringLiteral("%qml-expression-entry"); }; QVector<int> runtimeFunctionIndices(functions.size()); - QV4::Compiler::ScanFunctions scan(this, sourceCode, QV4::Compiler::ContextType::Global); + QV4::Compiler::ScanFunctions scan(this, document->code, QV4::Compiler::ContextType::Global); scan.enterGlobalEnvironment(QV4::Compiler::ContextType::Binding); for (const CompiledFunctionOrExpression &f : functions) { - Q_ASSERT(f.node != qmlRoot); - Q_ASSERT(f.parentNode && f.parentNode != qmlRoot); + Q_ASSERT(f.node != document->program); + Q_ASSERT(f.parentNode && f.parentNode != document->program); QQmlJS::AST::FunctionDeclaration *function = QQmlJS::AST::cast<QQmlJS::AST::FunctionDeclaration*>(f.node); if (function) { @@ -1799,7 +1791,7 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil for (int i = 0; i < functions.count(); ++i) { const CompiledFunctionOrExpression &qmlFunction = functions.at(i); QQmlJS::AST::Node *node = qmlFunction.node; - Q_ASSERT(node != qmlRoot); + Q_ASSERT(node != document->program); QQmlJS::AST::FunctionDeclaration *function = QQmlJS::AST::cast<QQmlJS::AST::FunctionDeclaration*>(node); @@ -1814,7 +1806,7 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil body = function->body; } else { // Synthesize source elements. - QQmlJS::MemoryPool *pool = jsEngine->pool(); + QQmlJS::MemoryPool *pool = document->jsParserEngine.pool(); QQmlJS::AST::Statement *stmt = node->statementCast(); if (!stmt) { @@ -1834,3 +1826,58 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil return runtimeFunctionIndices; } + +bool JSCodeGen::generateCodeForComponents(const QVector<quint32> &componentRoots) +{ + for (int i = 0; i < componentRoots.count(); ++i) { + if (!compileComponent(componentRoots.at(i))) + return false; + } + + return compileComponent(/*root object*/0); +} + +bool JSCodeGen::compileComponent(int contextObject) +{ + const QmlIR::Object *obj = document->objects.at(contextObject); + if (obj->flags & QV4::CompiledData::Object::IsComponent) { + Q_ASSERT(obj->bindingCount() == 1); + const QV4::CompiledData::Binding *componentBinding = obj->firstBinding(); + Q_ASSERT(componentBinding->type == QV4::CompiledData::Binding::Type_Object); + contextObject = componentBinding->value.objectIndex; + } + + return compileJavaScriptCodeInObjectsRecursively(contextObject, contextObject); +} + +bool JSCodeGen::compileJavaScriptCodeInObjectsRecursively(int objectIndex, int scopeObjectIndex) +{ + QmlIR::Object *object = document->objects.at(objectIndex); + if (object->flags & QV4::CompiledData::Object::IsComponent) + return true; + + if (object->functionsAndExpressions->count > 0) { + QList<QmlIR::CompiledFunctionOrExpression> functionsToCompile; + for (QmlIR::CompiledFunctionOrExpression *foe = object->functionsAndExpressions->first; foe; foe = foe->next) + functionsToCompile << *foe; + const QVector<int> runtimeFunctionIndices = generateJSCodeForFunctionsAndBindings(functionsToCompile); + if (hasError()) + return false; + + object->runtimeFunctionIndices.allocate(document->jsParserEngine.pool(), + runtimeFunctionIndices); + } + + for (const QmlIR::Binding *binding = object->firstBinding(); binding; binding = binding->next) { + if (binding->type < QV4::CompiledData::Binding::Type_Object) + continue; + + int target = binding->value.objectIndex; + int scope = binding->type == QV4::CompiledData::Binding::Type_Object ? target : scopeObjectIndex; + + if (!compileJavaScriptCodeInObjectsRecursively(binding->value.objectIndex, scope)) + return false; + } + + return true; +} diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h index e04fb923c3..b4a815f11b 100644 --- a/src/qml/compiler/qqmlirbuilder_p.h +++ b/src/qml/compiler/qqmlirbuilder_p.h @@ -518,18 +518,17 @@ private: struct Q_QML_PRIVATE_EXPORT JSCodeGen : public QV4::Compiler::Codegen { - JSCodeGen(const QString &sourceCode, QV4::Compiler::JSUnitGenerator *jsUnitGenerator, QV4::Compiler::Module *jsModule, - QQmlJS::Engine *jsEngine, QQmlJS::AST::UiProgram *qmlRoot, - const QV4::Compiler::StringTableGenerator *stringPool, const QSet<QString> &globalNames); + JSCodeGen(Document *document, const QSet<QString> &globalNames); // Returns mapping from input functions to index in IR::Module::functions / compiledData->runtimeFunctions QVector<int> generateJSCodeForFunctionsAndBindings(const QList<CompiledFunctionOrExpression> &functions); + bool generateCodeForComponents(const QVector<quint32> &componentRoots); + bool compileComponent(int contextObject); + bool compileJavaScriptCodeInObjectsRecursively(int objectIndex, int scopeObjectIndex); + private: - QString sourceCode; - QQmlJS::Engine *jsEngine; // needed for memory pool - QQmlJS::AST::UiProgram *qmlRoot; - const QV4::Compiler::StringTableGenerator *stringPool; + Document *document; }; } // namespace QmlIR diff --git a/src/qml/qml/qqmltypecompiler.cpp b/src/qml/qml/qqmltypecompiler.cpp index 6cbe81b4b8..c66fe75923 100644 --- a/src/qml/qml/qqmltypecompiler.cpp +++ b/src/qml/qml/qqmltypecompiler.cpp @@ -145,11 +145,11 @@ QQmlRefPointer<QV4::ExecutableCompilationUnit> QQmlTypeCompiler::compile() document->jsModule.fileName = typeData->urlString(); document->jsModule.finalUrl = typeData->finalUrlString(); - QmlIR::JSCodeGen v4CodeGenerator(document->code, &document->jsGenerator, &document->jsModule, &document->jsParserEngine, - document->program, &document->jsGenerator.stringTable, engine->v4engine()->illegalNames()); - QQmlJSCodeGenerator jsCodeGen(this, &v4CodeGenerator); - if (!jsCodeGen.generateCodeForComponents()) + QmlIR::JSCodeGen v4CodeGenerator(document, engine->v4engine()->illegalNames()); + if (!v4CodeGenerator.generateCodeForComponents(componentRoots())) { + recordError(v4CodeGenerator.error()); return nullptr; + } document->javaScriptCompilationUnit = v4CodeGenerator.generateCompilationUnit(/*generated unit data*/false); } @@ -1309,76 +1309,6 @@ bool QQmlDeferredAndCustomParserBindingScanner::scanObject(int objectIndex) return true; } -QQmlJSCodeGenerator::QQmlJSCodeGenerator(QQmlTypeCompiler *typeCompiler, QmlIR::JSCodeGen *v4CodeGen) - : QQmlCompilePass(typeCompiler) - , customParsers(typeCompiler->customParserCache()) - , qmlObjects(*typeCompiler->qmlObjects()) - , propertyCaches(typeCompiler->propertyCaches()) - , v4CodeGen(v4CodeGen) -{ -} - -bool QQmlJSCodeGenerator::generateCodeForComponents() -{ - const QVector<quint32> &componentRoots = compiler->componentRoots(); - for (int i = 0; i < componentRoots.count(); ++i) { - if (!compileComponent(componentRoots.at(i))) - return false; - } - - return compileComponent(/*root object*/0); -} - -bool QQmlJSCodeGenerator::compileComponent(int contextObject) -{ - const QmlIR::Object *obj = qmlObjects.at(contextObject); - if (obj->flags & QV4::CompiledData::Object::IsComponent) { - Q_ASSERT(obj->bindingCount() == 1); - const QV4::CompiledData::Binding *componentBinding = obj->firstBinding(); - Q_ASSERT(componentBinding->type == QV4::CompiledData::Binding::Type_Object); - contextObject = componentBinding->value.objectIndex; - } - - if (!compileJavaScriptCodeInObjectsRecursively(contextObject, contextObject)) - return false; - - return true; -} - -bool QQmlJSCodeGenerator::compileJavaScriptCodeInObjectsRecursively(int objectIndex, int scopeObjectIndex) -{ - QmlIR::Object *object = qmlObjects.at(objectIndex); - if (object->flags & QV4::CompiledData::Object::IsComponent) - return true; - - if (object->functionsAndExpressions->count > 0) { - QList<QmlIR::CompiledFunctionOrExpression> functionsToCompile; - for (QmlIR::CompiledFunctionOrExpression *foe = object->functionsAndExpressions->first; foe; foe = foe->next) - functionsToCompile << *foe; - const QVector<int> runtimeFunctionIndices = v4CodeGen->generateJSCodeForFunctionsAndBindings(functionsToCompile); - if (v4CodeGen->hasError()) { - compiler->recordError(v4CodeGen->error()); - return false; - } - - QQmlJS::MemoryPool *pool = compiler->memoryPool(); - object->runtimeFunctionIndices.allocate(pool, runtimeFunctionIndices); - } - - for (const QmlIR::Binding *binding = object->firstBinding(); binding; binding = binding->next) { - if (binding->type < QV4::CompiledData::Binding::Type_Object) - continue; - - int target = binding->value.objectIndex; - int scope = binding->type == QV4::CompiledData::Binding::Type_Object ? target : scopeObjectIndex; - - if (!compileJavaScriptCodeInObjectsRecursively(binding->value.objectIndex, scope)) - return false; - } - - return true; -} - QQmlDefaultPropertyMerger::QQmlDefaultPropertyMerger(QQmlTypeCompiler *typeCompiler) : QQmlCompilePass(typeCompiler) , qmlObjects(*typeCompiler->qmlObjects()) diff --git a/src/qml/qml/qqmltypecompiler_p.h b/src/qml/qml/qqmltypecompiler_p.h index 615694d4bc..40b0337848 100644 --- a/src/qml/qml/qqmltypecompiler_p.h +++ b/src/qml/qml/qqmltypecompiler_p.h @@ -309,24 +309,6 @@ private: bool _seenObjectWithId; }; -// ### merge with QtQml::JSCodeGen and operate directly on object->functionsAndExpressions once old compiler is gone. -class QQmlJSCodeGenerator : public QQmlCompilePass -{ -public: - QQmlJSCodeGenerator(QQmlTypeCompiler *typeCompiler, QmlIR::JSCodeGen *v4CodeGen); - - bool generateCodeForComponents(); - -private: - bool compileComponent(int componentRoot); - bool compileJavaScriptCodeInObjectsRecursively(int objectIndex, int scopeObjectIndex); - - const QHash<int, QQmlCustomParser*> &customParsers; - const QVector<QmlIR::Object*> &qmlObjects; - const QQmlPropertyCacheVector * const propertyCaches; - QmlIR::JSCodeGen * const v4CodeGen; -}; - class QQmlDefaultPropertyMerger : public QQmlCompilePass { public: diff --git a/tools/qmlcachegen/qmlcachegen.cpp b/tools/qmlcachegen/qmlcachegen.cpp index cbfc110089..2cbadeeb60 100644 --- a/tools/qmlcachegen/qmlcachegen.cpp +++ b/tools/qmlcachegen/qmlcachegen.cpp @@ -205,10 +205,7 @@ static bool compileQmlFile(const QString &inputFileName, SaveFunction saveFuncti annotateListElements(&irDocument); { - QmlIR::JSCodeGen v4CodeGen(irDocument.code, - &irDocument.jsGenerator, &irDocument.jsModule, - &irDocument.jsParserEngine, irDocument.program, - &irDocument.jsGenerator.stringTable, illegalNames); + QmlIR::JSCodeGen v4CodeGen(&irDocument, illegalNames); for (QmlIR::Object *object: qAsConst(irDocument.objects)) { if (object->functionsAndExpressions->count == 0) continue; @@ -309,9 +306,7 @@ static bool compileJSFile(const QString &inputFileName, const QString &inputFile } { - QmlIR::JSCodeGen v4CodeGen(irDocument.code, &irDocument.jsGenerator, - &irDocument.jsModule, &irDocument.jsParserEngine, - irDocument.program, &irDocument.jsGenerator.stringTable, illegalNames); + QmlIR::JSCodeGen v4CodeGen(&irDocument, illegalNames); v4CodeGen.generateFromProgram(inputFileName, inputFileUrl, sourceCode, program, &irDocument.jsModule, QV4::Compiler::ContextType::ScriptImportedByQML); if (v4CodeGen.hasError()) { |