1// Copyright (C) 2018 Crimson AS <info@crimson.no>
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <private/qv4iterator_p.h>
5#include <private/qv4estable_p.h>
6#include <private/qv4setiterator_p.h>
7#include <private/qv4setobject_p.h>
8#include <private/qv4symbol_p.h>
9
10using namespace QV4;
11
12DEFINE_OBJECT_VTABLE(SetIteratorObject);
13
14void SetIteratorPrototype::init(ExecutionEngine *e)
15{
16 defineDefaultProperty(QStringLiteral("next"), code: method_next, argumentCount: 0);
17
18 Scope scope(e);
19 ScopedString val(scope, e->newString(s: QLatin1String("Set Iterator")));
20 defineReadonlyConfigurableProperty(name: e->symbol_toStringTag(), value: val);
21}
22
23ReturnedValue SetIteratorPrototype::method_next(const FunctionObject *b, const Value *that, const Value *, int)
24{
25 Scope scope(b);
26 const SetIteratorObject *thisObject = that->as<SetIteratorObject>();
27 if (!thisObject)
28 return scope.engine->throwTypeError(message: QLatin1String("Not a Set Iterator instance"));
29
30 Scoped<SetObject> s(scope, thisObject->d()->iteratedSet);
31 uint index = thisObject->d()->setNextIndex;
32 IteratorKind itemKind = thisObject->d()->iterationKind;
33
34 if (!s) {
35 QV4::Value undefined = Value::undefinedValue();
36 return IteratorPrototype::createIterResultObject(engine: scope.engine, value: undefined, done: true);
37 }
38
39 Value *arguments = scope.alloc(nValues: 2);
40
41 while (index < s->d()->esTable->size()) {
42 s->d()->esTable->iterate(idx: index, k: &arguments[0], v: &arguments[1]);
43 thisObject->d()->setNextIndex = index + 1;
44
45 if (itemKind == KeyValueIteratorKind) {
46 ScopedArrayObject resultArray(scope, scope.engine->newArrayObject());
47 resultArray->arrayReserve(n: 2);
48 resultArray->arrayPut(index: 0, value: arguments[0]);
49 resultArray->arrayPut(index: 1, value: arguments[0]); // yes, the key is repeated.
50 resultArray->setArrayLengthUnchecked(2);
51
52 return IteratorPrototype::createIterResultObject(engine: scope.engine, value: resultArray, done: false);
53 }
54
55 return IteratorPrototype::createIterResultObject(engine: scope.engine, value: arguments[0], done: false);
56 }
57
58 thisObject->d()->iteratedSet.set(e: scope.engine, newVal: nullptr);
59 QV4::Value undefined = Value::undefinedValue();
60 return IteratorPrototype::createIterResultObject(engine: scope.engine, value: undefined, done: true);
61}
62
63

source code of qtdeclarative/src/qml/jsruntime/qv4setiterator.cpp