From 4866005aacda3bba754cfcc97eae9ca5d0f3e15c Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 18 Apr 2013 15:33:37 +0200 Subject: [PATCH] Implement QJSValueIterator Change-Id: I1aa5b3de0b68555359baf575c68424e1c16257a0 Reviewed-by: Simon Hausmann --- src/qml/qml/v4vm/qv4jsonobject.cpp | 2 +- src/qml/qml/v4vm/qv4object_p.h | 2 +- src/qml/qml/v4vm/qv4objectiterator.cpp | 7 +++-- src/qml/qml/v4vm/qv4objectiterator_p.h | 12 +++++---- src/qml/qml/v4vm/qv4objectproto.cpp | 6 ++--- src/qml/qml/v4vm/qv4v8.cpp | 4 +-- src/qml/qml/v8/qjsvalueiterator.cpp | 49 ++++++++++++++++++++++++++++------ src/qml/qml/v8/qjsvalueiterator_p.h | 13 +++++++++ 8 files changed, 71 insertions(+), 24 deletions(-) diff --git a/src/qml/qml/v4vm/qv4jsonobject.cpp b/src/qml/qml/v4vm/qv4jsonobject.cpp index 1c9b65c..1874edd 100644 --- a/src/qml/qml/v4vm/qv4jsonobject.cpp +++ b/src/qml/qml/v4vm/qv4jsonobject.cpp @@ -776,7 +776,7 @@ QString Stringify::JO(Object *o) QStringList partial; if (propertyList.isEmpty()) { - ObjectIterator it(ctx, o, ObjectIterator::EnumberableOnly); + ObjectIterator it(o, ObjectIterator::EnumberableOnly); while (1) { String *name; diff --git a/src/qml/qml/v4vm/qv4object_p.h b/src/qml/qml/v4vm/qv4object_p.h index 5bae2e6..c69733f 100644 --- a/src/qml/qml/v4vm/qv4object_p.h +++ b/src/qml/qml/v4vm/qv4object_p.h @@ -356,7 +356,7 @@ private: struct ForEachIteratorObject: Object { ObjectIterator it; ForEachIteratorObject(ExecutionContext *ctx, Object *o) - : Object(ctx->engine), it(ctx, o, ObjectIterator::EnumberableOnly|ObjectIterator::WithProtoChain) { + : Object(ctx->engine), it(o, ObjectIterator::EnumberableOnly|ObjectIterator::WithProtoChain) { vtbl = &static_vtbl; type = Type_ForeachIteratorObject; } diff --git a/src/qml/qml/v4vm/qv4objectiterator.cpp b/src/qml/qml/v4vm/qv4objectiterator.cpp index 5c1dd62..185b1e4 100644 --- a/src/qml/qml/v4vm/qv4objectiterator.cpp +++ b/src/qml/qml/v4vm/qv4objectiterator.cpp @@ -46,9 +46,8 @@ namespace QQmlJS { namespace VM { -ObjectIterator::ObjectIterator(ExecutionContext *context, Object *o, uint flags) - : context(context) - , object(o) +ObjectIterator::ObjectIterator(Object *o, uint flags) + : object(o) , current(o) , arrayNode(0) , arrayIndex(0) @@ -176,7 +175,7 @@ Value ObjectIterator::nextPropertyNameAsString() if (name) return Value::fromString(name); if (index < UINT_MAX) - return __qmljs_to_string(Value::fromDouble(index), context); + return __qmljs_to_string(Value::fromDouble(index), object->internalClass->engine->current); return Value::nullValue(); } diff --git a/src/qml/qml/v4vm/qv4objectiterator_p.h b/src/qml/qml/v4vm/qv4objectiterator_p.h index 8df6825..caa63db 100644 --- a/src/qml/qml/v4vm/qv4objectiterator_p.h +++ b/src/qml/qml/v4vm/qv4objectiterator_p.h @@ -41,9 +41,7 @@ #ifndef QV4OBJECTITERATOR_H #define QV4OBJECTITERATOR_H -#include "qv4value_p.h" -#include "qv4internalclass_p.h" -#include "qv4property_p.h" +#include "qv4global_p.h" QT_BEGIN_NAMESPACE @@ -52,6 +50,11 @@ namespace VM { struct SparseArrayNode; struct Object; +struct PropertyAttributes; +struct ExecutionContext; +struct Property; +struct Value; +struct String; struct ObjectIterator { @@ -62,7 +65,6 @@ struct ObjectIterator CurrentIsString = 0x4 }; - ExecutionContext *context; Object *object; Object *current; SparseArrayNode *arrayNode; @@ -70,7 +72,7 @@ struct ObjectIterator uint memberIndex; uint flags; - ObjectIterator(ExecutionContext *context, Object *o, uint flags); + ObjectIterator(Object *o, uint flags); Property *next(String **name, uint *index, PropertyAttributes *attributes = 0); Value nextPropertyName(); Value nextPropertyNameAsString(); diff --git a/src/qml/qml/v4vm/qv4objectproto.cpp b/src/qml/qml/v4vm/qv4objectproto.cpp index 19baa71..bc564a4 100644 --- a/src/qml/qml/v4vm/qv4objectproto.cpp +++ b/src/qml/qml/v4vm/qv4objectproto.cpp @@ -157,7 +157,7 @@ Value ObjectPrototype::method_getOwnPropertyNames(SimpleCallContext *context) context->throwTypeError(); ArrayObject *array = context->engine->newArrayObject(context)->asArrayObject(); - ObjectIterator it(context, O, ObjectIterator::NoFlags); + ObjectIterator it(O, ObjectIterator::NoFlags); while (1) { Value v = it.nextPropertyNameAsString(); if (v.isNull()) @@ -212,7 +212,7 @@ Value ObjectPrototype::method_defineProperties(SimpleCallContext *ctx) Object *o = ctx->argument(1).toObject(ctx); - ObjectIterator it(ctx, o, ObjectIterator::EnumberableOnly); + ObjectIterator it(o, ObjectIterator::EnumberableOnly); while (1) { uint index; String *name; @@ -356,7 +356,7 @@ Value ObjectPrototype::method_keys(SimpleCallContext *ctx) ArrayObject *a = ctx->engine->newArrayObject(ctx); - ObjectIterator it(ctx, o, ObjectIterator::EnumberableOnly); + ObjectIterator it(o, ObjectIterator::EnumberableOnly); while (1) { uint index; String *name; diff --git a/src/qml/qml/v4vm/qv4v8.cpp b/src/qml/qml/v4vm/qv4v8.cpp index b1a680e..2b63458 100644 --- a/src/qml/qml/v4vm/qv4v8.cpp +++ b/src/qml/qml/v4vm/qv4v8.cpp @@ -939,7 +939,7 @@ Local Object::GetPropertyNames() assert(o); VM::ArrayObject *array = currentEngine()->newArrayObject(currentEngine()->current)->asArrayObject(); - ObjectIterator it(currentEngine()->current, o, ObjectIterator::WithProtoChain|ObjectIterator::EnumberableOnly); + ObjectIterator it(o, ObjectIterator::WithProtoChain|ObjectIterator::EnumberableOnly); while (1) { VM::Value v = it.nextPropertyNameAsString(); if (v.isNull()) @@ -955,7 +955,7 @@ Local Object::GetOwnPropertyNames() assert(o); VM::Value arg = VM::Value::fromObject(o); ArrayObject *array = currentEngine()->newArrayObject(currentEngine()->current)->asArrayObject(); - ObjectIterator it(currentEngine()->current, o, ObjectIterator::EnumberableOnly); + ObjectIterator it(o, ObjectIterator::EnumberableOnly); while (1) { VM::Value v = it.nextPropertyNameAsString(); if (v.isNull()) diff --git a/src/qml/qml/v8/qjsvalueiterator.cpp b/src/qml/qml/v8/qjsvalueiterator.cpp index b349457..78f1256 100644 --- a/src/qml/qml/v8/qjsvalueiterator.cpp +++ b/src/qml/qml/v8/qjsvalueiterator.cpp @@ -41,9 +41,24 @@ #include "qjsvalueiterator.h" #include "qjsvalueiterator_p.h" +#include "qjsvalue_p.h" +#include "private/qv4string_p.h" QT_BEGIN_NAMESPACE +QJSValueIteratorPrivate::QJSValueIteratorPrivate(const QJSValue &v) + : value(v) + , iterator(QJSValuePrivate::get(v)->value.asObject(), QQmlJS::VM::ObjectIterator::EnumberableOnly) + , currentValue(0) + , currentName(0) + , currentIndex(UINT_MAX) + , nextValue(0) + , nextName(0) + , nextIndex(UINT_MAX) +{ +} + + /*! \class QJSValueIterator @@ -79,9 +94,9 @@ QT_BEGIN_NAMESPACE first property). */ QJSValueIterator::QJSValueIterator(const QJSValue& object) - : d_ptr(0) + : d_ptr(new QJSValueIteratorPrivate(object)) { - // ### + d_ptr->nextValue = d_ptr->iterator.next(&d_ptr->nextName, &d_ptr->nextIndex, &d_ptr->nextAttributes); } /*! @@ -89,7 +104,6 @@ QJSValueIterator::QJSValueIterator(const QJSValue& object) */ QJSValueIterator::~QJSValueIterator() { - // ### } /*! @@ -101,7 +115,7 @@ QJSValueIterator::~QJSValueIterator() */ bool QJSValueIterator::hasNext() const { - // ### + return d_ptr->nextValue != 0; } /*! @@ -117,7 +131,12 @@ bool QJSValueIterator::hasNext() const */ bool QJSValueIterator::next() { - // ### + d_ptr->currentValue = d_ptr->nextValue; + d_ptr->currentName = d_ptr->nextName; + d_ptr->currentIndex = d_ptr->nextIndex; + d_ptr->currentAttributes = d_ptr->nextAttributes; + + d_ptr->nextValue = d_ptr->iterator.next(&d_ptr->nextName, &d_ptr->nextIndex, &d_ptr->nextAttributes); } /*! @@ -128,7 +147,11 @@ bool QJSValueIterator::next() */ QString QJSValueIterator::name() const { - // ### + if (d_ptr->currentName) + return d_ptr->currentName->toQString(); + if (d_ptr->currentIndex < UINT_MAX) + return QString::number(d_ptr->currentIndex); + return QString(); } @@ -140,7 +163,16 @@ QString QJSValueIterator::name() const */ QJSValue QJSValueIterator::value() const { - // ### + if (!d_ptr->currentValue) + return QJSValue(); + + QQmlJS::VM::Object *o = d_ptr->iterator.object; + try { + QQmlJS::VM::Value v = o->getValue(o->internalClass->engine->current, d_ptr->currentValue, d_ptr->currentAttributes); + return new QJSValuePrivate(o->internalClass->engine, v); + } catch (QQmlJS::VM::Exception &e) { + return QJSValue(); + } } @@ -151,7 +183,8 @@ QJSValue QJSValueIterator::value() const */ QJSValueIterator& QJSValueIterator::operator=(QJSValue& object) { - // ### + d_ptr->iterator = QQmlJS::VM::ObjectIterator(QJSValuePrivate::get(object)->value.asObject(), QQmlJS::VM::ObjectIterator::EnumberableOnly); + d_ptr->nextValue = d_ptr->iterator.next(&d_ptr->nextName, &d_ptr->nextIndex, &d_ptr->nextAttributes); } QT_END_NAMESPACE diff --git a/src/qml/qml/v8/qjsvalueiterator_p.h b/src/qml/qml/v8/qjsvalueiterator_p.h index 0ab5acd..2f3b81e 100644 --- a/src/qml/qml/v8/qjsvalueiterator_p.h +++ b/src/qml/qml/v8/qjsvalueiterator_p.h @@ -43,6 +43,7 @@ #define QJSVALUEITERATOR_P_H #include "qjsvalue.h" +#include "private/qv4objectiterator_p.h" QT_BEGIN_NAMESPACE @@ -51,6 +52,18 @@ class QV8Engine; class QJSValueIteratorPrivate { public: + QJSValueIteratorPrivate(const QJSValue &v); + + QJSValue value; + QQmlJS::VM::ObjectIterator iterator; + QQmlJS::VM::Property *currentValue; + QQmlJS::VM::PropertyAttributes currentAttributes; + QQmlJS::VM::String *currentName; + uint currentIndex; + QQmlJS::VM::Property *nextValue; + QQmlJS::VM::PropertyAttributes nextAttributes; + QQmlJS::VM::String *nextName; + uint nextIndex; }; -- 2.7.4