1 | // Copyright (C) 2016 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | #ifndef QV4OBJECTITERATOR_H |
4 | #define QV4OBJECTITERATOR_H |
5 | |
6 | // |
7 | // W A R N I N G |
8 | // ------------- |
9 | // |
10 | // This file is not part of the Qt API. It exists purely as an |
11 | // implementation detail. This header file may change from version to |
12 | // version without notice, or even be removed. |
13 | // |
14 | // We mean it. |
15 | // |
16 | |
17 | #include "qv4global_p.h" |
18 | #include "qv4object_p.h" |
19 | |
20 | QT_BEGIN_NAMESPACE |
21 | |
22 | namespace QV4 { |
23 | |
24 | struct Q_QML_EXPORT ObjectIterator |
25 | { |
26 | enum Flags { |
27 | NoFlags = 0, |
28 | EnumerableOnly = 0x1, |
29 | WithSymbols = 0x2 |
30 | }; |
31 | |
32 | ExecutionEngine *engine; |
33 | Object *object; |
34 | OwnPropertyKeyIterator *iterator = nullptr; |
35 | uint flags; |
36 | |
37 | ObjectIterator(Scope &scope, const Object *o, uint flags) |
38 | { |
39 | engine = scope.engine; |
40 | object = static_cast<Object *>(scope.alloc()); |
41 | this->flags = flags; |
42 | object->setM(o ? o->m() : nullptr); |
43 | if (o) |
44 | iterator = object->ownPropertyKeys(target: object); |
45 | } |
46 | ~ObjectIterator() |
47 | { |
48 | delete iterator; |
49 | } |
50 | |
51 | PropertyKey next(Property *pd = nullptr, PropertyAttributes *attributes = nullptr); |
52 | ReturnedValue nextPropertyName(Value *value); |
53 | ReturnedValue nextPropertyNameAsString(Value *value); |
54 | ReturnedValue nextPropertyNameAsString(); |
55 | }; |
56 | |
57 | namespace Heap { |
58 | |
59 | #define ForInIteratorObjectMembers(class, Member) \ |
60 | Member(class, Pointer, Object *, object) \ |
61 | Member(class, Pointer, Object *, current) \ |
62 | Member(class, Pointer, Object *, target) \ |
63 | Member(class, NoMark, OwnPropertyKeyIterator *, iterator) |
64 | |
65 | DECLARE_HEAP_OBJECT(ForInIteratorObject, Object) { |
66 | void init(QV4::Object *o); |
67 | Value workArea[2]; |
68 | |
69 | static void markObjects(Heap::Base *that, MarkStack *markStack); |
70 | void destroy(); |
71 | }; |
72 | |
73 | } |
74 | |
75 | struct ForInIteratorPrototype : Object |
76 | { |
77 | V4_PROTOTYPE(iteratorPrototype) |
78 | void init(ExecutionEngine *engine); |
79 | |
80 | static ReturnedValue method_next(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc); |
81 | }; |
82 | |
83 | struct ForInIteratorObject: Object { |
84 | V4_OBJECT2(ForInIteratorObject, Object) |
85 | Q_MANAGED_TYPE(ForInIterator) |
86 | V4_PROTOTYPE(forInIteratorPrototype) |
87 | V4_NEEDS_DESTROY |
88 | |
89 | PropertyKey nextProperty() const; |
90 | }; |
91 | |
92 | inline |
93 | void Heap::ForInIteratorObject::init(QV4::Object *o) |
94 | { |
95 | Object::init(); |
96 | if (!o) |
97 | return; |
98 | object.set(e: o->engine(), newVal: o->d()); |
99 | current.set(e: o->engine(), newVal: o->d()); |
100 | Scope scope(o); |
101 | ScopedObject obj(scope); |
102 | iterator = o->ownPropertyKeys(target: obj.getRef()); |
103 | target.set(e: o->engine(), newVal: obj->d()); |
104 | } |
105 | |
106 | |
107 | } |
108 | |
109 | QT_END_NAMESPACE |
110 | |
111 | #endif |
112 | |