diff options
Diffstat (limited to 'src/qml/jsruntime')
-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 |
5 files changed, 47 insertions, 14 deletions
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(); } |