diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-05-03 21:50:18 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-05-04 18:12:50 +0000 |
commit | 4f086e3aacdab13625192b31adefe2d18ced2ae6 (patch) | |
tree | b466c2a4424f698b8b03285761ecedfe4f56be5e /src | |
parent | cff55a7a0da4e84527b6d04218da9b71c84e8f0e (diff) |
Rename ForeachIterator to ForInIterator
As it's being used for for(... in ...) loops. Also add a ES6
compatible iterator interface to it, so that we can unify
the handling of for-in and for-of.
Change-Id: I264f88ed049484945f5ea7e8bdf0227187456ba2
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/jsapi/qjsvalueiterator.cpp | 10 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 6 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine_p.h | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4objectiterator.cpp | 26 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4objectiterator_p.h | 19 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 6 |
6 files changed, 52 insertions, 19 deletions
diff --git a/src/qml/jsapi/qjsvalueiterator.cpp b/src/qml/jsapi/qjsvalueiterator.cpp index ce472ce7e5..222f63ed4a 100644 --- a/src/qml/jsapi/qjsvalueiterator.cpp +++ b/src/qml/jsapi/qjsvalueiterator.cpp @@ -57,7 +57,7 @@ QJSValueIteratorPrivate::QJSValueIteratorPrivate(const QJSValue &v) QV4::Scope scope(e); QV4::ScopedObject o(scope, QJSValuePrivate::getValue(&v)); - iterator.set(e, e->newForEachIteratorObject(o)); + iterator.set(e, e->newForInIteratorObject(o)); } @@ -102,7 +102,7 @@ QJSValueIterator::QJSValueIterator(const QJSValue& object) if (!v4) return; QV4::Scope scope(v4); - QV4::Scoped<QV4::ForEachIteratorObject> it(scope, d_ptr->iterator.value()); + QV4::Scoped<QV4::ForInIteratorObject> it(scope, d_ptr->iterator.value()); it->d()->it().flags = QV4::ObjectIterator::NoFlags; QV4::ScopedString nm(scope); QV4::Property nextProperty; @@ -153,7 +153,7 @@ bool QJSValueIterator::next() if (!v4) return false; QV4::Scope scope(v4); - QV4::Scoped<QV4::ForEachIteratorObject> it(scope, d_ptr->iterator.value()); + QV4::Scoped<QV4::ForInIteratorObject> it(scope, d_ptr->iterator.value()); QV4::ScopedString nm(scope); QV4::Property nextProperty; QV4::PropertyAttributes nextAttributes; @@ -229,8 +229,8 @@ QJSValueIterator& QJSValueIterator::operator=(QJSValue& object) QV4::Scope scope(v4); QV4::ScopedObject o(scope, QJSValuePrivate::getValue(&object)); - d_ptr->iterator.set(v4, v4->newForEachIteratorObject(o)); - QV4::Scoped<QV4::ForEachIteratorObject> it(scope, d_ptr->iterator.value()); + d_ptr->iterator.set(v4, v4->newForInIteratorObject(o)); + QV4::Scoped<QV4::ForInIteratorObject> it(scope, d_ptr->iterator.value()); it->d()->it().flags = QV4::ObjectIterator::NoFlags; QV4::ScopedString nm(scope); QV4::Property nextProperty; diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index f6478b6865..e326edd1a6 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -415,6 +415,7 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine) jsObjects[TypeError_Ctor] = memoryManager->allocate<TypeErrorCtor>(global); jsObjects[URIError_Ctor] = memoryManager->allocate<URIErrorCtor>(global); jsObjects[IteratorProto] = memoryManager->allocate<IteratorPrototype>(); + jsObjects[ForInIteratorProto] = memoryManager->allocObject<ForInIteratorPrototype>(newInternalClass(ForInIteratorPrototype::staticVTable(), iteratorPrototype())); jsObjects[ArrayIteratorProto] = memoryManager->allocObject<ArrayIteratorPrototype>(newInternalClass(ArrayIteratorPrototype::staticVTable(), iteratorPrototype())); jsObjects[StringIteratorProto] = memoryManager->allocObject<StringIteratorPrototype>(newInternalClass(StringIteratorPrototype::staticVTable(), iteratorPrototype())); @@ -438,6 +439,7 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine) static_cast<URIErrorPrototype *>(uRIErrorPrototype())->init(this, uRIErrorCtor()); static_cast<IteratorPrototype *>(iteratorPrototype())->init(this); + static_cast<ForInIteratorPrototype *>(forInIteratorPrototype())->init(this); static_cast<ArrayIteratorPrototype *>(arrayIteratorPrototype())->init(this); static_cast<StringIteratorPrototype *>(stringIteratorPrototype())->init(this); @@ -790,10 +792,10 @@ Heap::Object *ExecutionEngine::newVariantObject(const QVariant &v) return memoryManager->allocate<VariantObject>(v); } -Heap::Object *ExecutionEngine::newForEachIteratorObject(Object *o) +Heap::Object *ExecutionEngine::newForInIteratorObject(Object *o) { Scope scope(this); - ScopedObject obj(scope, memoryManager->allocate<ForEachIteratorObject>(o)); + ScopedObject obj(scope, memoryManager->allocate<ForInIteratorObject>(o)); return obj->d(); } diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index 64bbd1163f..e1b1ba38ca 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -190,6 +190,7 @@ public: ValueTypeProto, SignalHandlerProto, IteratorProto, + ForInIteratorProto, ArrayIteratorProto, StringIteratorProto, @@ -274,6 +275,7 @@ public: Object *valueTypeWrapperPrototype() const { return reinterpret_cast<Object *>(jsObjects + ValueTypeProto); } Object *signalHandlerPrototype() const { return reinterpret_cast<Object *>(jsObjects + SignalHandlerProto); } Object *iteratorPrototype() const { return reinterpret_cast<Object *>(jsObjects + IteratorProto); } + Object *forInIteratorPrototype() const { return reinterpret_cast<Object *>(jsObjects + ForInIteratorProto); } Object *arrayIteratorPrototype() const { return reinterpret_cast<Object *>(jsObjects + ArrayIteratorProto); } Object *stringIteratorPrototype() const { return reinterpret_cast<Object *>(jsObjects + StringIteratorProto); } @@ -489,7 +491,7 @@ public: Heap::Object *newVariantObject(const QVariant &v); - Heap::Object *newForEachIteratorObject(Object *o); + Heap::Object *newForInIteratorObject(Object *o); Heap::Object *newArrayIteratorObject(Object *o); Heap::QmlContext *qmlContext() const; diff --git a/src/qml/jsruntime/qv4objectiterator.cpp b/src/qml/jsruntime/qv4objectiterator.cpp index 7bf7e1aa04..1290a2c1b2 100644 --- a/src/qml/jsruntime/qv4objectiterator.cpp +++ b/src/qml/jsruntime/qv4objectiterator.cpp @@ -42,9 +42,29 @@ #include "qv4identifier_p.h" #include "qv4argumentsobject_p.h" #include "qv4string_p.h" +#include "qv4iterator_p.h" using namespace QV4; +void ForInIteratorPrototype::init(ExecutionEngine *) +{ + defineDefaultProperty(QStringLiteral("next"), method_next, 0); +} + +ReturnedValue ForInIteratorPrototype::method_next(const FunctionObject *b, const Value *thisObject, const Value *, int) +{ + const ForInIteratorObject *forIn = thisObject->as<ForInIteratorObject>(); + Q_ASSERT(forIn); + Scope scope(b->engine()); + ScopedValue n(scope, forIn->nextPropertyName()); + bool done = false; + if (n->asReturnedValue() == Encode::null()) { + done = true; + n = Primitive::undefinedValue(); + } + return IteratorPrototype::createIterResultObject(scope.engine, n, done); +} + void ObjectIterator::init(const Object *o) { object->setM(o ? o->m() : nullptr); @@ -175,11 +195,11 @@ ReturnedValue ObjectIterator::nextPropertyNameAsString() } -DEFINE_OBJECT_VTABLE(ForEachIteratorObject); +DEFINE_OBJECT_VTABLE(ForInIteratorObject); -void Heap::ForEachIteratorObject::markObjects(Heap::Base *that, MarkStack *markStack) +void Heap::ForInIteratorObject::markObjects(Heap::Base *that, MarkStack *markStack) { - ForEachIteratorObject *o = static_cast<ForEachIteratorObject *>(that); + ForInIteratorObject *o = static_cast<ForInIteratorObject *>(that); o->workArea[0].mark(markStack); o->workArea[1].mark(markStack); Object::markObjects(that, markStack); diff --git a/src/qml/jsruntime/qv4objectiterator_p.h b/src/qml/jsruntime/qv4objectiterator_p.h index 744d16301a..2b2410bf1f 100644 --- a/src/qml/jsruntime/qv4objectiterator_p.h +++ b/src/qml/jsruntime/qv4objectiterator_p.h @@ -111,7 +111,7 @@ private: }; namespace Heap { -struct ForEachIteratorObject : Object { +struct ForInIteratorObject : Object { void init(QV4::Object *o); ObjectIterator &it() { return *reinterpret_cast<ObjectIterator*>(&itData); } Value workArea[2]; @@ -123,15 +123,24 @@ private: } -struct ForEachIteratorObject: Object { - V4_OBJECT2(ForEachIteratorObject, Object) +struct ForInIteratorPrototype : Object +{ + V4_PROTOTYPE(iteratorPrototype) + void init(ExecutionEngine *engine); + + static ReturnedValue method_next(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc); +}; + +struct ForInIteratorObject: Object { + V4_OBJECT2(ForInIteratorObject, Object) Q_MANAGED_TYPE(ForeachIteratorObject) + V4_PROTOTYPE(forInIteratorPrototype) - ReturnedValue nextPropertyName() { return d()->it().nextPropertyNameAsString(); } + ReturnedValue nextPropertyName() const { return d()->it().nextPropertyNameAsString(); } }; inline -void Heap::ForEachIteratorObject::init(QV4::Object *o) +void Heap::ForInIteratorObject::init(QV4::Object *o) { Object::init(); it() = ObjectIterator(internalClass->engine, workArea, workArea + 1, o, diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index 3ddd543b40..1c1c3c3802 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -701,15 +701,15 @@ ReturnedValue Runtime::method_foreachIterator(ExecutionEngine *engine, const Val ScopedObject o(scope, (Object *)nullptr); if (!in.isNullOrUndefined()) o = in.toObject(engine); - return engine->newForEachIteratorObject(o)->asReturnedValue(); + return engine->newForInIteratorObject(o)->asReturnedValue(); } ReturnedValue Runtime::method_foreachNextPropertyName(const Value &foreach_iterator) { Q_ASSERT(foreach_iterator.isObject()); - ForEachIteratorObject *it = static_cast<ForEachIteratorObject *>(foreach_iterator.objectValue()); - Q_ASSERT(it->as<ForEachIteratorObject>()); + ForInIteratorObject *it = static_cast<ForInIteratorObject *>(foreach_iterator.objectValue()); + Q_ASSERT(it->as<ForInIteratorObject>()); return it->nextPropertyName(); } |