Remove Property * return value from ObjectIterator
authorLars Knoll <lars.knoll@digia.com>
Wed, 8 Jan 2014 12:08:41 +0000 (13:08 +0100)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Mon, 20 Jan 2014 20:13:48 +0000 (21:13 +0100)
The added side effect is that the QJSValueIterator is now
somewhat faster.

Change-Id: I01ba9f2a72a34224f5691130df69a91ab75b72e6
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
src/qml/jsapi/qjsvalueiterator.cpp
src/qml/jsapi/qjsvalueiterator_p.h
src/qml/jsruntime/qv4objectiterator.cpp
src/qml/jsruntime/qv4objectiterator_p.h
src/qml/jsruntime/qv4objectproto.cpp

index ed011ef..e3358b2 100644 (file)
@@ -109,7 +109,7 @@ QJSValueIterator::QJSValueIterator(const QJSValue& object)
     QV4::Scope scope(v4);
     QV4::Scoped<QV4::ForEachIteratorObject> it(scope, d_ptr->iterator.value());
     it->it.flags =  QV4::ObjectIterator::NoFlags;
-    it->it.next(d_ptr->nextName, &d_ptr->nextIndex, &d_ptr->nextAttributes);
+    it->it.next(d_ptr->nextName, &d_ptr->nextIndex, &d_ptr->nextProperty, &d_ptr->nextAttributes);
 }
 
 /*!
@@ -150,6 +150,7 @@ bool QJSValueIterator::next()
         return false;
     d_ptr->currentName = d_ptr->nextName;
     d_ptr->currentIndex = d_ptr->nextIndex;
+    d_ptr->currentProperty = d_ptr->nextProperty;
     d_ptr->currentAttributes = d_ptr->nextAttributes;
 
     QV4::ExecutionEngine *v4 = d_ptr->iterator.engine();
@@ -157,7 +158,7 @@ bool QJSValueIterator::next()
         return false;
     QV4::Scope scope(v4);
     QV4::Scoped<QV4::ForEachIteratorObject> it(scope, d_ptr->iterator.value());
-    it->it.next(d_ptr->nextName, &d_ptr->nextIndex, &d_ptr->nextAttributes);
+    it->it.next(d_ptr->nextName, &d_ptr->nextIndex, &d_ptr->nextProperty, &d_ptr->nextAttributes);
     return !!d_ptr->nextName || d_ptr->nextIndex != UINT_MAX;
 }
 
@@ -187,27 +188,19 @@ QString QJSValueIterator::name() const
 */
 QJSValue QJSValueIterator::value() const
 {
-    if (!QJSValuePrivate::get(d_ptr->value)->value.isObject())
-        return QJSValue();
-
     QV4::ExecutionEngine *engine = d_ptr->iterator.engine();
     if (!engine)
         return QJSValue();
-
     QV4::Scope scope(engine);
-    QV4::Scoped<QV4::ForEachIteratorObject> it(scope, d_ptr->iterator.value());
-    QV4::ScopedObject o(scope, it->it.object);
+    QV4::ScopedObject obj(scope, QJSValuePrivate::get(d_ptr->value)->value);
+    if (!obj)
+        return QJSValue();
 
     QV4::ExecutionContext *ctx = engine->currentContext();
-    QV4::ScopedValue v(scope);
-    if (!!d_ptr->currentName) {
-        QV4::ScopedString n(scope, d_ptr->currentName);
-        v = o->get(n);
-    } else if (d_ptr->currentIndex != UINT_MAX) {
-        v = o->getIndexed(d_ptr->currentIndex);
-    } else {
+    if (!d_ptr->currentName && d_ptr->currentIndex == UINT_MAX)
         return QJSValue();
-    }
+
+    QV4::ScopedValue v(scope, obj->getValue(obj, &d_ptr->currentProperty, d_ptr->currentAttributes));
     if (scope.hasException()) {
         ctx->catchException();
         return QJSValue();
@@ -240,7 +233,7 @@ QJSValueIterator& QJSValueIterator::operator=(QJSValue& object)
     d_ptr->iterator = v4->newForEachIteratorObject(v4->currentContext(), o)->asReturnedValue();
     QV4::Scoped<QV4::ForEachIteratorObject> it(scope, d_ptr->iterator.value());
     it->it.flags =  QV4::ObjectIterator::NoFlags;
-    it->it.next(d_ptr->nextName, &d_ptr->nextIndex, &d_ptr->nextAttributes);
+    it->it.next(d_ptr->nextName, &d_ptr->nextIndex, &d_ptr->nextProperty, &d_ptr->nextAttributes);
     return *this;
 }
 
index b7a9b4a..80d1885 100644 (file)
@@ -56,9 +56,11 @@ public:
 
     QJSValue value;
     QV4::PersistentValue iterator;
+    QV4::Property currentProperty;
     QV4::PropertyAttributes currentAttributes;
     QV4::SafeString currentName;
     uint currentIndex;
+    QV4::Property nextProperty;
     QV4::PropertyAttributes nextAttributes;
     QV4::SafeString nextName;
     uint nextIndex;
index f7a5cd7..64ab671 100644 (file)
@@ -82,12 +82,15 @@ ObjectIterator::ObjectIterator(Scope &scope, const ObjectRef o, uint flags)
     }
 }
 
-Property *ObjectIterator::next(StringRef name, uint *index, PropertyAttributes *attrs)
+void ObjectIterator::next(StringRef name, uint *index, Property *pd, PropertyAttributes *attrs)
 {
     name = (String *)0;
     *index = UINT_MAX;
-    if (!object)
-        return 0;
+
+    if (!object) {
+        *attrs = PropertyAttributes();
+        return;
+    }
 
     Property *p = 0;
     while (1) {
@@ -107,7 +110,8 @@ Property *ObjectIterator::next(StringRef name, uint *index, PropertyAttributes *
                 if (pp != p)
                     continue;
             }
-            return p;
+            *pd = *p;
+            return;
         }
 
         if (flags & WithProtoChain)
@@ -118,7 +122,7 @@ Property *ObjectIterator::next(StringRef name, uint *index, PropertyAttributes *
         arrayIndex = 0;
         memberIndex = 0;
     }
-    return 0;
+    *attrs = PropertyAttributes();
 }
 
 ReturnedValue ObjectIterator::nextPropertyName(ValueRef value)
@@ -127,14 +131,15 @@ ReturnedValue ObjectIterator::nextPropertyName(ValueRef value)
         return Encode::null();
 
     PropertyAttributes attrs;
+    Property p;
     uint index;
     Scope scope(object->engine());
     ScopedString name(scope);
-    Property *p = next(name, &index, &attrs);
-    if (!p)
+    next(name, &index, &p, &attrs);
+    if (attrs.isEmpty())
         return Encode::null();
 
-    value = object->getValue(p, attrs);
+    value = object->getValue(&p, attrs);
 
     if (!!name)
         return name->asReturnedValue();
@@ -148,14 +153,15 @@ ReturnedValue ObjectIterator::nextPropertyNameAsString(ValueRef value)
         return Encode::null();
 
     PropertyAttributes attrs;
+    Property p;
     uint index;
     Scope scope(object->engine());
     ScopedString name(scope);
-    Property *p = next(name, &index, &attrs);
-    if (!p)
+    next(name, &index, &p, &attrs);
+    if (attrs.isEmpty())
         return Encode::null();
 
-    value = object->getValue(p, attrs);
+    value = object->getValue(&p, attrs);
 
     if (!!name)
         return name->asReturnedValue();
@@ -169,11 +175,12 @@ ReturnedValue ObjectIterator::nextPropertyNameAsString()
         return Encode::null();
 
     PropertyAttributes attrs;
+    Property p;
     uint index;
     Scope scope(object->engine());
     ScopedString name(scope);
-    Property *p = next(name, &index, &attrs);
-    if (!p)
+    next(name, &index, &p, &attrs);
+    if (attrs.isEmpty())
         return Encode::null();
 
     if (!!name)
index 33228ce..142895a 100644 (file)
@@ -78,7 +78,7 @@ struct Q_QML_EXPORT ObjectIterator
 
     ObjectIterator(SafeObject *scratch1, SafeObject *scratch2, const ObjectRef o, uint flags);
     ObjectIterator(Scope &scope, const ObjectRef o, uint flags);
-    Property *next(StringRef name, uint *index, PropertyAttributes *attributes = 0);
+    void next(StringRef name, uint *index, Property *pd, PropertyAttributes *attributes = 0);
     ReturnedValue nextPropertyName(ValueRef value);
     ReturnedValue nextPropertyNameAsString(ValueRef value);
     ReturnedValue nextPropertyNameAsString();
index 9474442..806da83 100644 (file)
@@ -239,12 +239,13 @@ ReturnedValue ObjectPrototype::method_defineProperties(CallContext *ctx)
     while (1) {
         uint index;
         PropertyAttributes attrs;
-        Property *pd = it.next(name, &index, &attrs);
-        if (!pd)
+        Property pd;
+        it.next(name, &index, &pd, &attrs);
+        if (attrs.isEmpty())
             break;
         Property n;
         PropertyAttributes nattrs;
-        val = o->getValue(pd, attrs);
+        val = o->getValue(&pd, attrs);
         toPropertyDescriptor(ctx, val, &n, &nattrs);
         if (scope.engine->hasException)
             return Encode::undefined();