diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2014-03-31 16:49:14 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-04-02 14:04:11 +0200 |
commit | 4e012093462f07e7ffd42d4061539c54b4f43ace (patch) | |
tree | 5a90968cf1a57860af3a870d5a0d2c0619629bb6 /src/qml/qml | |
parent | 010e3e4f8d4045d3e807d612289886f3d709773c (diff) |
Avoid recompiling of signal handlers defined in QtQuick state changes and Connection objects
We can re-use the expression we've compiled at QML type compilation time, as
long as we "inject" the signal parameters in the dynamic qml lookup chain.
Change-Id: Icc417531c41dea06ff5d033011179af49b03f542
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml/qml')
-rw-r--r-- | src/qml/qml/qqmlbinding.cpp | 4 | ||||
-rw-r--r-- | src/qml/qml/qqmlboundsignal.cpp | 24 | ||||
-rw-r--r-- | src/qml/qml/qqmlboundsignal_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlcompiler_p.h | 3 | ||||
-rw-r--r-- | src/qml/qml/qqmlcustomparser_p.h | 4 | ||||
-rw-r--r-- | src/qml/qml/qqmlexpression.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 2 |
7 files changed, 36 insertions, 5 deletions
diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index e958b97f46..571d78312e 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -89,7 +89,7 @@ QQmlBinding::createBinding(Identifier id, QObject *obj, QQmlContext *ctxt) QV4::ExecutionEngine *v4 = engine->v4engine(); QV4::Scope valueScope(v4); QV4::Function *runtimeFunction = cdata->compilationUnit->runtimeFunctions[cdata->customParserBindings[id]]; - QV4::ScopedValue function(valueScope, QV4::QmlBindingWrapper::createQmlCallableForFunction(v4, ctxtdata, obj, runtimeFunction)); + QV4::ScopedValue function(valueScope, QV4::QmlBindingWrapper::createQmlCallableForFunction(ctxtdata, obj, runtimeFunction)); rv = new QQmlBinding(function, obj, ctxtdata); } @@ -147,7 +147,7 @@ QQmlBinding::QQmlBinding(const QQmlScriptString &script, QObject *obj, QQmlConte setScopeObject(obj ? obj : scriptPrivate->scope); if (runtimeFunction) { - v4function = QV4::QmlBindingWrapper::createQmlCallableForFunction(engine->v4engine(), ctxtdata, scopeObject(), runtimeFunction); + v4function = QV4::QmlBindingWrapper::createQmlCallableForFunction(ctxtdata, scopeObject(), runtimeFunction); } else { QString code = scriptPrivate->script; v4function = qmlBinding(context(), scopeObject(), code, url, scriptPrivate->lineNumber); diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp index b0834d7f21..876f367097 100644 --- a/src/qml/qml/qqmlboundsignal.cpp +++ b/src/qml/qml/qqmlboundsignal.cpp @@ -52,6 +52,7 @@ #include "qqmlglobal_p.h" #include <private/qqmlprofiler_p.h> #include <private/qv4debugservice_p.h> +#include <private/qqmlcompiler_p.h> #include "qqmlinfo.h" #include <private/qv4value_inl_p.h> @@ -59,6 +60,7 @@ #include <QtCore/qstringbuilder.h> #include <QtCore/qdebug.h> + QT_BEGIN_NAMESPACE static QQmlJavaScriptExpression::VTable QQmlBoundSignalExpression_jsvtable = { @@ -105,6 +107,28 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index, init(ctxt, scope); } +QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index, QQmlContextData *ctxt, QObject *scope, QV4::Function *runtimeFunction) + : QQmlJavaScriptExpression(&QQmlBoundSignalExpression_jsvtable), + m_target(target), + m_index(index), + m_extra(0) +{ + setExpressionFunctionValid(true); + setInvalidParameterName(false); + + // It's important to call init first, because m_index gets remapped in case of cloned signals. + init(ctxt, scope); + + QMetaMethod signal = QMetaObjectPrivate::signal(m_target->metaObject(), m_index); + QString error; + m_v8function = QV4::QmlBindingWrapper::createQmlCallableForFunction(ctxt, scope, runtimeFunction, signal.parameterNames(), &error); + if (!error.isEmpty()) { + qmlInfo(scopeObject()) << error; + setInvalidParameterName(true); + } else + setInvalidParameterName(false); +} + void QQmlBoundSignalExpression::init(QQmlContextData *ctxt, QObject *scope) { setNotifyOnValueChanged(false); diff --git a/src/qml/qml/qqmlboundsignal_p.h b/src/qml/qml/qqmlboundsignal_p.h index 054c6d2f80..43ff71f682 100644 --- a/src/qml/qml/qqmlboundsignal_p.h +++ b/src/qml/qml/qqmlboundsignal_p.h @@ -78,6 +78,8 @@ public: QQmlBoundSignalExpression(QObject *target, int index, QQmlContextData *ctxt, QObject *scope, const QV4::ValueRef &function); + QQmlBoundSignalExpression(QObject *target, int index, + QQmlContextData *ctxt, QObject *scope, QV4::Function *runtimeFunction); // "inherited" from QQmlJavaScriptExpression. static QString expressionIdentifier(QQmlJavaScriptExpression *); diff --git a/src/qml/qml/qqmlcompiler_p.h b/src/qml/qml/qqmlcompiler_p.h index 9432811f5b..f3b6f621ce 100644 --- a/src/qml/qml/qqmlcompiler_p.h +++ b/src/qml/qml/qqmlcompiler_p.h @@ -154,6 +154,9 @@ public: bool isInitialized() const { return hasEngine(); } void initialize(QQmlEngine *); + QV4::Function *functionForBindingId(int bindingId) const + { return compilationUnit->runtimeFunctions[customParserBindings[bindingId]]; } + protected: virtual void destroy(); // From QQmlRefCount virtual void clear(); // From QQmlCleanup diff --git a/src/qml/qml/qqmlcustomparser_p.h b/src/qml/qml/qqmlcustomparser_p.h index 4fbe235e21..2ce6375870 100644 --- a/src/qml/qml/qqmlcustomparser_p.h +++ b/src/qml/qml/qqmlcustomparser_p.h @@ -62,6 +62,8 @@ QT_BEGIN_NAMESPACE +class QQmlCompiledData; + struct QQmlCustomParserCompilerBackend { virtual ~QQmlCustomParserCompilerBackend() {} @@ -91,7 +93,7 @@ public: Flags flags() const { return m_flags; } virtual QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &bindings) = 0; - virtual void setCustomData(QObject *, const QByteArray &)=0; + virtual void setCustomData(QObject *, const QByteArray &, QQmlCompiledData *cdata) = 0; QList<QQmlError> errors() const { return exceptions; } diff --git a/src/qml/qml/qqmlexpression.cpp b/src/qml/qml/qqmlexpression.cpp index e3e5dff4d8..4dc3704bbb 100644 --- a/src/qml/qml/qqmlexpression.cpp +++ b/src/qml/qml/qqmlexpression.cpp @@ -81,7 +81,7 @@ void QQmlExpressionPrivate::init(QQmlContextData *ctxt, const QString &expr, QOb void QQmlExpressionPrivate::init(QQmlContextData *ctxt, QV4::Function *runtimeFunction, QObject *me) { expressionFunctionValid = true; - function = QV4::QmlBindingWrapper::createQmlCallableForFunction(QQmlEnginePrivate::getV4Engine(ctxt->engine), ctxt, me, runtimeFunction); + function = QV4::QmlBindingWrapper::createQmlCallableForFunction(ctxt, me, runtimeFunction); QQmlAbstractExpression::setContext(ctxt); setScopeObject(me); diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index ff32266588..d0c635b007 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -1117,7 +1117,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo if (customParser) { QHash<int, QQmlCompiledData::CustomParserData>::ConstIterator entry = compiledData->customParserData.find(index); if (entry != compiledData->customParserData.constEnd()) { - customParser->setCustomData(instance, entry->compilationArtifact); + customParser->setCustomData(instance, entry->compilationArtifact, compiledData); bindingsToSkip = entry->bindings; } } |