From f9b8436a07534867686627b656418d62f75ba3e5 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 2 Dec 2016 09:50:36 +0100 Subject: Mostly use the QV4::Function in javascript expressions Move the function() accessor from QQmlBoundSIgnal to QQmlJavaScriptExpression. Change the profiler to operate on QV4::Function objects for binding profiling. Change-Id: Ic7ce83c487ceb69cad4b16e3dab42026238b7e82 Reviewed-by: Simon Hausmann --- src/qml/debugger/qqmlprofiler_p.h | 9 +++++++-- src/qml/qml/qqmlbinding.cpp | 20 ++++++-------------- src/qml/qml/qqmlboundsignal.cpp | 19 ++----------------- src/qml/qml/qqmlboundsignal_p.h | 3 +-- src/qml/qml/qqmljavascriptexpression.cpp | 12 ++++++++++++ src/qml/qml/qqmljavascriptexpression_p.h | 2 ++ 6 files changed, 30 insertions(+), 35 deletions(-) diff --git a/src/qml/debugger/qqmlprofiler_p.h b/src/qml/debugger/qqmlprofiler_p.h index 6643695d11..242f26ee0d 100644 --- a/src/qml/debugger/qqmlprofiler_p.h +++ b/src/qml/debugger/qqmlprofiler_p.h @@ -204,6 +204,11 @@ public: ref(new BindingRefCount(binding), QQmlRefPointer::Adopt), sent(false) {} + RefLocation(QQmlBinding *binding, QV4::Function *function) : + Location(function->sourceLocation()), locationType(Binding), + ref(new BindingRefCount(binding), QQmlRefPointer::Adopt), sent(false) + {} + RefLocation(QV4::CompiledData::CompilationUnit *ref, const QUrl &url, const QV4::CompiledData::Object *obj, const QString &type) : Location(QQmlSourceLocation(type, obj->location.line, obj->location.column), url), @@ -231,7 +236,7 @@ public: typedef QHash LocationHash; - void startBinding(QQmlBinding *binding, QV4::FunctionObject *function) + void startBinding(QQmlBinding *binding, QV4::Function *function) { quintptr locationId(id(binding)); m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(), @@ -326,7 +331,7 @@ struct QQmlProfilerHelper : public QQmlProfilerDefinitions { struct QQmlBindingProfiler : public QQmlProfilerHelper { QQmlBindingProfiler(QQmlProfiler *profiler, QQmlBinding *binding, - QV4::FunctionObject *function) : + QV4::Function *function) : QQmlProfilerHelper(profiler) { Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileBinding, profiler, diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index 5f0f2eabcc..c7d185ff9a 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -155,13 +155,11 @@ void QQmlBinding::update(QQmlPropertyData::WriteFlags flags) QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context()->engine); QV4::Scope scope(ep->v4engine()); - QV4::ScopedFunctionObject f(scope, m_function.value()); - Q_ASSERT(f); if (canUseAccessor()) flags.setFlag(QQmlPropertyData::BypassInterceptor); - QQmlBindingProfiler prof(ep->profiler, this, f); + QQmlBindingProfiler prof(ep->profiler, this, function()); doUpdate(watcher, flags, scope); if (!watcher.wasDeleted()) @@ -420,14 +418,10 @@ QVariant QQmlBinding::evaluate() QString QQmlBinding::expressionIdentifier() { - QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context()->engine); - QV4::Scope scope(ep->v4engine()); - QV4::ScopedValue f(scope, m_function.value()); - QV4::Function *function = f->as()->function(); - - QString url = function->sourceFile(); - quint16 lineNumber = function->compiledFunction->location.line; - quint16 columnNumber = function->compiledFunction->location.column; + auto f = function(); + QString url = f->sourceFile(); + quint16 lineNumber = f->compiledFunction->location.line; + quint16 columnNumber = f->compiledFunction->location.column; return url + QString::asprintf(":%u:%u", uint(lineNumber), uint(columnNumber)); } @@ -458,9 +452,7 @@ void QQmlBinding::setEnabled(bool e, QQmlPropertyData::WriteFlags flags) QString QQmlBinding::expression() const { - QV4::Scope scope(QQmlEnginePrivate::get(context()->engine)->v4engine()); - QV4::ScopedValue v(scope, m_function.value()); - return v->toQStringNoThrow(); + return QStringLiteral("function() { [code] }"); } void QQmlBinding::setTarget(const QQmlProperty &prop) diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp index 7b7e6562ff..e88c836ce0 100644 --- a/src/qml/qml/qqmlboundsignal.cpp +++ b/src/qml/qml/qqmlboundsignal.cpp @@ -159,26 +159,11 @@ void QQmlBoundSignalExpression::expressionChanged() QString QQmlBoundSignalExpression::expression() const { - if (expressionFunctionValid()) { - Q_ASSERT (context() && engine()); - QV4::Scope scope(QQmlEnginePrivate::get(engine())->v4engine()); - QV4::ScopedValue v(scope, m_function.value()); - return v->toQStringNoThrow(); - } + if (expressionFunctionValid()) + return QStringLiteral("function() { [code] }"); return QString(); } -QV4::Function *QQmlBoundSignalExpression::function() const -{ - if (expressionFunctionValid()) { - Q_ASSERT (context() && engine()); - QV4::Scope scope(QQmlEnginePrivate::get(engine())->v4engine()); - QV4::ScopedFunctionObject v(scope, m_function.value()); - return v ? v->function() : 0; - } - return 0; -} - // Parts of this function mirror code in QQmlExpressionPrivate::value() and v8value(). // Changes made here may need to be made there and vice versa. void QQmlBoundSignalExpression::evaluate(void **a) diff --git a/src/qml/qml/qqmlboundsignal_p.h b/src/qml/qml/qqmlboundsignal_p.h index 2234f08497..b9b0c2b481 100644 --- a/src/qml/qml/qqmlboundsignal_p.h +++ b/src/qml/qml/qqmlboundsignal_p.h @@ -87,7 +87,6 @@ public: void evaluate(const QList &args); QString expression() const; - QV4::Function *function() const; QObject *target() const { return m_target; } QQmlEngine *engine() const { return context() ? context()->engine : 0; } @@ -97,7 +96,7 @@ private: void init(QQmlContextData *ctxt, QObject *scope); - bool expressionFunctionValid() const { return !m_function.isNullOrUndefined(); } + bool expressionFunctionValid() const { return function() != 0; } int m_index; QObject *m_target; diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp index f81320aa6b..a694b43447 100644 --- a/src/qml/qml/qqmljavascriptexpression.cpp +++ b/src/qml/qml/qqmljavascriptexpression.cpp @@ -48,6 +48,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -131,6 +132,9 @@ void QQmlJavaScriptExpression::resetNotifyOnValueChanged() QQmlSourceLocation QQmlJavaScriptExpression::sourceLocation() const { return m_function.valueRef()->as()->sourceLocation(); + // Can't use the below yet, as the source location for bindings gnerated with Qt.binding() would be wrong. +// auto f = function(); +// return f ? f->sourceLocation() : QQmlSourceLocation(); } void QQmlJavaScriptExpression::setContext(QQmlContextData *context) @@ -154,6 +158,14 @@ void QQmlJavaScriptExpression::setContext(QQmlContextData *context) } } +QV4::Function *QQmlJavaScriptExpression::function() const +{ + QV4::FunctionObject *f = m_function.valueRef()->as(); + if (f && f->isBinding()) + return static_cast(f)->d()->originalFunction->function; + return f ? f->function() : 0; +} + void QQmlJavaScriptExpression::refresh() { } diff --git a/src/qml/qml/qqmljavascriptexpression_p.h b/src/qml/qml/qqmljavascriptexpression_p.h index 038f9688a1..3e00d6be24 100644 --- a/src/qml/qml/qqmljavascriptexpression_p.h +++ b/src/qml/qml/qqmljavascriptexpression_p.h @@ -120,6 +120,8 @@ public: QQmlContextData *context() const { return m_context; } void setContext(QQmlContextData *context); + QV4::Function *function() const; + virtual void refresh(); class DeleteWatcher { -- cgit v1.2.3