aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2014-03-31 16:49:14 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-04-02 14:04:11 +0200
commit4e012093462f07e7ffd42d4061539c54b4f43ace (patch)
tree5a90968cf1a57860af3a870d5a0d2c0619629bb6 /src/qml/qml
parent010e3e4f8d4045d3e807d612289886f3d709773c (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.cpp4
-rw-r--r--src/qml/qml/qqmlboundsignal.cpp24
-rw-r--r--src/qml/qml/qqmlboundsignal_p.h2
-rw-r--r--src/qml/qml/qqmlcompiler_p.h3
-rw-r--r--src/qml/qml/qqmlcustomparser_p.h4
-rw-r--r--src/qml/qml/qqmlexpression.cpp2
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp2
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;
}
}