Fix the way we set the property name during iteration
authorLars Knoll <lars.knoll@digia.com>
Fri, 28 Nov 2014 12:25:56 +0000 (13:25 +0100)
committerSimon Hausmann <simon.hausmann@digia.com>
Sat, 20 Dec 2014 06:39:24 +0000 (07:39 +0100)
This was broken due to the new inheritance scheme for Managed

Change-Id: Ia9df50e7e655c3a812a01a2c78945e648aa444dc
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
15 files changed:
src/qml/jsapi/qjsvalueiterator.cpp
src/qml/jsruntime/qv4managed_p.h
src/qml/jsruntime/qv4object.cpp
src/qml/jsruntime/qv4object_p.h
src/qml/jsruntime/qv4objectiterator.cpp
src/qml/jsruntime/qv4objectiterator_p.h
src/qml/jsruntime/qv4objectproto.cpp
src/qml/jsruntime/qv4qobjectwrapper.cpp
src/qml/jsruntime/qv4qobjectwrapper_p.h
src/qml/jsruntime/qv4scopedvalue_p.h
src/qml/jsruntime/qv4sequenceobject.cpp
src/qml/jsruntime/qv4stringobject.cpp
src/qml/jsruntime/qv4stringobject_p.h
src/qml/qml/qqmllistwrapper.cpp
src/qml/qml/qqmllistwrapper_p.h

index 7eb1de4..eed8cf5 100644 (file)
@@ -102,8 +102,8 @@ QJSValueIterator::QJSValueIterator(const QJSValue& object)
     QV4::Scope scope(v4);
     QV4::Scoped<QV4::ForEachIteratorObject> it(scope, d_ptr->iterator.value());
     it->d()->it.flags =  QV4::ObjectIterator::NoFlags;
-    QV4::String *nm = 0;
-    it->d()->it.next(nm, &d_ptr->nextIndex, &d_ptr->nextProperty, &d_ptr->nextAttributes);
+    QV4::ScopedString nm(scope);
+    it->d()->it.next(nm.getRef(), &d_ptr->nextIndex, &d_ptr->nextProperty, &d_ptr->nextAttributes);
     d_ptr->nextName = nm;
 }
 
@@ -150,8 +150,8 @@ bool QJSValueIterator::next()
         return false;
     QV4::Scope scope(v4);
     QV4::Scoped<QV4::ForEachIteratorObject> it(scope, d_ptr->iterator.value());
-    QV4::String *nm = 0;
-    it->d()->it.next(nm, &d_ptr->nextIndex, &d_ptr->nextProperty, &d_ptr->nextAttributes);
+    QV4::ScopedString nm(scope);
+    it->d()->it.next(nm.getRef(), &d_ptr->nextIndex, &d_ptr->nextProperty, &d_ptr->nextAttributes);
     d_ptr->nextName = nm;
     return !!d_ptr->currentName || d_ptr->currentIndex != UINT_MAX;
 }
@@ -226,8 +226,8 @@ QJSValueIterator& QJSValueIterator::operator=(QJSValue& object)
     d_ptr->iterator = v4->newForEachIteratorObject(o)->asReturnedValue();
     QV4::Scoped<QV4::ForEachIteratorObject> it(scope, d_ptr->iterator.value());
     it->d()->it.flags =  QV4::ObjectIterator::NoFlags;
-    QV4::String *nm = 0;
-    it->d()->it.next(nm, &d_ptr->nextIndex, &d_ptr->nextProperty, &d_ptr->nextAttributes);
+    QV4::ScopedString nm(scope);
+    it->d()->it.next(nm.getRef(), &d_ptr->nextIndex, &d_ptr->nextProperty, &d_ptr->nextAttributes);
     d_ptr->nextName = nm;
     return *this;
 }
index e474a43..3b155a6 100644 (file)
@@ -138,7 +138,7 @@ struct ObjectVTable
     ReturnedValue (*getLookup)(Managed *m, Lookup *l);
     void (*setLookup)(Managed *m, Lookup *l, const ValueRef v);
     uint (*getLength)(const Managed *m);
-    void (*advanceIterator)(Managed *m, ObjectIterator *it, String *&name, uint *index, Property *p, PropertyAttributes *attributes);
+    void (*advanceIterator)(Managed *m, ObjectIterator *it, Heap::String **name, uint *index, Property *p, PropertyAttributes *attributes);
 };
 
 #define DEFINE_MANAGED_VTABLE_INT(classname, parentVTable) \
index 25ea9e1..0e3ea50 100644 (file)
@@ -516,10 +516,10 @@ void Object::setLookup(Managed *m, Lookup *l, const ValueRef value)
     l->setter = Lookup::setterGeneric;
 }
 
-void Object::advanceIterator(Managed *m, ObjectIterator *it, String *&name, uint *index, Property *pd, PropertyAttributes *attrs)
+void Object::advanceIterator(Managed *m, ObjectIterator *it, Heap::String **name, uint *index, Property *pd, PropertyAttributes *attrs)
 {
     Object *o = static_cast<Object *>(m);
-    name = (String *)0;
+    *name = 0;
     *index = UINT_MAX;
 
     if (o->arrayData()) {
@@ -574,8 +574,7 @@ void Object::advanceIterator(Managed *m, ObjectIterator *it, String *&name, uint
         PropertyAttributes a = o->internalClass()->propertyData[it->memberIndex];
         ++it->memberIndex;
         if (!(it->flags & ObjectIterator::EnumerableOnly) || a.isEnumerable()) {
-            // #### GC
-            name = reinterpret_cast<QV4::String*>(m->engine()->newString(n->string));
+            *name = m->engine()->newString(n->string);
             *attrs = a;
             pd->copy(*p, a);
             return;
index ade5383..d9c56b2 100644 (file)
@@ -230,7 +230,7 @@ public:
     { return vtable()->getLookup(this, l); }
     void setLookup(Lookup *l, const ValueRef v)
     { vtable()->setLookup(this, l, v); }
-    void advanceIterator(ObjectIterator *it, String *&name, uint *index, Property *p, PropertyAttributes *attributes)
+    void advanceIterator(ObjectIterator *it, Heap::String **name, uint *index, Property *p, PropertyAttributes *attributes)
     { vtable()->advanceIterator(this, it, name, index, p, attributes); }
     uint getLength() const { return vtable()->getLength(this); }
 
@@ -252,7 +252,7 @@ protected:
     static bool deleteIndexedProperty(Managed *m, uint index);
     static ReturnedValue getLookup(Managed *m, Lookup *l);
     static void setLookup(Managed *m, Lookup *l, const ValueRef v);
-    static void advanceIterator(Managed *m, ObjectIterator *it, String *&name, uint *index, Property *p, PropertyAttributes *attributes);
+    static void advanceIterator(Managed *m, ObjectIterator *it, Heap::String **name, uint *index, Property *p, PropertyAttributes *attributes);
     static uint getLength(const Managed *m);
 
 private:
index 338f756..80b73e5 100644 (file)
@@ -78,9 +78,9 @@ void ObjectIterator::init(Object *o)
     }
 }
 
-void ObjectIterator::next(String *&name, uint *index, Property *pd, PropertyAttributes *attrs)
+void ObjectIterator::next(Heap::String **name, uint *index, Property *pd, PropertyAttributes *attrs)
 {
-    name = (String *)0;
+    *name = 0;
     *index = UINT_MAX;
 
     if (!object->asObject()) {
@@ -89,6 +89,7 @@ void ObjectIterator::next(String *&name, uint *index, Property *pd, PropertyAttr
     }
     Scope scope(engine);
     ScopedObject o(scope);
+    ScopedString n(scope);
 
     while (1) {
         if (!current->asObject())
@@ -101,9 +102,10 @@ void ObjectIterator::next(String *&name, uint *index, Property *pd, PropertyAttr
             // check the property is not already defined earlier in the proto chain
             if (current->asObject() != object->asObject()) {
                 o = object->asObject();
+                n = *name;
                 bool shadowed = false;
                 while (o != current->asObject()) {
-                    if ((!!name && o->hasOwnProperty(name)) ||
+                    if ((!!n && o->hasOwnProperty(n)) ||
                         (*index != UINT_MAX && o->hasOwnProperty(*index))) {
                         shadowed = true;
                         break;
@@ -137,9 +139,7 @@ ReturnedValue ObjectIterator::nextPropertyName(ValueRef value)
     uint index;
     Scope scope(object->engine());
     ScopedString name(scope);
-    String *n;
-    next(n, &index, &p, &attrs);
-    name = n;
+    next(name.getRef(), &index, &p, &attrs);
     if (attrs.isEmpty())
         return Encode::null();
 
@@ -161,9 +161,7 @@ ReturnedValue ObjectIterator::nextPropertyNameAsString(ValueRef value)
     uint index;
     Scope scope(object->engine());
     ScopedString name(scope);
-    String *n;
-    next(n, &index, &p, &attrs);
-    name = n;
+    next(name.getRef(), &index, &p, &attrs);
     if (attrs.isEmpty())
         return Encode::null();
 
@@ -185,9 +183,7 @@ ReturnedValue ObjectIterator::nextPropertyNameAsString()
     uint index;
     Scope scope(object->engine());
     ScopedString name(scope);
-    String *n;
-    next(n, &index, &p, &attrs);
-    name = n;
+    next(name.getRef(), &index, &p, &attrs);
     if (attrs.isEmpty())
         return Encode::null();
 
index 7710543..f1f70d0 100644 (file)
@@ -59,7 +59,7 @@ struct Q_QML_EXPORT ObjectIterator
     ObjectIterator(ExecutionEngine *e, Value *scratch1, Value *scratch2, Object *o, uint flags);
     ObjectIterator(Scope &scope, Object *o, uint flags);
     void init(Object *o);
-    void next(String *&name, uint *index, Property *pd, PropertyAttributes *attributes = 0);
+    void next(Heap::String **name, uint *index, Property *pd, PropertyAttributes *attributes = 0);
     ReturnedValue nextPropertyName(ValueRef value);
     ReturnedValue nextPropertyNameAsString(ValueRef value);
     ReturnedValue nextPropertyNameAsString();
index 1ebc9ef..7595411 100644 (file)
@@ -215,9 +215,7 @@ ReturnedValue ObjectPrototype::method_defineProperties(CallContext *ctx)
         uint index;
         PropertyAttributes attrs;
         Property pd;
-        String *nm;
-        it.next(nm, &index, &pd, &attrs);
-        name = nm;
+        it.next(name.getRef(), &index, &pd, &attrs);
         if (attrs.isEmpty())
             break;
         Property n;
index 2e8eec1..720d651 100644 (file)
@@ -720,14 +720,14 @@ PropertyAttributes QObjectWrapper::query(const Managed *m, String *name)
         return QV4::Object::query(m, name);
 }
 
-void QObjectWrapper::advanceIterator(Managed *m, ObjectIterator *it, String *&name, uint *index, Property *p, PropertyAttributes *attributes)
+void QObjectWrapper::advanceIterator(Managed *m, ObjectIterator *it, Heap::String **name, uint *index, Property *p, PropertyAttributes *attributes)
 {
     // Used to block access to QObject::destroyed() and QObject::deleteLater() from QML
     static const int destroyedIdx1 = QObject::staticMetaObject.indexOfSignal("destroyed(QObject*)");
     static const int destroyedIdx2 = QObject::staticMetaObject.indexOfSignal("destroyed()");
     static const int deleteLaterIdx = QObject::staticMetaObject.indexOfSlot("deleteLater()");
 
-    name = (String *)0;
+    *name = (Heap::String *)0;
     *index = UINT_MAX;
 
     QObjectWrapper *that = static_cast<QObjectWrapper*>(m);
@@ -741,10 +741,10 @@ void QObjectWrapper::advanceIterator(Managed *m, ObjectIterator *it, String *&na
             // #### GC
             Scope scope(that->engine());
             ScopedString propName(scope, that->engine()->newString(QString::fromUtf8(mo->property(it->arrayIndex).name())));
-            name = propName.getPointer();
+            *name = propName->d();
             ++it->arrayIndex;
             *attributes = QV4::Attr_Data;
-            p->value = that->get(name);
+            p->value = that->get(propName);
             return;
         }
         const int methodCount = mo->methodCount();
@@ -757,9 +757,9 @@ void QObjectWrapper::advanceIterator(Managed *m, ObjectIterator *it, String *&na
             // #### GC
             Scope scope(that->engine());
             ScopedString methodName(scope, that->engine()->newString(QString::fromUtf8(method.name())));
-            name = methodName.getPointer();
+            *name = methodName->d();
             *attributes = QV4::Attr_Data;
-            p->value = that->get(name);
+            p->value = that->get(methodName);
             return;
         }
     }
index 7f271a8..5796241 100644 (file)
@@ -125,7 +125,7 @@ private:
     static ReturnedValue get(Managed *m, String *name, bool *hasProperty);
     static void put(Managed *m, String *name, const ValueRef value);
     static PropertyAttributes query(const Managed *, String *name);
-    static void advanceIterator(Managed *m, ObjectIterator *it, String *&name, uint *index, Property *p, PropertyAttributes *attributes);
+    static void advanceIterator(Managed *m, ObjectIterator *it, Heap::String **name, uint *index, Property *p, PropertyAttributes *attributes);
     static void markObjects(Heap::Base *that, QV4::ExecutionEngine *e);
     static void destroy(Heap::Base *that);
 
index 9a76ffc..1337da7 100644 (file)
@@ -215,6 +215,10 @@ struct Scoped
     Scoped(const Scope &scope)
     {
         ptr = scope.engine->jsStackTop++;
+        ptr->m = 0;
+#if QT_POINTER_SIZE == 4
+        ptr->tag = QV4::Value::Managed_Type;
+#endif
 #ifndef QT_NO_DEBUG
         ++scope.size;
 #endif
@@ -358,6 +362,9 @@ struct Scoped
     T *getPointer() {
         return static_cast<T *>(ptr->managed());
     }
+    typename T::Data **getRef() {
+        return reinterpret_cast<typename T::Data **>(&ptr->m);
+    }
 
     ReturnedValue asReturnedValue() const {
 #if QT_POINTER_SIZE == 8
index 5e45f65..3c8b835 100644 (file)
@@ -272,9 +272,9 @@ public:
         return (signedIdx < d()->container.count()) ? QV4::Attr_Data : QV4::Attr_Invalid;
     }
 
-    void containerAdvanceIterator(ObjectIterator *it, String *&name, uint *index, Property *p, PropertyAttributes *attrs)
+    void containerAdvanceIterator(ObjectIterator *it, Heap::String **name, uint *index, Property *p, PropertyAttributes *attrs)
     {
-        name = (String *)0;
+        *name = (Heap::String *)0;
         *index = UINT_MAX;
 
         if (d()->isReference) {
@@ -492,7 +492,7 @@ public:
     { return static_cast<QQmlSequence<Container> *>(that)->containerDeleteIndexedProperty(index); }
     static bool isEqualTo(Managed *that, Managed *other)
     { return static_cast<QQmlSequence<Container> *>(that)->containerIsEqualTo(other); }
-    static void advanceIterator(Managed *that, ObjectIterator *it, String *&name, uint *index, Property *p, PropertyAttributes *attrs)
+    static void advanceIterator(Managed *that, ObjectIterator *it, Heap::String **name, uint *index, Property *p, PropertyAttributes *attrs)
     { return static_cast<QQmlSequence<Container> *>(that)->containerAdvanceIterator(it, name, index, p, attrs); }
 
 };
index dec361a..e148782 100644 (file)
@@ -122,9 +122,9 @@ bool StringObject::deleteIndexedProperty(Managed *m, uint index)
     return true;
 }
 
-void StringObject::advanceIterator(Managed *m, ObjectIterator *it, String *&name, uint *index, Property *p, PropertyAttributes *attrs)
+void StringObject::advanceIterator(Managed *m, ObjectIterator *it, Heap::String **name, uint *index, Property *p, PropertyAttributes *attrs)
 {
-    name = (String *)0;
+    *name = (Heap::String *)0;
     StringObject *s = static_cast<StringObject *>(m);
     uint slen = s->d()->value.stringValue()->toQString().length();
     if (it->arrayIndex <= slen) {
index ba441c9..a5851cb 100644 (file)
@@ -70,7 +70,7 @@ struct StringObject: Object {
     static bool deleteIndexedProperty(Managed *m, uint index);
 
 protected:
-    static void advanceIterator(Managed *m, ObjectIterator *it, String *&name, uint *index, Property *p, PropertyAttributes *attrs);
+    static void advanceIterator(Managed *m, ObjectIterator *it, Heap::String **name, uint *index, Property *p, PropertyAttributes *attrs);
     static void markObjects(Heap::Base *that, ExecutionEngine *e);
 };
 
index 6cef1d4..d27ed95 100644 (file)
@@ -143,9 +143,9 @@ void QmlListWrapper::put(Managed *m, String *name, const ValueRef value)
     Q_UNUSED(value);
 }
 
-void QmlListWrapper::advanceIterator(Managed *m, ObjectIterator *it, String *&name, uint *index, Property *p, PropertyAttributes *attrs)
+void QmlListWrapper::advanceIterator(Managed *m, ObjectIterator *it, Heap::String **name, uint *index, Property *p, PropertyAttributes *attrs)
 {
-    name = (String *)0;
+    *name = (Heap::String *)0;
     *index = UINT_MAX;
     Q_ASSERT(m->as<QmlListWrapper>());
     QmlListWrapper *w = static_cast<QmlListWrapper *>(m);
index 65d7154..1345365 100644 (file)
@@ -85,7 +85,7 @@ struct Q_QML_EXPORT QmlListWrapper : Object
     static ReturnedValue get(Managed *m, String *name, bool *hasProperty);
     static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
     static void put(Managed *m, String *name, const ValueRef value);
-    static void advanceIterator(Managed *m, ObjectIterator *it, String *&name, uint *index, Property *p, PropertyAttributes *attributes);
+    static void advanceIterator(Managed *m, ObjectIterator *it, Heap::String **name, uint *index, Property *p, PropertyAttributes *attributes);
 };
 
 }