From 6a8d4f614171444a77a127dc2e22f295d1ffabe2 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 29 Apr 2019 13:05:03 +0200 Subject: Don't wrap the attachedProperties function into a template Otherwise it gets a separate address for each CU in which the template is instantiated. We want to use the address as key to the attached properties, though. Fixes: QTBUG-75385 Change-Id: Iaec82db116a032f7cb1d40670bb47fdf610664a2 Reviewed-by: Mitch Curtis Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlprivate.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/qml/qml') diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h index fa05b3fe19..ae84803648 100644 --- a/src/qml/qml/qqmlprivate.h +++ b/src/qml/qml/qqmlprivate.h @@ -190,16 +190,13 @@ namespace QQmlPrivate template class AttachedPropertySelector { - static inline QObject *attachedProperties(QObject *obj) { - return T::qmlAttachedProperties(obj); - } template static inline const QMetaObject *attachedPropertiesMetaObject(ReturnType *(*)(QObject *)) { return &ReturnType::staticMetaObject; } public: static inline QQmlAttachedPropertiesFunc func() { - return &attachedProperties; + return QQmlAttachedPropertiesFunc(&T::qmlAttachedProperties); } static inline const QMetaObject *metaObject() { return attachedPropertiesMetaObject(&T::qmlAttachedProperties); -- cgit v1.2.3 From d2c089eb11d3ad6a9917efde8f13b36931b35baf Mon Sep 17 00:00:00 2001 From: Milian Wolff Date: Mon, 29 Apr 2019 10:46:02 +0200 Subject: Add Q_TRACE calls to QtQml for QML profiler trace points This adds tracepoints for LTTng/ETW at the positions that are also used by the QML profiler within QtQml. I.e. with the tracepoints here, you'll see which QML function is being executed which is already quite helpful. This will allow us to bridge the gap between C++ and QML when tracing with LTTng/ETW. Additionally, you'll also be able to see kernel tracepoints which bridges another gap. Combined, this approach can give much deeper insights into what the (embedded) system is doing compared to just looking at the QML profiler alone. Change-Id: Ia8f71bf6d44b7f51c3c5aaa38f032675604aeca6 Reviewed-by: Ulf Hermann Reviewed-by: Rafael Roquetto --- src/qml/qml/qqmlobjectcreator.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'src/qml/qml') diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index b62b07e39c..d5b15a7a5a 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -57,6 +57,8 @@ #include #include +#include + QT_USE_NAMESPACE namespace { @@ -1130,6 +1132,9 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo { const QV4::CompiledData::Object *obj = compilationUnit->objectAt(index); QQmlObjectCreationProfiler profiler(sharedState->profiler.profiler, obj); + Q_TRACE(QQmlObjectCreator_createInstance_entry, compilationUnit.data(), obj, context->url()); + QString typeName; + Q_TRACE_EXIT(QQmlObjectCreator_createInstance_exit, typeName); ActiveOCRestorer ocRestorer(this, QQmlEnginePrivate::get(engine)); @@ -1143,8 +1148,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo if (obj->flags & QV4::CompiledData::Object::IsComponent) { isComponent = true; QQmlComponent *component = new QQmlComponent(engine, compilationUnit.data(), index, parent); - Q_QML_OC_PROFILE(sharedState->profiler, profiler.update( - compilationUnit.data(), obj, QStringLiteral(""), context->url())); + typeName = QStringLiteral(""); QQmlComponentPrivate::get(component)->creationContext = context; instance = component; ddata = QQmlData::get(instance, /*create*/true); @@ -1155,8 +1159,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo installPropertyCache = !typeRef->isFullyDynamicType; QQmlType type = typeRef->type; if (type.isValid()) { - Q_QML_OC_PROFILE(sharedState->profiler, profiler.update( - compilationUnit.data(), obj, type.qmlTypeName(), context->url())); + typeName = type.qmlTypeName(); void *ddataMemory = nullptr; type.create(&instance, &ddataMemory, sizeof(QQmlData)); @@ -1188,9 +1191,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo sharedState->allCreatedObjects.push(instance); } else { Q_ASSERT(typeRef->compilationUnit); - Q_QML_OC_PROFILE(sharedState->profiler, profiler.update( - compilationUnit.data(), obj, typeRef->compilationUnit->fileName(), - context->url())); + typeName = typeRef->compilationUnit->fileName(); if (typeRef->compilationUnit->unitData()->isSingleton()) { recordError(obj->location, tr("Composite Singleton Type %1 is not creatable").arg(stringAt(obj->inheritedTypeNameIndex))); @@ -1217,6 +1218,11 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo ddata = QQmlData::get(instance, /*create*/true); } + + Q_QML_OC_PROFILE(sharedState->profiler, profiler.update( + compilationUnit.data(), obj, typeName, context->url())); + Q_UNUSED(typeName); // only relevant for tracing + ddata->lineNumber = obj->location.line; ddata->columnNumber = obj->location.column; -- cgit v1.2.3 From 5032ff5c2b48d53e4580bb7d50b1f6de081263b0 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 4 Apr 2019 15:41:18 +0200 Subject: Move workerscript to its own module Change-Id: I778cfe842ddf1c600a837d8f2061a338887eed95 Reviewed-by: Lars Knoll --- src/qml/qml/qqmlengine.cpp | 16 ---------------- src/qml/qml/qqmlengine_p.h | 4 +--- 2 files changed, 1 insertion(+), 19 deletions(-) (limited to 'src/qml/qml') diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index bb2b3e462c..cb94ae379e 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -87,9 +87,6 @@ #include #endif #include -#if QT_CONFIG(qml_worker_script) -#include -#endif #include #ifdef Q_OS_WIN // for %APPDATA% @@ -239,9 +236,6 @@ void QQmlEnginePrivate::registerQuickTypes() #endif qmlRegisterType(uri, 2, 8, "LoggingCategory"); qmlRegisterType(uri, 2, 12, "LoggingCategory"); -#if QT_CONFIG(qml_worker_script) - qmlRegisterType(uri, 2, 0, "WorkerScript"); -#endif #if QT_CONFIG(qml_locale) qmlRegisterUncreatableType(uri, 2, 0, "Locale", QQmlEngine::tr("Locale cannot be instantiated. Use Qt.locale()")); #endif @@ -968,16 +962,6 @@ void QQmlEnginePrivate::init() rootContext = new QQmlContext(q,true); } -#if QT_CONFIG(qml_worker_script) -QQuickWorkerScriptEngine *QQmlEnginePrivate::getWorkerScriptEngine() -{ - Q_Q(QQmlEngine); - if (!workerScriptEngine) - workerScriptEngine = new QQuickWorkerScriptEngine(q); - return workerScriptEngine; -} -#endif - /*! \class QQmlEngine \since 5.0 diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h index 4f7fb79593..6ef88404fd 100644 --- a/src/qml/qml/qqmlengine_p.h +++ b/src/qml/qml/qqmlengine_p.h @@ -94,7 +94,6 @@ class QQmlTypeNameCache; class QQmlComponentAttached; class QQmlCleanup; class QQmlDelayedError; -class QQuickWorkerScriptEngine; class QQmlObjectCreator; class QDir; class QQmlIncubator; @@ -154,8 +153,7 @@ public: QV4::ExecutionEngine *v4engine() const { return q_func()->handle(); } #if QT_CONFIG(qml_worker_script) - QQuickWorkerScriptEngine *getWorkerScriptEngine(); - QQuickWorkerScriptEngine *workerScriptEngine; + QThread *workerScriptEngine; #endif QUrl baseUrl; -- cgit v1.2.3 From 791e63021e1e1333ff3c678674df8f4f18212e43 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 6 May 2019 13:06:15 +0200 Subject: Move QQmlIR::IRLoader out of qqmlirbuilder* We don't need it to build the IR and we can drop a few checks for V4_BOOTSTRAP this way. Change-Id: I9464e65528c70c42ebc8ddad576eaab001dc9d2f Reviewed-by: Simon Hausmann --- src/qml/qml/qqmltypeloader.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/qml/qml') diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 457558fb56..1f80e1905e 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -52,6 +52,7 @@ #include #include #include +#include #include #include @@ -2502,7 +2503,7 @@ void QQmlTypeData::dataReceived(const SourceCodeData &data) void QQmlTypeData::initializeFromCachedUnit(const QV4::CompiledData::Unit *unit) { m_document.reset(new QmlIR::Document(isDebugging())); - QmlIR::IRLoader loader(unit, m_document.data()); + QQmlIRLoader loader(unit, m_document.data()); loader.load(); m_document->jsModule.fileName = urlString(); m_document->jsModule.finalUrl = finalUrlString(); @@ -2544,7 +2545,7 @@ bool QQmlTypeData::loadFromSource() void QQmlTypeData::restoreIR(QQmlRefPointer unit) { m_document.reset(new QmlIR::Document(isDebugging())); - QmlIR::IRLoader 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(); -- cgit v1.2.3 From a8b3536d6e5e7eb1c51fb20df071185dbce317a2 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 8 May 2019 13:29:50 +0200 Subject: Move compileModule() into qv4codegen.cpp This is a better fit for the method. In turn, remove all the V4_BOOTSTRAP conditions from qv4engine_p.h and make sure we don't include or compile it in bootstrap mode. Change-Id: I5933b0724e561313ca20c420b83e4d70e63bddf5 Reviewed-by: Simon Hausmann --- src/qml/qml/qqmltypeloader.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/qml/qml') diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 1f80e1905e..a953e677fa 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -3049,7 +3049,8 @@ void QQmlScriptBlob::dataReceived(const SourceCodeData &data) if (m_isModule) { QList diagnostics; - unit = QV4::ExecutionEngine::compileModule(isDebugging(), urlString(), source, data.sourceTimeStamp(), &diagnostics); + unit = QV4::Compiler::Codegen::compileModule(isDebugging(), urlString(), source, + data.sourceTimeStamp(), &diagnostics); QList errors = QQmlEnginePrivate::qmlErrorFromDiagnostics(urlString(), diagnostics); if (!errors.isEmpty()) { setError(errors); -- cgit v1.2.3 From fd6321c03e2d63997078bfa41332dbddefbb86b0 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Fri, 5 Apr 2019 09:59:10 +0200 Subject: Remove last traces of QV8Engine Change-Id: I59f738402d51e39188bbbca2ef1fbc8a61612372 Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlcomponent.cpp | 2 +- src/qml/qml/qqmlengine.cpp | 2 +- src/qml/qml/qqmlengine_p.h | 10 - src/qml/qml/qqmlglobal_p.h | 1 - src/qml/qml/qqmllocale.cpp | 2 +- src/qml/qml/qqmlpropertycache.cpp | 2 +- src/qml/qml/qqmltypeloader.cpp | 2 +- src/qml/qml/qqmlvaluetype.cpp | 1 + src/qml/qml/qqmlxmlhttprequest.cpp | 18 +- src/qml/qml/v8/qqmlbuiltinfunctions.cpp | 15 +- src/qml/qml/v8/qv8engine.cpp | 331 -------------------------------- src/qml/qml/v8/qv8engine_p.h | 228 ---------------------- src/qml/qml/v8/v8.pri | 2 - 13 files changed, 19 insertions(+), 597 deletions(-) delete mode 100644 src/qml/qml/v8/qv8engine.cpp delete mode 100644 src/qml/qml/v8/qv8engine_p.h (limited to 'src/qml/qml') diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index 64d2a064df..f9f26b6b1e 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -72,7 +72,7 @@ namespace { QT_BEGIN_NAMESPACE -class QQmlComponentExtension : public QV8Engine::Deletable +class QQmlComponentExtension : public QV4::ExecutionEngine::Deletable { public: QQmlComponentExtension(QV4::ExecutionEngine *v4); diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index cb94ae379e..8bdbe0fc47 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -957,7 +957,7 @@ void QQmlEnginePrivate::init() qRegisterMetaType >(); qRegisterMetaType(); - v8engine()->setEngine(q); + q->handle()->setQmlEngine(q); rootContext = new QQmlContext(q,true); } diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h index 6ef88404fd..668dfed91e 100644 --- a/src/qml/qml/qqmlengine_p.h +++ b/src/qml/qml/qqmlengine_p.h @@ -76,7 +76,6 @@ #include -#include #include #include @@ -149,7 +148,6 @@ public: QQmlDelayedError *erroredBindings; int inProgressCreations; - QV8Engine *v8engine() const { return q_func()->handle()->v8Engine; } QV4::ExecutionEngine *v4engine() const { return q_func()->handle(); } #if QT_CONFIG(qml_worker_script) @@ -240,7 +238,6 @@ public: static void warning(QQmlEnginePrivate *, const QQmlError &); static void warning(QQmlEnginePrivate *, const QList &); - inline static QV8Engine *getV8Engine(QQmlEngine *e); inline static QV4::ExecutionEngine *getV4Engine(QQmlEngine *e); inline static QQmlEnginePrivate *get(QQmlEngine *e); inline static const QQmlEnginePrivate *get(const QQmlEngine *e); @@ -388,13 +385,6 @@ QQmlPropertyCache *QQmlEnginePrivate::cache(const QQmlType &type, int minorVersi return QQmlMetaType::propertyCache(type, minorVersion); } -QV8Engine *QQmlEnginePrivate::getV8Engine(QQmlEngine *e) -{ - Q_ASSERT(e); - - return e->handle()->v8Engine; -} - QV4::ExecutionEngine *QQmlEnginePrivate::getV4Engine(QQmlEngine *e) { Q_ASSERT(e); diff --git a/src/qml/qml/qqmlglobal_p.h b/src/qml/qml/qqmlglobal_p.h index 53caffe040..136159993a 100644 --- a/src/qml/qml/qqmlglobal_p.h +++ b/src/qml/qml/qqmlglobal_p.h @@ -55,7 +55,6 @@ #include #include #include -#include QT_BEGIN_NAMESPACE diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp index 2b17037df0..dca13ac8d4 100644 --- a/src/qml/qml/qqmllocale.cpp +++ b/src/qml/qml/qqmllocale.cpp @@ -662,7 +662,7 @@ LOCALE_STRING_PROPERTY(exponential) LOCALE_STRING_PROPERTY(amText) LOCALE_STRING_PROPERTY(pmText) -class QV4LocaleDataDeletable : public QV8Engine::Deletable +class QV4LocaleDataDeletable : public QV4::ExecutionEngine::Deletable { public: QV4LocaleDataDeletable(QV4::ExecutionEngine *engine); diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp index a6546ae330..48c4216d54 100644 --- a/src/qml/qml/qqmlpropertycache.cpp +++ b/src/qml/qml/qqmlpropertycache.cpp @@ -868,7 +868,7 @@ QQmlPropertyCacheMethodArguments *QQmlPropertyCache::createArgumentsObject(int a QString QQmlPropertyCache::signalParameterStringForJS(QV4::ExecutionEngine *engine, const QList ¶meterNameList, QString *errorString) { bool unnamedParameter = false; - const QSet &illegalNames = engine->v8Engine->illegalNames(); + const QSet &illegalNames = engine->illegalNames(); QString parameters; for (int i = 0; i < parameterNameList.count(); ++i) { diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index a953e677fa..d694909c7c 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -2516,7 +2516,7 @@ bool QQmlTypeData::loadFromSource() m_document.reset(new QmlIR::Document(isDebugging())); m_document->jsModule.sourceTimeStamp = m_backupSourceCode.sourceTimeStamp(); QQmlEngine *qmlEngine = typeLoader()->engine(); - QmlIR::IRBuilder compiler(qmlEngine->handle()->v8Engine->illegalNames()); + QmlIR::IRBuilder compiler(qmlEngine->handle()->illegalNames()); QString sourceError; const QString source = m_backupSourceCode.readAll(&sourceError); diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp index f08005fd20..fce753cd26 100644 --- a/src/qml/qml/qqmlvaluetype.cpp +++ b/src/qml/qml/qqmlvaluetype.cpp @@ -39,6 +39,7 @@ #include "qqmlvaluetype_p.h" +#include #include #include #include diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp index c6b7f2ab3f..b435f8ef66 100644 --- a/src/qml/qml/qqmlxmlhttprequest.cpp +++ b/src/qml/qml/qqmlxmlhttprequest.cpp @@ -95,7 +95,7 @@ struct QQmlXMLHttpRequestData { static inline QQmlXMLHttpRequestData *xhrdata(ExecutionEngine *v4) { - return (QQmlXMLHttpRequestData *)v4->v8Engine->xmlHttpRequestData(); + return (QQmlXMLHttpRequestData *)v4->xmlHttpRequestData(); } QQmlXMLHttpRequestData::QQmlXMLHttpRequestData() @@ -591,7 +591,7 @@ ReturnedValue NodePrototype::getProto(ExecutionEngine *v4) if (d->nodePrototype.isUndefined()) { ScopedObject p(scope, v4->memoryManager->allocate()); d->nodePrototype.set(v4, p); - v4->v8Engine->freezeObject(p); + v4->freezeObject(p); } return d->nodePrototype.value(); } @@ -640,7 +640,7 @@ ReturnedValue Element::prototype(ExecutionEngine *engine) p->setPrototypeUnchecked((pp = NodePrototype::getProto(engine))); p->defineAccessorProperty(QStringLiteral("tagName"), NodePrototype::method_get_nodeName, nullptr); d->elementPrototype.set(engine, p); - engine->v8Engine->freezeObject(p); + engine->freezeObject(p); } return d->elementPrototype.value(); } @@ -657,7 +657,7 @@ ReturnedValue Attr::prototype(ExecutionEngine *engine) p->defineAccessorProperty(QStringLiteral("value"), method_value, nullptr); p->defineAccessorProperty(QStringLiteral("ownerElement"), method_ownerElement, nullptr); d->attrPrototype.set(engine, p); - engine->v8Engine->freezeObject(p); + engine->freezeObject(p); } return d->attrPrototype.value(); } @@ -713,7 +713,7 @@ ReturnedValue CharacterData::prototype(ExecutionEngine *v4) p->defineAccessorProperty(QStringLiteral("data"), NodePrototype::method_get_nodeValue, nullptr); p->defineAccessorProperty(QStringLiteral("length"), method_length, nullptr); d->characterDataPrototype.set(v4, p); - v4->v8Engine->freezeObject(p); + v4->freezeObject(p); } return d->characterDataPrototype.value(); } @@ -749,7 +749,7 @@ ReturnedValue Text::prototype(ExecutionEngine *v4) p->defineAccessorProperty(QStringLiteral("isElementContentWhitespace"), method_isElementContentWhitespace, nullptr); p->defineAccessorProperty(QStringLiteral("wholeText"), method_wholeText, nullptr); d->textPrototype.set(v4, p); - v4->v8Engine->freezeObject(p); + v4->freezeObject(p); } return d->textPrototype.value(); } @@ -764,7 +764,7 @@ ReturnedValue CDATA::prototype(ExecutionEngine *v4) ScopedObject pp(scope); p->setPrototypeUnchecked((pp = Text::prototype(v4))); d->cdataPrototype.set(v4, p); - v4->v8Engine->freezeObject(p); + v4->freezeObject(p); } return d->cdataPrototype.value(); } @@ -782,7 +782,7 @@ ReturnedValue Document::prototype(ExecutionEngine *v4) p->defineAccessorProperty(QStringLiteral("xmlStandalone"), method_xmlStandalone, nullptr); p->defineAccessorProperty(QStringLiteral("documentElement"), method_documentElement, nullptr); d->documentPrototype.set(v4, p); - v4->v8Engine->freezeObject(p); + v4->freezeObject(p); } return d->documentPrototype.value(); } @@ -1646,7 +1646,7 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject Scope scope(f->engine()); const QQmlXMLHttpRequestCtor *ctor = static_cast(f); - QQmlXMLHttpRequest *r = new QQmlXMLHttpRequest(scope.engine->v8Engine->networkAccessManager(), scope.engine); + QQmlXMLHttpRequest *r = new QQmlXMLHttpRequest(scope.engine->qmlEngine()->networkAccessManager(), scope.engine); Scoped w(scope, scope.engine->memoryManager->allocate(r)); ScopedObject proto(scope, ctor->d()->proto); w->setPrototypeUnchecked(proto); diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index 3bc588b50e..532bfa8754 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -47,7 +47,6 @@ #if QT_CONFIG(qml_locale) #include #endif -#include #include #include @@ -1684,10 +1683,8 @@ ReturnedValue ConsoleObject::method_time(const FunctionObject *b, const Value *, if (argc != 1) THROW_GENERIC_ERROR("console.time(): Invalid arguments"); - QV8Engine *v8engine = scope.engine->v8Engine; - QString name = argv[0].toQStringNoThrow(); - v8engine->startTimer(name); + scope.engine->startTimer(name); return QV4::Encode::undefined(); } @@ -1697,11 +1694,9 @@ ReturnedValue ConsoleObject::method_timeEnd(const FunctionObject *b, const Value if (argc != 1) THROW_GENERIC_ERROR("console.timeEnd(): Invalid arguments"); - QV8Engine *v8engine = scope.engine->v8Engine; - QString name = argv[0].toQStringNoThrow(); bool wasRunning; - qint64 elapsed = v8engine->stopTimer(name, &wasRunning); + qint64 elapsed = scope.engine->stopTimer(name, &wasRunning); if (wasRunning) { qDebug("%s: %llims", qPrintable(name), elapsed); } @@ -1717,13 +1712,12 @@ ReturnedValue ConsoleObject::method_count(const FunctionObject *b, const Value * Scope scope(b); QV4::ExecutionEngine *v4 = scope.engine; - QV8Engine *v8engine = scope.engine->v8Engine; QV4::CppStackFrame *frame = v4->currentStackFrame; QString scriptName = frame->source(); - int value = v8engine->consoleCountHelper(scriptName, frame->lineNumber(), 0); + int value = v4->consoleCountHelper(scriptName, frame->lineNumber(), 0); QString message = name + QLatin1String(": ") + QString::number(value); QMessageLogger(qPrintable(scriptName), frame->lineNumber(), @@ -2147,8 +2141,7 @@ function. */ ReturnedValue QtObject::method_callLater(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc) { - QV8Engine *v8engine = b->engine()->v8Engine; - return v8engine->delayedCallQueue()->addUniquelyAndExecuteLater(b, thisObject, argv, argc); + return b->engine()->delayedCallQueue()->addUniquelyAndExecuteLater(b, thisObject, argv, argc); } QT_END_NAMESPACE diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp deleted file mode 100644 index d76344b613..0000000000 --- a/src/qml/qml/v8/qv8engine.cpp +++ /dev/null @@ -1,331 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQml module 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$ -** -****************************************************************************/ - -#include "qv8engine_p.h" - -#if QT_CONFIG(qml_sequence_object) -#include "qv4sequenceobject_p.h" -#endif - -#include "private/qjsengine_p.h" - -#include -#include -#include -#if QT_CONFIG(qml_xml_http_request) -#include -#endif -#if QT_CONFIG(qml_locale) -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include - -#include "qv4domerrors_p.h" -#include "qv4sqlerrors_p.h" - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -Q_DECLARE_METATYPE(QList) - - -// XXX TODO: Need to check all the global functions will also work in a worker script where the -// QQmlEngine is not available -QT_BEGIN_NAMESPACE - -template -ReturnType convertJSValueToVariantType(const QJSValue &value) -{ - return value.toVariant().value(); -} - -static void saveJSValue(QDataStream &stream, const void *data) -{ - const QJSValue *jsv = reinterpret_cast(data); - quint32 isNullOrUndefined = 0; - if (jsv->isNull()) - isNullOrUndefined |= 0x1; - if (jsv->isUndefined()) - isNullOrUndefined |= 0x2; - stream << isNullOrUndefined; - if (!isNullOrUndefined) - reinterpret_cast(data)->toVariant().save(stream); -} - -static void restoreJSValue(QDataStream &stream, void *data) -{ - QJSValue *jsv = reinterpret_cast(data); - - quint32 isNullOrUndefined; - stream >> isNullOrUndefined; - - if (isNullOrUndefined & 0x1) { - *jsv = QJSValue(QJSValue::NullValue); - } else if (isNullOrUndefined & 0x2) { - *jsv = QJSValue(); - } else { - QVariant v; - v.load(stream); - QJSValuePrivate::setVariant(jsv, v); - } -} - -QV8Engine::QV8Engine(QV4::ExecutionEngine *v4) - : m_engine(nullptr) - , m_v4Engine(v4) -#if QT_CONFIG(qml_xml_http_request) - , m_xmlHttpRequestData(nullptr) -#endif -{ -#ifndef Q_OS_WASM // wasm does not have working simd QTBUG-63924 -#ifdef Q_PROCESSOR_X86_32 - if (!qCpuHasFeature(SSE2)) { - qFatal("This program requires an X86 processor that supports SSE2 extension, at least a Pentium 4 or newer"); - } -#endif -#endif - - QML_MEMORY_SCOPE_STRING("QV8Engine::QV8Engine"); - qMetaTypeId(); - qMetaTypeId >(); - - if (!QMetaType::hasRegisteredConverterFunction()) - QMetaType::registerConverter(convertJSValueToVariantType); - if (!QMetaType::hasRegisteredConverterFunction()) - QMetaType::registerConverter(convertJSValueToVariantType); - if (!QMetaType::hasRegisteredConverterFunction()) - QMetaType::registerConverter(convertJSValueToVariantType); - QMetaType::registerStreamOperators(qMetaTypeId(), saveJSValue, restoreJSValue); - - m_delayedCallQueue.init(m_v4Engine); - - QV4::QObjectWrapper::initializeBindings(m_v4Engine); -} - -QV8Engine::~QV8Engine() -{ - qDeleteAll(m_extensionData); - m_extensionData.clear(); - -#if QT_CONFIG(qml_xml_http_request) - qt_rem_qmlxmlhttprequest(m_v4Engine, m_xmlHttpRequestData); - m_xmlHttpRequestData = nullptr; -#endif -} - -#if QT_CONFIG(qml_network) -QNetworkAccessManager *QV8Engine::networkAccessManager() -{ - return QQmlEnginePrivate::get(m_engine)->getNetworkAccessManager(); -} -#endif - -const QSet &QV8Engine::illegalNames() const -{ - return m_illegalNames; -} - -void QV8Engine::initializeGlobal() -{ - QV4::Scope scope(m_v4Engine); - QV4::GlobalExtensions::init(m_v4Engine->globalObject, QJSEngine::AllExtensions); - - QV4::ScopedObject qt(scope, m_v4Engine->memoryManager->allocate(m_engine)); - m_v4Engine->globalObject->defineDefaultProperty(QStringLiteral("Qt"), qt); - -#if QT_CONFIG(qml_locale) - QQmlLocale::registerStringLocaleCompare(m_v4Engine); - QQmlDateExtension::registerExtension(m_v4Engine); - QQmlNumberExtension::registerExtension(m_v4Engine); -#endif - -#if QT_CONFIG(qml_xml_http_request) - qt_add_domexceptions(m_v4Engine); - m_xmlHttpRequestData = qt_add_qmlxmlhttprequest(m_v4Engine); -#endif - - qt_add_sqlexceptions(m_v4Engine); - - { - for (uint i = 0; i < m_v4Engine->globalObject->internalClass()->size; ++i) { - if (m_v4Engine->globalObject->internalClass()->nameMap.at(i).isString()) { - QV4::PropertyKey id = m_v4Engine->globalObject->internalClass()->nameMap.at(i); - m_illegalNames.insert(id.toQString()); - } - } - } -} - -static void freeze_recursive(QV4::ExecutionEngine *v4, QV4::Object *object) -{ - if (object->as()) - return; - - QV4::Scope scope(v4); - - bool instanceOfObject = false; - QV4::ScopedObject p(scope, object->getPrototypeOf()); - while (p) { - if (p->d() == v4->objectPrototype()->d()) { - instanceOfObject = true; - break; - } - p = p->getPrototypeOf(); - } - if (!instanceOfObject) - return; - - QV4::Heap::InternalClass *frozen = object->internalClass()->propertiesFrozen(); - if (object->internalClass() == frozen) - return; - object->setInternalClass(frozen); - - QV4::ScopedObject o(scope); - for (uint i = 0; i < frozen->size; ++i) { - if (!frozen->nameMap.at(i).isStringOrSymbol()) - continue; - o = *object->propertyData(i); - if (o) - freeze_recursive(v4, o); - } -} - -void QV8Engine::freezeObject(const QV4::Value &value) -{ - QV4::Scope scope(m_v4Engine); - QV4::ScopedObject o(scope, value); - freeze_recursive(m_v4Engine, o); -} - -struct QV8EngineRegistrationData -{ - QV8EngineRegistrationData() : extensionCount(0) {} - - QMutex mutex; - int extensionCount; -}; -Q_GLOBAL_STATIC(QV8EngineRegistrationData, registrationData); - -QMutex *QV8Engine::registrationMutex() -{ - return ®istrationData()->mutex; -} - -int QV8Engine::registerExtension() -{ - return registrationData()->extensionCount++; -} - -void QV8Engine::setExtensionData(int index, Deletable *data) -{ - if (m_extensionData.count() <= index) - m_extensionData.resize(index + 1); - - if (m_extensionData.at(index)) - delete m_extensionData.at(index); - - m_extensionData[index] = data; -} - -void QV8Engine::initQmlGlobalObject() -{ - initializeGlobal(); - freezeObject(*m_v4Engine->globalObject); -} - -void QV8Engine::setEngine(QQmlEngine *engine) -{ - m_engine = engine; - initQmlGlobalObject(); -} - -void QV8Engine::startTimer(const QString &timerName) -{ - if (!m_time.isValid()) - m_time.start(); - m_startedTimers[timerName] = m_time.elapsed(); -} - -qint64 QV8Engine::stopTimer(const QString &timerName, bool *wasRunning) -{ - if (!m_startedTimers.contains(timerName)) { - *wasRunning = false; - return 0; - } - *wasRunning = true; - qint64 startedAt = m_startedTimers.take(timerName); - return m_time.elapsed() - startedAt; -} - -int QV8Engine::consoleCountHelper(const QString &file, quint16 line, quint16 column) -{ - const QString key = file + QString::number(line) + QString::number(column); - int number = m_consoleCount.value(key, 0); - number++; - m_consoleCount.insert(key, number); - return number; -} - -QT_END_NAMESPACE - diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h deleted file mode 100644 index f9b69cfacc..0000000000 --- a/src/qml/qml/v8/qv8engine_p.h +++ /dev/null @@ -1,228 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQml module 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$ -** -****************************************************************************/ - -#ifndef QQMLV8ENGINE_P_H -#define QQMLV8ENGINE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "private/qintrusivelist_p.h" - - -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -namespace QV4 { - struct ArrayObject; - struct ExecutionEngine; - struct QObjectMethod; -} - -#define V4_DEFINE_EXTENSION(dataclass, datafunction) \ - static inline dataclass *datafunction(QV4::ExecutionEngine *engine) \ - { \ - static int extensionId = -1; \ - if (extensionId == -1) { \ - QV8Engine::registrationMutex()->lock(); \ - if (extensionId == -1) \ - extensionId = QV8Engine::registerExtension(); \ - QV8Engine::registrationMutex()->unlock(); \ - } \ - dataclass *rv = (dataclass *)engine->v8Engine->extensionData(extensionId); \ - if (!rv) { \ - rv = new dataclass(engine); \ - engine->v8Engine->setExtensionData(extensionId, rv); \ - } \ - return rv; \ - } \ - -// Used to allow a QObject method take and return raw V4 handles without having to expose -// 48 in the public API. -// Use like this: -// class MyClass : public QObject { -// Q_OBJECT -// ... -// Q_INVOKABLE void myMethod(QQmlV4Function*); -// }; -// The QQmlV8Function - and consequently the arguments and return value - only remains -// valid during the call. If the return value isn't set within myMethod(), the will return -// undefined. - -class QQmlV4Function -{ -public: - int length() const { return callData->argc(); } - QV4::ReturnedValue operator[](int idx) const { return (idx < callData->argc() ? callData->args[idx].asReturnedValue() : QV4::Encode::undefined()); } - void setReturnValue(QV4::ReturnedValue rv) { *retVal = rv; } - QV4::ExecutionEngine *v4engine() const { return e; } -private: - friend struct QV4::QObjectMethod; - QQmlV4Function(); - QQmlV4Function(const QQmlV4Function &); - QQmlV4Function &operator=(const QQmlV4Function &); - - QQmlV4Function(QV4::CallData *callData, QV4::Value *retVal, QV4::ExecutionEngine *e) - : callData(callData), retVal(retVal), e(e) - { - callData->thisObject = QV4::Encode::undefined(); - } - - QV4::CallData *callData; - QV4::Value *retVal; - QV4::ExecutionEngine *e; -}; - -class QObject; -class QQmlEngine; -class QNetworkAccessManager; -class QQmlContextData; - -class Q_QML_PRIVATE_EXPORT QV8Engine -{ - friend class QJSEngine; -public: -// static QJSEngine* get(QV8Engine* d) { Q_ASSERT(d); return d->q; } - static QV4::ExecutionEngine *getV4(QV8Engine *d) { return d->m_v4Engine; } - - QV8Engine(QV4::ExecutionEngine *v4); - virtual ~QV8Engine(); - - // This enum should be in sync with QQmlEngine::ObjectOwnership - enum ObjectOwnership { CppOwnership, JavaScriptOwnership }; - - struct Deletable { - virtual ~Deletable() {} - }; - - void initQmlGlobalObject(); - void setEngine(QQmlEngine *engine); - QQmlEngine *engine() { return m_engine; } - QQmlDelayedCallQueue *delayedCallQueue() { return &m_delayedCallQueue; } - -#if QT_CONFIG(qml_xml_http_request) - void *xmlHttpRequestData() const { return m_xmlHttpRequestData; } -#endif - - void freezeObject(const QV4::Value &value); - -#if QT_CONFIG(qml_network) - // Return the network access manager for this engine. By default this returns the network - // access manager of the QQmlEngine. It is overridden in the case of a threaded v8 - // instance (like in WorkerScript). - virtual QNetworkAccessManager *networkAccessManager(); -#endif - - // Return the list of illegal id names (the names of the properties on the global object) - const QSet &illegalNames() const; - - static QMutex *registrationMutex(); - static int registerExtension(); - - inline Deletable *extensionData(int) const; - void setExtensionData(int, Deletable *); - -public: - // used for console.time(), console.timeEnd() - void startTimer(const QString &timerName); - qint64 stopTimer(const QString &timerName, bool *wasRunning); - - // used for console.count() - int consoleCountHelper(const QString &file, quint16 line, quint16 column); - -protected: - QQmlEngine *m_engine; - QQmlDelayedCallQueue m_delayedCallQueue; - - QV4::ExecutionEngine *m_v4Engine; - -#if QT_CONFIG(qml_xml_http_request) - void *m_xmlHttpRequestData; -#endif - - QVector m_extensionData; - - QSet m_illegalNames; - - QElapsedTimer m_time; - QHash m_startedTimers; - - QHash m_consoleCount; - - void initializeGlobal(); - -private: - Q_DISABLE_COPY(QV8Engine) -}; - -inline QV8Engine::Deletable *QV8Engine::extensionData(int index) const -{ - if (index < m_extensionData.count()) - return m_extensionData[index]; - else - return nullptr; -} - - -QT_END_NAMESPACE - -#endif // QQMLV8ENGINE_P_H diff --git a/src/qml/qml/v8/v8.pri b/src/qml/qml/v8/v8.pri index 4592022939..fbcc47de0c 100644 --- a/src/qml/qml/v8/v8.pri +++ b/src/qml/qml/v8/v8.pri @@ -1,11 +1,9 @@ HEADERS += \ - $$PWD/qv8engine_p.h \ $$PWD/qv4domerrors_p.h \ $$PWD/qv4sqlerrors_p.h \ $$PWD/qqmlbuiltinfunctions_p.h SOURCES += \ - $$PWD/qv8engine.cpp \ $$PWD/qv4domerrors.cpp \ $$PWD/qv4sqlerrors.cpp \ $$PWD/qqmlbuiltinfunctions.cpp -- cgit v1.2.3 From 12829b50fc85587c9c08c834efd63ebe8ccbbcd2 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 8 May 2019 11:05:39 +0200 Subject: Register QObject along with QQmlComponent as basic type of the language Apparently we need it somewhere. Before the restructuring of imports all QtQml types were automatically registered on QQmlEnginePrivate::init(). We don't do this anymore, so we need to register the basic building blocks of the language separately now. Fixes: QTBUG-75645 Change-Id: I77fe23f709304586cd16986650b0056ea87bcd45 Reviewed-by: Liang Qi Reviewed-by: Mitch Curtis Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlengine.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/qml/qml') diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 8bdbe0fc47..ea639d870b 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -944,7 +944,11 @@ void QQmlEnginePrivate::init() Q_Q(QQmlEngine); if (baseModulesUninitialized) { - qmlRegisterType("QML", 1, 0, "Component"); // required for the Compiler. + + // required for the Compiler. + qmlRegisterType("QML", 1, 0, "QtObject"); + qmlRegisterType("QML", 1, 0, "Component"); + QQmlData::init(); baseModulesUninitialized = false; } -- cgit v1.2.3 From ae8c798a0a01334d1af33a59acdaeda8898a9f5c Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 6 May 2019 13:21:17 +0200 Subject: Drop some dead bootstrap code The dependencies are only hashed if a dependencyHasher is given. This is generally not the case when compiling ahead of time. There is also no need to hide the declaration of DependentTypesHasher from the bootstrap code. Change-Id: I0ea74c3079656ce1fe353956999820916c8ff626 Reviewed-by: Simon Hausmann --- src/qml/qml/qqmltypeloader.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/qml/qml') diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index d694909c7c..2233af6cd8 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -2357,10 +2357,12 @@ void QQmlTypeData::done() QQmlEngine *const engine = typeLoader()->engine(); - const auto dependencyHasher = [engine, &resolvedTypeCache, this](QCryptographicHash *hash) { - if (!resolvedTypeCache.addToHash(hash, engine)) - return false; - return ::addTypeReferenceChecksumsToHash(m_compositeSingletons, hash, engine); + const auto dependencyHasher = [engine, &resolvedTypeCache, this]() { + QCryptographicHash hash(QCryptographicHash::Md5); + return (resolvedTypeCache.addToHash(&hash, engine) + && ::addTypeReferenceChecksumsToHash(m_compositeSingletons, &hash, engine)) + ? hash.result() + : QByteArray(); }; // verify if any dependencies changed if we're using a cache -- cgit v1.2.3 From c1829ea50bf5c99428f0a19887c503b4c7bd4b9a Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 13 May 2019 15:49:42 +0200 Subject: Fix illegal downcast on QQmlEngine destruction Make QQmlEnginePrivate::isEngineThread() legal to call during QQmlEngine destruction. Change-Id: I2bae9d70883cf8013f39f2046ebe83bb8dbcd46b Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlengine_p.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src/qml/qml') diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h index d05c945ae4..92e56cd957 100644 --- a/src/qml/qml/qqmlengine_p.h +++ b/src/qml/qml/qqmlengine_p.h @@ -309,8 +309,8 @@ Returns true if the calling thread is the QQmlEngine thread. */ bool QQmlEnginePrivate::isEngineThread() const { - Q_Q(const QQmlEngine); - return QThread::currentThread() == q->thread(); + + return QThread::currentThread() == q_ptr->thread(); } /*! @@ -335,8 +335,6 @@ the instance directly if not. template void QQmlEnginePrivate::deleteInEngineThread(T *value) { - Q_Q(QQmlEngine); - Q_ASSERT(value); if (isEngineThread()) { delete value; @@ -352,7 +350,7 @@ void QQmlEnginePrivate::deleteInEngineThread(T *value) toDeleteInEngineThread.append(i); mutex.unlock(); if (wasEmpty) - QCoreApplication::postEvent(q, new QEvent(QEvent::User)); + QCoreApplication::postEvent(q_ptr, new QEvent(QEvent::User)); } } -- cgit v1.2.3 From 7f7d87c68da4cb29b2b2b9c324c6863228da0c26 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Tue, 7 May 2019 12:47:33 +0200 Subject: Split CompiledData::CompilationUnit in two We need a CompilationUnit that only holds the data needed for compilation and another one that is executable by the runtime. Change-Id: I704d859ba028576a18460f5e3a59f210f64535d3 Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlbinding.cpp | 6 +-- src/qml/qml/qqmlbinding_p.h | 2 +- src/qml/qml/qqmlcomponent.cpp | 3 +- src/qml/qml/qqmlcomponent.h | 7 ++- src/qml/qml/qqmlcomponent_p.h | 2 +- src/qml/qml/qqmlcontext.cpp | 2 +- src/qml/qml/qqmlcontext_p.h | 6 +-- src/qml/qml/qqmlcustomparser_p.h | 4 +- src/qml/qml/qqmldata_p.h | 8 ++-- src/qml/qml/qqmlengine.cpp | 6 +-- src/qml/qml/qqmlengine_p.h | 6 +-- src/qml/qml/qqmlincubator_p.h | 2 +- src/qml/qml/qqmljavascriptexpression.cpp | 4 +- src/qml/qml/qqmljavascriptexpression_p.h | 4 +- src/qml/qml/qqmlmetatype.cpp | 4 +- src/qml/qml/qqmlmetatype_p.h | 6 ++- src/qml/qml/qqmlobjectcreator.cpp | 60 ++++++++++++------------- src/qml/qml/qqmlobjectcreator_p.h | 8 ++-- src/qml/qml/qqmlproperty_p.h | 1 + src/qml/qml/qqmltype.cpp | 4 +- src/qml/qml/qqmltypeloader.cpp | 77 +++++++++++++++++--------------- src/qml/qml/qqmltypeloader_p.h | 19 ++++---- src/qml/qml/qqmltypewrapper.cpp | 2 +- src/qml/qml/qqmlvmemetaobject.cpp | 2 +- src/qml/qml/qqmlvmemetaobject_p.h | 4 +- src/qml/qml/v8/qqmlbuiltinfunctions.cpp | 3 +- 26 files changed, 130 insertions(+), 122 deletions(-) (limited to 'src/qml/qml') diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index 656c7dd515..7fb15af570 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -335,7 +335,7 @@ protected: class QQmlTranslationBinding : public GenericBinding { public: - QQmlTranslationBinding(const QQmlRefPointer &compilationUnit, const QV4::CompiledData::Binding *binding) + QQmlTranslationBinding(const QQmlRefPointer &compilationUnit, const QV4::CompiledData::Binding *binding) { setCompilationUnit(compilationUnit); m_binding = binding; @@ -356,7 +356,7 @@ public: if (!isAddedToObject() || hasError()) return; - const QString result = m_binding->valueAsString(m_compilationUnit.data()); + const QString result = m_compilationUnit->bindingValueAsString(m_binding); Q_ASSERT(targetObject()); @@ -378,7 +378,7 @@ private: const QV4::CompiledData::Binding *m_binding; }; -QQmlBinding *QQmlBinding::createTranslationBinding(const QQmlRefPointer &unit, const QV4::CompiledData::Binding *binding, QObject *obj, QQmlContextData *ctxt) +QQmlBinding *QQmlBinding::createTranslationBinding(const QQmlRefPointer &unit, const QV4::CompiledData::Binding *binding, QObject *obj, QQmlContextData *ctxt) { QQmlTranslationBinding *b = new QQmlTranslationBinding(unit, binding); diff --git a/src/qml/qml/qqmlbinding_p.h b/src/qml/qml/qqmlbinding_p.h index f192de4342..85b02dcde4 100644 --- a/src/qml/qml/qqmlbinding_p.h +++ b/src/qml/qml/qqmlbinding_p.h @@ -79,7 +79,7 @@ public: const QString &url = QString(), quint16 lineNumber = 0); static QQmlBinding *create(const QQmlPropertyData *property, QV4::Function *function, QObject *obj, QQmlContextData *ctxt, QV4::ExecutionContext *scope); - static QQmlBinding *createTranslationBinding(const QQmlRefPointer &unit, const QV4::CompiledData::Binding *binding, + static QQmlBinding *createTranslationBinding(const QQmlRefPointer &unit, const QV4::CompiledData::Binding *binding, QObject *obj, QQmlContextData *ctxt); ~QQmlBinding() override; diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index f9f26b6b1e..04debc0615 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -550,7 +550,8 @@ QQmlComponent::QQmlComponent(QQmlEngine *engine, const QString &fileName, /*! \internal */ -QQmlComponent::QQmlComponent(QQmlEngine *engine, QV4::CompiledData::CompilationUnit *compilationUnit, int start, QObject *parent) +QQmlComponent::QQmlComponent(QQmlEngine *engine, QV4::ExecutableCompilationUnit *compilationUnit, + int start, QObject *parent) : QQmlComponent(engine, parent) { Q_D(QQmlComponent); diff --git a/src/qml/qml/qqmlcomponent.h b/src/qml/qml/qqmlcomponent.h index 20199d0b21..39b6d4526f 100644 --- a/src/qml/qml/qqmlcomponent.h +++ b/src/qml/qml/qqmlcomponent.h @@ -59,9 +59,7 @@ class QQmlComponentPrivate; class QQmlComponentAttached; namespace QV4 { -namespace CompiledData { -struct CompilationUnit; -} +class ExecutableCompilationUnit; } class Q_QML_EXPORT QQmlComponent : public QObject @@ -128,7 +126,8 @@ protected: Q_INVOKABLE void incubateObject(QQmlV4Function *); private: - QQmlComponent(QQmlEngine *, QV4::CompiledData::CompilationUnit *compilationUnit, int, QObject *parent); + QQmlComponent(QQmlEngine *, QV4::ExecutableCompilationUnit *compilationUnit, int, + QObject *parent); Q_DISABLE_COPY(QQmlComponent) friend class QQmlTypeData; diff --git a/src/qml/qml/qqmlcomponent_p.h b/src/qml/qml/qqmlcomponent_p.h index 4d9e4c6c15..71275a2cd3 100644 --- a/src/qml/qml/qqmlcomponent_p.h +++ b/src/qml/qml/qqmlcomponent_p.h @@ -105,7 +105,7 @@ public: qreal progress; int start; - QQmlRefPointer compilationUnit; + QQmlRefPointer compilationUnit; struct ConstructionState { ConstructionState() diff --git a/src/qml/qml/qqmlcontext.cpp b/src/qml/qml/qqmlcontext.cpp index 3710cee162..e23f1e1e73 100644 --- a/src/qml/qml/qqmlcontext.cpp +++ b/src/qml/qml/qqmlcontext.cpp @@ -845,7 +845,7 @@ QQmlContextPrivate *QQmlContextData::asQQmlContextPrivate() return QQmlContextPrivate::get(asQQmlContext()); } -void QQmlContextData::initFromTypeCompilationUnit(const QQmlRefPointer &unit, int subComponentIndex) +void QQmlContextData::initFromTypeCompilationUnit(const QQmlRefPointer &unit, int subComponentIndex) { typeCompilationUnit = unit; componentObjectIndex = subComponentIndex == -1 ? /*root object*/0 : subComponentIndex; diff --git a/src/qml/qml/qqmlcontext_p.h b/src/qml/qml/qqmlcontext_p.h index 7e3cef8e1d..1ddd04c9ff 100644 --- a/src/qml/qml/qqmlcontext_p.h +++ b/src/qml/qml/qqmlcontext_p.h @@ -66,7 +66,7 @@ #include #include -#include +#include #include QT_BEGIN_NAMESPACE @@ -152,12 +152,12 @@ public: QQmlIncubatorPrivate *incubator; // Compilation unit for contexts that belong to a compiled type. - QQmlRefPointer typeCompilationUnit; + QQmlRefPointer typeCompilationUnit; // object index in CompiledData::Unit to component that created this context int componentObjectIndex; - void initFromTypeCompilationUnit(const QQmlRefPointer &unit, int subComponentIndex); + void initFromTypeCompilationUnit(const QQmlRefPointer &unit, int subComponentIndex); // flag indicates whether the context owns the cache (after mutation) or not. mutable QV4::IdentifierHash propertyNameCache; diff --git a/src/qml/qml/qqmlcustomparser_p.h b/src/qml/qml/qqmlcustomparser_p.h index aa933553a8..c8e1300a1b 100644 --- a/src/qml/qml/qqmlcustomparser_p.h +++ b/src/qml/qml/qqmlcustomparser_p.h @@ -80,8 +80,8 @@ public: void clearErrors(); Flags flags() const { return m_flags; } - virtual void verifyBindings(const QQmlRefPointer &, const QList &) = 0; - virtual void applyBindings(QObject *, const QQmlRefPointer &, const QList &) = 0; + virtual void verifyBindings(const QQmlRefPointer &, const QList &) = 0; + virtual void applyBindings(QObject *, const QQmlRefPointer &, const QList &) = 0; QVector errors() const { return exceptions; } diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h index f4c03fc17c..299476f5c8 100644 --- a/src/qml/qml/qqmldata_p.h +++ b/src/qml/qml/qqmldata_p.h @@ -76,8 +76,8 @@ class QQmlDataExtended; class QQmlNotifierEndpoint; namespace QV4 { +class ExecutableCompilationUnit; namespace CompiledData { -struct CompilationUnit; struct Binding; } } @@ -226,14 +226,14 @@ public: ~DeferredData(); unsigned int deferredIdx; QMultiHash bindings; - QQmlRefPointer compilationUnit;//Not always the same as the other compilation unit + QQmlRefPointer compilationUnit;//Not always the same as the other compilation unit QQmlContextData *context;//Could be either context or outerContext Q_DISABLE_COPY(DeferredData); }; - QQmlRefPointer compilationUnit; + QQmlRefPointer compilationUnit; QVector deferredData; - void deferData(int objectIndex, const QQmlRefPointer &, QQmlContextData *); + void deferData(int objectIndex, const QQmlRefPointer &, QQmlContextData *); void releaseDeferredData(); QV4::WeakValue jsWrapper; diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index ea639d870b..8faace521a 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -1770,7 +1770,7 @@ void QQmlData::NotifyList::layout() todo = nullptr; } -void QQmlData::deferData(int objectIndex, const QQmlRefPointer &compilationUnit, QQmlContextData *context) +void QQmlData::deferData(int objectIndex, const QQmlRefPointer &compilationUnit, QQmlContextData *context) { QQmlData::DeferredData *deferData = new QQmlData::DeferredData; deferData->deferredIdx = objectIndex; @@ -2407,7 +2407,7 @@ QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t, int minorVe } } -void QQmlEnginePrivate::registerInternalCompositeType(QV4::CompiledData::CompilationUnit *compilationUnit) +void QQmlEnginePrivate::registerInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit) { compilationUnit->isRegisteredWithEngine = true; @@ -2417,7 +2417,7 @@ void QQmlEnginePrivate::registerInternalCompositeType(QV4::CompiledData::Compila m_compositeTypes.insert(compilationUnit->metaTypeId, compilationUnit); } -void QQmlEnginePrivate::unregisterInternalCompositeType(QV4::CompiledData::CompilationUnit *compilationUnit) +void QQmlEnginePrivate::unregisterInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit) { compilationUnit->isRegisteredWithEngine = false; diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h index ffe0e36d75..3b716683fd 100644 --- a/src/qml/qml/qqmlengine_p.h +++ b/src/qml/qml/qqmlengine_p.h @@ -219,8 +219,8 @@ public: QQmlMetaObject metaObjectForType(int) const; QQmlPropertyCache *propertyCacheForType(int); QQmlPropertyCache *rawPropertyCacheForType(int, int minorVersion = -1); - void registerInternalCompositeType(QV4::CompiledData::CompilationUnit *compilationUnit); - void unregisterInternalCompositeType(QV4::CompiledData::CompilationUnit *compilationUnit); + void registerInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit); + void unregisterInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit); bool isTypeLoaded(const QUrl &url) const; bool isScriptLoaded(const QUrl &url) const; @@ -265,7 +265,7 @@ private: // These members must be protected by a QQmlEnginePrivate::Locker as they are required by // the threaded loader. Only access them through their respective accessor methods. - QHash m_compositeTypes; + QHash m_compositeTypes; static bool s_designerMode; // These members is protected by the full QQmlEnginePrivate::mutex mutex diff --git a/src/qml/qml/qqmlincubator_p.h b/src/qml/qml/qqmlincubator_p.h index 676ba1a29a..57ec8249cb 100644 --- a/src/qml/qml/qqmlincubator_p.h +++ b/src/qml/qml/qqmlincubator_p.h @@ -87,7 +87,7 @@ public: QPointer result; QQmlGuardedContextData rootContext; QQmlEnginePrivate *enginePriv; - QQmlRefPointer compilationUnit; + QQmlRefPointer compilationUnit; QScopedPointer creator; int subComponentToCreate; QQmlVMEGuard vmeGuard; diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp index 9a3a5218e0..e799267769 100644 --- a/src/qml/qml/qqmljavascriptexpression.cpp +++ b/src/qml/qml/qqmljavascriptexpression.cpp @@ -392,10 +392,10 @@ void QQmlJavaScriptExpression::setupFunction(QV4::ExecutionContext *qmlContext, return; m_qmlScope.set(qmlContext->engine(), *qmlContext); m_v4Function = f; - setCompilationUnit(m_v4Function->compilationUnit); + setCompilationUnit(m_v4Function->executableCompilationUnit()); } -void QQmlJavaScriptExpression::setCompilationUnit(const QQmlRefPointer &compilationUnit) +void QQmlJavaScriptExpression::setCompilationUnit(const QQmlRefPointer &compilationUnit) { m_compilationUnit = compilationUnit; } diff --git a/src/qml/qml/qqmljavascriptexpression_p.h b/src/qml/qml/qqmljavascriptexpression_p.h index 92f2ccbb4a..eecee08062 100644 --- a/src/qml/qml/qqmljavascriptexpression_p.h +++ b/src/qml/qml/qqmljavascriptexpression_p.h @@ -153,7 +153,7 @@ protected: void createQmlBinding(QQmlContextData *ctxt, QObject *scope, const QString &code, const QString &filename, quint16 line); void setupFunction(QV4::ExecutionContext *qmlContext, QV4::Function *f); - void setCompilationUnit(const QQmlRefPointer &compilationUnit); + void setCompilationUnit(const QQmlRefPointer &compilationUnit); // We store some flag bits in the following flag pointers. // activeGuards:flag1 - notifyOnValueChanged @@ -178,7 +178,7 @@ private: QQmlJavaScriptExpression *m_nextExpression; QV4::PersistentValue m_qmlScope; - QQmlRefPointer m_compilationUnit; + QQmlRefPointer m_compilationUnit; QV4::Function *m_v4Function; }; diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index 09df23de51..a5b92d14f7 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -499,7 +499,7 @@ QQmlType QQmlMetaType::registerCompositeType(const QQmlPrivate::RegisterComposit return QQmlType(priv); } -void QQmlMetaType::registerInternalCompositeType(QV4::CompiledData::CompilationUnit *compilationUnit) +void QQmlMetaType::registerInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit) { QByteArray name = compilationUnit->rootPropertyCache()->className(); @@ -526,7 +526,7 @@ void QQmlMetaType::registerInternalCompositeType(QV4::CompiledData::CompilationU data->qmlLists.insert(lst_type, ptr_type); } -void QQmlMetaType::unregisterInternalCompositeType(QV4::CompiledData::CompilationUnit *compilationUnit) +void QQmlMetaType::unregisterInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit) { int ptr_type = compilationUnit->metaTypeId; int lst_type = compilationUnit->listMetaTypeId; diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index 9af982d1c3..911e519cf2 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -61,6 +61,8 @@ class QQmlTypeModule; class QMutex; class QQmlError; +namespace QV4 { class ExecutableCompilationUnit; } + class Q_QML_PRIVATE_EXPORT QQmlMetaType { public: @@ -78,8 +80,8 @@ public: static void unregisterType(int type); - static void registerInternalCompositeType(QV4::CompiledData::CompilationUnit *compilationUnit); - static void unregisterInternalCompositeType(QV4::CompiledData::CompilationUnit *compilationUnit); + static void registerInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit); + static void unregisterInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit); static void registerModule(const char *uri, int versionMajor, int versionMinor); static bool protectModule(const char *uri, int majVersion); diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 18105aa75f..177c0d38bd 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -73,7 +73,7 @@ struct ActiveOCRestorer }; } -QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, const QQmlRefPointer &compilationUnit, QQmlContextData *creationContext, +QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, const QQmlRefPointer &compilationUnit, QQmlContextData *creationContext, QQmlIncubatorPrivate *incubator) : phase(Startup) , compilationUnit(compilationUnit) @@ -100,7 +100,7 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, const QQmlR } } -QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, const QQmlRefPointer &compilationUnit, QQmlObjectCreatorSharedState *inheritedSharedState) +QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, const QQmlRefPointer &compilationUnit, QQmlObjectCreatorSharedState *inheritedSharedState) : phase(Startup) , compilationUnit(compilationUnit) , propertyCaches(&compilationUnit->propertyCaches) @@ -373,7 +373,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const propertyType = QMetaType::Int; } else { // ### This should be resolved earlier at compile time and the binding value should be changed accordingly. - QVariant value = binding->valueAsString(compilationUnit.data()); + QVariant value = compilationUnit->bindingValueAsString(binding); bool ok = QQmlPropertyPrivate::write(_qobject, *property, value, context); Q_ASSERT(ok); Q_UNUSED(ok); @@ -438,7 +438,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const property->writeProperty(_qobject, &nullValue, propertyWriteFlags); } } else { - QString stringValue = binding->valueAsString(compilationUnit.data()); + QString stringValue = compilationUnit->bindingValueAsString(binding); if (property->isVarProperty()) { QV4::ScopedString s(scope, v4->newString(stringValue)); _vmeMetaObject->setVMEProperty(property->coreIndex(), s); @@ -451,25 +451,25 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const break; case QVariant::String: { assertOrNull(binding->evaluatesToString()); - QString value = binding->valueAsString(compilationUnit.data()); + QString value = compilationUnit->bindingValueAsString(binding); property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::StringList: { assertOrNull(binding->evaluatesToString()); - QStringList value(binding->valueAsString(compilationUnit.data())); + QStringList value(compilationUnit->bindingValueAsString(binding)); property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::ByteArray: { assertType(QV4::CompiledData::Binding::Type_String); - QByteArray value(binding->valueAsString(compilationUnit.data()).toUtf8()); + QByteArray value(compilationUnit->bindingValueAsString(binding).toUtf8()); property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::Url: { assertType(QV4::CompiledData::Binding::Type_String); - QString string = binding->valueAsString(compilationUnit.data()); + QString string = compilationUnit->bindingValueAsString(binding); // Encoded dir-separators defeat QUrl processing - decode them first string.replace(QLatin1String("%2f"), QLatin1String("/"), Qt::CaseInsensitive); QUrl value = string.isEmpty() ? QUrl() : compilationUnit->finalUrl().resolved(QUrl(string)); @@ -509,7 +509,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const break; case QVariant::Color: { bool ok = false; - uint colorValue = QQmlStringConverters::rgbaFromString(binding->valueAsString(compilationUnit.data()), &ok); + uint colorValue = QQmlStringConverters::rgbaFromString(compilationUnit->bindingValueAsString(binding), &ok); assertOrNull(ok); struct { void *data[4]; } buffer; if (QQml_valueTypeProvider()->storeValueType(property->propType(), &colorValue, &buffer, sizeof(buffer))) { @@ -520,21 +520,21 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const #if QT_CONFIG(datestring) case QVariant::Date: { bool ok = false; - QDate value = QQmlStringConverters::dateFromString(binding->valueAsString(compilationUnit.data()), &ok); + QDate value = QQmlStringConverters::dateFromString(compilationUnit->bindingValueAsString(binding), &ok); assertOrNull(ok); property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::Time: { bool ok = false; - QTime value = QQmlStringConverters::timeFromString(binding->valueAsString(compilationUnit.data()), &ok); + QTime value = QQmlStringConverters::timeFromString(compilationUnit->bindingValueAsString(binding), &ok); assertOrNull(ok); property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::DateTime: { bool ok = false; - QDateTime value = QQmlStringConverters::dateTimeFromString(binding->valueAsString(compilationUnit.data()), &ok); + QDateTime value = QQmlStringConverters::dateTimeFromString(compilationUnit->bindingValueAsString(binding), &ok); // ### VME compatibility :( { const qint64 date = value.date().toJulianDay(); @@ -548,42 +548,42 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const #endif // datestring case QVariant::Point: { bool ok = false; - QPoint value = QQmlStringConverters::pointFFromString(binding->valueAsString(compilationUnit.data()), &ok).toPoint(); + QPoint value = QQmlStringConverters::pointFFromString(compilationUnit->bindingValueAsString(binding), &ok).toPoint(); assertOrNull(ok); property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::PointF: { bool ok = false; - QPointF value = QQmlStringConverters::pointFFromString(binding->valueAsString(compilationUnit.data()), &ok); + QPointF value = QQmlStringConverters::pointFFromString(compilationUnit->bindingValueAsString(binding), &ok); assertOrNull(ok); property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::Size: { bool ok = false; - QSize value = QQmlStringConverters::sizeFFromString(binding->valueAsString(compilationUnit.data()), &ok).toSize(); + QSize value = QQmlStringConverters::sizeFFromString(compilationUnit->bindingValueAsString(binding), &ok).toSize(); assertOrNull(ok); property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::SizeF: { bool ok = false; - QSizeF value = QQmlStringConverters::sizeFFromString(binding->valueAsString(compilationUnit.data()), &ok); + QSizeF value = QQmlStringConverters::sizeFFromString(compilationUnit->bindingValueAsString(binding), &ok); assertOrNull(ok); property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::Rect: { bool ok = false; - QRect value = QQmlStringConverters::rectFFromString(binding->valueAsString(compilationUnit.data()), &ok).toRect(); + QRect value = QQmlStringConverters::rectFFromString(compilationUnit->bindingValueAsString(binding), &ok).toRect(); assertOrNull(ok); property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::RectF: { bool ok = false; - QRectF value = QQmlStringConverters::rectFFromString(binding->valueAsString(compilationUnit.data()), &ok); + QRectF value = QQmlStringConverters::rectFFromString(compilationUnit->bindingValueAsString(binding), &ok); assertOrNull(ok); property->writeProperty(_qobject, &value, propertyWriteFlags); } @@ -599,7 +599,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const float xp; float yp; } vec; - bool ok = QQmlStringConverters::createFromString(QMetaType::QVector2D, binding->valueAsString(compilationUnit.data()), &vec, sizeof(vec)); + bool ok = QQmlStringConverters::createFromString(QMetaType::QVector2D, compilationUnit->bindingValueAsString(binding), &vec, sizeof(vec)); assertOrNull(ok); Q_UNUSED(ok); property->writeProperty(_qobject, &vec, propertyWriteFlags); @@ -611,7 +611,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const float yp; float zy; } vec; - bool ok = QQmlStringConverters::createFromString(QMetaType::QVector3D, binding->valueAsString(compilationUnit.data()), &vec, sizeof(vec)); + bool ok = QQmlStringConverters::createFromString(QMetaType::QVector3D, compilationUnit->bindingValueAsString(binding), &vec, sizeof(vec)); assertOrNull(ok); Q_UNUSED(ok); property->writeProperty(_qobject, &vec, propertyWriteFlags); @@ -624,7 +624,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const float zy; float wp; } vec; - bool ok = QQmlStringConverters::createFromString(QMetaType::QVector4D, binding->valueAsString(compilationUnit.data()), &vec, sizeof(vec)); + bool ok = QQmlStringConverters::createFromString(QMetaType::QVector4D, compilationUnit->bindingValueAsString(binding), &vec, sizeof(vec)); assertOrNull(ok); Q_UNUSED(ok); property->writeProperty(_qobject, &vec, propertyWriteFlags); @@ -637,7 +637,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const float yp; float zp; } vec; - bool ok = QQmlStringConverters::createFromString(QMetaType::QQuaternion, binding->valueAsString(compilationUnit.data()), &vec, sizeof(vec)); + bool ok = QQmlStringConverters::createFromString(QMetaType::QQuaternion, compilationUnit->bindingValueAsString(binding), &vec, sizeof(vec)); assertOrNull(ok); Q_UNUSED(ok); property->writeProperty(_qobject, &vec, propertyWriteFlags); @@ -669,7 +669,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const break; } else if (property->propType() == qMetaTypeId >()) { assertType(QV4::CompiledData::Binding::Type_String); - QString urlString = binding->valueAsString(compilationUnit.data()); + QString urlString = compilationUnit->bindingValueAsString(binding); QUrl u = urlString.isEmpty() ? QUrl() : compilationUnit->finalUrl().resolved(QUrl(urlString)); QList value; @@ -679,7 +679,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const } else if (property->propType() == qMetaTypeId >()) { assertOrNull(binding->evaluatesToString()); QList value; - value.append(binding->valueAsString(compilationUnit.data())); + value.append(compilationUnit->bindingValueAsString(binding)); property->writeProperty(_qobject, &value, propertyWriteFlags); break; } else if (property->propType() == qMetaTypeId()) { @@ -695,14 +695,14 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const } else if (binding->type == QV4::CompiledData::Binding::Type_Null) { value = QJSValue::NullValue; } else { - value = QJSValue(binding->valueAsString(compilationUnit.data())); + value = QJSValue(compilationUnit->bindingValueAsString(binding)); } property->writeProperty(_qobject, &value, propertyWriteFlags); break; } // otherwise, try a custom type assignment - QString stringValue = binding->valueAsString(compilationUnit.data()); + QString stringValue = compilationUnit->bindingValueAsString(binding); QQmlMetaType::StringConverter converter = QQmlMetaType::customStringConverter(property->propType()); Q_ASSERT(converter); QVariant value = (*converter)(stringValue); @@ -816,7 +816,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper { if (binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) { Q_ASSERT(stringAt(compilationUnit->objectAt(binding->value.objectIndex)->inheritedTypeNameIndex).isEmpty()); - QV4::CompiledData::ResolvedTypeReference *tr = resolvedType(binding->propertyNameIndex); + QV4::ResolvedTypeReference *tr = resolvedType(binding->propertyNameIndex); Q_ASSERT(tr); QQmlType attachedType = tr->type; if (!attachedType.isValid()) { @@ -835,7 +835,8 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper // ### resolve this at compile time if (bindingProperty && bindingProperty->propType() == qMetaTypeId()) { - QQmlScriptString ss(binding->valueAsScriptString(compilationUnit.data()), context->asQQmlContext(), _scopeObject); + QQmlScriptString ss(compilationUnit->bindingValueAsScriptString(binding), + context->asQQmlContext(), _scopeObject); ss.d.data()->bindingId = binding->type == QV4::CompiledData::Binding::Type_Script ? binding->value.compiledScriptIndex : (quint32)QQmlBinding::Invalid; ss.d.data()->lineNumber = binding->location.line; ss.d.data()->columnNumber = binding->location.column; @@ -1184,8 +1185,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo instance = component; ddata = QQmlData::get(instance, /*create*/true); } else { - QV4::CompiledData::ResolvedTypeReference *typeRef - = resolvedType(obj->inheritedTypeNameIndex); + QV4::ResolvedTypeReference *typeRef = resolvedType(obj->inheritedTypeNameIndex); Q_ASSERT(typeRef); installPropertyCache = !typeRef->isFullyDynamicType; QQmlType type = typeRef->type; diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h index 5aca60e2f0..0766e2082e 100644 --- a/src/qml/qml/qqmlobjectcreator_p.h +++ b/src/qml/qml/qqmlobjectcreator_p.h @@ -85,7 +85,7 @@ class Q_QML_PRIVATE_EXPORT QQmlObjectCreator { Q_DECLARE_TR_FUNCTIONS(QQmlObjectCreator) public: - QQmlObjectCreator(QQmlContextData *parentContext, const QQmlRefPointer &compilationUnit, QQmlContextData *creationContext, QQmlIncubatorPrivate *incubator = nullptr); + QQmlObjectCreator(QQmlContextData *parentContext, const QQmlRefPointer &compilationUnit, QQmlContextData *creationContext, QQmlIncubatorPrivate *incubator = nullptr); ~QQmlObjectCreator(); QObject *create(int subComponentIndex = -1, QObject *parent = nullptr, QQmlInstantiationInterrupt *interrupt = nullptr); @@ -104,7 +104,7 @@ public: QFiniteStack > &allCreatedObjects() const { return sharedState->allCreatedObjects; } private: - QQmlObjectCreator(QQmlContextData *contextData, const QQmlRefPointer &compilationUnit, QQmlObjectCreatorSharedState *inheritedSharedState); + QQmlObjectCreator(QQmlContextData *contextData, const QQmlRefPointer &compilationUnit, QQmlObjectCreatorSharedState *inheritedSharedState); void init(QQmlContextData *parentContext); @@ -125,7 +125,7 @@ private: inline QV4::QmlContext *currentQmlContext(); Q_NEVER_INLINE void createQmlContext(); - QV4::CompiledData::ResolvedTypeReference *resolvedType(int id) const + QV4::ResolvedTypeReference *resolvedType(int id) const { return compilationUnit->resolvedType(id); } @@ -141,7 +141,7 @@ private: QQmlEngine *engine; QV4::ExecutionEngine *v4; - QQmlRefPointer compilationUnit; + QQmlRefPointer compilationUnit; const QV4::CompiledData::Unit *qmlUnit; QQmlGuardedContextData parentContext; QQmlContextData *context; diff --git a/src/qml/qml/qqmlproperty_p.h b/src/qml/qml/qqmlproperty_p.h index bafcba5971..285c34d7fa 100644 --- a/src/qml/qml/qqmlproperty_p.h +++ b/src/qml/qml/qqmlproperty_p.h @@ -59,6 +59,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE diff --git a/src/qml/qml/qqmltype.cpp b/src/qml/qml/qqmltype.cpp index 926e2810d5..6b4e0a0734 100644 --- a/src/qml/qml/qqmltype.cpp +++ b/src/qml/qml/qqmltype.cpp @@ -178,7 +178,7 @@ QQmlType QQmlType::resolveCompositeBaseType(QQmlEnginePrivate *engine) const QQmlRefPointer td(engine->typeLoader.getType(sourceUrl())); if (td.isNull() || !td->isComplete()) return QQmlType(); - QV4::CompiledData::CompilationUnit *compilationUnit = td->compilationUnit(); + QV4::ExecutableCompilationUnit *compilationUnit = td->compilationUnit(); const QMetaObject *mo = compilationUnit->rootPropertyCache()->firstCppMetaObject(); return QQmlMetaType::qmlType(mo); } @@ -192,7 +192,7 @@ QQmlPropertyCache *QQmlType::compositePropertyCache(QQmlEnginePrivate *engine) c QQmlRefPointer td(engine->typeLoader.getType(sourceUrl())); if (td.isNull() || !td->isComplete()) return nullptr; - QV4::CompiledData::CompilationUnit *compilationUnit = td->compilationUnit(); + QV4::ExecutableCompilationUnit *compilationUnit = td->compilationUnit(); return compilationUnit->rootPropertyCache().data(); } diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 2233af6cd8..1022412292 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -2136,7 +2136,7 @@ const QList &QQmlTypeData::resolvedScripts() cons return m_scripts; } -QV4::CompiledData::CompilationUnit *QQmlTypeData::compilationUnit() const +QV4::ExecutableCompilationUnit *QQmlTypeData::compilationUnit() const { return m_compiledData.data(); } @@ -2166,7 +2166,7 @@ bool QQmlTypeData::tryLoadFromDiskCache() if (!v4) return false; - QQmlRefPointer unit = QV4::Compiler::Codegen::createUnitForLoading(); + QQmlRefPointer unit = QV4::ExecutableCompilationUnit::create(); { QString error; if (!unit->loadFromDisk(url(), m_backupSourceCode.sourceTimeStamp(), &error)) { @@ -2176,7 +2176,7 @@ bool QQmlTypeData::tryLoadFromDiskCache() } if (unit->unitData()->flags & QV4::CompiledData::Unit::PendingTypeCompilation) { - restoreIR(unit); + restoreIR(std::move(*unit)); return true; } @@ -2232,8 +2232,9 @@ bool QQmlTypeData::tryLoadFromDiskCache() return true; } -void QQmlTypeData::createTypeAndPropertyCaches(const QQmlRefPointer &typeNameCache, - const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache) +void QQmlTypeData::createTypeAndPropertyCaches( + const QQmlRefPointer &typeNameCache, + const QV4::ResolvedTypeReferenceMap &resolvedTypeCache) { Q_ASSERT(m_compiledData); m_compiledData->typeNameCache = typeNameCache; @@ -2244,9 +2245,9 @@ void QQmlTypeData::createTypeAndPropertyCaches(const QQmlRefPointer propertyCacheCreator(&m_compiledData->propertyCaches, - &pendingGroupPropertyBindings, - engine, m_compiledData.data(), &m_importCache); + QQmlPropertyCacheCreator propertyCacheCreator( + &m_compiledData->propertyCaches, &pendingGroupPropertyBindings, engine, + m_compiledData.data(), &m_importCache); QQmlCompileError error = propertyCacheCreator.buildMetaObjects(); if (error.isSet()) { setError(error); @@ -2254,7 +2255,8 @@ void QQmlTypeData::createTypeAndPropertyCaches(const QQmlRefPointer aliasCreator(&m_compiledData->propertyCaches, m_compiledData.data()); + QQmlPropertyCacheAliasCreator aliasCreator( + &m_compiledData->propertyCaches, m_compiledData.data()); aliasCreator.appendAliasPropertiesToMetaObjects(); pendingGroupPropertyBindings.resolveMissingPropertyCaches(engine, &m_compiledData->propertyCaches); @@ -2346,7 +2348,7 @@ void QQmlTypeData::done() } QQmlRefPointer typeNameCache; - QV4::CompiledData::ResolvedTypeReferenceMap resolvedTypeCache; + QV4::ResolvedTypeReferenceMap resolvedTypeCache; { QQmlCompileError error = buildTypeResolutionCaches(&typeNameCache, &resolvedTypeCache); if (error.isSet()) { @@ -2509,7 +2511,7 @@ void QQmlTypeData::initializeFromCachedUnit(const QV4::CompiledData::Unit *unit) loader.load(); m_document->jsModule.fileName = urlString(); m_document->jsModule.finalUrl = finalUrlString(); - m_document->javaScriptCompilationUnit.adopt(new QV4::CompiledData::CompilationUnit(unit)); + m_document->javaScriptCompilationUnit = QV4::CompiledData::CompilationUnit(unit); continueLoadFromIR(); } @@ -2544,14 +2546,14 @@ bool QQmlTypeData::loadFromSource() return true; } -void QQmlTypeData::restoreIR(QQmlRefPointer unit) +void QQmlTypeData::restoreIR(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 = unit; + m_document->javaScriptCompilationUnit = std::move(unit); continueLoadFromIR(); } @@ -2650,12 +2652,13 @@ QString QQmlTypeData::stringAt(int index) const } void QQmlTypeData::compile(const QQmlRefPointer &typeNameCache, - QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache, + QV4::ResolvedTypeReferenceMap *resolvedTypeCache, const QV4::CompiledData::DependentTypesHasher &dependencyHasher) { Q_ASSERT(m_compiledData.isNull()); - const bool typeRecompilation = m_document && m_document->javaScriptCompilationUnit && m_document->javaScriptCompilationUnit->unitData()->flags & QV4::CompiledData::Unit::PendingTypeCompilation; + const bool typeRecompilation = m_document && 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); @@ -2774,7 +2777,7 @@ void QQmlTypeData::resolveTypes() QQmlCompileError QQmlTypeData::buildTypeResolutionCaches( QQmlRefPointer *typeNameCache, - QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache + QV4::ResolvedTypeReferenceMap *resolvedTypeCache ) const { typeNameCache->adopt(new QQmlTypeNameCache(m_importCache)); @@ -2791,7 +2794,7 @@ QQmlCompileError QQmlTypeData::buildTypeResolutionCaches( QQmlEnginePrivate * const engine = QQmlEnginePrivate::get(typeLoader()->engine()); for (auto resolvedType = m_resolvedTypes.constBegin(), end = m_resolvedTypes.constEnd(); resolvedType != end; ++resolvedType) { - QScopedPointer ref(new QV4::CompiledData::ResolvedTypeReference); + QScopedPointer ref(new QV4::ResolvedTypeReference); QQmlType qmlType = resolvedType->type; if (resolvedType->typeData) { if (resolvedType->needsCreation && qmlType.isCompositeSingleton()) { @@ -3022,7 +3025,8 @@ QQmlRefPointer QQmlScriptBlob::scriptData() const void QQmlScriptBlob::dataReceived(const SourceCodeData &data) { if (!disableDiskCache() || forceDiskCache()) { - QQmlRefPointer unit = QV4::Compiler::Codegen::createUnitForLoading(); + QQmlRefPointer unit + = QV4::ExecutableCompilationUnit::create(); QString error; if (unit->loadFromDisk(url(), data.sourceTimeStamp(), &error)) { initializeFromCompilationUnit(unit); @@ -3047,7 +3051,7 @@ void QQmlScriptBlob::dataReceived(const SourceCodeData &data) return; } - QQmlRefPointer unit; + QV4::CompiledData::CompilationUnit unit; if (m_isModule) { QList diagnostics; @@ -3067,44 +3071,43 @@ void QQmlScriptBlob::dataReceived(const SourceCodeData &data) irUnit.jsParserEngine.setDirectives(&collector); QList errors; - unit = QV4::Script::precompile( - &irUnit.jsModule, &irUnit.jsParserEngine, &irUnit.jsGenerator, urlString(), finalUrlString(), - source, &errors, QV4::Compiler::ContextType::ScriptImportedByQML); - // No need to addref on unit, it's initial refcount is 1 + irUnit.javaScriptCompilationUnit = QV4::Script::precompile( + &irUnit.jsModule, &irUnit.jsParserEngine, &irUnit.jsGenerator, urlString(), finalUrlString(), + source, &errors, QV4::Compiler::ContextType::ScriptImportedByQML); + source.clear(); if (!errors.isEmpty()) { setError(errors); return; } - if (!unit) { - unit.adopt(new QV4::CompiledData::CompilationUnit); - } - irUnit.javaScriptCompilationUnit = unit; QmlIR::QmlUnitGenerator qmlGenerator; qmlGenerator.generate(irUnit); + unit = std::move(irUnit.javaScriptCompilationUnit); } + auto executableUnit = QV4::ExecutableCompilationUnit::create(std::move(unit)); + if ((!disableDiskCache() || forceDiskCache()) && !isDebugging()) { QString errorString; - if (unit->saveToDisk(url(), &errorString)) { + if (executableUnit->saveToDisk(url(), &errorString)) { QString error; - if (!unit->loadFromDisk(url(), data.sourceTimeStamp(), &error)) { + if (!executableUnit->loadFromDisk(url(), data.sourceTimeStamp(), &error)) { // ignore error, keep using the in-memory compilation unit. } } else { - qCDebug(DBG_DISK_CACHE()) << "Error saving cached version of" << unit->fileName() << "to disk:" << errorString; + qCDebug(DBG_DISK_CACHE()) << "Error saving cached version of" + << executableUnit->fileName() << "to disk:" << errorString; } } - initializeFromCompilationUnit(unit); + initializeFromCompilationUnit(executableUnit); } void QQmlScriptBlob::initializeFromCachedUnit(const QV4::CompiledData::Unit *unit) { - QQmlRefPointer compilationUnit; - compilationUnit.adopt(new QV4::CompiledData::CompilationUnit(unit, urlString(), finalUrlString())); - initializeFromCompilationUnit(compilationUnit); + initializeFromCompilationUnit(QV4::ExecutableCompilationUnit::create( + QV4::CompiledData::CompilationUnit(unit, urlString(), finalUrlString()))); } void QQmlScriptBlob::done() @@ -3169,7 +3172,7 @@ void QQmlScriptBlob::scriptImported(const QQmlRefPointer &blob, m_scripts << ref; } -void QQmlScriptBlob::initializeFromCompilationUnit(const QQmlRefPointer &unit) +void QQmlScriptBlob::initializeFromCompilationUnit(const QQmlRefPointer &unit) { Q_ASSERT(!m_scriptData); m_scriptData.adopt(new QQmlScriptData()); @@ -3179,7 +3182,7 @@ void QQmlScriptBlob::initializeFromCompilationUnit(const QQmlRefPointer script = m_scriptData->m_precompiledScript; + QQmlRefPointer script = m_scriptData->m_precompiledScript; if (!m_isModule) { QList errors; diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h index 987e47222d..d87812d48e 100644 --- a/src/qml/qml/qqmltypeloader_p.h +++ b/src/qml/qml/qqmltypeloader_p.h @@ -70,6 +70,7 @@ #include #include #include +#include #include #include @@ -453,7 +454,7 @@ public: const QList &resolvedScripts() const; - QV4::CompiledData::CompilationUnit *compilationUnit() const; + QV4::ExecutableCompilationUnit *compilationUnit() const; // Used by QQmlComponent to get notifications struct TypeDataCallback { @@ -477,18 +478,18 @@ protected: private: bool tryLoadFromDiskCache(); bool loadFromSource(); - void restoreIR(QQmlRefPointer unit); + void restoreIR(QV4::CompiledData::CompilationUnit &&unit); void continueLoadFromIR(); void resolveTypes(); QQmlCompileError buildTypeResolutionCaches( QQmlRefPointer *typeNameCache, - QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache + QV4::ResolvedTypeReferenceMap *resolvedTypeCache ) const; void compile(const QQmlRefPointer &typeNameCache, - QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache, + QV4::ResolvedTypeReferenceMap *resolvedTypeCache, const QV4::CompiledData::DependentTypesHasher &dependencyHasher); void createTypeAndPropertyCaches(const QQmlRefPointer &typeNameCache, - const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache); + const QV4::ResolvedTypeReferenceMap &resolvedTypeCache); bool resolveType(const QString &typeName, int &majorVersion, int &minorVersion, TypeReference &ref, int lineNumber = -1, int columnNumber = -1, bool reportErrors = true, @@ -512,7 +513,7 @@ private: QMap m_resolvedTypes; bool m_typesResolved:1; - QQmlRefPointer m_compiledData; + QQmlRefPointer m_compiledData; QList m_callbacks; @@ -542,7 +543,7 @@ public: QV4::ReturnedValue scriptValueForContext(QQmlContextData *parentCtxt); - QQmlRefPointer compilationUnit() const { return m_precompiledScript; } + QQmlRefPointer compilationUnit() const { return m_precompiledScript; } protected: void clear() override; // From QQmlCleanup @@ -554,7 +555,7 @@ private: QQmlContextData *qmlContextDataForContext(QQmlContextData *parentQmlContextData); bool m_loaded; - QQmlRefPointer m_precompiledScript; + QQmlRefPointer m_precompiledScript; QV4::PersistentValue m_value; }; @@ -587,7 +588,7 @@ protected: private: void scriptImported(const QQmlRefPointer &blob, const QV4::CompiledData::Location &location, const QString &qualifier, const QString &nameSpace) override; - void initializeFromCompilationUnit(const QQmlRefPointer &unit); + void initializeFromCompilationUnit(const QQmlRefPointer &unit); QList m_scripts; QQmlRefPointer m_scriptData; diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp index 236daac75c..9db089c330 100644 --- a/src/qml/qml/qqmltypewrapper.cpp +++ b/src/qml/qml/qqmltypewrapper.cpp @@ -418,7 +418,7 @@ ReturnedValue QQmlTypeWrapper::virtualInstanceOf(const Object *typeObject, const return Encode(false); QQmlRefPointer td = qenginepriv->typeLoader.getType(typeWrapper->d()->type().sourceUrl()); - CompiledData::CompilationUnit *cu = td->compilationUnit(); + ExecutableCompilationUnit *cu = td->compilationUnit(); myQmlType = qenginepriv->metaObjectForType(cu->metaTypeId); } else { myQmlType = qenginepriv->metaObjectForType(myTypeId); diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index 5d13415513..2881e71805 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -316,7 +316,7 @@ QAbstractDynamicMetaObject *QQmlInterceptorMetaObject::toDynamicMetaObject(QObje QQmlVMEMetaObject::QQmlVMEMetaObject(QV4::ExecutionEngine *engine, QObject *obj, - const QQmlRefPointer &cache, const QQmlRefPointer &qmlCompilationUnit, int qmlObjectId) + const QQmlRefPointer &cache, const QQmlRefPointer &qmlCompilationUnit, int qmlObjectId) : QQmlInterceptorMetaObject(obj, cache), engine(engine), ctxt(QQmlData::get(obj, true)->outerContext), diff --git a/src/qml/qml/qqmlvmemetaobject_p.h b/src/qml/qml/qqmlvmemetaobject_p.h index 2371d70f10..5025987586 100644 --- a/src/qml/qml/qqmlvmemetaobject_p.h +++ b/src/qml/qml/qqmlvmemetaobject_p.h @@ -144,7 +144,7 @@ class QQmlVMEMetaObjectEndpoint; class Q_QML_PRIVATE_EXPORT QQmlVMEMetaObject : public QQmlInterceptorMetaObject { public: - QQmlVMEMetaObject(QV4::ExecutionEngine *engine, QObject *obj, const QQmlRefPointer &cache, const QQmlRefPointer &qmlCompilationUnit, int qmlObjectId); + QQmlVMEMetaObject(QV4::ExecutionEngine *engine, QObject *obj, const QQmlRefPointer &cache, const QQmlRefPointer &qmlCompilationUnit, int qmlObjectId); ~QQmlVMEMetaObject() override; bool aliasTarget(int index, QObject **target, int *coreIndex, int *valueTypeIndex) const; @@ -226,7 +226,7 @@ public: // keep a reference to the compilation unit in order to still // do property access when the context has been invalidated. - QQmlRefPointer compilationUnit; + QQmlRefPointer compilationUnit; const QV4::CompiledData::Object *compiledObject; }; diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index 532bfa8754..4838ef3814 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -1950,7 +1950,8 @@ ReturnedValue GlobalExtensions::method_qsTr(const FunctionObject *b, const Value CppStackFrame *frame = scope.engine->currentStackFrame; // The first non-empty source URL in the call stack determines the translation context. while (frame && context.isEmpty()) { - if (CompiledData::CompilationUnit *unit = frame->v4Function->compilationUnit) { + if (CompiledData::CompilationUnitBase *baseUnit = frame->v4Function->compilationUnit) { + const auto *unit = static_cast(baseUnit); QString fileName = unit->fileName(); QUrl url(unit->fileName()); if (url.isValid() && url.isRelative()) { -- cgit v1.2.3 From f38e071f5b353cbf9ce6c6c104bd82099ae0aa14 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Mon, 29 Apr 2019 10:42:00 +0200 Subject: Restore value bindings when disabling a Binding element We previously only restored script bindings that were replaced by a Binding. Now we handle both. [ChangeLog] QML Binding elements now support restoring previous values of the bound property when the binding is disabled. This will be the default behavior in Qt 5.15. Reliance on the old behavior of only restoring binding, not literal values results in a warning now. Fixes: QTBUG-33444 Change-Id: I833403b0645c08eee486fbd4acf5d3c7de2ef73a Reviewed-by: Michael Brasser --- src/qml/qml/qqmlengine.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/qml/qml') diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 8faace521a..f977934b3e 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -204,6 +204,7 @@ void QQmlEnginePrivate::defineModule() qmlRegisterType(uri, 2, 0, "QtObject"); qmlRegisterType(uri, 2, 0, "Binding"); qmlRegisterType(uri, 2, 8, "Binding"); // Only available in >= 2.8 + qmlRegisterType(uri, 2, 14, "Binding"); qmlRegisterCustomType(uri, 2, 0, "Connections", new QQmlConnectionsParser); qmlRegisterCustomType(uri, 2, 3, "Connections", new QQmlConnectionsParser); // Only available in QtQml >= 2.3 #if QT_CONFIG(qml_animation) -- cgit v1.2.3 From 540134d66dd0a235ace91ddc28940d2d88c24ac3 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Fri, 10 May 2019 15:48:50 +0200 Subject: Move valueAsNumber into ExecutableCompilationUnit This reduces our dependence on QV4::Value in the devtools. Change-Id: I4b3f937bc08c16f7e2543fdc5cc34c0cfb121f8f Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlobjectcreator.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src/qml/qml') diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 177c0d38bd..e5f376fd34 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -406,7 +406,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const switch (propertyType) { case QMetaType::QVariant: { if (binding->type == QV4::CompiledData::Binding::Type_Number) { - double n = binding->valueAsNumber(compilationUnit->constants); + double n = compilationUnit->bindingValueAsNumber(binding); if (double(int(n)) == n) { if (property->isVarProperty()) { _vmeMetaObject->setVMEProperty(property->coreIndex(), QV4::Value::fromInt32(int(n))); @@ -481,7 +481,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const break; case QVariant::UInt: { assertType(QV4::CompiledData::Binding::Type_Number); - double d = binding->valueAsNumber(compilationUnit->constants); + double d = compilationUnit->bindingValueAsNumber(binding); uint value = uint(d); property->writeProperty(_qobject, &value, propertyWriteFlags); break; @@ -489,7 +489,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const break; case QVariant::Int: { assertType(QV4::CompiledData::Binding::Type_Number); - double d = binding->valueAsNumber(compilationUnit->constants); + double d = compilationUnit->bindingValueAsNumber(binding); int value = int(d); property->writeProperty(_qobject, &value, propertyWriteFlags); break; @@ -497,13 +497,13 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const break; case QMetaType::Float: { assertType(QV4::CompiledData::Binding::Type_Number); - float value = float(binding->valueAsNumber(compilationUnit->constants)); + float value = float(compilationUnit->bindingValueAsNumber(binding)); property->writeProperty(_qobject, &value, propertyWriteFlags); } break; case QVariant::Double: { assertType(QV4::CompiledData::Binding::Type_Number); - double value = binding->valueAsNumber(compilationUnit->constants); + double value = compilationUnit->bindingValueAsNumber(binding); property->writeProperty(_qobject, &value, propertyWriteFlags); } break; @@ -651,12 +651,12 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const if (property->propType() == qMetaTypeId >()) { assertType(QV4::CompiledData::Binding::Type_Number); QList value; - value.append(binding->valueAsNumber(compilationUnit->constants)); + value.append(compilationUnit->bindingValueAsNumber(binding)); property->writeProperty(_qobject, &value, propertyWriteFlags); break; } else if (property->propType() == qMetaTypeId >()) { assertType(QV4::CompiledData::Binding::Type_Number); - double n = binding->valueAsNumber(compilationUnit->constants); + double n = compilationUnit->bindingValueAsNumber(binding); QList value; value.append(int(n)); property->writeProperty(_qobject, &value, propertyWriteFlags); @@ -687,7 +687,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const if (binding->type == QV4::CompiledData::Binding::Type_Boolean) { value = QJSValue(binding->valueAsBoolean()); } else if (binding->type == QV4::CompiledData::Binding::Type_Number) { - double n = binding->valueAsNumber(compilationUnit->constants); + double n = compilationUnit->bindingValueAsNumber(binding); if (double(int(n)) == n) { value = QJSValue(int(n)); } else @@ -842,7 +842,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper ss.d.data()->columnNumber = binding->location.column; ss.d.data()->isStringLiteral = binding->type == QV4::CompiledData::Binding::Type_String; ss.d.data()->isNumberLiteral = binding->type == QV4::CompiledData::Binding::Type_Number; - ss.d.data()->numberValue = binding->valueAsNumber(compilationUnit->constants); + ss.d.data()->numberValue = compilationUnit->bindingValueAsNumber(binding); QQmlPropertyData::WriteFlags propertyWriteFlags = QQmlPropertyData::BypassInterceptor | QQmlPropertyData::RemoveBindingOnAliasWrite; -- cgit v1.2.3 From 19ca4af1a248486844ea9bf96eba62ce564ecdc9 Mon Sep 17 00:00:00 2001 From: Pavel Tumakaev Date: Wed, 22 May 2019 17:32:25 +0300 Subject: Remove null pointer checks for "this" from QQmlContextData::resolvedUrl() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to ISO/IEC 14882 §5.2.5/3 "If E1 has the type “pointer to class X,” then the expression E1->E2 is converted to the equivalent form (*(E1)).E2;". Thus, as QQmlContextData::resolvedUrl() is non-static method, it cannot be called on a null pointer because it leads to undefined behavior, and “this“ in QQmlContextData::resolvedUrl() cannot be a null pointer. According to this document: https://gcc.gnu.org/gcc-6/porting_to.html , starting from version 6, GCC optimizations remove null pointer checks for "this", since "the this pointer can never be null, which is guaranteed by the language rules." Thus, on the one hand the “if (ctxt)“ check in QQmlContextData::resolvedUrl() does nothing, on the other “if (engine“ check leads to undefined behavior if ctxt/this == nullptr. Task-number: QTBUG-75983 Change-Id: Idfb1e26758d83223bb0845139d63e2e8e80dc714 Reviewed-by: Ulf Hermann --- src/qml/qml/qqmlcontext.cpp | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'src/qml/qml') diff --git a/src/qml/qml/qqmlcontext.cpp b/src/qml/qml/qqmlcontext.cpp index e23f1e1e73..bd59409475 100644 --- a/src/qml/qml/qqmlcontext.cpp +++ b/src/qml/qml/qqmlcontext.cpp @@ -438,23 +438,20 @@ QUrl QQmlContext::resolvedUrl(const QUrl &src) QUrl QQmlContextData::resolvedUrl(const QUrl &src) { - QQmlContextData *ctxt = this; - QUrl resolved; if (src.isRelative() && !src.isEmpty()) { - if (ctxt) { - while(ctxt) { - if (ctxt->url().isValid()) - break; - else - ctxt = ctxt->parent; - } - - if (ctxt) - resolved = ctxt->url().resolved(src); - else if (engine) - resolved = engine->baseUrl().resolved(src); - } + QQmlContextData *ctxt = this; + do { + if (ctxt->url().isValid()) + break; + else + ctxt = ctxt->parent; + } while (ctxt); + + if (ctxt) + resolved = ctxt->url().resolved(src); + else if (engine) + resolved = engine->baseUrl().resolved(src); } else { resolved = src; } -- cgit v1.2.3