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/qv4mapiterator_p.h>
7#include <private/qv4mapobject_p.h>
8#include <private/qv4symbol_p.h>
9
10using namespace QV4;
11
12DEFINE_OBJECT_VTABLE(MapIteratorObject);
13
14void MapIteratorPrototype::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("Map Iterator")));
20 defineReadonlyConfigurableProperty(name: e->symbol_toStringTag(), value: val);
21}
22
23ReturnedValue MapIteratorPrototype::method_next(const FunctionObject *b, const Value *that, const Value *, int)
24{
25 Scope scope(b);
26 const MapIteratorObject *thisObject = that->as<MapIteratorObject>();
27 if (!thisObject)
28 return scope.engine->throwTypeError(message: QLatin1String("Not a Map Iterator instance"));
29
30 Scoped<MapObject> s(scope, thisObject->d()->iteratedMap);
31 uint index = thisObject->d()->mapNextIndex;
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()->mapNextIndex = index + 1;
44
45 ScopedValue result(scope);
46
47 if (itemKind == KeyIteratorKind) {
48 result = arguments[0];
49 } else if (itemKind == ValueIteratorKind) {
50 result = arguments[1];
51 } else {
52 Q_ASSERT(itemKind == KeyValueIteratorKind);
53
54 result = scope.engine->newArrayObject();
55
56 Scoped<ArrayObject> resultArray(scope, result);
57 resultArray->arrayReserve(n: 2);
58 resultArray->arrayPut(index: 0, value: arguments[0]);
59 resultArray->arrayPut(index: 1, value: arguments[1]);
60 resultArray->setArrayLengthUnchecked(2);
61 }
62
63 return IteratorPrototype::createIterResultObject(engine: scope.engine, value: result, done: false);
64 }
65
66 thisObject->d()->iteratedMap.set(e: scope.engine, newVal: nullptr);
67 QV4::Value undefined = Value::undefinedValue();
68 return IteratorPrototype::createIterResultObject(engine: scope.engine, value: undefined, done: true);
69}
70
71
72

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