1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
11 * JavaScript iterators.
14 #include "mozilla/MemoryReporting.h"
18 #include "gc/Barrier.h"
22 * For cacheable native iterators, whether the iterator is currently active.
23 * Not serialized by XDR.
25 #define JSITER_ACTIVE 0x1000
26 #define JSITER_UNREUSABLE 0x2000
32 HeapPtrObject obj
; // Object being iterated.
33 JSObject
* iterObj_
; // Internal iterator object.
34 HeapPtrFlatString
* props_array
;
35 HeapPtrFlatString
* props_cursor
;
36 HeapPtrFlatString
* props_end
;
38 uint32_t shapes_length
;
43 /* While in compartment->enumerators, these form a doubly linked list. */
44 NativeIterator
* next_
;
45 NativeIterator
* prev_
;
48 bool isKeyIter() const {
49 return (flags
& JSITER_FOREACH
) == 0;
52 inline HeapPtrFlatString
* begin() const {
56 inline HeapPtrFlatString
* end() const {
60 size_t numKeys() const {
61 return end() - begin();
64 JSObject
* iterObj() const {
67 HeapPtrFlatString
* current() const {
68 MOZ_ASSERT(props_cursor
< props_end
);
72 NativeIterator
* next() {
76 static inline size_t offsetOfNext() {
77 return offsetof(NativeIterator
, next_
);
79 static inline size_t offsetOfPrev() {
80 return offsetof(NativeIterator
, prev_
);
84 props_cursor
= props_cursor
+ 1;
86 void link(NativeIterator
* other
) {
87 /* A NativeIterator cannot appear in the enumerator list twice. */
88 MOZ_ASSERT(!next_
&& !prev_
);
89 MOZ_ASSERT(flags
& JSITER_ENUMERATE
);
92 this->prev_
= other
->prev_
;
93 other
->prev_
->next_
= this;
97 MOZ_ASSERT(flags
& JSITER_ENUMERATE
);
100 prev_
->next_
= next_
;
105 static NativeIterator
* allocateSentinel(JSContext
* cx
);
106 static NativeIterator
* allocateIterator(JSContext
* cx
, uint32_t slength
,
107 const js::AutoIdVector
& props
);
108 void init(JSObject
* obj
, JSObject
* iterObj
, unsigned flags
, uint32_t slength
, uint32_t key
);
110 void mark(JSTracer
* trc
);
112 static void destroy(NativeIterator
* iter
) {
117 class PropertyIteratorObject
: public NativeObject
120 static const Class class_
;
122 NativeIterator
* getNativeIterator() const {
123 return static_cast<js::NativeIterator
*>(getPrivate());
125 void setNativeIterator(js::NativeIterator
* ni
) {
129 size_t sizeOfMisc(mozilla::MallocSizeOf mallocSizeOf
) const;
132 static void trace(JSTracer
* trc
, JSObject
* obj
);
133 static void finalize(FreeOp
* fop
, JSObject
* obj
);
136 class ArrayIteratorObject
: public JSObject
139 static const Class class_
;
142 class StringIteratorObject
: public JSObject
145 static const Class class_
;
149 VectorToIdArray(JSContext
* cx
, AutoIdVector
& props
, JSIdArray
** idap
);
152 GetIterator(JSContext
* cx
, HandleObject obj
, unsigned flags
, MutableHandleObject objp
);
155 GetIteratorObject(JSContext
* cx
, HandleObject obj
, unsigned flags
);
158 * Creates either a key or value iterator, depending on flags. For a value
159 * iterator, performs value-lookup to convert the given list of jsids.
162 EnumeratedIdVectorToIterator(JSContext
* cx
, HandleObject obj
, unsigned flags
, AutoIdVector
& props
,
163 MutableHandleObject objp
);
166 NewEmptyPropertyIterator(JSContext
* cx
, unsigned flags
, MutableHandleObject objp
);
169 * Convert the value stored in *vp to its iteration object. The flags should
170 * contain JSITER_ENUMERATE if js::ValueToIterator is called when enumerating
171 * for-in semantics are required, and when the caller can guarantee that the
172 * iterator will never be exposed to scripts.
175 ValueToIterator(JSContext
* cx
, unsigned flags
, MutableHandleValue vp
);
178 CloseIterator(JSContext
* cx
, HandleObject iterObj
);
181 UnwindIteratorForException(JSContext
* cx
, HandleObject obj
);
184 UnwindIteratorForUncatchableException(JSContext
* cx
, JSObject
* obj
);
187 IteratorConstructor(JSContext
* cx
, unsigned argc
, Value
* vp
);
190 SuppressDeletedProperty(JSContext
* cx
, HandleObject obj
, jsid id
);
193 SuppressDeletedElement(JSContext
* cx
, HandleObject obj
, uint32_t index
);
196 SuppressDeletedElements(JSContext
* cx
, HandleObject obj
, uint32_t begin
, uint32_t end
);
199 * IteratorMore() returns the next iteration value. If no value is available,
200 * MagicValue(JS_NO_ITER_VALUE) is returned.
203 IteratorMore(JSContext
* cx
, HandleObject iterobj
, MutableHandleValue rval
);
206 ThrowStopIteration(JSContext
* cx
);
209 * Create an object of the form { value: VALUE, done: DONE }.
210 * ES6 draft from 2013-09-05, section 25.4.3.4.
213 CreateItrResultObject(JSContext
* cx
, HandleValue value
, bool done
);
218 js_InitIteratorClasses(JSContext
* cx
, js::HandleObject obj
);
220 #endif /* jsiter_h */