From a05d1796b88e628655afdba6063a186d3a0803bf Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 25 Jul 2018 11:40:18 +0200 Subject: Simplify signal handler parameter handling Unify the two QQmlBoundSignalExpression constructors and always call updateInternalClass on the run-time function to set up the parameter name -> argument mapping. This streamlines the code, shares the error handling for unnamed parameter clashes and allows getting rid of the code to extend the formals of functions that become signal handlers in AOT generated cache files. Either onThatSignal: function(param1, param2) { ... } syntax is used and the mapping is fixed and known at AOT/compile time. Or alternatively the dynamic variant is used where the formals are determined at signal handler installation time. Saves a whopping KB of RAM on the QQC1 gallery. Change-Id: I33a9afc06474143d7893f42366cb6553a07ce937 Reviewed-by: Lars Knoll --- src/qml/qml/qqmlboundsignal.cpp | 48 ++++++++++++++++------------------------- 1 file changed, 18 insertions(+), 30 deletions(-) (limited to 'src/qml/qml/qqmlboundsignal.cpp') diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp index d5117c8cec..3d67b45fe8 100644 --- a/src/qml/qml/qqmlboundsignal.cpp +++ b/src/qml/qml/qqmlboundsignal.cpp @@ -110,46 +110,34 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index, m_index(index), m_target(target) { - // If the function is marked as having a nested function, then the user wrote: - // onSomeSignal: function() { /*....*/ } - // So take that nested function: - if (auto closure = function->nestedFunction()) - function = closure; - - setupFunction(scope, function); + // It's important to call init first, because m_index gets remapped in case of cloned signals. init(ctxt, scopeObject); -} -QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index, QQmlContextData *ctxt, QObject *scope, QV4::Function *runtimeFunction) - : QQmlJavaScriptExpression(), - m_index(index), - m_target(target) -{ - // It's important to call init first, because m_index gets remapped in case of cloned signals. - init(ctxt, scope); + QV4::ExecutionEngine *engine = ctxt->engine->handle(); // If the function is marked as having a nested function, then the user wrote: // onSomeSignal: function() { /*....*/ } // So take that nested function: - if (auto closure = runtimeFunction->nestedFunction()) - runtimeFunction = closure; - - QV4::ExecutionEngine *engine = ctxt->engine->handle(); - - QList signalParameters = QMetaObjectPrivate::signal(m_target->metaObject(), m_index).parameterNames(); - if (!signalParameters.isEmpty()) { - QString error; - QQmlPropertyCache::signalParameterStringForJS(engine, signalParameters, &error); - if (!error.isEmpty()) { - qmlWarning(scopeObject()) << error; - return; + if (auto closure = function->nestedFunction()) { + function = closure; + } else { + QList signalParameters = QMetaObjectPrivate::signal(m_target->metaObject(), m_index).parameterNames(); + if (!signalParameters.isEmpty()) { + QString error; + QQmlPropertyCache::signalParameterStringForJS(engine, signalParameters, &error); + if (!error.isEmpty()) { + qmlWarning(scopeObject) << error; + return; + } + function->updateInternalClass(engine, signalParameters); } - runtimeFunction->updateInternalClass(engine, signalParameters); } QV4::Scope valueScope(engine); - QV4::Scoped qmlContext(valueScope, QV4::QmlContext::create(engine->rootContext(), ctxt, scope)); - setupFunction(qmlContext, runtimeFunction); + QV4::Scoped qmlContext(valueScope, scope); + if (!qmlContext) + qmlContext = QV4::QmlContext::create(engine->rootContext(), ctxt, scopeObject); + setupFunction(qmlContext, function); } void QQmlBoundSignalExpression::init(QQmlContextData *ctxt, QObject *scope) -- cgit v1.2.3