Use static dispatch tables for QQmlAbstractBinding
authorAaron Kennedy <aaron.kennedy@nokia.com>
Wed, 23 May 2012 15:01:21 +0000 (16:01 +0100)
committerQt by Nokia <qt-info@nokia.com>
Thu, 24 May 2012 15:50:13 +0000 (17:50 +0200)
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 <roberto.raggi@nokia.com>

12 files changed:
src/qml/qml/qqmlabstractbinding.cpp
src/qml/qml/qqmlabstractbinding_p.h
src/qml/qml/qqmlbinding.cpp
src/qml/qml/qqmlbinding_p.h
src/qml/qml/qqmlengine.cpp
src/qml/qml/qqmlproperty.cpp
src/qml/qml/qqmlvaluetypeproxybinding.cpp
src/qml/qml/qqmlvaluetypeproxybinding_p.h
src/qml/qml/v4/qv4bindings.cpp
src/qml/qml/v4/qv4bindings_p.h
src/qml/qml/v8/qv8bindings.cpp
src/qml/qml/v8/qv8bindings_p.h

index 672e3f5..1e5ce8d 100644 (file)
 
 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.
 
 This transfers ownership of the binding to the object, marks the object's property as
@@ -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<QQmlValueTypeProxyBinding *>(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("<Unknown>");
 }
 
-void QQmlAbstractBinding::setEnabled(bool enabled, QQmlPropertyPrivate::WriteFlags flags)
-{
-    if (enabled) update(flags);
-}
-
-
 QT_END_NAMESPACE
index f3071cf..b9f8ecd 100644 (file)
@@ -63,28 +63,41 @@ QT_BEGIN_NAMESPACE
 class Q_QML_PRIVATE_EXPORT QQmlAbstractBinding
 {
 public:
-    typedef QWeakPointer<QQmlAbstractBinding> 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<QQmlAbstractBinding> 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<typename T>
+    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<typename T>
+void QQmlAbstractBinding::default_destroy(QQmlAbstractBinding *This)
+{
+    This->removeFromObject();
+    This->clear();
+    delete static_cast<T *>(This);
+}
+
 QT_END_NAMESPACE
 
 #endif // QQMLABSTRACTBINDING_P_H
index 2c2c801..81826d7 100644 (file)
 
 QT_BEGIN_NAMESPACE
 
+// Used in qqmlabstractbinding.cpp
+QQmlAbstractBinding::VTable QQmlBinding_vtable = {
+    QQmlAbstractBinding::default_destroy<QQmlBinding>,
+    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<const QQmlBinding *>(This)->expression();
+}
+
+int QQmlBinding::propertyIndex(const QQmlAbstractBinding *This)
+{
+    return static_cast<const QQmlBinding *>(This)->propertyIndex();
+}
+
+QObject *QQmlBinding::object(const QQmlAbstractBinding *This)
+{
+    return static_cast<const QQmlBinding *>(This)->object();
+}
+
+void QQmlBinding::setEnabled(QQmlAbstractBinding *This, bool e, QQmlPropertyPrivate::WriteFlags f)
+{
+    static_cast<QQmlBinding *>(This)->setEnabled(e, f);
+}
+
+void QQmlBinding::update(QQmlAbstractBinding *This , QQmlPropertyPrivate::WriteFlags f)
+{
+    static_cast<QQmlBinding *>(This)->update(f);
+}
+
+void QQmlBinding::retargetBinding(QQmlAbstractBinding *This, QObject *o, int i)
+{
+    static_cast<QQmlBinding *>(This)->retargetBinding(o, i);
+}
+
 void QQmlBinding::setEnabled(bool e, QQmlPropertyPrivate::WriteFlags flags)
 {
     setEnabledFlag(e);
index 2cf7b80..bea74e4 100644 (file)
@@ -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:
index 08dd845..2634145 100644 (file)
@@ -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;
     }
index 7af7848..5ef833c 100644 (file)
@@ -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;
index 2b891dc..f8d54a6 100644 (file)
 
 QT_BEGIN_NAMESPACE
 
+// Used in qqmlabstractbinding.cpp
+QQmlAbstractBinding::VTable QQmlValueTypeProxyBinding_vtable = {
+    QQmlAbstractBinding::default_destroy<QQmlValueTypeProxyBinding>,
+    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<QQmlValueTypeProxyBinding *>(_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<const QQmlValueTypeProxyBinding *>(This)->m_index;
+}
+
+QObject *QQmlValueTypeProxyBinding::object(const QQmlAbstractBinding *This)
+{
+    return static_cast<const QQmlValueTypeProxyBinding *>(This)->m_object;
+}
+
 int QQmlValueTypeProxyBinding::propertyIndex() const
 {
     return m_index;
index 0135d57..a77562e 100644 (file)
@@ -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();
 
index 39b571f..ba90654 100644 (file)
@@ -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<QV4Bindings::Binding *>(_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<QV4Bindings::Binding *>(_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<QV4Bindings::Binding *>(_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<const QV4Bindings::Binding *>(_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<const QV4Bindings::Binding *>(_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<QV4Bindings::Binding *>(_This);
+
+    This->target.value().target = t;
+    This->target.value().targetProperty = i;
 }
 
 QV4Bindings::Subscription::Subscription()
index d2d8520..e9c6301 100644 (file)
@@ -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:
index c92b87a..d8624c7 100644 (file)
 
 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<QV8Bindings::Binding *>(_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<const QV8Bindings::Binding *>(_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<const QV8Bindings::Binding *>(_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<QV8Bindings::Binding *>(_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<QV8Bindings::Binding *>(_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<QV8Bindings::Binding *>(_This);
+
+    This->setEnabledFlag(false);
+    This->setDestroyedFlag(true);
+    This->removeFromObject();
+    This->clear();
+    This->clearError();
+    This->parent->release();
 }
 
 QV8Bindings::QV8Bindings(QQmlCompiledData::V8Program *program,
index 7cc1cc9..fc6617b 100644 (file)
@@ -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;