1// Copyright (C) 2017 Crimson AS <info@crimson.no>
2// Copyright (C) 2018 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#include <private/qv4iterator_p.h>
6#include <private/qv4arrayiterator_p.h>
7#include <private/qv4typedarray_p.h>
8#include <private/qv4symbol_p.h>
9
10using namespace QV4;
11
12DEFINE_OBJECT_VTABLE(ArrayIteratorObject);
13
14void ArrayIteratorPrototype::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("Array Iterator")));
20 defineReadonlyConfigurableProperty(name: e->symbol_toStringTag(), value: val);
21}
22
23ReturnedValue ArrayIteratorPrototype::method_next(const FunctionObject *b, const Value *that, const Value *, int)
24{
25 Scope scope(b);
26 const ArrayIteratorObject *thisObject = that->as<ArrayIteratorObject>();
27 if (!thisObject)
28 return scope.engine->throwTypeError(message: QLatin1String("Not an Array Iterator instance"));
29
30 ScopedObject a(scope, thisObject->d()->iteratedObject);
31 if (!a) {
32 QV4::Value undefined = Value::undefinedValue();
33 return IteratorPrototype::createIterResultObject(engine: scope.engine, value: undefined, done: true);
34 }
35
36 quint32 index = thisObject->d()->nextIndex;
37 IteratorKind itemKind = thisObject->d()->iterationKind;
38
39 quint32 len = a->getLength();
40
41 if (index >= len) {
42 thisObject->d()->iteratedObject.set(e: scope.engine, newVal: nullptr);
43 QV4::Value undefined = Value::undefinedValue();
44 return IteratorPrototype::createIterResultObject(engine: scope.engine, value: undefined, done: true);
45 }
46
47 thisObject->d()->nextIndex = index + 1;
48 if (itemKind == KeyIteratorKind) {
49 return IteratorPrototype::createIterResultObject(engine: scope.engine, value: Value::fromInt32(i: index), done: false);
50 }
51
52 QV4::ScopedValue elementValue(scope, a->get(idx: index));
53 CHECK_EXCEPTION();
54
55 if (itemKind == ValueIteratorKind) {
56 return IteratorPrototype::createIterResultObject(engine: scope.engine, value: elementValue, done: false);
57 } else {
58 Q_ASSERT(itemKind == KeyValueIteratorKind);
59
60 ScopedArrayObject resultArray(scope, scope.engine->newArrayObject());
61 resultArray->arrayReserve(n: 2);
62 resultArray->arrayPut(index: 0, value: Value::fromInt32(i: index));
63 resultArray->arrayPut(index: 1, value: elementValue);
64 resultArray->setArrayLengthUnchecked(2);
65
66 return IteratorPrototype::createIterResultObject(engine: scope.engine, value: resultArray, done: false);
67 }
68}
69
70

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