From 54daa0035c9649ab92a70ae050534832b37c09be Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 13 Apr 2015 11:49:18 +0200 Subject: Remove the manual vtable from QQmlJavaScriptExpression Now that the class got unified with QQmlAbstractExpression, it has a vtable anyway, so we can just as well remove the old hack. Change-Id: Ifa095297e3d75564c4305ce3655eaa57436ef4a8 Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlbinding.cpp | 28 ++++++++++------------------ src/qml/qml/qqmlbinding_p.h | 4 ++-- src/qml/qml/qqmlboundsignal.cpp | 18 ++++++------------ src/qml/qml/qqmlboundsignal_p.h | 6 +++--- src/qml/qml/qqmlexpression.cpp | 18 +++--------------- src/qml/qml/qqmlexpression_p.h | 5 ++--- src/qml/qml/qqmljavascriptexpression.cpp | 23 ++++++++++++----------- src/qml/qml/qqmljavascriptexpression_p.h | 21 +++++++-------------- 8 files changed, 45 insertions(+), 78 deletions(-) diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index 2a53365f69..9123825f65 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -62,13 +62,8 @@ QQmlAbstractBinding::VTable QQmlBinding_vtable = { QQmlBinding::Identifier QQmlBinding::Invalid = -1; -static QQmlJavaScriptExpression::VTable QQmlBinding_jsvtable = { - QQmlBinding::expressionIdentifier, - QQmlBinding::expressionChanged -}; - QQmlBinding::QQmlBinding(const QString &str, QObject *obj, QQmlContext *ctxt) -: QQmlJavaScriptExpression(&QQmlBinding_jsvtable), QQmlAbstractBinding(Binding) +: QQmlJavaScriptExpression(), QQmlAbstractBinding(Binding) { setNotifyOnValueChanged(true); QQmlJavaScriptExpression::setContext(QQmlContextData::get(ctxt)); @@ -79,7 +74,7 @@ QQmlBinding::QQmlBinding(const QString &str, QObject *obj, QQmlContext *ctxt) } QQmlBinding::QQmlBinding(const QQmlScriptString &script, QObject *obj, QQmlContext *ctxt) -: QQmlJavaScriptExpression(&QQmlBinding_jsvtable), QQmlAbstractBinding(Binding) +: QQmlJavaScriptExpression(), QQmlAbstractBinding(Binding) { if (ctxt && !ctxt->isValid()) return; @@ -113,7 +108,7 @@ QQmlBinding::QQmlBinding(const QQmlScriptString &script, QObject *obj, QQmlConte } QQmlBinding::QQmlBinding(const QString &str, QObject *obj, QQmlContextData *ctxt) -: QQmlJavaScriptExpression(&QQmlBinding_jsvtable), QQmlAbstractBinding(Binding) +: QQmlJavaScriptExpression(), QQmlAbstractBinding(Binding) { setNotifyOnValueChanged(true); QQmlJavaScriptExpression::setContext(ctxt); @@ -126,7 +121,7 @@ QQmlBinding::QQmlBinding(const QString &str, QObject *obj, QQmlContextData *ctxt QQmlBinding::QQmlBinding(const QString &str, QObject *obj, QQmlContextData *ctxt, const QString &url, quint16 lineNumber, quint16 columnNumber) -: QQmlJavaScriptExpression(&QQmlBinding_jsvtable), QQmlAbstractBinding(Binding) +: QQmlJavaScriptExpression(), QQmlAbstractBinding(Binding) { Q_UNUSED(columnNumber); setNotifyOnValueChanged(true); @@ -138,7 +133,7 @@ QQmlBinding::QQmlBinding(const QString &str, QObject *obj, } QQmlBinding::QQmlBinding(const QV4::Value &functionPtr, QObject *obj, QQmlContextData *ctxt) -: QQmlJavaScriptExpression(&QQmlBinding_jsvtable), QQmlAbstractBinding(Binding) +: QQmlJavaScriptExpression(), QQmlAbstractBinding(Binding) { setNotifyOnValueChanged(true); QQmlJavaScriptExpression::setContext(ctxt); @@ -238,13 +233,11 @@ QVariant QQmlBinding::evaluate() return scope.engine->toVariant(result, qMetaTypeId >()); } -QString QQmlBinding::expressionIdentifier(QQmlJavaScriptExpression *e) +QString QQmlBinding::expressionIdentifier() { - QQmlBinding *This = static_cast(e); - - QQmlEnginePrivate *ep = QQmlEnginePrivate::get(This->context()->engine); + QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context()->engine); QV4::Scope scope(ep->v4engine()); - QV4::ScopedValue f(scope, This->v4function.value()); + QV4::ScopedValue f(scope, v4function.value()); QV4::Function *function = f->as()->function(); QString url = function->sourceFile(); @@ -254,10 +247,9 @@ QString QQmlBinding::expressionIdentifier(QQmlJavaScriptExpression *e) return url + QLatin1Char(':') + QString::number(lineNumber) + QLatin1Char(':') + QString::number(columnNumber); } -void QQmlBinding::expressionChanged(QQmlJavaScriptExpression *e) +void QQmlBinding::expressionChanged() { - QQmlBinding *This = static_cast(e); - This->update(); + update(); } void QQmlBinding::refresh() diff --git a/src/qml/qml/qqmlbinding_p.h b/src/qml/qml/qqmlbinding_p.h index 79c61574a5..4f1c27c248 100644 --- a/src/qml/qml/qqmlbinding_p.h +++ b/src/qml/qml/qqmlbinding_p.h @@ -104,8 +104,8 @@ public: QVariant evaluate(); - static QString expressionIdentifier(QQmlJavaScriptExpression *); - static void expressionChanged(QQmlJavaScriptExpression *); + virtual QString expressionIdentifier(); + virtual void expressionChanged(); protected: friend class QQmlAbstractBinding; diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp index 387c162b82..c24cfed2ff 100644 --- a/src/qml/qml/qqmlboundsignal.cpp +++ b/src/qml/qml/qqmlboundsignal.cpp @@ -55,11 +55,6 @@ QT_BEGIN_NAMESPACE -static QQmlJavaScriptExpression::VTable QQmlBoundSignalExpression_jsvtable = { - QQmlBoundSignalExpression::expressionIdentifier, - QQmlBoundSignalExpression::expressionChanged -}; - QQmlBoundSignalExpression::ExtraData::ExtraData(const QString &handlerName, const QString ¶meterString, const QString &expression, const QString &fileName, quint16 line, quint16 column) @@ -75,7 +70,7 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index, const QString &fileName, quint16 line, quint16 column, const QString &handlerName, const QString ¶meterString) - : QQmlJavaScriptExpression(&QQmlBoundSignalExpression_jsvtable), + : QQmlJavaScriptExpression(), m_index(index), m_target(target), m_extra(new ExtraData(handlerName, parameterString, expression, fileName, line, column)) @@ -87,7 +82,7 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index, } QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index, QQmlContextData *ctxt, QObject *scope, const QV4::Value &function) - : QQmlJavaScriptExpression(&QQmlBoundSignalExpression_jsvtable), + : QQmlJavaScriptExpression(), m_index(index), m_function(function.as()->engine(), function), m_target(target), @@ -100,7 +95,7 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index, } QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index, QQmlContextData *ctxt, QObject *scope, QV4::Function *runtimeFunction) - : QQmlJavaScriptExpression(&QQmlBoundSignalExpression_jsvtable), + : QQmlJavaScriptExpression(), m_index(index), m_target(target), m_extra(0) @@ -137,14 +132,13 @@ QQmlBoundSignalExpression::~QQmlBoundSignalExpression() delete m_extra.data(); } -QString QQmlBoundSignalExpression::expressionIdentifier(QQmlJavaScriptExpression *e) +QString QQmlBoundSignalExpression::expressionIdentifier() { - QQmlBoundSignalExpression *This = static_cast(e); - QQmlSourceLocation loc = This->sourceLocation(); + QQmlSourceLocation loc = sourceLocation(); return loc.sourceFile + QLatin1Char(':') + QString::number(loc.line); } -void QQmlBoundSignalExpression::expressionChanged(QQmlJavaScriptExpression *) +void QQmlBoundSignalExpression::expressionChanged() { // bound signals do not notify on change. } diff --git a/src/qml/qml/qqmlboundsignal_p.h b/src/qml/qml/qqmlboundsignal_p.h index c65742da8a..fb9c878fd2 100644 --- a/src/qml/qml/qqmlboundsignal_p.h +++ b/src/qml/qml/qqmlboundsignal_p.h @@ -72,9 +72,9 @@ public: QQmlBoundSignalExpression(QObject *target, int index, QQmlContextData *ctxt, QObject *scope, QV4::Function *runtimeFunction); - // "inherited" from QQmlJavaScriptExpression. - static QString expressionIdentifier(QQmlJavaScriptExpression *); - static void expressionChanged(QQmlJavaScriptExpression *); + // inherited from QQmlJavaScriptExpression. + virtual QString expressionIdentifier(); + virtual void expressionChanged(); // evaluation of a bound signal expression doesn't return any value void evaluate(void **a); diff --git a/src/qml/qml/qqmlexpression.cpp b/src/qml/qml/qqmlexpression.cpp index 9617e430b8..f84a5c2e16 100644 --- a/src/qml/qml/qqmlexpression.cpp +++ b/src/qml/qml/qqmlexpression.cpp @@ -45,13 +45,8 @@ QT_BEGIN_NAMESPACE -static QQmlJavaScriptExpression::VTable QQmlExpressionPrivate_jsvtable = { - QQmlExpressionPrivate::expressionIdentifier, - QQmlExpressionPrivate::expressionChanged -}; - QQmlExpressionPrivate::QQmlExpressionPrivate() -: QQmlJavaScriptExpression(&QQmlExpressionPrivate_jsvtable), +: QQmlJavaScriptExpression(), expressionFunctionValid(true), line(0), column(0) { @@ -432,22 +427,15 @@ QQmlError QQmlExpression::error() const calling QQmlExpression::evaluate()) before this signal will be emitted. */ -void QQmlExpressionPrivate::expressionChanged(QQmlJavaScriptExpression *e) -{ - QQmlExpressionPrivate *This = static_cast(e); - This->expressionChanged(); -} - void QQmlExpressionPrivate::expressionChanged() { Q_Q(QQmlExpression); emit q->valueChanged(); } -QString QQmlExpressionPrivate::expressionIdentifier(QQmlJavaScriptExpression *e) +QString QQmlExpressionPrivate::expressionIdentifier() { - QQmlExpressionPrivate *This = static_cast(e); - return QLatin1Char('"') + This->expression + QLatin1Char('"'); + return QLatin1Char('"') + expression + QLatin1Char('"'); } QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlexpression_p.h b/src/qml/qml/qqmlexpression_p.h index f1c02c51b0..f7fb7cb7c3 100644 --- a/src/qml/qml/qqmlexpression_p.h +++ b/src/qml/qml/qqmlexpression_p.h @@ -80,9 +80,8 @@ public: bool expressionFunctionValid:1; - // "Inherited" from QQmlJavaScriptExpression - static QString expressionIdentifier(QQmlJavaScriptExpression *); - static void expressionChanged(QQmlJavaScriptExpression *); + // Inherited from QQmlJavaScriptExpression + virtual QString expressionIdentifier(); virtual void expressionChanged(); QString expression; diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp index 41599a9f42..204f917e41 100644 --- a/src/qml/qml/qqmljavascriptexpression.cpp +++ b/src/qml/qml/qqmljavascriptexpression.cpp @@ -83,8 +83,8 @@ void QQmlDelayedError::catchJavaScriptException(QV4::ExecutionEngine *engine) } -QQmlJavaScriptExpression::QQmlJavaScriptExpression(VTable *v) - : m_vtable(v), +QQmlJavaScriptExpression::QQmlJavaScriptExpression() + : m_error(0), m_context(0), m_prevExpression(0), m_nextExpression(0) @@ -257,7 +257,7 @@ void QQmlJavaScriptExpression::GuardCapture::captureProperty(QObject *o, int c, if (!errorString) { errorString = new QStringList; QString preamble = QLatin1String("QQmlExpression: Expression ") + - expression->m_vtable->expressionIdentifier(expression) + + expression->expressionIdentifier() + QLatin1String(" depends on non-NOTIFYable properties:"); errorString->append(preamble); } @@ -292,25 +292,26 @@ void QQmlJavaScriptExpression::GuardCapture::captureProperty(QObject *o, int c, void QQmlJavaScriptExpression::clearError() { - if (m_vtable.hasValue()) { - m_vtable.value().clearError(); - m_vtable.value().removeError(); - } + if (m_error) + delete m_error; + m_error = 0; } QQmlError QQmlJavaScriptExpression::error(QQmlEngine *engine) const { Q_UNUSED(engine); - if (m_vtable.hasValue()) - return m_vtable.constValue()->error(); + if (m_error) + return m_error->error(); else return QQmlError(); } QQmlDelayedError *QQmlJavaScriptExpression::delayedError() { - return &m_vtable.value(); + if (!m_error) + m_error = new QQmlDelayedError; + return m_error; } QV4::ReturnedValue @@ -392,7 +393,7 @@ void QQmlJavaScriptExpressionGuard_callback(QQmlNotifierEndpoint *e, void **) QQmlJavaScriptExpression *expression = static_cast(e)->expression; - expression->m_vtable->expressionChanged(expression); + expression->expressionChanged(); } QT_END_NAMESPACE diff --git a/src/qml/qml/qqmljavascriptexpression_p.h b/src/qml/qml/qqmljavascriptexpression_p.h index c8f54527a0..f9f304a524 100644 --- a/src/qml/qml/qqmljavascriptexpression_p.h +++ b/src/qml/qml/qqmljavascriptexpression_p.h @@ -92,19 +92,12 @@ private: class Q_QML_PRIVATE_EXPORT QQmlJavaScriptExpression { public: - // Although this looks crazy, we implement our own "vtable" here, rather than relying on - // C++ virtuals, to save memory. By doing it ourselves, we can overload the storage - // location that is use for the vtable to also store the rarely used delayed error. - // If we use C++ virtuals, we can't do this and it consts us an extra sizeof(void *) in - // memory for every expression. - struct VTable { - QString (*expressionIdentifier)(QQmlJavaScriptExpression *); - void (*expressionChanged)(QQmlJavaScriptExpression *); - }; - - QQmlJavaScriptExpression(VTable *vtable); + QQmlJavaScriptExpression(); virtual ~QQmlJavaScriptExpression(); + virtual QString expressionIdentifier() = 0; + virtual void expressionChanged() = 0; + QV4::ReturnedValue evaluate(QQmlContextData *, const QV4::Value &function, bool *isUndefined); QV4::ReturnedValue evaluate(QQmlContextData *, const QV4::Value &function, QV4::CallData *callData, bool *isUndefined); @@ -176,7 +169,7 @@ private: QStringList *errorString; }; - QPointerValuePair m_vtable; + QQmlDelayedError *m_error; // We store some flag bits in the following flag pointers. // activeGuards:flag1 - notifyOnValueChanged @@ -234,12 +227,12 @@ void QQmlJavaScriptExpression::setScopeObject(QObject *v) bool QQmlJavaScriptExpression::hasError() const { - return m_vtable.hasValue() && m_vtable.constValue()->isValid(); + return m_error && m_error->isValid(); } bool QQmlJavaScriptExpression::hasDelayedError() const { - return m_vtable.hasValue(); + return m_error; } QQmlJavaScriptExpressionGuard::QQmlJavaScriptExpressionGuard(QQmlJavaScriptExpression *e) -- cgit v1.2.3