From d12c9306ee2355a76e3e037877ee445b31f66a23 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 23 May 2012 16:01:21 +0100 Subject: Use static dispatch tables for QQmlAbstractBinding This saves us the space of the virtual table pointer, but does somewhat limit us to the 4 QQmlAbstractBinding types that we have today. Change-Id: I03d06ef2ec0c51271c28e7a5aab6dc689d369da4 Reviewed-by: Roberto Raggi --- src/qml/qml/qqmlabstractbinding.cpp | 72 +++++++++++++---------------- src/qml/qml/qqmlabstractbinding_p.h | 75 +++++++++++++++++++++++++------ src/qml/qml/qqmlbinding.cpp | 52 +++++++++++++++++++-- src/qml/qml/qqmlbinding_p.h | 25 +++++++---- src/qml/qml/qqmlengine.cpp | 4 +- src/qml/qml/qqmlproperty.cpp | 6 +-- src/qml/qml/qqmlvaluetypeproxybinding.cpp | 58 +++++++++++++++++------- src/qml/qml/qqmlvaluetypeproxybinding_p.h | 14 +++--- src/qml/qml/v4/qv4bindings.cpp | 64 +++++++++++++++++--------- src/qml/qml/v4/qv4bindings_p.h | 20 ++++----- src/qml/qml/v8/qv8bindings.cpp | 68 ++++++++++++++++++++-------- src/qml/qml/v8/qv8bindings_p.h | 17 ++++--- 12 files changed, 326 insertions(+), 149 deletions(-) diff --git a/src/qml/qml/qqmlabstractbinding.cpp b/src/qml/qml/qqmlabstractbinding.cpp index 672e3f5bed..1e5ce8d64a 100644 --- a/src/qml/qml/qqmlabstractbinding.cpp +++ b/src/qml/qml/qqmlabstractbinding.cpp @@ -47,33 +47,31 @@ QT_BEGIN_NAMESPACE -QQmlAbstractBinding::QQmlAbstractBinding() -: m_nextBinding(0) +extern QQmlAbstractBinding::VTable QQmlBinding_vtable; +extern QQmlAbstractBinding::VTable QQmlValueTypeProxyBinding_vtable; +extern QQmlAbstractBinding::VTable QV4Bindings_Binding_vtable; +extern QQmlAbstractBinding::VTable QV8Bindings_Binding_vtable; + +QQmlAbstractBinding::VTable *QQmlAbstractBinding::vTables[] = { + &QQmlBinding_vtable, + &QV4Bindings_Binding_vtable, + &QV8Bindings_Binding_vtable, + &QQmlValueTypeProxyBinding_vtable +}; + +QQmlAbstractBinding::QQmlAbstractBinding(BindingType bt) +: m_nextBindingPtr(bt) { + Q_ASSERT(bt <= 0x03); } QQmlAbstractBinding::~QQmlAbstractBinding() { Q_ASSERT(isAddedToObject() == false); - Q_ASSERT(m_nextBinding == 0); + Q_ASSERT(nextBinding() == 0); Q_ASSERT(*m_mePtr == 0); } -/*! -Destroy the binding. Use this instead of calling delete. - -Bindings are free to implement their own memory management, so the delete operator is not -necessarily safe. The default implementation clears the binding, removes it from the object -and calls delete. -*/ -void QQmlAbstractBinding::destroy() -{ - removeFromObject(); - clear(); - - delete this; -} - /*! Add this binding to \a object. @@ -84,7 +82,7 @@ However, it does not enable the binding itself or call update() on it. */ void QQmlAbstractBinding::addToObject() { - Q_ASSERT(!m_nextBinding); + Q_ASSERT(!nextBinding()); Q_ASSERT(isAddedToObject() == false); QObject *obj = object(); @@ -104,7 +102,7 @@ void QQmlAbstractBinding::addToObject() if (data->hasBindingBit(coreIndex)) { QQmlAbstractBinding *b = data->bindings; while (b && b->propertyIndex() != coreIndex) - b = b->m_nextBinding; + b = b->nextBinding(); Q_ASSERT(b && b->bindingType() == QQmlAbstractBinding::ValueTypeProxy); proxy = static_cast(b); } @@ -118,11 +116,11 @@ void QQmlAbstractBinding::addToObject() proxy->addToObject(); } - m_nextBinding = proxy->m_bindings; + setNextBinding(proxy->m_bindings); proxy->m_bindings = this; } else { - m_nextBinding = data->bindings; + setNextBinding(data->bindings); data->bindings = this; data->setBindingBit(obj, index); @@ -148,7 +146,7 @@ void QQmlAbstractBinding::removeFromObject() // Find the value type binding QQmlAbstractBinding *vtbinding = data->bindings; while (vtbinding->propertyIndex() != (index & 0xFFFFFF)) { - vtbinding = vtbinding->m_nextBinding; + vtbinding = vtbinding->nextBinding(); Q_ASSERT(vtbinding); } Q_ASSERT(vtbinding->bindingType() == QQmlAbstractBinding::ValueTypeProxy); @@ -158,13 +156,13 @@ void QQmlAbstractBinding::removeFromObject() QQmlAbstractBinding *binding = vtproxybinding->m_bindings; if (binding == this) { - vtproxybinding->m_bindings = m_nextBinding; + vtproxybinding->m_bindings = nextBinding(); } else { - while (binding->m_nextBinding != this) { - binding = binding->m_nextBinding; + while (binding->nextBinding() != this) { + binding = binding->nextBinding(); Q_ASSERT(binding); } - binding->m_nextBinding = m_nextBinding; + binding->setNextBinding(nextBinding()); } // Value type - we don't remove the proxy from the object. It will sit their happily @@ -174,20 +172,20 @@ void QQmlAbstractBinding::removeFromObject() } else { if (data->bindings == this) { - data->bindings = m_nextBinding; + data->bindings = nextBinding(); } else { QQmlAbstractBinding *binding = data->bindings; - while (binding->m_nextBinding != this) { - binding = binding->m_nextBinding; + while (binding->nextBinding() != this) { + binding = binding->nextBinding(); Q_ASSERT(binding); } - binding->m_nextBinding = m_nextBinding; + binding->setNextBinding(nextBinding()); } data->clearBindingBit(index); } - m_nextBinding = 0; + setNextBinding(0); setAddedToObject(false); } } @@ -218,20 +216,14 @@ void QQmlAbstractBinding::clear() } } -void QQmlAbstractBinding::retargetBinding(QObject *, int) +void QQmlAbstractBinding::default_retargetBinding(QQmlAbstractBinding *, QObject *, int) { qFatal("QQmlAbstractBinding::retargetBinding() called on illegal binding."); } -QString QQmlAbstractBinding::expression() const +QString QQmlAbstractBinding::default_expression(const QQmlAbstractBinding *) { return QLatin1String(""); } -void QQmlAbstractBinding::setEnabled(bool enabled, QQmlPropertyPrivate::WriteFlags flags) -{ - if (enabled) update(flags); -} - - QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlabstractbinding_p.h b/src/qml/qml/qqmlabstractbinding_p.h index f3071cf8bf..b9f8ecda5d 100644 --- a/src/qml/qml/qqmlabstractbinding_p.h +++ b/src/qml/qml/qqmlabstractbinding_p.h @@ -63,28 +63,41 @@ QT_BEGIN_NAMESPACE class Q_QML_PRIVATE_EXPORT QQmlAbstractBinding { public: - typedef QWeakPointer Pointer; + struct VTable { + void (*destroy)(QQmlAbstractBinding *); + QString (*expression)(const QQmlAbstractBinding *); + int (*propertyIndex)(const QQmlAbstractBinding *); + QObject *(*object)(const QQmlAbstractBinding *); + void (*setEnabled)(QQmlAbstractBinding *, bool, QQmlPropertyPrivate::WriteFlags); + void (*update)(QQmlAbstractBinding *, QQmlPropertyPrivate::WriteFlags); + void (*retargetBinding)(QQmlAbstractBinding *, QObject *, int); + }; - virtual void destroy(); + typedef QWeakPointer Pointer; - virtual QString expression() const; + enum BindingType { Binding = 0, V4 = 1, V8 = 2, ValueTypeProxy = 3 }; + inline BindingType bindingType() const; - enum Type { PropertyBinding, ValueTypeProxy }; - virtual Type bindingType() const { return PropertyBinding; } + // Destroy the binding. Use this instead of calling delete. + // Bindings are free to implement their own memory management, so the delete operator is + // not necessarily safe. The default implementation clears the binding, removes it from + // the object and calls delete. + void destroy() { vtable()->destroy(this); } + QString expression() const { return vtable()->expression(this); } // Should return the encoded property index for the binding. Should return this value // even if the binding is not enabled or added to an object. // Encoding is: coreIndex | (valueTypeIndex << 24) - virtual int propertyIndex() const = 0; + int propertyIndex() const { return vtable()->propertyIndex(this); } // Should return the object for the binding. Should return this object even if the // binding is not enabled or added to the object. - virtual QObject *object() const = 0; + QObject *object() const { return vtable()->object(this); } void setEnabled(bool e) { setEnabled(e, QQmlPropertyPrivate::DontRemoveBinding); } - virtual void setEnabled(bool, QQmlPropertyPrivate::WriteFlags) = 0; + void setEnabled(bool e, QQmlPropertyPrivate::WriteFlags f) { vtable()->setEnabled(this, e, f); } void update() { update(QQmlPropertyPrivate::DontRemoveBinding); } - virtual void update(QQmlPropertyPrivate::WriteFlags) = 0; + void update(QQmlPropertyPrivate::WriteFlags f) { vtable()->update(this, f); } void addToObject(); void removeFromObject(); @@ -92,15 +105,22 @@ public: static inline Pointer getPointer(QQmlAbstractBinding *p); static void printBindingLoopError(QQmlProperty &prop); + // Default implementation for some VTable functions + template + static void default_destroy(QQmlAbstractBinding *); + static QString default_expression(const QQmlAbstractBinding *); + static void default_retargetBinding(QQmlAbstractBinding *, QObject *, int); + protected: - QQmlAbstractBinding(); - virtual ~QQmlAbstractBinding(); + QQmlAbstractBinding(BindingType); + ~QQmlAbstractBinding(); void clear(); // Called by QQmlPropertyPrivate to "move" a binding to a different property. // This is only used for alias properties. The default implementation qFatal()'s // to ensure that the method is never called for binding types that don't support it. - virtual void retargetBinding(QObject *, int); + void retargetBinding(QObject *o, int i) { vtable()->retargetBinding(this, o, i); } + private: Pointer weakPointer(); @@ -120,7 +140,13 @@ private: inline void setAddedToObject(bool v); inline bool isAddedToObject() const; - QQmlAbstractBinding *m_nextBinding; + inline QQmlAbstractBinding *nextBinding() const; + inline void setNextBinding(QQmlAbstractBinding *); + + uintptr_t m_nextBindingPtr; + + static VTable *vTables[]; + inline const VTable *vtable() const { return vTables[bindingType()]; } }; QQmlAbstractBinding::Pointer @@ -139,6 +165,29 @@ bool QQmlAbstractBinding::isAddedToObject() const return m_mePtr.flag(); } +QQmlAbstractBinding *QQmlAbstractBinding::nextBinding() const +{ + return (QQmlAbstractBinding *)(m_nextBindingPtr & ~0x3); +} + +void QQmlAbstractBinding::setNextBinding(QQmlAbstractBinding *b) +{ + m_nextBindingPtr = uintptr_t(b) | (m_nextBindingPtr & 0x3); +} + +QQmlAbstractBinding::BindingType QQmlAbstractBinding::bindingType() const +{ + return (BindingType)(m_nextBindingPtr & 0x3); +} + +template +void QQmlAbstractBinding::default_destroy(QQmlAbstractBinding *This) +{ + This->removeFromObject(); + This->clear(); + delete static_cast(This); +} + QT_END_NAMESPACE #endif // QQMLABSTRACTBINDING_P_H diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index 2c2c801594..81826d704d 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -56,6 +56,17 @@ QT_BEGIN_NAMESPACE +// Used in qqmlabstractbinding.cpp +QQmlAbstractBinding::VTable QQmlBinding_vtable = { + QQmlAbstractBinding::default_destroy, + QQmlBinding::expression, + QQmlBinding::propertyIndex, + QQmlBinding::object, + QQmlBinding::setEnabled, + QQmlBinding::update, + QQmlBinding::retargetBinding +}; + QQmlBinding::Identifier QQmlBinding::Invalid = -1; QQmlBinding * @@ -89,7 +100,8 @@ static QQmlJavaScriptExpression::VTable QQmlBinding_jsvtable = { }; QQmlBinding::QQmlBinding(const QString &str, QObject *obj, QQmlContext *ctxt) -: QQmlJavaScriptExpression(&QQmlBinding_jsvtable), m_lineNumber(-1), m_columnNumber(-1) +: QQmlJavaScriptExpression(&QQmlBinding_jsvtable), QQmlAbstractBinding(Binding), + m_lineNumber(-1), m_columnNumber(-1) { setNotifyOnValueChanged(true); QQmlAbstractExpression::setContext(QQmlContextData::get(ctxt)); @@ -103,7 +115,8 @@ QQmlBinding::QQmlBinding(const QString &str, QObject *obj, QQmlContext *ctxt) } QQmlBinding::QQmlBinding(const QString &str, QObject *obj, QQmlContextData *ctxt) -: QQmlJavaScriptExpression(&QQmlBinding_jsvtable), m_lineNumber(-1), m_columnNumber(-1) +: QQmlJavaScriptExpression(&QQmlBinding_jsvtable), QQmlAbstractBinding(Binding), + m_lineNumber(-1), m_columnNumber(-1) { setNotifyOnValueChanged(true); QQmlAbstractExpression::setContext(ctxt); @@ -119,7 +132,8 @@ QQmlBinding::QQmlBinding(const QString &str, QObject *obj, QQmlContextData *ctxt QQmlBinding::QQmlBinding(const QString &str, bool isRewritten, QObject *obj, QQmlContextData *ctxt, const QString &url, int lineNumber, int columnNumber) -: QQmlJavaScriptExpression(&QQmlBinding_jsvtable), m_lineNumber(-1), m_columnNumber(-1) +: QQmlJavaScriptExpression(&QQmlBinding_jsvtable), QQmlAbstractBinding(Binding), + m_lineNumber(-1), m_columnNumber(-1) { setNotifyOnValueChanged(true); QQmlAbstractExpression::setContext(ctxt); @@ -151,7 +165,7 @@ QQmlBinding::QQmlBinding(const QString &str, bool isRewritten, QObject *obj, */ QQmlBinding::QQmlBinding(void *functionPtr, QObject *obj, QQmlContextData *ctxt, const QString &url, int lineNumber, int columnNumber) -: QQmlJavaScriptExpression(&QQmlBinding_jsvtable), +: QQmlJavaScriptExpression(&QQmlBinding_jsvtable), QQmlAbstractBinding(Binding), m_url(url), m_lineNumber(lineNumber), m_columnNumber(columnNumber) { setNotifyOnValueChanged(true); @@ -293,6 +307,36 @@ void QQmlBinding::refresh() update(); } +QString QQmlBinding::expression(const QQmlAbstractBinding *This) +{ + return static_cast(This)->expression(); +} + +int QQmlBinding::propertyIndex(const QQmlAbstractBinding *This) +{ + return static_cast(This)->propertyIndex(); +} + +QObject *QQmlBinding::object(const QQmlAbstractBinding *This) +{ + return static_cast(This)->object(); +} + +void QQmlBinding::setEnabled(QQmlAbstractBinding *This, bool e, QQmlPropertyPrivate::WriteFlags f) +{ + static_cast(This)->setEnabled(e, f); +} + +void QQmlBinding::update(QQmlAbstractBinding *This , QQmlPropertyPrivate::WriteFlags f) +{ + static_cast(This)->update(f); +} + +void QQmlBinding::retargetBinding(QQmlAbstractBinding *This, QObject *o, int i) +{ + static_cast(This)->retargetBinding(o, i); +} + void QQmlBinding::setEnabled(bool e, QQmlPropertyPrivate::WriteFlags flags) { setEnabledFlag(e); diff --git a/src/qml/qml/qqmlbinding_p.h b/src/qml/qml/qqmlbinding_p.h index 2cf7b80290..bea74e43e2 100644 --- a/src/qml/qml/qqmlbinding_p.h +++ b/src/qml/qml/qqmlbinding_p.h @@ -97,13 +97,22 @@ public: // Inherited from QQmlAbstractExpression virtual void refresh(); - // Inherited from QQmlAbstractBinding - virtual void setEnabled(bool, QQmlPropertyPrivate::WriteFlags flags); - virtual void update(QQmlPropertyPrivate::WriteFlags flags); - virtual QString expression() const; - virtual QObject *object() const; - virtual int propertyIndex() const; - virtual void retargetBinding(QObject *, int); + // "Inherited" from QQmlAbstractBinding + static QString expression(const QQmlAbstractBinding *); + static int propertyIndex(const QQmlAbstractBinding *); + static QObject *object(const QQmlAbstractBinding *); + static void setEnabled(QQmlAbstractBinding *, bool, QQmlPropertyPrivate::WriteFlags); + static void update(QQmlAbstractBinding *, QQmlPropertyPrivate::WriteFlags); + static void retargetBinding(QQmlAbstractBinding *, QObject *, int); + + void setEnabled(bool, QQmlPropertyPrivate::WriteFlags flags); + void update(QQmlPropertyPrivate::WriteFlags flags); + void update() { update(QQmlPropertyPrivate::DontRemoveBinding); } + + QString expression() const; + QObject *object() const; + int propertyIndex() const; + void retargetBinding(QObject *, int); typedef int Identifier; static Identifier Invalid; @@ -111,12 +120,12 @@ public: static QQmlBinding *createBinding(Identifier, QObject *, QQmlContext *, const QString &, int); QVariant evaluate(); - void update() { update(QQmlPropertyPrivate::DontRemoveBinding); } static QString expressionIdentifier(QQmlJavaScriptExpression *); static void expressionChanged(QQmlJavaScriptExpression *); protected: + friend class QQmlAbstractBinding; ~QQmlBinding(); private: diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 08dd845dd6..2634145aa3 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -1292,9 +1292,9 @@ void QQmlData::destroyed(QObject *object) QQmlAbstractBinding *binding = bindings; while (binding) { - QQmlAbstractBinding *next = binding->m_nextBinding; + QQmlAbstractBinding *next = binding->nextBinding(); binding->setAddedToObject(false); - binding->m_nextBinding = 0; + binding->setNextBinding(0); binding->destroy(); binding = next; } diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index 7af7848ddb..5ef833cce0 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -785,7 +785,7 @@ QQmlPropertyPrivate::binding(QObject *object, int coreIndex, int valueTypeIndex) QQmlAbstractBinding *binding = data->bindings; while (binding && binding->propertyIndex() != coreIndex) - binding = binding->m_nextBinding; + binding = binding->nextBinding(); if (binding && valueTypeIndex != -1) { if (binding->bindingType() == QQmlAbstractBinding::ValueTypeProxy) { @@ -862,7 +862,7 @@ QQmlPropertyPrivate::setBinding(QObject *object, int coreIndex, int valueTypeInd binding = data->bindings; while (binding && binding->propertyIndex() != coreIndex) - binding = binding->m_nextBinding; + binding = binding->nextBinding(); } int index = coreIndex; @@ -921,7 +921,7 @@ QQmlPropertyPrivate::setBindingNoEnable(QObject *object, int coreIndex, int valu binding = data->bindings; while (binding && binding->propertyIndex() != coreIndex) - binding = binding->m_nextBinding; + binding = binding->nextBinding(); } int index = coreIndex; diff --git a/src/qml/qml/qqmlvaluetypeproxybinding.cpp b/src/qml/qml/qqmlvaluetypeproxybinding.cpp index 2b891dc4e1..f8d54a6815 100644 --- a/src/qml/qml/qqmlvaluetypeproxybinding.cpp +++ b/src/qml/qml/qqmlvaluetypeproxybinding.cpp @@ -43,8 +43,19 @@ QT_BEGIN_NAMESPACE +// Used in qqmlabstractbinding.cpp +QQmlAbstractBinding::VTable QQmlValueTypeProxyBinding_vtable = { + QQmlAbstractBinding::default_destroy, + QQmlAbstractBinding::default_expression, + QQmlValueTypeProxyBinding::propertyIndex, + QQmlValueTypeProxyBinding::object, + QQmlValueTypeProxyBinding::setEnabled, + QQmlValueTypeProxyBinding::update, + QQmlAbstractBinding::default_retargetBinding +}; + QQmlValueTypeProxyBinding::QQmlValueTypeProxyBinding(QObject *o, int index) -: m_object(o), m_index(index), m_bindings(0) +: QQmlAbstractBinding(ValueTypeProxy), m_object(o), m_index(index), m_bindings(0) { } @@ -53,22 +64,25 @@ QQmlValueTypeProxyBinding::~QQmlValueTypeProxyBinding() QQmlAbstractBinding *binding = m_bindings; // This must be identical to the logic in QQmlData::destroyed() while (binding) { - QQmlAbstractBinding *next = binding->m_nextBinding; + QQmlAbstractBinding *next = binding->nextBinding(); binding->setAddedToObject(false); - binding->m_nextBinding = 0; + binding->setNextBinding(0); binding->destroy(); binding = next; } } -void QQmlValueTypeProxyBinding::setEnabled(bool e, QQmlPropertyPrivate::WriteFlags flags) +void QQmlValueTypeProxyBinding::setEnabled(QQmlAbstractBinding *_This, + bool e, QQmlPropertyPrivate::WriteFlags flags) { + QQmlValueTypeProxyBinding *This = static_cast(_This); + if (e) { - QQmlAbstractBinding *bindings = m_bindings; - recursiveEnable(bindings, flags); + QQmlAbstractBinding *bindings = This->m_bindings; + This->recursiveEnable(bindings, flags); } else { - QQmlAbstractBinding *bindings = m_bindings; - recursiveDisable(bindings); + QQmlAbstractBinding *bindings = This->m_bindings; + This->recursiveDisable(bindings); } } @@ -77,7 +91,7 @@ void QQmlValueTypeProxyBinding::recursiveEnable(QQmlAbstractBinding *b, QQmlProp if (!b) return; - recursiveEnable(b->m_nextBinding, flags); + recursiveEnable(b->nextBinding(), flags); if (b) b->setEnabled(true, flags); @@ -88,13 +102,13 @@ void QQmlValueTypeProxyBinding::recursiveDisable(QQmlAbstractBinding *b) if (!b) return; - recursiveDisable(b->m_nextBinding); + recursiveDisable(b->nextBinding()); if (b) b->setEnabled(false, 0); } -void QQmlValueTypeProxyBinding::update(QQmlPropertyPrivate::WriteFlags) +void QQmlValueTypeProxyBinding::update(QQmlAbstractBinding *, QQmlPropertyPrivate::WriteFlags) { } @@ -103,7 +117,7 @@ QQmlAbstractBinding *QQmlValueTypeProxyBinding::binding(int propertyIndex) QQmlAbstractBinding *binding = m_bindings; while (binding && binding->propertyIndex() != propertyIndex) - binding = binding->m_nextBinding; + binding = binding->nextBinding(); return binding; } @@ -119,23 +133,33 @@ void QQmlValueTypeProxyBinding::removeBindings(quint32 mask) while (binding) { if (mask & (1 << (binding->propertyIndex() >> 24))) { QQmlAbstractBinding *remove = binding; - binding = remove->m_nextBinding; + binding = remove->nextBinding(); if (lastBinding == 0) - m_bindings = remove->m_nextBinding; + m_bindings = remove->nextBinding(); else - lastBinding->m_nextBinding = remove->m_nextBinding; + lastBinding->setNextBinding(remove->nextBinding()); remove->setAddedToObject(false); - remove->m_nextBinding = 0; + remove->setNextBinding(0); remove->destroy(); } else { lastBinding = binding; - binding = binding->m_nextBinding; + binding = binding->nextBinding(); } } } +int QQmlValueTypeProxyBinding::propertyIndex(const QQmlAbstractBinding *This) +{ + return static_cast(This)->m_index; +} + +QObject *QQmlValueTypeProxyBinding::object(const QQmlAbstractBinding *This) +{ + return static_cast(This)->m_object; +} + int QQmlValueTypeProxyBinding::propertyIndex() const { return m_index; diff --git a/src/qml/qml/qqmlvaluetypeproxybinding_p.h b/src/qml/qml/qqmlvaluetypeproxybinding_p.h index 0135d575df..a77562ed63 100644 --- a/src/qml/qml/qqmlvaluetypeproxybinding_p.h +++ b/src/qml/qml/qqmlvaluetypeproxybinding_p.h @@ -62,17 +62,19 @@ class QQmlValueTypeProxyBinding : public QQmlAbstractBinding public: QQmlValueTypeProxyBinding(QObject *o, int coreIndex); - virtual Type bindingType() const { return ValueTypeProxy; } - - virtual void setEnabled(bool, QQmlPropertyPrivate::WriteFlags); - virtual void update(QQmlPropertyPrivate::WriteFlags); - virtual int propertyIndex() const; - virtual QObject *object() const; + int propertyIndex() const; + QObject *object() const; QQmlAbstractBinding *binding(int propertyIndex); void removeBindings(quint32 mask); + // "Inherited" from QQmlAbstractBinding + static void setEnabled(QQmlAbstractBinding *, bool, QQmlPropertyPrivate::WriteFlags); + static void update(QQmlAbstractBinding *, QQmlPropertyPrivate::WriteFlags); + static int propertyIndex(const QQmlAbstractBinding *); + static QObject *object(const QQmlAbstractBinding *); + protected: ~QQmlValueTypeProxyBinding(); diff --git a/src/qml/qml/v4/qv4bindings.cpp b/src/qml/qml/v4/qv4bindings.cpp index 39b571f336..ba90654661 100644 --- a/src/qml/qml/v4/qv4bindings.cpp +++ b/src/qml/qml/v4/qv4bindings.cpp @@ -73,6 +73,16 @@ QT_BEGIN_NAMESPACE using namespace QQmlJS; +QQmlAbstractBinding::VTable QV4Bindings_Binding_vtable = { + QV4Bindings::Binding::destroy, + QQmlAbstractBinding::default_expression, + QV4Bindings::Binding::propertyIndex, + QV4Bindings::Binding::object, + QV4Bindings::Binding::setEnabled, + QV4Bindings::Binding::update, + QV4Bindings::Binding::retargetBinding +}; + namespace { struct Register { typedef QQmlRegisterType Type; @@ -307,46 +317,58 @@ QQmlAbstractBinding *QV4Bindings::configBinding(int index, QObject *target, return rv; } -void QV4Bindings::Binding::setEnabled(bool e, QQmlPropertyPrivate::WriteFlags flags) +void QV4Bindings::Binding::setEnabled(QQmlAbstractBinding *_This, + bool e, QQmlPropertyPrivate::WriteFlags flags) { - if (enabled != e) { - enabled = e; + QV4Bindings::Binding *This = static_cast(_This); - if (e) update(flags); + if (This->enabled != e) { + This->enabled = e; + + if (e) update(_This, flags); } } -void QV4Bindings::Binding::update(QQmlPropertyPrivate::WriteFlags flags) +void QV4Bindings::Binding::update(QQmlAbstractBinding *_This, QQmlPropertyPrivate::WriteFlags flags) { - parent->run(this, flags); + QV4Bindings::Binding *This = static_cast(_This); + This->parent->run(This, flags); } -void QV4Bindings::Binding::destroy() +void QV4Bindings::Binding::destroy(QQmlAbstractBinding *_This) { - enabled = false; - removeFromObject(); - clear(); - removeError(); - parent->release(); + QV4Bindings::Binding *This = static_cast(_This); + + This->enabled = false; + This->removeFromObject(); + This->clear(); + This->removeError(); + This->parent->release(); } -int QV4Bindings::Binding::propertyIndex() const +int QV4Bindings::Binding::propertyIndex(const QQmlAbstractBinding *_This) { - if (target.hasValue()) return target.constValue()->targetProperty; + const QV4Bindings::Binding *This = static_cast(_This); + + if (This->target.hasValue()) return This->target.constValue()->targetProperty; //mask out the type information set for value types - else return property & 0xFF00FFFF; + else return This->property & 0xFF00FFFF; } -QObject *QV4Bindings::Binding::object() const +QObject *QV4Bindings::Binding::object(const QQmlAbstractBinding *_This) { - if (target.hasValue()) return target.constValue()->target; - return *target; + const QV4Bindings::Binding *This = static_cast(_This); + + if (This->target.hasValue()) return This->target.constValue()->target; + return *This->target; } -void QV4Bindings::Binding::retargetBinding(QObject *t, int i) +void QV4Bindings::Binding::retargetBinding(QQmlAbstractBinding *_This, QObject *t, int i) { - target.value().target = t; - target.value().targetProperty = i; + QV4Bindings::Binding *This = static_cast(_This); + + This->target.value().target = t; + This->target.value().targetProperty = i; } QV4Bindings::Subscription::Subscription() diff --git a/src/qml/qml/v4/qv4bindings_p.h b/src/qml/qml/v4/qv4bindings_p.h index d2d8520a83..e9c6301cef 100644 --- a/src/qml/qml/v4/qv4bindings_p.h +++ b/src/qml/qml/v4/qv4bindings_p.h @@ -79,20 +79,17 @@ public: static void **getDecodeInstrTable(); #endif -private: - Q_DISABLE_COPY(QV4Bindings) - struct Binding : public QQmlAbstractBinding, public QQmlDelayedError { - Binding() : enabled(false), updating(0), property(0), + Binding() : QQmlAbstractBinding(V4), enabled(false), updating(0), property(0), scope(0), target(0), executedBlocks(0), parent(0) {} // Inherited from QQmlAbstractBinding - virtual void setEnabled(bool, QQmlPropertyPrivate::WriteFlags flags); - virtual void update(QQmlPropertyPrivate::WriteFlags flags); - virtual void destroy(); - virtual int propertyIndex() const; - virtual void retargetBinding(QObject *, int); - virtual QObject *object() const; + static void destroy(QQmlAbstractBinding *); + static int propertyIndex(const QQmlAbstractBinding *); + static QObject *object(const QQmlAbstractBinding *); + static void setEnabled(QQmlAbstractBinding *, bool, QQmlPropertyPrivate::WriteFlags); + static void update(QQmlAbstractBinding *, QQmlPropertyPrivate::WriteFlags); + static void retargetBinding(QQmlAbstractBinding *, QObject *, int); struct Retarget { QObject *target; @@ -114,6 +111,9 @@ private: QV4Bindings *parent; }; +private: + Q_DISABLE_COPY(QV4Bindings) + class Subscription : public QQmlNotifierEndpoint { public: diff --git a/src/qml/qml/v8/qv8bindings.cpp b/src/qml/qml/v8/qv8bindings.cpp index c92b87ac6c..d8624c7ad6 100644 --- a/src/qml/qml/v8/qv8bindings.cpp +++ b/src/qml/qml/v8/qv8bindings.cpp @@ -52,22 +52,35 @@ QT_BEGIN_NAMESPACE +QQmlAbstractBinding::VTable QV8Bindings_Binding_vtable = { + QV8Bindings::Binding::destroy, + QQmlAbstractBinding::default_expression, + QV8Bindings::Binding::propertyIndex, + QV8Bindings::Binding::object, + QV8Bindings::Binding::setEnabled, + QV8Bindings::Binding::update, + QV8Bindings::Binding::retargetBinding +}; + static QQmlJavaScriptExpression::VTable QV8Bindings_Binding_jsvtable = { QV8Bindings::Binding::expressionIdentifier, QV8Bindings::Binding::expressionChanged }; QV8Bindings::Binding::Binding() -: QQmlJavaScriptExpression(&QV8Bindings_Binding_jsvtable), parent(0) +: QQmlJavaScriptExpression(&QV8Bindings_Binding_jsvtable), QQmlAbstractBinding(V8), parent(0) { } -void QV8Bindings::Binding::setEnabled(bool e, QQmlPropertyPrivate::WriteFlags flags) +void QV8Bindings::Binding::setEnabled(QQmlAbstractBinding *_This, bool e, + QQmlPropertyPrivate::WriteFlags flags) { - if (enabledFlag() != e) { - setEnabledFlag(e); + QV8Bindings::Binding *This = static_cast(_This); + + if (This->enabledFlag() != e) { + This->setEnabledFlag(e); - if (e) update(flags); + if (e) This->update(flags); } } @@ -83,10 +96,19 @@ void QV8Bindings::Binding::refresh() update(); } -int QV8Bindings::Binding::propertyIndex() const +int QV8Bindings::Binding::propertyIndex(const QQmlAbstractBinding *_This) { - if (target.hasValue()) return target.constValue()->targetProperty; - else return instruction->property.encodedIndex(); + const QV8Bindings::Binding *This = static_cast(_This); + if (This->target.hasValue()) return This->target.constValue()->targetProperty; + else return This->instruction->property.encodedIndex(); +} + +QObject *QV8Bindings::Binding::object(const QQmlAbstractBinding *_This) +{ + const QV8Bindings::Binding *This = static_cast(_This); + + if (This->target.hasValue()) return This->target.constValue()->target; + else return *This->target; } QObject *QV8Bindings::Binding::object() const @@ -95,10 +117,18 @@ QObject *QV8Bindings::Binding::object() const else return *target; } -void QV8Bindings::Binding::retargetBinding(QObject *t, int i) +void QV8Bindings::Binding::retargetBinding(QQmlAbstractBinding *_This, QObject *t, int i) +{ + QV8Bindings::Binding *This = static_cast(_This); + + This->target.value().target = t; + This->target.value().targetProperty = i; +} + +void QV8Bindings::Binding::update(QQmlAbstractBinding *_This, QQmlPropertyPrivate::WriteFlags flags) { - target.value().target = t; - target.value().targetProperty = i; + QV8Bindings::Binding *This = static_cast(_This); + This->update(flags); } void QV8Bindings::Binding::update(QQmlPropertyPrivate::WriteFlags flags) @@ -184,14 +214,16 @@ void QV8Bindings::Binding::expressionChanged(QQmlJavaScriptExpression *e) This->update(QQmlPropertyPrivate::DontRemoveBinding); } -void QV8Bindings::Binding::destroy() +void QV8Bindings::Binding::destroy(QQmlAbstractBinding *_This) { - setEnabledFlag(false); - setDestroyedFlag(true); - removeFromObject(); - clear(); - clearError(); - parent->release(); + QV8Bindings::Binding *This = static_cast(_This); + + This->setEnabledFlag(false); + This->setDestroyedFlag(true); + This->removeFromObject(); + This->clear(); + This->clearError(); + This->parent->release(); } QV8Bindings::QV8Bindings(QQmlCompiledData::V8Program *program, diff --git a/src/qml/qml/v8/qv8bindings_p.h b/src/qml/qml/v8/qv8bindings_p.h index 7cc1cc9c21..fc6617b516 100644 --- a/src/qml/qml/v8/qv8bindings_p.h +++ b/src/qml/qml/v8/qv8bindings_p.h @@ -93,13 +93,16 @@ public: static QString expressionIdentifier(QQmlJavaScriptExpression *); static void expressionChanged(QQmlJavaScriptExpression *); - // Inherited from QQmlAbstractBinding - virtual void setEnabled(bool, QQmlPropertyPrivate::WriteFlags flags); - virtual void update(QQmlPropertyPrivate::WriteFlags flags); - virtual void destroy(); - virtual QObject *object() const; - virtual int propertyIndex() const; - virtual void retargetBinding(QObject *, int); + // "Inherited" from QQmlAbstractBinding + static void destroy(QQmlAbstractBinding *); + static int propertyIndex(const QQmlAbstractBinding *); + static QObject *object(const QQmlAbstractBinding *); + static void setEnabled(QQmlAbstractBinding *, bool, QQmlPropertyPrivate::WriteFlags); + static void update(QQmlAbstractBinding *, QQmlPropertyPrivate::WriteFlags); + static void retargetBinding(QQmlAbstractBinding *, QObject *, int); + + QObject *object() const; + void update(QQmlPropertyPrivate::WriteFlags flags); QV8Bindings *parent; -- cgit v1.2.3