aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-05-03 21:50:18 +0200
committerLars Knoll <lars.knoll@qt.io>2018-05-04 18:12:50 +0000
commit4f086e3aacdab13625192b31adefe2d18ced2ae6 (patch)
treeb466c2a4424f698b8b03285761ecedfe4f56be5e /src/qml
parentcff55a7a0da4e84527b6d04218da9b71c84e8f0e (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/qml')
-rw-r--r--src/qml/jsapi/qjsvalueiterator.cpp10
-rw-r--r--src/qml/jsruntime/qv4engine.cpp6
-rw-r--r--src/qml/jsruntime/qv4engine_p.h4
-rw-r--r--src/qml/jsruntime/qv4objectiterator.cpp26
-rw-r--r--src/qml/jsruntime/qv4objectiterator_p.h19
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp6
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();
}