jseption 0.0.5 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -6
- package/dist/atoms.d.ts +1 -0
- package/dist/atoms.js +2 -1
- package/dist/atoms.js.map +1 -1
- package/dist/builtins/base64.d.ts +14 -0
- package/dist/builtins/base64.js +219 -0
- package/dist/builtins/base64.js.map +1 -0
- package/dist/builtins/bigint.js +3 -3
- package/dist/builtins/bigint.js.map +1 -1
- package/dist/builtins/date.d.ts +1 -0
- package/dist/builtins/date.js +26 -12
- package/dist/builtins/date.js.map +1 -1
- package/dist/builtins/error.js +9 -0
- package/dist/builtins/error.js.map +1 -1
- package/dist/builtins/float16.d.ts +3 -0
- package/dist/builtins/float16.js +69 -0
- package/dist/builtins/float16.js.map +1 -0
- package/dist/builtins/function.js +2 -2
- package/dist/builtins/index.js +9 -6
- package/dist/builtins/index.js.map +1 -1
- package/dist/builtins/iterator.d.ts +2 -0
- package/dist/builtins/iterator.js +624 -0
- package/dist/builtins/iterator.js.map +1 -0
- package/dist/builtins/json.d.ts +13 -1
- package/dist/builtins/json.js +283 -211
- package/dist/builtins/json.js.map +1 -1
- package/dist/builtins/mapset.js +365 -6
- package/dist/builtins/mapset.js.map +1 -1
- package/dist/builtins/math.js +203 -3
- package/dist/builtins/math.js.map +1 -1
- package/dist/builtins/native.js +6 -6
- package/dist/builtins/object.js +9 -2
- package/dist/builtins/object.js.map +1 -1
- package/dist/builtins/promise.js +31 -11
- package/dist/builtins/promise.js.map +1 -1
- package/dist/builtins/proxy.js +2 -2
- package/dist/builtins/reflect.js +6 -2
- package/dist/builtins/reflect.js.map +1 -1
- package/dist/builtins/regexp.js +74 -3
- package/dist/builtins/regexp.js.map +1 -1
- package/dist/builtins/string.js +1 -1
- package/dist/builtins/symbol.js +1 -1
- package/dist/builtins/symbol.js.map +1 -1
- package/dist/builtins/typedarray.d.ts +4 -1
- package/dist/builtins/typedarray.js +325 -37
- package/dist/builtins/typedarray.js.map +1 -1
- package/dist/builtins/weakref.js +7 -7
- package/dist/embed.d.ts +5 -0
- package/dist/embed.js +36 -11
- package/dist/embed.js.map +1 -1
- package/dist/interpreter.js +15 -14
- package/dist/interpreter.js.map +1 -1
- package/dist/jit.d.ts +1 -0
- package/dist/jit.js +51 -13
- package/dist/jit.js.map +1 -1
- package/dist/jit_hook.d.ts +1 -0
- package/dist/jit_hook.js.map +1 -1
- package/dist/jit_runtime.d.ts +1 -1
- package/dist/jit_runtime.js +6 -6
- package/dist/jit_runtime.js.map +1 -1
- package/dist/jit_stack.d.ts +1 -0
- package/dist/jit_stack.js +2 -1
- package/dist/jit_stack.js.map +1 -1
- package/dist/jseption.d.ts +2 -0
- package/dist/jseption.js +1 -0
- package/dist/jseption.js.map +1 -1
- package/dist/membrane.d.ts +6 -0
- package/dist/membrane.js +7 -3
- package/dist/membrane.js.map +1 -1
- package/dist/module.js +5 -3
- package/dist/module.js.map +1 -1
- package/dist/parser.js +26 -9
- package/dist/parser.js.map +1 -1
- package/dist/print.d.ts +12 -0
- package/dist/print.js +494 -0
- package/dist/print.js.map +1 -0
- package/dist/qjs.js +13 -10
- package/dist/qjs.js.map +1 -1
- package/dist/quickjs.d.ts +8 -0
- package/dist/quickjs.js +132 -53
- package/dist/quickjs.js.map +1 -1
- package/dist/std.d.ts +4 -2
- package/dist/std.js +42 -8
- package/dist/std.js.map +1 -1
- package/dist/values.d.ts +31 -27
- package/dist/values.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,624 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The Iterator global, %IteratorPrototype% helpers (map, filter, take, drop,
|
|
3
|
+
* flatMap, reduce, toArray, forEach, some, every, find), Iterator.from with
|
|
4
|
+
* %WrapForValidIteratorPrototype%, %IteratorHelperPrototype% and
|
|
5
|
+
* Iterator.concat. Port of the "Iterator" section of quickjs.c 2026-06-04
|
|
6
|
+
* (js_iterator_*, js_create_iterator_helper, js_iterator_helper_next).
|
|
7
|
+
*
|
|
8
|
+
* The guest's %IteratorPrototype% is ctx.iterator_proto (builtins/index.ts):
|
|
9
|
+
* every guest iterator prototype (array, map, set, string, regexp string,
|
|
10
|
+
* generator) already inherits from it, so the helpers apply to all of them.
|
|
11
|
+
*
|
|
12
|
+
* Deviations from the C, where the C does not follow the specification
|
|
13
|
+
* (each one checked against the host engine, which implements these
|
|
14
|
+
* natively, by tests/iterator.test.ts):
|
|
15
|
+
* - %IteratorHelperPrototype%.return closes the underlying iterator with
|
|
16
|
+
* IteratorClose (a missing `return` method is not an error) and returns
|
|
17
|
+
* {value: undefined, done: true}; the C calls the underlying `return` as
|
|
18
|
+
* if it were `next`, throws when it is missing and passes its result on.
|
|
19
|
+
* - a helper whose step throws is finished, as a generator is; in the C a
|
|
20
|
+
* later next() goes on with the underlying iterator.
|
|
21
|
+
* - drop() reads only `done` of the results it skips (IteratorStep).
|
|
22
|
+
* - flatMap() reads the inner iterator's `next` once.
|
|
23
|
+
* - reduce() on an empty iterator with no initial value throws without
|
|
24
|
+
* closing the (exhausted) iterator, and a failed `next` lookup is not
|
|
25
|
+
* followed by IteratorClose.
|
|
26
|
+
* - %WrapForValidIteratorPrototype%.next and .return return the result of
|
|
27
|
+
* the underlying call as it is, instead of a new result object.
|
|
28
|
+
* - Iterator.concat returns an Iterator Helper (%IteratorHelperPrototype%,
|
|
29
|
+
* tag "Iterator Helper") as the specification says, not an object of its
|
|
30
|
+
* own class; a step that throws finishes it.
|
|
31
|
+
* - the Iterator.prototype.constructor setter follows
|
|
32
|
+
* SetterThatIgnoresPrototypeProperties like the Symbol.toStringTag one.
|
|
33
|
+
*/
|
|
34
|
+
import { JS_EXCEPTION, JS_IsException, JS_IsUndefined, JS_IsObject, JS_IsFunction, JS_IsNull, JS_NewObjectProto, JS_NewObjectClass, JS_NewArray, JS_NewCFunction2, JS_NewCFunctionData, JS_SetOpaque, JS_GetOpaque2, JS_GetProperty, JS_SetProperty, JS_Call, JS_GetIterator2, JS_IteratorNext, JS_IteratorNext2, JS_IteratorClose, JS_OrdinaryIsInstanceOf, JS_ThrowTypeError, JS_ThrowRangeError, JS_ThrowTypeErrorNotAnObject, JS_ToNumber, JS_ToFloat64, JS_ToBoolFree, JS_DefineProperty, JS_DefinePropertyValue, JS_DefinePropertyValueInt64, JS_DefinePropertyValueStr, JS_GetOwnProperty, JS_SetPropertyFunctionList, JS_SetConstructor, js_create_from_ctor, js_meta, hooks, JS_NewClass1, JS_IsRegisteredClass, JS_CFUNC_DEF, JS_CFUNC_MAGIC_DEF, JS_CGETSET_DEF, JS_ITERATOR_NEXT_DEF, JS_PROP_STRING_DEF, JS_PROP_WRITABLE, JS_PROP_CONFIGURABLE, JS_PROP_C_W_E, JS_PROP_THROW, JS_PROP_HAS_GET, JS_PROP_HAS_SET, JS_PROP_HAS_CONFIGURABLE, JS_PROP_HAS_ENUMERABLE, JS_ATOM_next, JS_ATOM_return, JS_ATOM_length, JS_ATOM_constructor, JS_ATOM_Symbol_iterator, JS_ATOM_Symbol_toStringTag, } from "../quickjs.js";
|
|
35
|
+
import { GEN_MAGIC_NEXT, GEN_MAGIC_RETURN } from "../interpreter.js";
|
|
36
|
+
const MAX_SAFE_INTEGER = 9007199254740991;
|
|
37
|
+
/* pdone.done for an iterator_next function: return the value as it is,
|
|
38
|
+
without wrapping it in a new result object (js_call_c_function) */
|
|
39
|
+
const RAW_RESULT = 2;
|
|
40
|
+
function check_function(ctx, obj) {
|
|
41
|
+
if (JS_IsFunction(ctx, obj))
|
|
42
|
+
return 0;
|
|
43
|
+
JS_ThrowTypeError(ctx, 'not a function');
|
|
44
|
+
return -1;
|
|
45
|
+
}
|
|
46
|
+
/* the Iterator constructor of each context (ctx->iterator_ctor) */
|
|
47
|
+
const iterator_ctors = new WeakMap();
|
|
48
|
+
/* ------------------------------------------------------------------ */
|
|
49
|
+
/* Iterator Wrap (%WrapForValidIteratorPrototype%) */
|
|
50
|
+
class JSIteratorWrapData {
|
|
51
|
+
wrapped_iter;
|
|
52
|
+
wrapped_next;
|
|
53
|
+
constructor(wrapped_iter, wrapped_next) {
|
|
54
|
+
this.wrapped_iter = wrapped_iter;
|
|
55
|
+
this.wrapped_next = wrapped_next;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function js_iterator_wrap_next(ctx, this_val, argv, pdone, magic) {
|
|
59
|
+
const it = JS_GetOpaque2(ctx, this_val, 59 /* JSClassID.ITERATOR_WRAP */);
|
|
60
|
+
if (!it)
|
|
61
|
+
return JS_EXCEPTION;
|
|
62
|
+
if (magic === GEN_MAGIC_NEXT) {
|
|
63
|
+
/* Return ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]]) */
|
|
64
|
+
pdone.done = RAW_RESULT;
|
|
65
|
+
return JS_Call(ctx, it.wrapped_next, it.wrapped_iter, []);
|
|
66
|
+
}
|
|
67
|
+
const method = JS_GetProperty(ctx, it.wrapped_iter, JS_ATOM_return);
|
|
68
|
+
if (JS_IsException(method))
|
|
69
|
+
return JS_EXCEPTION;
|
|
70
|
+
if (JS_IsNull(method) || JS_IsUndefined(method)) {
|
|
71
|
+
pdone.done = 1;
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
pdone.done = RAW_RESULT;
|
|
75
|
+
return JS_Call(ctx, method, it.wrapped_iter, []);
|
|
76
|
+
}
|
|
77
|
+
const js_iterator_wrap_proto_funcs = [
|
|
78
|
+
JS_ITERATOR_NEXT_DEF('next', 0, js_iterator_wrap_next, GEN_MAGIC_NEXT),
|
|
79
|
+
JS_ITERATOR_NEXT_DEF('return', 0, js_iterator_wrap_next, GEN_MAGIC_RETURN),
|
|
80
|
+
];
|
|
81
|
+
/* ------------------------------------------------------------------ */
|
|
82
|
+
/* Iterator */
|
|
83
|
+
/* SetterThatIgnoresPrototypeProperties(this, %Iterator.prototype%, p, v) */
|
|
84
|
+
function js_iterator_proto_setter(ctx, this_val, prop, val) {
|
|
85
|
+
if (!JS_IsObject(this_val))
|
|
86
|
+
return JS_ThrowTypeErrorNotAnObject(ctx);
|
|
87
|
+
if (this_val === ctx.class_proto[57 /* JSClassID.ITERATOR */])
|
|
88
|
+
return JS_ThrowTypeError(ctx, 'Cannot assign to read only property');
|
|
89
|
+
const res = JS_GetOwnProperty(ctx, null, this_val, prop);
|
|
90
|
+
if (res < 0)
|
|
91
|
+
return JS_EXCEPTION;
|
|
92
|
+
if (res) {
|
|
93
|
+
if (JS_SetProperty(ctx, this_val, prop, val) < 0)
|
|
94
|
+
return JS_EXCEPTION;
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
if (JS_DefinePropertyValue(ctx, this_val, prop, val, JS_PROP_C_W_E | JS_PROP_THROW) < 0)
|
|
98
|
+
return JS_EXCEPTION;
|
|
99
|
+
}
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
function js_iterator_constructor_getset(ctx, this_val, argv, magic, func_data) {
|
|
103
|
+
if (argv.length > 0)
|
|
104
|
+
return js_iterator_proto_setter(ctx, this_val, JS_ATOM_constructor, argv[0]); /* setter */
|
|
105
|
+
return func_data[0];
|
|
106
|
+
}
|
|
107
|
+
function js_iterator_constructor(ctx, new_target, argv) {
|
|
108
|
+
if (!JS_IsObject(new_target))
|
|
109
|
+
return JS_ThrowTypeError(ctx, "constructor requires 'new'");
|
|
110
|
+
const cf = js_meta.get(new_target)?.cfunc;
|
|
111
|
+
if (cf !== undefined && cf !== null && cf.func === js_iterator_constructor) {
|
|
112
|
+
return JS_ThrowTypeError(ctx, 'abstract class not constructable');
|
|
113
|
+
}
|
|
114
|
+
return js_create_from_ctor(ctx, new_target, 57 /* JSClassID.ITERATOR */);
|
|
115
|
+
}
|
|
116
|
+
/* ------------------------------------------------------------------ */
|
|
117
|
+
/* Iterator.from */
|
|
118
|
+
function js_iterator_from(ctx, this_val, argv) {
|
|
119
|
+
const obj = argv[0];
|
|
120
|
+
if (!JS_IsObject(obj) && typeof obj !== 'string')
|
|
121
|
+
return JS_ThrowTypeError(ctx, 'Iterator.from called on non-object');
|
|
122
|
+
let method = JS_GetProperty(ctx, obj, JS_ATOM_Symbol_iterator);
|
|
123
|
+
if (JS_IsException(method))
|
|
124
|
+
return JS_EXCEPTION;
|
|
125
|
+
let iter;
|
|
126
|
+
if (JS_IsNull(method) || JS_IsUndefined(method)) {
|
|
127
|
+
iter = obj;
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
iter = JS_GetIterator2(ctx, obj, method);
|
|
131
|
+
if (JS_IsException(iter))
|
|
132
|
+
return JS_EXCEPTION;
|
|
133
|
+
}
|
|
134
|
+
method = JS_GetProperty(ctx, iter, JS_ATOM_next);
|
|
135
|
+
if (JS_IsException(method))
|
|
136
|
+
return JS_EXCEPTION;
|
|
137
|
+
const ret = JS_OrdinaryIsInstanceOf(ctx, iter, iterator_ctors.get(ctx));
|
|
138
|
+
if (ret < 0)
|
|
139
|
+
return JS_EXCEPTION;
|
|
140
|
+
if (ret)
|
|
141
|
+
return iter;
|
|
142
|
+
const wrapper = JS_NewObjectClass(ctx, 59 /* JSClassID.ITERATOR_WRAP */);
|
|
143
|
+
if (JS_IsException(wrapper))
|
|
144
|
+
return JS_EXCEPTION;
|
|
145
|
+
JS_SetOpaque(wrapper, new JSIteratorWrapData(iter, method));
|
|
146
|
+
return wrapper;
|
|
147
|
+
}
|
|
148
|
+
class JSIteratorHelperData {
|
|
149
|
+
kind;
|
|
150
|
+
obj;
|
|
151
|
+
next;
|
|
152
|
+
func;
|
|
153
|
+
count;
|
|
154
|
+
inner = undefined; /* innerValue (flatMap) */
|
|
155
|
+
inner_next = undefined;
|
|
156
|
+
executing = false;
|
|
157
|
+
done = false;
|
|
158
|
+
/* concat: the (iterable, @@iterator method) pairs and the next pair to open */
|
|
159
|
+
values = [];
|
|
160
|
+
index = 0;
|
|
161
|
+
constructor(kind, obj, /* the underlying iterator (concat: the open one, or undefined) */ next, /* its next method */ func, /* predicate (filter) or mapper (flatMap, map) */ count) {
|
|
162
|
+
this.kind = kind;
|
|
163
|
+
this.obj = obj;
|
|
164
|
+
this.next = next;
|
|
165
|
+
this.func = func;
|
|
166
|
+
this.count = count;
|
|
167
|
+
} /* limit (drop, take) or counter (filter, map, flatMap) */
|
|
168
|
+
}
|
|
169
|
+
function js_create_iterator_helper(ctx, this_val, argv, magic) {
|
|
170
|
+
if (!JS_IsObject(this_val))
|
|
171
|
+
return JS_ThrowTypeErrorNotAnObject(ctx);
|
|
172
|
+
let func = undefined;
|
|
173
|
+
let count = 0;
|
|
174
|
+
fail: {
|
|
175
|
+
switch (magic) {
|
|
176
|
+
case 0 /* Kind.DROP */:
|
|
177
|
+
case 8 /* Kind.TAKE */: {
|
|
178
|
+
const v = JS_ToNumber(ctx, argv[0]);
|
|
179
|
+
if (JS_IsException(v))
|
|
180
|
+
break fail;
|
|
181
|
+
const dlimit = JS_ToFloat64(ctx, v);
|
|
182
|
+
if (JS_IsException(dlimit))
|
|
183
|
+
break fail;
|
|
184
|
+
const d = dlimit;
|
|
185
|
+
if (Number.isNaN(d)) {
|
|
186
|
+
JS_ThrowRangeError(ctx, 'must be positive');
|
|
187
|
+
break fail;
|
|
188
|
+
}
|
|
189
|
+
if (!Number.isFinite(d)) {
|
|
190
|
+
if (d < 0) {
|
|
191
|
+
JS_ThrowRangeError(ctx, 'must be positive');
|
|
192
|
+
break fail;
|
|
193
|
+
}
|
|
194
|
+
count = MAX_SAFE_INTEGER;
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
count = Math.trunc(d);
|
|
198
|
+
}
|
|
199
|
+
if (count < 0) {
|
|
200
|
+
JS_ThrowRangeError(ctx, 'must be positive');
|
|
201
|
+
break fail;
|
|
202
|
+
}
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
205
|
+
case 2 /* Kind.FILTER */:
|
|
206
|
+
case 4 /* Kind.FLAT_MAP */:
|
|
207
|
+
case 6 /* Kind.MAP */:
|
|
208
|
+
func = argv[0];
|
|
209
|
+
if (check_function(ctx, func))
|
|
210
|
+
break fail;
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
const method = JS_GetProperty(ctx, this_val, JS_ATOM_next);
|
|
214
|
+
if (JS_IsException(method))
|
|
215
|
+
return JS_EXCEPTION; /* GetIteratorDirect: no IteratorClose */
|
|
216
|
+
const obj = JS_NewObjectClass(ctx, 58 /* JSClassID.ITERATOR_HELPER */);
|
|
217
|
+
if (JS_IsException(obj))
|
|
218
|
+
break fail;
|
|
219
|
+
JS_SetOpaque(obj, new JSIteratorHelperData(magic, this_val, method, func, count));
|
|
220
|
+
return obj;
|
|
221
|
+
}
|
|
222
|
+
JS_IteratorClose(ctx, this_val, true);
|
|
223
|
+
return JS_EXCEPTION;
|
|
224
|
+
}
|
|
225
|
+
/* Iterator.concat(...items) */
|
|
226
|
+
function js_iterator_concat(ctx, this_val, argv) {
|
|
227
|
+
const values = [];
|
|
228
|
+
for (let i = 0; i < argv.length; i++) {
|
|
229
|
+
const obj = argv[i];
|
|
230
|
+
if (!JS_IsObject(obj))
|
|
231
|
+
return JS_ThrowTypeErrorNotAnObject(ctx);
|
|
232
|
+
const method = JS_GetProperty(ctx, obj, JS_ATOM_Symbol_iterator);
|
|
233
|
+
if (JS_IsException(method))
|
|
234
|
+
return JS_EXCEPTION;
|
|
235
|
+
if (!JS_IsFunction(ctx, method))
|
|
236
|
+
return JS_ThrowTypeError(ctx, 'not a function');
|
|
237
|
+
values.push(obj, method);
|
|
238
|
+
}
|
|
239
|
+
const obj = JS_NewObjectClass(ctx, 58 /* JSClassID.ITERATOR_HELPER */);
|
|
240
|
+
if (JS_IsException(obj))
|
|
241
|
+
return JS_EXCEPTION;
|
|
242
|
+
const it = new JSIteratorHelperData(9 /* Kind.CONCAT */, undefined, undefined, undefined, 0);
|
|
243
|
+
it.values = values;
|
|
244
|
+
JS_SetOpaque(obj, it);
|
|
245
|
+
return obj;
|
|
246
|
+
}
|
|
247
|
+
/* every, find, forEach, some */
|
|
248
|
+
function js_iterator_proto_func(ctx, this_val, argv, magic) {
|
|
249
|
+
if (!JS_IsObject(this_val))
|
|
250
|
+
return JS_ThrowTypeErrorNotAnObject(ctx);
|
|
251
|
+
const func = argv[0];
|
|
252
|
+
if (check_function(ctx, func)) {
|
|
253
|
+
JS_IteratorClose(ctx, this_val, true);
|
|
254
|
+
return JS_EXCEPTION;
|
|
255
|
+
}
|
|
256
|
+
const method = JS_GetProperty(ctx, this_val, JS_ATOM_next);
|
|
257
|
+
if (JS_IsException(method))
|
|
258
|
+
return JS_EXCEPTION;
|
|
259
|
+
const pdone = { done: 0 };
|
|
260
|
+
let r = magic === 1 /* Kind.EVERY */ ? true : magic === 7 /* Kind.SOME */ ? false : undefined;
|
|
261
|
+
for (let idx = 0;; idx++) {
|
|
262
|
+
const item = JS_IteratorNext(ctx, this_val, method, [], pdone);
|
|
263
|
+
if (JS_IsException(item))
|
|
264
|
+
return JS_EXCEPTION;
|
|
265
|
+
if (pdone.done)
|
|
266
|
+
break;
|
|
267
|
+
const ret = JS_Call(ctx, func, undefined, [item, idx]);
|
|
268
|
+
if (JS_IsException(ret)) {
|
|
269
|
+
JS_IteratorClose(ctx, this_val, true);
|
|
270
|
+
return JS_EXCEPTION;
|
|
271
|
+
}
|
|
272
|
+
if (magic === 5 /* Kind.FOR_EACH */)
|
|
273
|
+
continue;
|
|
274
|
+
const b = JS_ToBoolFree(ctx, ret);
|
|
275
|
+
let stop, result;
|
|
276
|
+
switch (magic) {
|
|
277
|
+
case 1 /* Kind.EVERY */:
|
|
278
|
+
stop = !b;
|
|
279
|
+
result = false;
|
|
280
|
+
break;
|
|
281
|
+
case 3 /* Kind.FIND */:
|
|
282
|
+
stop = b;
|
|
283
|
+
result = item;
|
|
284
|
+
break;
|
|
285
|
+
default:
|
|
286
|
+
stop = b;
|
|
287
|
+
result = true;
|
|
288
|
+
break; /* SOME */
|
|
289
|
+
}
|
|
290
|
+
if (stop) {
|
|
291
|
+
if (JS_IteratorClose(ctx, this_val, false) < 0)
|
|
292
|
+
return JS_EXCEPTION;
|
|
293
|
+
r = result;
|
|
294
|
+
break;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return r;
|
|
298
|
+
}
|
|
299
|
+
function js_iterator_proto_reduce(ctx, this_val, argv) {
|
|
300
|
+
if (!JS_IsObject(this_val))
|
|
301
|
+
return JS_ThrowTypeErrorNotAnObject(ctx);
|
|
302
|
+
const func = argv[0];
|
|
303
|
+
if (check_function(ctx, func)) {
|
|
304
|
+
JS_IteratorClose(ctx, this_val, true);
|
|
305
|
+
return JS_EXCEPTION;
|
|
306
|
+
}
|
|
307
|
+
const method = JS_GetProperty(ctx, this_val, JS_ATOM_next);
|
|
308
|
+
if (JS_IsException(method))
|
|
309
|
+
return JS_EXCEPTION;
|
|
310
|
+
const pdone = { done: 0 };
|
|
311
|
+
let acc, idx;
|
|
312
|
+
if (argv.length > 1) {
|
|
313
|
+
acc = argv[1];
|
|
314
|
+
idx = 0;
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
acc = JS_IteratorNext(ctx, this_val, method, [], pdone);
|
|
318
|
+
if (JS_IsException(acc))
|
|
319
|
+
return JS_EXCEPTION;
|
|
320
|
+
if (pdone.done)
|
|
321
|
+
return JS_ThrowTypeError(ctx, 'empty iterator');
|
|
322
|
+
idx = 1;
|
|
323
|
+
}
|
|
324
|
+
for (;; idx++) {
|
|
325
|
+
const item = JS_IteratorNext(ctx, this_val, method, [], pdone);
|
|
326
|
+
if (JS_IsException(item))
|
|
327
|
+
return JS_EXCEPTION;
|
|
328
|
+
if (pdone.done)
|
|
329
|
+
break;
|
|
330
|
+
const ret = JS_Call(ctx, func, undefined, [acc, item, idx]);
|
|
331
|
+
if (JS_IsException(ret)) {
|
|
332
|
+
JS_IteratorClose(ctx, this_val, true);
|
|
333
|
+
return JS_EXCEPTION;
|
|
334
|
+
}
|
|
335
|
+
acc = ret;
|
|
336
|
+
}
|
|
337
|
+
return acc;
|
|
338
|
+
}
|
|
339
|
+
function js_iterator_proto_toArray(ctx, this_val, argv) {
|
|
340
|
+
if (!JS_IsObject(this_val))
|
|
341
|
+
return JS_ThrowTypeErrorNotAnObject(ctx);
|
|
342
|
+
const method = JS_GetProperty(ctx, this_val, JS_ATOM_next);
|
|
343
|
+
if (JS_IsException(method))
|
|
344
|
+
return JS_EXCEPTION;
|
|
345
|
+
const result = JS_NewArray(ctx);
|
|
346
|
+
if (JS_IsException(result))
|
|
347
|
+
return JS_EXCEPTION;
|
|
348
|
+
const pdone = { done: 0 };
|
|
349
|
+
let idx = 0;
|
|
350
|
+
for (;; idx++) {
|
|
351
|
+
const item = JS_IteratorNext(ctx, this_val, method, [], pdone);
|
|
352
|
+
if (JS_IsException(item))
|
|
353
|
+
return JS_EXCEPTION;
|
|
354
|
+
if (pdone.done)
|
|
355
|
+
break;
|
|
356
|
+
if (JS_DefinePropertyValueInt64(ctx, result, idx, item, JS_PROP_C_W_E | JS_PROP_THROW) < 0)
|
|
357
|
+
return JS_EXCEPTION;
|
|
358
|
+
}
|
|
359
|
+
if (JS_SetProperty(ctx, result, JS_ATOM_length, idx) < 0)
|
|
360
|
+
return JS_EXCEPTION;
|
|
361
|
+
return result;
|
|
362
|
+
}
|
|
363
|
+
function js_iterator_proto_get_toStringTag(ctx, this_val) {
|
|
364
|
+
return 'Iterator';
|
|
365
|
+
}
|
|
366
|
+
function js_iterator_proto_set_toStringTag(ctx, this_val, val) {
|
|
367
|
+
return js_iterator_proto_setter(ctx, this_val, JS_ATOM_Symbol_toStringTag, val);
|
|
368
|
+
}
|
|
369
|
+
/* one step of Iterator.concat: the next value, or done when every iterable is exhausted */
|
|
370
|
+
function concat_step(ctx, it, pdone) {
|
|
371
|
+
for (;;) {
|
|
372
|
+
if (JS_IsUndefined(it.obj)) {
|
|
373
|
+
if (it.index >= it.values.length) {
|
|
374
|
+
pdone.done = 1;
|
|
375
|
+
return undefined;
|
|
376
|
+
}
|
|
377
|
+
const iter = JS_GetIterator2(ctx, it.values[it.index], it.values[it.index + 1]);
|
|
378
|
+
it.values[it.index] = it.values[it.index + 1] = undefined;
|
|
379
|
+
it.index += 2;
|
|
380
|
+
if (JS_IsException(iter))
|
|
381
|
+
return JS_EXCEPTION;
|
|
382
|
+
const next = JS_GetProperty(ctx, iter, JS_ATOM_next);
|
|
383
|
+
if (JS_IsException(next))
|
|
384
|
+
return JS_EXCEPTION;
|
|
385
|
+
it.obj = iter;
|
|
386
|
+
it.next = next;
|
|
387
|
+
}
|
|
388
|
+
const d = { done: 0 };
|
|
389
|
+
const item = JS_IteratorNext(ctx, it.obj, it.next, [], d);
|
|
390
|
+
if (JS_IsException(item))
|
|
391
|
+
return JS_EXCEPTION;
|
|
392
|
+
if (!d.done)
|
|
393
|
+
return item;
|
|
394
|
+
/* this iterable is exhausted: go on with the next one */
|
|
395
|
+
it.obj = undefined;
|
|
396
|
+
it.next = undefined;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
function js_iterator_helper_next(ctx, this_val, argv, pdone, magic) {
|
|
400
|
+
pdone.done = 0;
|
|
401
|
+
const it = JS_GetOpaque2(ctx, this_val, 58 /* JSClassID.ITERATOR_HELPER */);
|
|
402
|
+
if (!it)
|
|
403
|
+
return JS_EXCEPTION;
|
|
404
|
+
if (it.executing)
|
|
405
|
+
return JS_ThrowTypeError(ctx, 'cannot invoke a running iterator');
|
|
406
|
+
if (it.done) {
|
|
407
|
+
pdone.done = 1;
|
|
408
|
+
return undefined;
|
|
409
|
+
}
|
|
410
|
+
it.executing = true;
|
|
411
|
+
let ret;
|
|
412
|
+
if (magic === GEN_MAGIC_RETURN) {
|
|
413
|
+
/* GeneratorResumeAbrupt with a return completion: close the inner
|
|
414
|
+
(flatMap) and the underlying iterator, then report done */
|
|
415
|
+
ret = undefined;
|
|
416
|
+
pdone.done = 1;
|
|
417
|
+
it.done = true;
|
|
418
|
+
it.values = [];
|
|
419
|
+
if (!JS_IsUndefined(it.inner)) {
|
|
420
|
+
const inner = it.inner;
|
|
421
|
+
it.inner = undefined;
|
|
422
|
+
if (JS_IteratorClose(ctx, inner, false) < 0) {
|
|
423
|
+
if (!JS_IsUndefined(it.obj))
|
|
424
|
+
JS_IteratorClose(ctx, it.obj, true);
|
|
425
|
+
ret = JS_EXCEPTION;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
if (!JS_IsException(ret) && !JS_IsUndefined(it.obj) && JS_IteratorClose(ctx, it.obj, false) < 0)
|
|
429
|
+
ret = JS_EXCEPTION;
|
|
430
|
+
it.executing = false;
|
|
431
|
+
return ret;
|
|
432
|
+
}
|
|
433
|
+
const method = it.next;
|
|
434
|
+
done: {
|
|
435
|
+
fail: {
|
|
436
|
+
switch (it.kind) {
|
|
437
|
+
case 0 /* Kind.DROP */: {
|
|
438
|
+
while (it.count > 0) {
|
|
439
|
+
it.count--;
|
|
440
|
+
/* IteratorStep: only `done` is read */
|
|
441
|
+
const r = JS_IteratorNext2(ctx, it.obj, method, [], pdone);
|
|
442
|
+
if (JS_IsException(r)) {
|
|
443
|
+
ret = JS_EXCEPTION;
|
|
444
|
+
break done;
|
|
445
|
+
}
|
|
446
|
+
if (pdone.done) {
|
|
447
|
+
ret = undefined;
|
|
448
|
+
break done;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
ret = JS_IteratorNext(ctx, it.obj, method, [], pdone);
|
|
452
|
+
break done;
|
|
453
|
+
}
|
|
454
|
+
case 2 /* Kind.FILTER */: {
|
|
455
|
+
for (;;) {
|
|
456
|
+
const item = JS_IteratorNext(ctx, it.obj, method, [], pdone);
|
|
457
|
+
if (JS_IsException(item)) {
|
|
458
|
+
ret = JS_EXCEPTION;
|
|
459
|
+
break done;
|
|
460
|
+
}
|
|
461
|
+
if (pdone.done) {
|
|
462
|
+
ret = item;
|
|
463
|
+
break done;
|
|
464
|
+
}
|
|
465
|
+
const selected = JS_Call(ctx, it.func, undefined, [item, it.count++]);
|
|
466
|
+
if (JS_IsException(selected))
|
|
467
|
+
break fail;
|
|
468
|
+
if (JS_ToBoolFree(ctx, selected)) {
|
|
469
|
+
ret = item;
|
|
470
|
+
break done;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
case 4 /* Kind.FLAT_MAP */: {
|
|
475
|
+
for (;;) {
|
|
476
|
+
if (JS_IsUndefined(it.inner)) {
|
|
477
|
+
const item = JS_IteratorNext(ctx, it.obj, method, [], pdone);
|
|
478
|
+
if (JS_IsException(item)) {
|
|
479
|
+
ret = JS_EXCEPTION;
|
|
480
|
+
break done;
|
|
481
|
+
}
|
|
482
|
+
if (pdone.done) {
|
|
483
|
+
ret = item;
|
|
484
|
+
break done;
|
|
485
|
+
}
|
|
486
|
+
const mapped = JS_Call(ctx, it.func, undefined, [item, it.count++]);
|
|
487
|
+
if (JS_IsException(mapped))
|
|
488
|
+
break fail;
|
|
489
|
+
/* GetIteratorFlattenable(mapped, reject-primitives) */
|
|
490
|
+
if (!JS_IsObject(mapped)) {
|
|
491
|
+
JS_ThrowTypeError(ctx, 'not an object');
|
|
492
|
+
break fail;
|
|
493
|
+
}
|
|
494
|
+
const m = JS_GetProperty(ctx, mapped, JS_ATOM_Symbol_iterator);
|
|
495
|
+
if (JS_IsException(m))
|
|
496
|
+
break fail;
|
|
497
|
+
let iter;
|
|
498
|
+
if (JS_IsNull(m) || JS_IsUndefined(m)) {
|
|
499
|
+
iter = mapped;
|
|
500
|
+
}
|
|
501
|
+
else {
|
|
502
|
+
iter = JS_GetIterator2(ctx, mapped, m);
|
|
503
|
+
if (JS_IsException(iter))
|
|
504
|
+
break fail;
|
|
505
|
+
}
|
|
506
|
+
const inner_next = JS_GetProperty(ctx, iter, JS_ATOM_next);
|
|
507
|
+
if (JS_IsException(inner_next))
|
|
508
|
+
break fail;
|
|
509
|
+
it.inner = iter;
|
|
510
|
+
it.inner_next = inner_next;
|
|
511
|
+
}
|
|
512
|
+
const d = { done: 0 };
|
|
513
|
+
const item = JS_IteratorNext(ctx, it.inner, it.inner_next, [], d);
|
|
514
|
+
if (JS_IsException(item)) {
|
|
515
|
+
it.inner = it.inner_next = undefined;
|
|
516
|
+
break fail;
|
|
517
|
+
}
|
|
518
|
+
if (d.done) {
|
|
519
|
+
/* the inner iterator is exhausted: the outer one goes on */
|
|
520
|
+
it.inner = it.inner_next = undefined;
|
|
521
|
+
continue;
|
|
522
|
+
}
|
|
523
|
+
ret = item;
|
|
524
|
+
break done;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
case 6 /* Kind.MAP */: {
|
|
528
|
+
const item = JS_IteratorNext(ctx, it.obj, method, [], pdone);
|
|
529
|
+
if (JS_IsException(item)) {
|
|
530
|
+
ret = JS_EXCEPTION;
|
|
531
|
+
break done;
|
|
532
|
+
}
|
|
533
|
+
if (pdone.done) {
|
|
534
|
+
ret = item;
|
|
535
|
+
break done;
|
|
536
|
+
}
|
|
537
|
+
ret = JS_Call(ctx, it.func, undefined, [item, it.count++]);
|
|
538
|
+
if (JS_IsException(ret))
|
|
539
|
+
break fail;
|
|
540
|
+
break done;
|
|
541
|
+
}
|
|
542
|
+
case 8 /* Kind.TAKE */: {
|
|
543
|
+
if (it.count > 0) {
|
|
544
|
+
it.count--;
|
|
545
|
+
ret = JS_IteratorNext(ctx, it.obj, method, [], pdone);
|
|
546
|
+
break done;
|
|
547
|
+
}
|
|
548
|
+
pdone.done = 1;
|
|
549
|
+
ret = JS_IteratorClose(ctx, it.obj, false) < 0 ? JS_EXCEPTION : undefined;
|
|
550
|
+
break done;
|
|
551
|
+
}
|
|
552
|
+
case 9 /* Kind.CONCAT */:
|
|
553
|
+
ret = concat_step(ctx, it, pdone);
|
|
554
|
+
break done;
|
|
555
|
+
default:
|
|
556
|
+
throw new Error('iterator helper: bad kind');
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
/* close the iterator object, preserving the pending exception */
|
|
560
|
+
JS_IteratorClose(ctx, it.obj, true);
|
|
561
|
+
ret = JS_EXCEPTION;
|
|
562
|
+
}
|
|
563
|
+
/* an exception ends the helper, as it ends a generator */
|
|
564
|
+
if (JS_IsException(ret) || pdone.done) {
|
|
565
|
+
it.done = true;
|
|
566
|
+
it.values = [];
|
|
567
|
+
}
|
|
568
|
+
it.executing = false;
|
|
569
|
+
return ret;
|
|
570
|
+
}
|
|
571
|
+
const js_iterator_funcs = [
|
|
572
|
+
JS_CFUNC_DEF('concat', 0, js_iterator_concat),
|
|
573
|
+
JS_CFUNC_DEF('from', 1, js_iterator_from),
|
|
574
|
+
];
|
|
575
|
+
const js_iterator_proto_funcs = [
|
|
576
|
+
JS_CFUNC_MAGIC_DEF('drop', 1, js_create_iterator_helper, 0 /* Kind.DROP */),
|
|
577
|
+
JS_CFUNC_MAGIC_DEF('filter', 1, js_create_iterator_helper, 2 /* Kind.FILTER */),
|
|
578
|
+
JS_CFUNC_MAGIC_DEF('flatMap', 1, js_create_iterator_helper, 4 /* Kind.FLAT_MAP */),
|
|
579
|
+
JS_CFUNC_MAGIC_DEF('map', 1, js_create_iterator_helper, 6 /* Kind.MAP */),
|
|
580
|
+
JS_CFUNC_MAGIC_DEF('take', 1, js_create_iterator_helper, 8 /* Kind.TAKE */),
|
|
581
|
+
JS_CFUNC_MAGIC_DEF('every', 1, js_iterator_proto_func, 1 /* Kind.EVERY */),
|
|
582
|
+
JS_CFUNC_MAGIC_DEF('find', 1, js_iterator_proto_func, 3 /* Kind.FIND */),
|
|
583
|
+
JS_CFUNC_MAGIC_DEF('forEach', 1, js_iterator_proto_func, 5 /* Kind.FOR_EACH */),
|
|
584
|
+
JS_CFUNC_MAGIC_DEF('some', 1, js_iterator_proto_func, 7 /* Kind.SOME */),
|
|
585
|
+
JS_CFUNC_DEF('reduce', 1, js_iterator_proto_reduce),
|
|
586
|
+
JS_CFUNC_DEF('toArray', 0, js_iterator_proto_toArray),
|
|
587
|
+
/* [Symbol.iterator] is defined with %IteratorPrototype% (builtins/index.ts) */
|
|
588
|
+
JS_CGETSET_DEF(JS_ATOM_Symbol_toStringTag, js_iterator_proto_get_toStringTag, js_iterator_proto_set_toStringTag),
|
|
589
|
+
];
|
|
590
|
+
const js_iterator_helper_proto_funcs = [
|
|
591
|
+
JS_ITERATOR_NEXT_DEF('next', 0, js_iterator_helper_next, GEN_MAGIC_NEXT),
|
|
592
|
+
JS_ITERATOR_NEXT_DEF('return', 0, js_iterator_helper_next, GEN_MAGIC_RETURN),
|
|
593
|
+
JS_PROP_STRING_DEF(JS_ATOM_Symbol_toStringTag, 'Iterator Helper', JS_PROP_CONFIGURABLE),
|
|
594
|
+
];
|
|
595
|
+
/* the class ids of this file, registered in every runtime */
|
|
596
|
+
hooks.init_runtime.push((rt) => {
|
|
597
|
+
for (const [id, name] of [[57 /* JSClassID.ITERATOR */, 'Iterator'], [58 /* JSClassID.ITERATOR_HELPER */, 'Iterator Helper'],
|
|
598
|
+
[59 /* JSClassID.ITERATOR_WRAP */, 'Iterator Wrap']]) {
|
|
599
|
+
if (!JS_IsRegisteredClass(rt, id))
|
|
600
|
+
JS_NewClass1(rt, id, { class_name: rt.atoms.newAtomStr(name) });
|
|
601
|
+
}
|
|
602
|
+
});
|
|
603
|
+
/* Iterator and its prototypes; %IteratorPrototype% is ctx.iterator_proto */
|
|
604
|
+
export function JS_AddIntrinsicIterator(ctx) {
|
|
605
|
+
const proto = ctx.iterator_proto;
|
|
606
|
+
ctx.class_proto[57 /* JSClassID.ITERATOR */] = proto;
|
|
607
|
+
JS_SetPropertyFunctionList(ctx, proto, js_iterator_proto_funcs);
|
|
608
|
+
const ctor = JS_NewCFunction2(ctx, js_iterator_constructor, 'Iterator', 0, 4 /* JSCFunctionEnum.constructor_or_func */, 0);
|
|
609
|
+
JS_SetPropertyFunctionList(ctx, ctor, js_iterator_funcs);
|
|
610
|
+
JS_DefinePropertyValueStr(ctx, ctx.global_obj, 'Iterator', ctor, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE);
|
|
611
|
+
JS_SetConstructor(ctx, ctor, proto);
|
|
612
|
+
/* quirk: Iterator.prototype.constructor is an accessor property */
|
|
613
|
+
const getset = JS_NewCFunctionData(ctx, js_iterator_constructor_getset, 0, 0, [ctor]);
|
|
614
|
+
JS_DefineProperty(ctx, proto, JS_ATOM_constructor, undefined, getset, getset, JS_PROP_HAS_GET | JS_PROP_HAS_SET | JS_PROP_HAS_CONFIGURABLE | JS_PROP_CONFIGURABLE |
|
|
615
|
+
JS_PROP_HAS_ENUMERABLE);
|
|
616
|
+
iterator_ctors.set(ctx, ctor);
|
|
617
|
+
for (const [id, funcs] of [[58 /* JSClassID.ITERATOR_HELPER */, js_iterator_helper_proto_funcs],
|
|
618
|
+
[59 /* JSClassID.ITERATOR_WRAP */, js_iterator_wrap_proto_funcs]]) {
|
|
619
|
+
const p = JS_NewObjectProto(ctx, proto);
|
|
620
|
+
ctx.class_proto[id] = p;
|
|
621
|
+
JS_SetPropertyFunctionList(ctx, p, funcs);
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
//# sourceMappingURL=iterator.js.map
|