Coverage Report

Created: 2026-06-28 06:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/moddable/xs/sources/xsGenerator.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2016-2017  Moddable Tech, Inc.
3
 *
4
 *   This file is part of the Moddable SDK Runtime.
5
 * 
6
 *   The Moddable SDK Runtime is free software: you can redistribute it and/or modify
7
 *   it under the terms of the GNU Lesser General Public License as published by
8
 *   the Free Software Foundation, either version 3 of the License, or
9
 *   (at your option) any later version.
10
 * 
11
 *   The Moddable SDK Runtime is distributed in the hope that it will be useful,
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *   GNU Lesser General Public License for more details.
15
 * 
16
 *   You should have received a copy of the GNU Lesser General Public License
17
 *   along with the Moddable SDK Runtime.  If not, see <http://www.gnu.org/licenses/>.
18
 *
19
 * This file incorporates work covered by the following copyright and  
20
 * permission notice:  
21
 *
22
 *       Copyright (C) 2010-2016 Marvell International Ltd.
23
 *       Copyright (C) 2002-2010 Kinoma, Inc.
24
 *
25
 *       Licensed under the Apache License, Version 2.0 (the "License");
26
 *       you may not use this file except in compliance with the License.
27
 *       You may obtain a copy of the License at
28
 *
29
 *        http://www.apache.org/licenses/LICENSE-2.0
30
 *
31
 *       Unless required by applicable law or agreed to in writing, software
32
 *       distributed under the License is distributed on an "AS IS" BASIS,
33
 *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
34
 *       See the License for the specific language governing permissions and
35
 *       limitations under the License.
36
 */
37
38
#include "xsAll.h"
39
40
//#define mxPromisePrint 1
41
42
43
static txSlot* fxCheckIteratorStep(txMachine* the, txSlot* slot);
44
static txBoolean fxGetIteratorFlattenable(txMachine* the, txSlot* iterable, txSlot* iterator, txSlot* next, txBoolean optional);
45
static txSlot* fxNewIteratorHelperInstance(txMachine* the, txSlot* iterator, txInteger step);
46
47
static void fxNewGeneratorResult(txMachine* the, txBoolean done);
48
49
static txSlot* fxCheckGeneratorInstance(txMachine* the, txSlot* slot);
50
static void fx_Generator_prototype_aux(txMachine* the, txFlag status);
51
52
static void fxAsyncGeneratorStep(txMachine* the, txSlot* generator, txFlag status);
53
static txSlot* fxCheckAsyncGeneratorInstance(txMachine* the, txSlot* slot);
54
static void fx_AsyncGenerator_prototype_aux(txMachine* the, txFlag status);
55
56
static txSlot* fxCheckAsyncFromSyncIteratorInstance(txMachine* the, txSlot* slot);
57
static void fx_AsyncFromSyncIterator_prototype_aux(txMachine* the, txFlag status, txSlot* iterator, txBoolean* flag);
58
59
void fxBuildGenerator(txMachine* the)
60
31.7k
{
61
31.7k
  txSlot* slot;
62
31.7k
  txSlot* property;
63
64
31.7k
  mxPush(mxIteratorPrototype);
65
31.7k
  slot = fxLastProperty(the, the->stack->value.reference);
66
31.7k
#if mxECMAScript2025
67
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Iterator_prototype_drop), 1, mxID(_drop), XS_DONT_ENUM_FLAG);
68
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Iterator_prototype_every), 1, mxID(_every), XS_DONT_ENUM_FLAG);
69
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Iterator_prototype_filter), 1, mxID(_filter), XS_DONT_ENUM_FLAG);
70
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Iterator_prototype_find), 1, mxID(_find), XS_DONT_ENUM_FLAG);
71
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Iterator_prototype_flatMap), 1, mxID(_flatMap), XS_DONT_ENUM_FLAG);
72
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Iterator_prototype_forEach), 1, mxID(_forEach), XS_DONT_ENUM_FLAG);
73
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Iterator_prototype_map), 1, mxID(_map), XS_DONT_ENUM_FLAG);
74
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Iterator_prototype_reduce), 1, mxID(_reduce), XS_DONT_ENUM_FLAG);
75
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Iterator_prototype_some), 1, mxID(_some), XS_DONT_ENUM_FLAG);
76
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Iterator_prototype_take), 1, mxID(_take), XS_DONT_ENUM_FLAG);
77
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Iterator_prototype_toArray), 0, mxID(_toArray), XS_DONT_ENUM_FLAG);
78
31.7k
  slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_Iterator_prototype_toStringTag_get), mxCallback(fx_Iterator_prototype_toStringTag_set), mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG);
79
31.7k
#endif
80
31.7k
#if mxExplicitResourceManagement
81
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Iterator_prototype_dispose), 0, mxID(_Symbol_dispose), XS_DONT_ENUM_FLAG);
82
31.7k
#endif
83
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Iterator_prototype_iterator), 0, mxID(_Symbol_iterator), XS_DONT_ENUM_FLAG);
84
31.7k
#if mxECMAScript2025
85
31.7k
  property = slot;
86
31.7k
  slot = fxBuildHostConstructor(the, mxCallback(fx_Iterator), 0, mxID(_Iterator));
87
31.7k
  mxIteratorConstructor = *the->stack;
88
31.7k
  slot = fxLastProperty(the, slot);
89
31.7k
#if mxECMAScript2026
90
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Iterator_concat), 0, mxID(_concat), XS_DONT_ENUM_FLAG);
91
31.7k
#endif
92
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Iterator_from), 1, mxID(_from), XS_DONT_ENUM_FLAG);
93
  
94
31.7k
  mxPush(mxIteratorPrototype);
95
31.7k
  property = fxNextHostAccessorProperty(the, property, mxCallback(fx_Iterator_prototype_constructor_get), mxCallback(fx_Iterator_prototype_constructor_set), mxID(_constructor), XS_DONT_ENUM_FLAG);
96
31.7k
  mxPop();
97
  
98
31.7k
  mxPush(mxIteratorPrototype);
99
31.7k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
100
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_IteratorHelper_prototype_next), 1, mxID(_next), XS_DONT_ENUM_FLAG);
101
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_IteratorHelper_prototype_return), 1, mxID(_return), XS_DONT_ENUM_FLAG);
102
31.7k
  slot = fxNextStringXProperty(the, slot, "Iterator Helper", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
103
31.7k
  mxPull(mxIteratorHelperPrototype);
104
  
105
31.7k
  mxPush(mxIteratorPrototype);
106
31.7k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
107
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_IteratorWrapper_prototype_next), 1, mxID(_next), XS_DONT_ENUM_FLAG);
108
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_IteratorWrapper_prototype_return), 1, mxID(_return), XS_DONT_ENUM_FLAG);
109
31.7k
  mxPull(mxIteratorWrapperPrototype);
110
111
31.7k
#endif
112
113
31.7k
  mxPush(mxIteratorPrototype);
114
31.7k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
115
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Generator_prototype_next), 1, mxID(_next), XS_DONT_ENUM_FLAG);
116
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Generator_prototype_return), 1, mxID(_return), XS_DONT_ENUM_FLAG);
117
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Generator_prototype_throw), 1, mxID(_throw), XS_DONT_ENUM_FLAG);
118
31.7k
  slot = fxNextStringXProperty(the, slot, "Generator", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
119
31.7k
  mxGeneratorPrototype = *the->stack;
120
31.7k
  mxPop();
121
  
122
31.7k
  mxPush(mxFunctionPrototype);
123
31.7k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
124
31.7k
  slot = fxNextSlotProperty(the, slot, &mxGeneratorPrototype, mxID(_prototype), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
125
31.7k
  property = mxBehaviorSetProperty(the, mxGeneratorPrototype.value.reference, mxID(_constructor), 0, XS_OWN);
126
31.7k
  property->flag = XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG;
127
31.7k
  property->kind = the->stack->kind;
128
31.7k
  property->value = the->stack->value;
129
31.7k
  slot = fxNextStringXProperty(the, slot, "GeneratorFunction", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
130
31.7k
  mxGeneratorFunctionPrototype = *the->stack;
131
31.7k
  slot = fxBuildHostConstructor(the, mxCallback(fx_GeneratorFunction), 1, mxID(_GeneratorFunction));
132
31.7k
  slot = mxBehaviorGetProperty(the, mxGeneratorFunctionPrototype.value.reference, mxID(_constructor), 0, XS_OWN);
133
31.7k
  slot->flag |= XS_DONT_SET_FLAG;
134
31.7k
  mxPop();
135
  
136
31.7k
  mxPush(mxIteratorPrototype);
137
31.7k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
138
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Enumerator_prototype_next), 0, mxID(_next), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG);
139
31.7k
  fxNewHostConstructor(the, mxCallback(fx_Enumerator), 0, XS_NO_ID);
140
31.7k
  mxPull(mxEnumeratorFunction);
141
142
31.7k
  mxPush(mxObjectPrototype);
143
31.7k
  slot = fxNewObjectInstance(the);
144
31.7k
#if mxExplicitResourceManagement
145
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_AsyncIterator_prototype_asyncDispose), 0, mxID(_Symbol_asyncDispose), XS_DONT_ENUM_FLAG);
146
31.7k
#endif
147
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_AsyncIterator_prototype_asyncIterator), 0, mxID(_Symbol_asyncIterator), XS_DONT_ENUM_FLAG);
148
31.7k
  mxPull(mxAsyncIteratorPrototype);
149
  
150
31.7k
  mxPush(mxAsyncIteratorPrototype);
151
31.7k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
152
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_AsyncGenerator_prototype_next), 1, mxID(_next), XS_DONT_ENUM_FLAG);
153
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_AsyncGenerator_prototype_return), 1, mxID(_return), XS_DONT_ENUM_FLAG);
154
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_AsyncGenerator_prototype_throw), 1, mxID(_throw), XS_DONT_ENUM_FLAG);
155
31.7k
  slot = fxNextStringXProperty(the, slot, "AsyncGenerator", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
156
31.7k
  mxAsyncGeneratorPrototype = *the->stack;
157
31.7k
  mxPop();
158
159
31.7k
  mxPush(mxFunctionPrototype);
160
31.7k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
161
31.7k
  slot = fxNextSlotProperty(the, slot, &mxAsyncGeneratorPrototype, mxID(_prototype), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
162
31.7k
  property = mxBehaviorSetProperty(the, mxAsyncGeneratorPrototype.value.reference, mxID(_constructor), 0, XS_OWN);
163
31.7k
  property->flag = XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG;
164
31.7k
  property->kind = the->stack->kind;
165
31.7k
  property->value = the->stack->value;
166
31.7k
  slot = fxNextStringXProperty(the, slot, "AsyncGeneratorFunction", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
167
31.7k
  mxAsyncGeneratorFunctionPrototype = *the->stack;
168
31.7k
  slot = fxBuildHostConstructor(the, mxCallback(fx_AsyncGeneratorFunction), 1, mxID(_AsyncGeneratorFunction));
169
31.7k
  slot = mxBehaviorGetProperty(the, mxAsyncGeneratorFunctionPrototype.value.reference, mxID(_constructor), 0, XS_OWN);
170
31.7k
  slot->flag |= XS_DONT_SET_FLAG;
171
31.7k
  mxPop();
172
  
173
31.7k
  mxPush(mxAsyncIteratorPrototype);
174
31.7k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
175
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_AsyncFromSyncIterator_prototype_next), 1, mxID(_next), XS_DONT_ENUM_FLAG);
176
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_AsyncFromSyncIterator_prototype_return), 1, mxID(_return), XS_DONT_ENUM_FLAG);
177
31.7k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_AsyncFromSyncIterator_prototype_throw), 1, mxID(_throw), XS_DONT_ENUM_FLAG);
178
31.7k
  slot = fxNextStringXProperty(the, slot, "Async-from-Sync Iterator", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
179
31.7k
  mxAsyncFromSyncIteratorPrototype = *the->stack;
180
31.7k
  mxPop();
181
31.7k
}
182
183
typedef txBoolean (*txIteratorStep)(txMachine* the, txSlot* iterator, txSlot* next, txSlot* extra, txSlot* value, txFlag status);
184
185
enum {
186
  mx_Iterator_prototype_drop = 0,
187
  mx_Iterator_prototype_filter,
188
  mx_Iterator_prototype_flatMap,
189
  mx_Iterator_prototype_map,
190
  mx_Iterator_prototype_take,
191
  mx_Iterator_concat,
192
  mxIteratorStepCount
193
};
194
195
static txBoolean fx_Iterator_prototype_drop_step(txMachine* the, txSlot* iterator, txSlot* next, txSlot* extra, txSlot* value, txFlag status);
196
static txBoolean fx_Iterator_prototype_filter_step(txMachine* the, txSlot* iterator, txSlot* next, txSlot* extra, txSlot* value, txFlag status);
197
static txBoolean fx_Iterator_prototype_flatMap_step(txMachine* the, txSlot* iterator, txSlot* next, txSlot* extra, txSlot* value, txFlag status);
198
static txBoolean fx_Iterator_prototype_map_step(txMachine* the, txSlot* iterator, txSlot* next, txSlot* extra, txSlot* value, txFlag status);
199
static txBoolean fx_Iterator_prototype_take_step(txMachine* the, txSlot* iterator, txSlot* next, txSlot* extra, txSlot* value, txFlag status);
200
static txBoolean fx_Iterator_concat_step(txMachine* the, txSlot* iterator, txSlot* next, txSlot* extra, txSlot* value, txFlag status);
201
202
const txIteratorStep ICACHE_FLASH_ATTR gxIteratorSteps[mxIteratorStepCount]  = {
203
  fx_Iterator_prototype_drop_step,
204
  fx_Iterator_prototype_filter_step,
205
  fx_Iterator_prototype_flatMap_step,
206
  fx_Iterator_prototype_map_step,
207
  fx_Iterator_prototype_take_step,
208
  fx_Iterator_concat_step,
209
};
210
211
const txID ICACHE_FLASH_ATTR gxIteratorStepIDs[mxIteratorStepCount]  = {
212
  mxID(_drop),
213
  mxID(_filter),
214
  mxID(_flatMap),
215
  mxID(_map),
216
  mxID(_take),
217
};
218
219
txSlot* fxCheckIteratorInstance(txMachine* the, txSlot* slot, txID id)
220
7.21M
{
221
7.21M
  txSlot* instance;
222
7.21M
  if (slot->kind == XS_REFERENCE_KIND) {
223
7.21M
    instance = slot->value.reference;
224
7.21M
    slot = instance->next;
225
7.21M
    if (slot && (slot->flag & XS_INTERNAL_FLAG) && (slot->ID == id) && (slot->kind == XS_REFERENCE_KIND)) {
226
7.21M
      return instance;
227
7.21M
    }
228
7.21M
  }
229
7.21M
  mxTypeError("this: not an iterator");
230
0
  return C_NULL;
231
7.21M
}
232
233
txSlot* fxCheckIteratorResult(txMachine* the, txSlot* result) 
234
7.04M
{
235
7.04M
  txSlot* value = result->value.reference->next;
236
7.04M
  while (value && (value->flag & XS_INTERNAL_FLAG))
237
0
    value = value->next;
238
7.04M
  mxCheck(the, (value != C_NULL) && (value->ID == mxID(_value)));
239
7.04M
  mxCheck(the, (value->next != C_NULL) && (value->next->ID == mxID(_done)));
240
7.04M
  return value;
241
7.04M
}
242
243
txSlot* fxCheckIteratorStep(txMachine* the, txSlot* slot) 
244
99.6k
{
245
99.6k
  if (slot && (slot->kind == XS_INTEGER_KIND)) {
246
99.6k
    txInteger step = slot->value.integer;
247
99.6k
    if ((0 <= step) && (step < mxIteratorStepCount)) {
248
99.6k
      if (slot->ID == gxIteratorStepIDs[step]) {
249
99.6k
        return slot;
250
99.6k
      }
251
99.6k
    }
252
99.6k
  }
253
99.6k
  mxTypeError("this: not an iterator helper");
254
0
  return C_NULL;
255
99.6k
}
256
257
txBoolean fxIteratorNext(txMachine* the, txSlot* iterator, txSlot* next, txSlot* value)
258
8.16M
{
259
8.16M
  mxPushSlot(iterator);
260
8.16M
  mxPushSlot(next);
261
8.16M
  mxCall();
262
8.16M
  mxRunCount(0);
263
8.16M
  if (!mxIsReference(the->stack))
264
6
    mxTypeError("iterator result: not an object");
265
8.16M
  mxDub();
266
8.16M
  mxGetID(mxID(_done));
267
8.16M
  if (fxToBoolean(the, the->stack)) {
268
903k
    mxPop();
269
903k
    mxPop();
270
903k
    return 0;
271
903k
  }
272
7.25M
  mxPop();
273
7.25M
  mxGetID(mxID(_value));
274
7.25M
  mxPullSlot(value);
275
7.25M
  return 1;
276
8.16M
}
277
278
void fxIteratorReturn(txMachine* the, txSlot* iterator, txBoolean abrupt)
279
253
{
280
253
  if (abrupt)
281
185
    mxPush(mxException);
282
253
  mxTry(the) {
283
253
    mxPushSlot(iterator);
284
253
    mxDub();
285
253
    mxGetID(mxID(_return));
286
253
    if (mxIsUndefined(the->stack) || mxIsNull(the->stack)) 
287
78
      mxPop();
288
175
    else {
289
175
      mxCall();
290
175
      mxRunCount(0);
291
175
      if (!mxIsReference(the->stack))
292
11
        mxTypeError("iterator result: not an object");
293
175
    }
294
242
    mxPop();
295
242
  }
296
242
  mxCatch(the) {
297
43
    if (!abrupt)
298
7
      fxJump(the);
299
43
  }
300
235
  if (abrupt)
301
185
    mxPull(mxException);
302
235
}
303
304
txBoolean fxGetIterator(txMachine* the, txSlot* iterable, txSlot* iterator, txSlot* next, txBoolean optional)
305
911k
{
306
911k
  mxPushSlot(iterable);
307
911k
  mxDub();
308
911k
  mxGetID(mxID(_Symbol_iterator));
309
911k
  if (optional && (mxIsUndefined(the->stack) || mxIsNull(the->stack))) {
310
2.89k
    mxPop();
311
2.89k
    mxPop();
312
2.89k
    return 0;
313
2.89k
  }
314
908k
  mxCall();
315
908k
  mxRunCount(0);
316
908k
  if (!mxIsReference(the->stack))
317
1
    mxTypeError("iterator: not an object");
318
908k
  if (next) {
319
826k
    mxDub();
320
826k
    mxGetID(mxID(_next));
321
826k
    mxPullSlot(next);
322
826k
  }
323
908k
  mxPullSlot(iterator);
324
908k
  return 1;
325
908k
}
326
327
txBoolean fxGetIteratorFlattenable(txMachine* the, txSlot* iterable, txSlot* iterator, txSlot* next, txBoolean optional)
328
47.8k
{
329
47.8k
  if (!mxIsReference(iterable)) {
330
18
    if (optional) {
331
14
      if ((iterable->kind != XS_STRING_KIND) && (iterable->kind != XS_STRING_X_KIND))
332
13
        mxTypeError("iterator: not a string");
333
14
    }
334
4
    else
335
4
      mxTypeError("iterator: not an object");
336
18
  }
337
47.8k
  mxPushSlot(iterable);
338
47.8k
  mxDub();
339
47.8k
  mxGetID(mxID(_Symbol_iterator));
340
47.8k
  if ((mxIsUndefined(the->stack) || mxIsNull(the->stack)))
341
23
    mxPop();
342
47.8k
  else {
343
47.8k
    mxCall();
344
47.8k
    mxRunCount(0);
345
47.8k
  }
346
47.8k
  if (!mxIsReference(the->stack))
347
0
    mxTypeError("iterator: not an object");
348
47.8k
  mxDub();
349
47.8k
  mxGetID(mxID(_next));
350
47.8k
  mxPullSlot(next);
351
47.8k
  mxPullSlot(iterator);
352
47.8k
  return 1;
353
47.8k
}
354
355
txSlot* fxNewIteratorInstance(txMachine* the, txSlot* iterable, txID id) 
356
960k
{
357
960k
  txSlot* instance;
358
960k
  txSlot* result;
359
960k
  txSlot* property;
360
960k
  instance = fxNewObjectInstance(the);
361
960k
  mxPush(mxObjectPrototype);
362
960k
  result = fxNewObjectInstance(the);
363
960k
  property = fxNextUndefinedProperty(the, result, mxID(_value), XS_DONT_DELETE_FLAG | XS_DONT_SET_FLAG);
364
960k
  property = fxNextBooleanProperty(the, property, 0, mxID(_done), XS_DONT_DELETE_FLAG | XS_DONT_SET_FLAG);
365
960k
  property = fxNextSlotProperty(the, instance, the->stack, id, XS_INTERNAL_FLAG);
366
960k
  property = fxNextSlotProperty(the, property, iterable, XS_NO_ID, XS_INTERNAL_FLAG);
367
960k
  property = fxNextIntegerProperty(the, property, 0, XS_NO_ID, XS_INTERNAL_FLAG);
368
960k
  mxPop();
369
960k
  return instance;
370
960k
}
371
372
void fxSetterThatIgnoresPrototypeProperties(txMachine* the, txSlot* reference, txID id, txString name, txSlot* value)
373
62
{
374
62
  txSlot* instance = fxGetInstance(the, reference);
375
62
  txSlot* home = mxFunctionInstanceHome(mxFunction->value.reference);
376
62
  txSlot* property;
377
62
  if (!instance)
378
44
    mxTypeError("set %s: not an object", name);
379
18
  if (home->value.home.object == instance)
380
10
    mxTypeError("set %s: not writable", name);
381
8
  mxTemporary(property);
382
8
  if (!mxBehaviorGetOwnProperty(the, instance, id, 0, property)) {
383
5
    if (!mxBehaviorDefineOwnProperty(the, instance, id, 0, value, XS_NO_FLAG))
384
0
      mxTypeError("set %s: not extensible", name);
385
5
  }
386
3
  else /*if (!mxIsProxy(instance))*/ {
387
3
    property = mxBehaviorSetProperty(the, instance, id, 0, XS_OWN);
388
3
    if (!property)
389
0
      mxTypeError("set %s: not writable", name);
390
3
        if (property->kind == XS_ACCESSOR_KIND) {
391
0
            txSlot* function = property->value.accessor.setter;
392
0
            if (!mxIsFunction(function))
393
0
                mxTypeError("set %s: not writable", name);
394
0
            mxPushSlot(reference);
395
0
            mxPushReference(function);
396
0
            mxCall();
397
0
            mxPushSlot(value);
398
0
            mxRunCount(1);
399
0
            mxPop();
400
0
       }
401
3
        else {
402
3
            property->kind = value->kind;
403
3
            property->value = value->value;
404
3
        }
405
3
  }
406
8
  mxPop();
407
8
}
408
409
void fx_Iterator(txMachine* the)
410
81
{
411
81
  if (!mxHasTarget)
412
2
    mxTypeError("call: Iterator");
413
79
  if (fxIsSameSlot(the, mxTarget, mxFunction))
414
1
    mxTypeError("new: Iterator");
415
78
  mxPushSlot(mxTarget);
416
78
  fxGetPrototypeFromConstructor(the, &mxIteratorPrototype);
417
78
  fxNewObjectInstance(the);
418
78
  mxPullSlot(mxResult);
419
78
}
420
421
void fx_Iterator_concat(txMachine* the)
422
65
{
423
65
  txSlot* list = fxNewInstance(the);
424
65
  txSlot* slot = list;
425
65
  txSlot* property;
426
65
  txInteger c = mxArgc, i;
427
121
  for (i = 0; i < c; i++) {
428
86
    txSlot* item = mxArgv(i);
429
86
    if (!mxIsReference(item))
430
9
      mxTypeError("items[%d]: not an object", i);
431
77
    mxPushSlot(item);
432
77
    slot = fxNextSlotProperty(the, slot, the->stack, XS_NO_ID, XS_NO_FLAG);
433
77
    mxGetID(mxID(_Symbol_iterator));
434
77
    if (!fxIsCallable(the, the->stack))
435
21
      mxTypeError("items[%d]: not iterable", i);
436
56
    slot = fxNextSlotProperty(the, slot, the->stack, XS_NO_ID, XS_NO_FLAG);
437
56
    mxPop();
438
56
  }
439
35
  mxPushNull();
440
35
  property = fxLastProperty(the, fxNewIteratorHelperInstance(the, the->stack, mx_Iterator_concat));
441
35
  property = fxNextReferenceProperty(the, property, list, XS_NO_ID, XS_INTERNAL_FLAG);
442
35
  mxPullSlot(mxResult);
443
35
  mxPop();
444
35
  mxPop();
445
35
}
446
447
txBoolean fx_Iterator_concat_step(txMachine* the, txSlot* iterator, txSlot* next, txSlot* extra, txSlot* value, txFlag status)
448
63
{
449
63
  if (status == XS_NO_STATUS) {
450
56
    for (;;) {
451
56
      if (mxIsNull(iterator)) {
452
41
        txSlot* iterable = extra->value.reference->next;
453
41
        if (!iterable)
454
5
          break;
455
36
        mxPushSlot(iterable);
456
36
        mxPushSlot(iterable->next);
457
36
        extra->value.reference->next = iterable->next->next;
458
36
        mxCall();
459
36
        mxRunCount(0);
460
36
        if (!mxIsReference(the->stack))
461
10
          mxTypeError("iterator: not an object");
462
26
        mxDub();
463
26
        mxGetID(mxID(_next));
464
26
        mxPullSlot(next);
465
26
        mxPullSlot(iterator);
466
26
      }
467
41
      if (fxIteratorNext(the, iterator, next, value))
468
26
        return 1;
469
15
      next->kind = XS_NULL_KIND;
470
15
      iterator->kind = XS_NULL_KIND;
471
15
    }
472
43
  }
473
20
  else if (status == XS_RETURN_STATUS) {
474
8
    if (!mxIsNull(iterator))
475
7
      fxIteratorReturn(the, iterator, 0);
476
8
  }
477
12
  else if (status == XS_THROW_STATUS) {
478
12
    if (!mxIsNull(iterator))
479
1
      fxIteratorReturn(the, iterator, 1);
480
12
  }
481
27
  return 0;
482
63
}
483
484
void fx_Iterator_from(txMachine* the)
485
37
{
486
37
  txSlot *iterator, *next, *property;
487
37
  mxTemporary(iterator);
488
37
  mxTemporary(next);
489
37
  fxGetIteratorFlattenable(the, mxArgv(0), iterator, next, 1);
490
37
  mxPush(mxIteratorConstructor);
491
37
  mxDub();
492
37
  mxGetID(mxID(_Symbol_hasInstance));
493
37
  mxCall();
494
37
  mxPushSlot(iterator);
495
37
  mxRunCount(1);
496
37
  if (fxToBoolean(the, the->stack)) {
497
10
    mxResult->kind = iterator->kind;
498
10
    mxResult->value = iterator->value;
499
10
  }
500
27
  else {
501
27
    mxPush(mxIteratorWrapperPrototype);
502
27
    property = fxLastProperty(the, fxNewIteratorInstance(the, iterator, mxID(_Iterator)));
503
27
    property = fxNextSlotProperty(the, property, next, XS_NO_ID, XS_INTERNAL_FLAG);
504
27
    mxPullSlot(mxResult);
505
27
  }
506
37
  mxPop();
507
37
  mxPop();
508
37
  mxPop();
509
37
}
510
511
void fx_Iterator_prototype_constructor_get(txMachine* the)
512
28
{
513
28
  mxPush(mxIteratorConstructor);
514
28
  mxPullSlot(mxResult);
515
28
}
516
517
void fx_Iterator_prototype_constructor_set(txMachine* the)
518
35
{
519
35
  fxSetterThatIgnoresPrototypeProperties(the, mxThis, mxID(_constructor), "constructor", mxArgv(0));
520
35
}
521
522
void fx_Iterator_prototype_dispose(txMachine* the)
523
1
{ 
524
1
  fxIteratorReturn(the, mxThis, 1);
525
1
}
526
527
void fx_Iterator_prototype_drop(txMachine* the)
528
1.72k
{
529
1.72k
  txSlot *iterator, *property;
530
1.72k
  txNumber limit;
531
1.72k
  if (!fxGetInstance(the, mxThis))
532
6
    mxTypeError("this: not an object");
533
1.72k
  iterator = mxThis;
534
1.72k
  {
535
1.72k
    mxTry(the) {
536
1.72k
      if (mxArgc > 0)
537
1.71k
        mxPushSlot(mxArgv(0));
538
3
      else
539
3
        mxPushUndefined();
540
1.72k
      limit = fxToNumber(the, the->stack);
541
1.72k
      if (c_isnan(limit))
542
7
        mxRangeError("limit: NaN");
543
1.71k
      if (c_isfinite(limit))
544
1.71k
        limit = c_trunc(limit);
545
1.71k
      if (limit < 0)
546
4
        mxRangeError("limit: < 0");
547
1.71k
    }
548
1.71k
    mxCatch(the) {
549
11
      fxIteratorReturn(the, iterator, 1);
550
11
      fxJump(the);
551
11
    }
552
1.72k
  }
553
1.69k
  property = fxLastProperty(the, fxNewIteratorHelperInstance(the, iterator, mx_Iterator_prototype_drop));
554
1.69k
  property = fxNextNumberProperty(the, property, limit, XS_NO_ID, XS_INTERNAL_FLAG);
555
1.69k
  mxPullSlot(mxResult);
556
1.69k
  mxPop();
557
1.69k
}
558
559
txBoolean fx_Iterator_prototype_drop_step(txMachine* the, txSlot* iterator, txSlot* next, txSlot* extra, txSlot* value, txFlag status)
560
1.73k
{
561
1.73k
  txNumber remaining = extra->value.number;
562
1.73k
  if (status == XS_NO_STATUS) {
563
5.02k
    while (remaining > 0) {
564
4.95k
      if (fxIteratorNext(the, iterator, next, value)) {
565
3.30k
        if (c_isfinite(remaining)) {
566
3.30k
          remaining--;
567
3.30k
          extra->value.number = remaining;
568
3.30k
        }
569
3.30k
      }
570
1.65k
      else
571
1.65k
        return 0;
572
4.95k
    }
573
68
    if (fxIteratorNext(the, iterator, next, value))
574
45
      return 1;
575
68
  }
576
14
  else if (status == XS_RETURN_STATUS)
577
10
    fxIteratorReturn(the, iterator, 0);
578
4
  else if (status == XS_THROW_STATUS)
579
4
    fxIteratorReturn(the, iterator, 1);
580
37
  return 0;
581
1.73k
}
582
583
void fx_Iterator_prototype_every(txMachine* the)
584
16
{ 
585
16
  txSlot *iterator, *predicate, *next, *value;
586
16
  txInteger counter;
587
16
  if (!fxGetInstance(the, mxThis))
588
3
    mxTypeError("this: not an object");
589
13
  iterator = mxThis;
590
13
  {
591
13
    mxTry(the) {
592
13
      if (mxArgc > 0)
593
12
        mxPushSlot(mxArgv(0));
594
1
      else
595
1
        mxPushUndefined();
596
13
      predicate = the->stack;
597
13
      if (!fxIsCallable(the, predicate))
598
3
        mxTypeError("predicate: not a function");
599
13
    }
600
10
    mxCatch(the) {
601
3
      fxIteratorReturn(the, iterator, 1);
602
3
      fxJump(the);
603
3
    }
604
13
  }
605
7
  mxPushSlot(iterator);
606
7
  mxGetID(mxID(_next));
607
7
  next = the->stack;
608
7
  mxTemporary(value);
609
7
  counter = 0;
610
7
  mxResult->kind = XS_BOOLEAN_KIND;
611
7
  mxResult->value.boolean = 1;
612
7
  {
613
10
    mxTry(the) {
614
57.3k
      while (fxIteratorNext(the, iterator, next, value)) {
615
57.3k
        mxPushUndefined();
616
57.3k
        mxPushSlot(predicate);
617
57.3k
        mxCall();
618
57.3k
        mxPushSlot(value);
619
57.3k
        mxPushInteger(counter);
620
57.3k
        mxRunCount(2);
621
57.3k
        mxResult->value.boolean = fxToBoolean(the, the->stack);
622
57.3k
        mxPop();
623
57.3k
        if (!mxResult->value.boolean) {
624
3
          fxIteratorReturn(the, iterator, 0);
625
3
          break;
626
3
        }
627
57.3k
        counter++;
628
57.3k
      }
629
10
    }
630
18.4E
    mxCatch(the) {
631
2
      fxIteratorReturn(the, iterator, 1);
632
2
      fxJump(the);
633
2
    }
634
7
  }
635
5
  mxPop();
636
5
  mxPop();
637
5
  mxPop();
638
5
}
639
640
void fx_Iterator_prototype_filter(txMachine* the)
641
23
{ 
642
23
  txSlot *iterator, *predicate, *property;
643
23
  if (!fxGetInstance(the, mxThis))
644
3
    mxTypeError("this: not an object");
645
20
  iterator = mxThis;
646
20
  {
647
20
    mxTry(the) {
648
20
      if (mxArgc > 0)
649
19
        mxPushSlot(mxArgv(0));
650
1
      else
651
1
        mxPushUndefined();
652
20
      predicate = the->stack;
653
20
      if (!fxIsCallable(the, predicate))
654
3
        mxTypeError("predicate: not a function");
655
20
    }
656
17
    mxCatch(the) {
657
3
      fxIteratorReturn(the, iterator, 1);
658
3
      fxJump(the);
659
3
    }
660
20
  }
661
14
  property = fxLastProperty(the, fxNewIteratorHelperInstance(the, iterator, mx_Iterator_prototype_filter));
662
14
  property = fxNextSlotProperty(the, property, predicate, XS_NO_ID, XS_INTERNAL_FLAG);
663
14
  property = fxNextIntegerProperty(the, property, 0, XS_NO_ID, XS_INTERNAL_FLAG);
664
14
  mxPullSlot(mxResult);
665
14
  mxPop();
666
14
}
667
668
txBoolean fx_Iterator_prototype_filter_step(txMachine* the, txSlot* iterator, txSlot* next, txSlot* extra, txSlot* value, txFlag status)
669
34.8k
{
670
34.8k
  txSlot* counter = extra->next;
671
34.8k
  txBoolean selected = 0;
672
34.8k
  if (status == XS_NO_STATUS) {
673
35.1k
    while (fxIteratorNext(the, iterator, next, value)) {
674
35.1k
      mxPushUndefined();
675
35.1k
      mxPushSlot(extra);
676
35.1k
      mxCall();
677
35.1k
      mxPushSlot(value);
678
35.1k
      mxPushSlot(counter);
679
35.1k
      mxRunCount(2);
680
35.1k
      selected = fxToBoolean(the, the->stack);
681
35.1k
      mxPop();
682
35.1k
      counter->value.integer++;
683
35.1k
      if (selected)
684
34.8k
        return 1;
685
35.1k
    }
686
34.8k
  }
687
2
  else if (status == XS_RETURN_STATUS)
688
1
    fxIteratorReturn(the, iterator, 0);
689
1
  else if (status == XS_THROW_STATUS)
690
1
    fxIteratorReturn(the, iterator, 1);
691
12
  return 0;
692
34.8k
}
693
694
void fx_Iterator_prototype_find(txMachine* the)
695
1.65k
{ 
696
1.65k
  txSlot *iterator, *predicate, *next, *value;
697
1.65k
  txInteger counter;
698
1.65k
  txBoolean result;
699
1.65k
  if (!fxGetInstance(the, mxThis))
700
3
    mxTypeError("this: not an object");
701
1.65k
  iterator = mxThis;
702
1.65k
  {
703
1.65k
    mxTry(the) {
704
1.65k
      if (mxArgc > 0)
705
1.65k
        mxPushSlot(mxArgv(0));
706
1
      else
707
1
        mxPushUndefined();
708
1.65k
      predicate = the->stack;
709
1.65k
      if (!fxIsCallable(the, predicate))
710
3
        mxTypeError("predicate: not a function");
711
1.65k
    }
712
1.65k
    mxCatch(the) {
713
3
      fxIteratorReturn(the, iterator, 1);
714
3
      fxJump(the);
715
3
    }
716
1.65k
  }
717
1.64k
  mxPushSlot(iterator);
718
1.64k
  mxGetID(mxID(_next));
719
1.64k
  next = the->stack;
720
1.64k
  mxTemporary(value);
721
1.64k
  counter = 0;
722
1.64k
  {
723
1.65k
    mxTry(the) {
724
6.68k
      while (fxIteratorNext(the, iterator, next, value)) {
725
5.03k
        mxPushUndefined();
726
5.03k
        mxPushSlot(predicate);
727
5.03k
        mxCall();
728
5.03k
        mxPushSlot(value);
729
5.03k
        mxPushInteger(counter);
730
5.03k
        mxRunCount(2);
731
5.03k
        result = fxToBoolean(the, the->stack);
732
5.03k
        mxPop();
733
5.03k
        if (result) {
734
2
          mxResult->kind = value->kind;
735
2
          mxResult->value = value->value;
736
2
          fxIteratorReturn(the, iterator, 0);
737
2
          break;
738
2
        }
739
5.02k
        counter++;
740
5.02k
      }
741
1.65k
    }
742
18.4E
    mxCatch(the) {
743
4
      fxIteratorReturn(the, iterator, 1);
744
4
      fxJump(the);
745
4
    }
746
1.64k
  }
747
1.64k
  mxPop();
748
1.64k
  mxPop();
749
1.64k
  mxPop();
750
1.64k
}
751
752
void fx_Iterator_prototype_flatMap(txMachine* the)
753
41
{ 
754
41
  txSlot *iterator, *mapper, *property;
755
41
  if (!fxGetInstance(the, mxThis))
756
3
    mxTypeError("this: not an object");
757
38
  iterator = mxThis;
758
38
  {
759
38
    mxTry(the) {
760
38
      if (mxArgc > 0)
761
37
        mxPushSlot(mxArgv(0));
762
1
      else
763
1
        mxPushUndefined();
764
38
      mapper = the->stack;
765
38
      if (!fxIsCallable(the, mapper))
766
3
        mxTypeError("mapper: not a function");
767
38
    }
768
35
    mxCatch(the) {
769
3
      fxIteratorReturn(the, iterator, 1);
770
3
      fxJump(the);
771
3
    }
772
38
  }
773
32
  property = fxLastProperty(the, fxNewIteratorHelperInstance(the, iterator, mx_Iterator_prototype_flatMap));
774
32
  property = fxNextSlotProperty(the, property, mapper, XS_NO_ID, XS_INTERNAL_FLAG);
775
32
  property = fxNextIntegerProperty(the, property, 0, XS_NO_ID, XS_INTERNAL_FLAG);
776
32
  property = fxNextNullProperty(the, property, XS_NO_ID, XS_INTERNAL_FLAG);
777
32
  property = fxNextNullProperty(the, property, XS_NO_ID, XS_INTERNAL_FLAG);
778
32
  mxPullSlot(mxResult);
779
32
  mxPop();
780
32
}
781
782
txBoolean fx_Iterator_prototype_flatMap_step(txMachine* the, txSlot* iterator, txSlot* next, txSlot* extra, txSlot* value, txFlag status)
783
261
{
784
261
  txSlot* counter = extra->next;
785
261
  txSlot* innerIterator = counter->next;
786
261
  txSlot* innerNext = innerIterator->next;
787
261
  if (status == XS_NO_STATUS) {
788
48.0k
  again:
789
48.0k
    if (mxIsNull(innerIterator)) {
790
47.8k
      if (fxIteratorNext(the, iterator, next, value)) {
791
47.8k
        mxPushUndefined();
792
47.8k
        mxPushSlot(extra);
793
47.8k
        mxCall();
794
47.8k
        mxPushSlot(value);
795
47.8k
        mxPushSlot(counter);
796
47.8k
        mxRunCount(2);
797
47.8k
        fxGetIteratorFlattenable(the, the->stack, innerIterator, innerNext, 0);
798
47.8k
        mxPop();
799
47.8k
        counter->value.integer++;
800
47.8k
      }
801
18
      else
802
18
        return 0;
803
47.8k
    }
804
48.0k
    if (fxIteratorNext(the, innerIterator, innerNext, value))
805
221
      return 1;
806
47.8k
    innerIterator->kind = XS_NULL_KIND;
807
47.8k
    innerNext->kind = XS_NULL_KIND;
808
47.8k
    goto again;
809
48.0k
  }
810
13
  else if (status == XS_RETURN_STATUS) {
811
2
    if (!mxIsNull(innerIterator))
812
1
      fxIteratorReturn(the, innerIterator, 0);
813
2
    fxIteratorReturn(the, iterator, 0);
814
2
  }
815
11
  else if (status == XS_THROW_STATUS) {
816
11
    if (!mxIsNull(innerIterator))
817
2
      fxIteratorReturn(the, innerIterator, 1);
818
11
    fxIteratorReturn(the, iterator, 1);
819
11
  }
820
13
  return 0;
821
261
}
822
823
void fx_Iterator_prototype_forEach(txMachine* the)
824
16
{ 
825
16
  txSlot *iterator, *procedure, *next, *value;
826
16
  txInteger counter;
827
16
  if (!fxGetInstance(the, mxThis))
828
3
    mxTypeError("this: not an object");
829
13
  iterator = mxThis;
830
13
  {
831
13
    mxTry(the) {
832
13
      if (mxArgc > 0)
833
11
        mxPushSlot(mxArgv(0));
834
2
      else
835
2
        mxPushUndefined();
836
13
      procedure = the->stack;
837
13
      if (!fxIsCallable(the, procedure))
838
4
        mxTypeError("procedure: not a function");
839
13
    }
840
9
    mxCatch(the) {
841
4
      fxIteratorReturn(the, iterator, 1);
842
4
      fxJump(the);
843
4
    }
844
13
  }
845
5
  mxPushSlot(iterator);
846
5
  mxGetID(mxID(_next));
847
5
  next = the->stack;
848
5
  mxTemporary(value);
849
5
  counter = 0;
850
5
  {
851
9
    mxTry(the) {
852
19
      while (fxIteratorNext(the, iterator, next, value)) {
853
10
        mxPushUndefined();
854
10
        mxPushSlot(procedure);
855
10
        mxCall();
856
10
        mxPushSlot(value);
857
10
        mxPushInteger(counter);
858
10
        mxRunCount(2);
859
10
        mxPop();
860
10
        counter++;
861
10
      }
862
9
    }
863
18.4E
    mxCatch(the) {
864
2
      fxIteratorReturn(the, iterator, 1);
865
2
      fxJump(the);
866
2
    }
867
5
  }
868
3
  mxPop();
869
3
  mxPop();
870
3
  mxPop();
871
3
}
872
873
void fx_Iterator_prototype_iterator(txMachine* the)
874
31.9k
{
875
31.9k
  *mxResult = *mxThis;
876
31.9k
}
877
878
void fx_Iterator_prototype_map(txMachine* the)
879
25
{ 
880
25
  txSlot *iterator, *mapper, *property;
881
25
  if (!fxGetInstance(the, mxThis))
882
3
    mxTypeError("this: not an object");
883
22
  iterator = mxThis;
884
22
  {
885
22
    mxTry(the) {
886
22
      if (mxArgc > 0)
887
20
        mxPushSlot(mxArgv(0));
888
2
      else
889
2
        mxPushUndefined();
890
22
      mapper = the->stack;
891
22
      if (!fxIsCallable(the, mapper))
892
5
        mxTypeError("mapper: not a function");
893
22
    }
894
17
    mxCatch(the) {
895
5
      fxIteratorReturn(the, iterator, 1);
896
5
      fxJump(the);
897
5
    }
898
22
  }
899
12
  property = fxLastProperty(the, fxNewIteratorHelperInstance(the, iterator, mx_Iterator_prototype_map));
900
12
  property = fxNextSlotProperty(the, property, mapper, XS_NO_ID, XS_INTERNAL_FLAG);
901
12
  property = fxNextIntegerProperty(the, property, 0, XS_NO_ID, XS_INTERNAL_FLAG);
902
12
  mxPullSlot(mxResult);
903
12
  mxPop();
904
12
}
905
906
txBoolean fx_Iterator_prototype_map_step(txMachine* the, txSlot* iterator, txSlot* next, txSlot* extra, txSlot* value, txFlag status)
907
34.0k
{
908
34.0k
  txSlot* counter = extra->next;
909
34.0k
  if (status == XS_NO_STATUS) {
910
33.9k
    if (fxIteratorNext(the, iterator, next, value)) {
911
33.9k
      mxPushUndefined();
912
33.9k
      mxPushSlot(extra);
913
33.9k
      mxCall();
914
33.9k
      mxPushSlot(value);
915
33.9k
      mxPushSlot(counter);
916
33.9k
      mxRunCount(2);
917
33.9k
      mxPullSlot(value);
918
33.9k
      counter->value.integer++;
919
33.9k
      return 1;
920
33.9k
    }
921
33.9k
  }
922
3
  else if (status == XS_RETURN_STATUS)
923
1
    fxIteratorReturn(the, iterator, 0);
924
2
  else if (status == XS_THROW_STATUS)
925
2
    fxIteratorReturn(the, iterator, 1);
926
13
  return 0;
927
34.0k
}
928
929
void fx_Iterator_prototype_reduce(txMachine* the)
930
33
{ 
931
33
  txSlot *iterator, *reducer, *next, *value;
932
33
  txInteger counter;
933
33
  if (!fxGetInstance(the, mxThis))
934
9
    mxTypeError("this: not an object");
935
24
  iterator = mxThis;
936
24
  {
937
24
    mxTry(the) {
938
24
      if (mxArgc > 0)
939
23
        mxPushSlot(mxArgv(0));
940
1
      else
941
1
        mxPushUndefined();
942
24
      reducer = the->stack;
943
24
      if (!fxIsCallable(the, reducer))
944
5
        mxTypeError("reducer: not a function");
945
24
    }
946
19
    mxCatch(the) {
947
5
      fxIteratorReturn(the, iterator, 1);
948
5
      fxJump(the);
949
5
    }
950
24
  }
951
14
  mxPushSlot(iterator);
952
14
  mxGetID(mxID(_next));
953
14
  next = the->stack;
954
14
  mxTemporary(value);
955
14
  if (mxArgc > 1) {
956
8
    mxPushSlot(mxArgv(1));
957
8
    counter = 0;
958
8
  }
959
6
  else {
960
6
    mxPushUndefined();
961
6
    if (!fxIteratorNext(the, iterator, next, the->stack))
962
1
      mxTypeError("no initial value");
963
5
    counter = 1;
964
5
  }
965
13
  mxPullSlot(mxResult);
966
13
  {
967
18
    mxTry(the) {
968
35.1k
      while (fxIteratorNext(the, iterator, next, value)) {
969
35.1k
        mxPushUndefined();
970
35.1k
        mxPushSlot(reducer);
971
35.1k
        mxCall();
972
35.1k
        mxPushSlot(mxResult);
973
35.1k
        mxPushSlot(value);
974
35.1k
        mxPushInteger(counter);
975
35.1k
        mxRunCount(3);
976
35.1k
        mxPullSlot(mxResult);
977
35.1k
        counter++;
978
35.1k
      }
979
18
    }
980
18.4E
    mxCatch(the) {
981
2
      fxIteratorReturn(the, iterator, 1);
982
2
      fxJump(the);
983
2
    }
984
13
  }
985
11
  mxPop();
986
11
  mxPop();
987
11
  mxPop();
988
11
}
989
990
void fx_Iterator_prototype_some(txMachine* the)
991
17
{ 
992
17
  txSlot *iterator, *predicate, *next, *value;
993
17
  txInteger counter;
994
17
  if (!fxGetInstance(the, mxThis))
995
3
    mxTypeError("this: not an object");
996
14
  iterator = mxThis;
997
14
  {
998
14
    mxTry(the) {
999
14
      if (mxArgc > 0)
1000
13
        mxPushSlot(mxArgv(0));
1001
1
      else
1002
1
        mxPushUndefined();
1003
14
      predicate = the->stack;
1004
14
      if (!fxIsCallable(the, predicate))
1005
3
        mxTypeError("predicate: not a function");
1006
14
    }
1007
11
    mxCatch(the) {
1008
3
      fxIteratorReturn(the, iterator, 1);
1009
3
      fxJump(the);
1010
3
    }
1011
14
  }
1012
8
  mxPushSlot(iterator);
1013
8
  mxGetID(mxID(_next));
1014
8
  next = the->stack;
1015
8
  mxTemporary(value);
1016
8
  counter = 0;
1017
8
  mxResult->kind = XS_BOOLEAN_KIND;
1018
8
  mxResult->value.boolean = 0;
1019
8
  {
1020
11
    mxTry(the) {
1021
34
      while (fxIteratorNext(the, iterator, next, value)) {
1022
25
        mxPushUndefined();
1023
25
        mxPushSlot(predicate);
1024
25
        mxCall();
1025
25
        mxPushSlot(value);
1026
25
        mxPushInteger(counter);
1027
25
        mxRunCount(2);
1028
25
        mxResult->value.boolean = fxToBoolean(the, the->stack);
1029
25
        mxPop();
1030
25
        if (mxResult->value.boolean) {
1031
2
          fxIteratorReturn(the, iterator, 0);
1032
2
          break;
1033
2
        }
1034
23
        counter++;
1035
23
      }
1036
11
    }
1037
18.4E
    mxCatch(the) {
1038
3
      fxIteratorReturn(the, iterator, 1);
1039
3
      fxJump(the);
1040
3
    }
1041
8
  }
1042
5
  mxPop();
1043
5
  mxPop();
1044
5
  mxPop();
1045
5
}
1046
1047
void fx_Iterator_prototype_take(txMachine* the)
1048
28.7k
{ 
1049
28.7k
  txSlot *iterator, *property;
1050
28.7k
  txNumber limit;
1051
28.7k
  if (!fxGetInstance(the, mxThis))
1052
6
    mxTypeError("this: not an object");
1053
28.7k
  iterator = mxThis;
1054
28.7k
  {
1055
28.7k
    mxTry(the) {
1056
28.7k
      if (mxArgc > 0)
1057
28.7k
        mxPushSlot(mxArgv(0));
1058
3
      else
1059
3
        mxPushUndefined();
1060
28.7k
      limit = fxToNumber(the, the->stack);
1061
28.7k
      if (c_isnan(limit))
1062
12
        mxRangeError("limit: NaN");
1063
28.7k
      if (c_isfinite(limit))
1064
28.7k
        limit = c_trunc(limit);
1065
28.7k
      if (limit < 0)
1066
13
        mxRangeError("limit: < 0");
1067
28.7k
    }
1068
28.7k
    mxCatch(the) {
1069
26
      fxIteratorReturn(the, iterator, 1);
1070
26
      fxJump(the);
1071
26
    }
1072
28.7k
  }
1073
28.6k
  property = fxLastProperty(the, fxNewIteratorHelperInstance(the, iterator, mx_Iterator_prototype_take));
1074
28.6k
  property = fxNextNumberProperty(the, property, limit, XS_NO_ID, XS_INTERNAL_FLAG);
1075
28.6k
  mxPullSlot(mxResult);
1076
28.6k
  mxPop();
1077
28.6k
}
1078
1079
txBoolean fx_Iterator_prototype_take_step(txMachine* the, txSlot* iterator, txSlot* next, txSlot* extra, txSlot* value, txFlag status)
1080
28.6k
{
1081
28.6k
  txNumber remaining = extra->value.number;
1082
28.6k
  if (status == XS_NO_STATUS) {
1083
28.6k
    if (remaining == 0) {
1084
7
      fxIteratorReturn(the, iterator, 0);
1085
7
      return 0;
1086
7
    }
1087
28.6k
    if (c_isfinite(remaining)) {
1088
28.6k
      remaining--;
1089
28.6k
      extra->value.number = remaining;
1090
28.6k
    }
1091
28.6k
    if (fxIteratorNext(the, iterator, next, value))
1092
12
      return 1;
1093
28.6k
  }
1094
28
  else if (status == XS_RETURN_STATUS)
1095
18
    fxIteratorReturn(the, iterator, 0);
1096
10
  else if (status == XS_THROW_STATUS)
1097
10
    fxIteratorReturn(the, iterator, 1);
1098
28.6k
  return 0;
1099
28.6k
}
1100
1101
void fx_Iterator_prototype_toArray(txMachine* the)
1102
13
{ 
1103
13
  txSlot *iterator, *next, *value, *instance, *internal, *item;
1104
13
  if (!fxGetInstance(the, mxThis))
1105
3
    mxTypeError("this: not an object");
1106
10
  iterator = mxThis;
1107
10
  mxPushSlot(iterator);
1108
10
  mxGetID(mxID(_next));
1109
10
  next = the->stack;
1110
10
  mxTemporary(value);
1111
10
  mxPush(mxArrayPrototype);
1112
10
  instance = fxNewArrayInstance(the);
1113
10
  mxPullSlot(mxResult);
1114
10
  internal = instance->next;
1115
10
  item = internal;
1116
178k
  while (fxIteratorNext(the, iterator, next, value)) {
1117
178k
    internal->value.array.length++;
1118
178k
    item->next = fxNewSlot(the);
1119
178k
    item = item->next;
1120
178k
    item->kind = value->kind;
1121
178k
    item->value = value->value;
1122
178k
  }
1123
10
  fxCacheArray(the, instance);
1124
10
  mxPop();
1125
10
  mxPop();
1126
10
}
1127
1128
void fx_Iterator_prototype_toStringTag_get(txMachine* the)
1129
24
{ 
1130
24
  mxPushStringC("Iterator");
1131
24
  mxPullSlot(mxResult);
1132
24
}
1133
1134
void fx_Iterator_prototype_toStringTag_set(txMachine* the)
1135
27
{ 
1136
27
  fxSetterThatIgnoresPrototypeProperties(the, mxThis, mxID(_Symbol_toStringTag), "Symbol(toStringTag)", mxArgv(0));
1137
27
}
1138
1139
txSlot* fxNewIteratorHelperInstance(txMachine* the, txSlot* iterator, txInteger step) 
1140
30.5k
{
1141
30.5k
  txSlot* instance;
1142
30.5k
  txSlot* property;
1143
30.5k
  mxPush(mxIteratorHelperPrototype);
1144
30.5k
  instance = fxNewIteratorInstance(the, iterator, mxID(_Iterator));
1145
30.5k
  property = fxLastProperty(the, instance);
1146
30.5k
  property->ID = gxIteratorStepIDs[step];
1147
30.5k
  property->value.integer = step;
1148
30.5k
  if (mxIsNull(iterator))
1149
35
    property = fxNextNullProperty(the, property, XS_NO_ID, XS_INTERNAL_FLAG);
1150
30.4k
  else {
1151
30.4k
    mxPushSlot(iterator);
1152
30.4k
    mxGetID(mxID(_next));
1153
30.4k
    property = fxNextSlotProperty(the, property, the->stack, XS_NO_ID, XS_INTERNAL_FLAG);
1154
30.4k
    mxPop();
1155
30.4k
  }
1156
30.5k
  return instance;
1157
30.5k
}
1158
1159
void fx_IteratorHelper_prototype_next(txMachine* the)
1160
99.5k
{
1161
99.5k
  txSlot* instance = fxCheckIteratorInstance(the, mxThis, mxID(_Iterator));
1162
99.5k
  txSlot* result = instance->next;
1163
99.5k
  txSlot* iterator = result->next;
1164
99.5k
  txSlot* step = fxCheckIteratorStep(the, iterator->next);
1165
99.5k
  txSlot* next = step->next;
1166
99.5k
  txSlot* extra = next->next;
1167
99.5k
  txSlot* value = fxCheckIteratorResult(the, result);
1168
99.5k
  txSlot* done = value->next;
1169
99.5k
  if (step->flag & XS_DONT_SET_FLAG)
1170
1
    mxTypeError("recursive iterator");
1171
99.5k
  {
1172
99.5k
    mxTry(the) {
1173
99.5k
      step->flag |= XS_DONT_SET_FLAG;
1174
99.5k
      if (!done->value.boolean) {
1175
99.5k
        if (!(*gxIteratorSteps[step->value.integer])(the, iterator, next, extra, value, XS_NO_STATUS)) {
1176
28.7k
          value->kind = XS_UNDEFINED_KIND;
1177
28.7k
          done->value.boolean = 1;
1178
28.7k
        }
1179
99.5k
      }
1180
99.5k
      mxResult->kind = result->kind;
1181
99.5k
      mxResult->value = result->value;
1182
99.5k
      step->flag &= ~XS_DONT_SET_FLAG;
1183
99.5k
    }
1184
99.5k
    mxCatch(the) {
1185
40
      step->flag &= ~XS_DONT_SET_FLAG;
1186
40
      value->kind = XS_UNDEFINED_KIND;
1187
40
      done->value.boolean = 1;
1188
40
      (*gxIteratorSteps[step->value.integer])(the, iterator, next, extra, value, XS_THROW_STATUS);
1189
40
      fxJump(the);
1190
40
    }
1191
99.5k
  }
1192
99.5k
}
1193
1194
void fx_IteratorHelper_prototype_return(txMachine* the)
1195
62
{
1196
62
  txSlot* instance = fxCheckIteratorInstance(the, mxThis, mxID(_Iterator));
1197
62
  txSlot* result = instance->next;
1198
62
  txSlot* iterator = result->next;
1199
62
  txSlot* step = fxCheckIteratorStep(the, iterator->next);
1200
62
  txSlot* next = step->next;
1201
62
  txSlot* extra = next->next;
1202
62
  txSlot* value = fxCheckIteratorResult(the, result);
1203
62
  txSlot* done = value->next;
1204
62
  if (step->flag & XS_DONT_SET_FLAG)
1205
1
    mxTypeError("recursive iterator");
1206
61
  {
1207
61
    mxTry(the) {
1208
61
      step->flag |= XS_DONT_SET_FLAG;
1209
61
      if (!done->value.boolean) {
1210
40
        value->kind = XS_UNDEFINED_KIND;
1211
40
        done->value.boolean = 1;
1212
40
        (*gxIteratorSteps[step->value.integer])(the, iterator, next, extra, value, XS_RETURN_STATUS);
1213
40
      }
1214
61
      mxResult->kind = result->kind;
1215
61
      mxResult->value = result->value;
1216
61
      step->flag &= ~XS_DONT_SET_FLAG;
1217
61
    }
1218
61
    mxCatch(the) {
1219
2
      step->flag &= ~XS_DONT_SET_FLAG;
1220
2
      fxJump(the);
1221
2
    }
1222
61
  }
1223
61
}
1224
1225
void fx_IteratorWrapper_prototype_next(txMachine* the)
1226
172k
{
1227
172k
  txSlot* instance = fxCheckIteratorInstance(the, mxThis, mxID(_Iterator));
1228
172k
  txSlot* result = instance->next;
1229
172k
  txSlot* iterator = result->next;
1230
172k
  txSlot* step = iterator->next;
1231
172k
  txSlot* next = step->next;
1232
172k
  mxPushSlot(iterator);
1233
172k
  mxPushSlot(next);
1234
172k
  mxCall();
1235
172k
  mxRunCount(0);
1236
172k
  mxPullSlot(mxResult);
1237
172k
}
1238
1239
void fx_IteratorWrapper_prototype_return(txMachine* the)
1240
2
{
1241
2
  txSlot* instance = fxCheckIteratorInstance(the, mxThis, mxID(_Iterator));
1242
2
  txSlot* result = instance->next;
1243
2
  txSlot* iterator = result->next;
1244
2
  txSlot* value = fxCheckIteratorResult(the, result);
1245
2
  txSlot* done = value->next;
1246
2
  mxPushSlot(iterator);
1247
2
  mxDub();
1248
2
  mxGetID(mxID(_return));
1249
2
  if (mxIsUndefined(the->stack) || mxIsNull(the->stack)) {
1250
1
    mxPop();
1251
1
    value->kind = XS_UNDEFINED_KIND;
1252
1
    done->value.boolean = 1;
1253
1
    mxResult->kind = result->kind;
1254
1
    mxResult->value = result->value;
1255
1
  }
1256
1
  else {
1257
1
    mxCall();
1258
1
    mxRunCount(0);
1259
1
    mxPullSlot(mxResult);
1260
1
  }
1261
2
}
1262
1263
txSlot* fxCheckGeneratorInstance(txMachine* the, txSlot* slot)
1264
197k
{
1265
197k
  if (slot->kind == XS_REFERENCE_KIND) {
1266
197k
    txSlot* instance = slot->value.reference;
1267
197k
    slot = instance->next;
1268
197k
    if (slot && (slot->flag & XS_INTERNAL_FLAG) && (slot->kind == XS_STACK_KIND))
1269
197k
      return instance;
1270
197k
  }
1271
197k
  mxTypeError("this: not a Generator instance");
1272
0
  return C_NULL;
1273
197k
}
1274
1275
txSlot* fxNewGeneratorInstance(txMachine* the)
1276
2.29M
{
1277
2.29M
  txSlot* prototype;
1278
2.29M
  txSlot* instance;
1279
2.29M
  txSlot* property;
1280
1281
2.29M
  prototype = (the->stack->kind == XS_REFERENCE_KIND) ? the->stack->value.reference : mxGeneratorPrototype.value.reference;
1282
1283
2.29M
  instance = fxNewSlot(the);
1284
2.29M
  instance->kind = XS_INSTANCE_KIND;
1285
2.29M
  instance->value.instance.garbage = C_NULL;
1286
2.29M
  instance->value.instance.prototype = prototype;
1287
2.29M
  the->stack->value.reference = instance;
1288
2.29M
  the->stack->kind = XS_REFERENCE_KIND;
1289
1290
2.29M
  property = instance->next = fxNewSlot(the);
1291
2.29M
  property->flag = XS_INTERNAL_FLAG;
1292
2.29M
  property->kind = XS_STACK_KIND;
1293
2.29M
  property->ID = XS_NO_ID;
1294
2.29M
    property->value.stack.length = 0;
1295
2.29M
    property->value.stack.address = C_NULL;
1296
  
1297
2.29M
    property = property->next = fxNewSlot(the);
1298
2.29M
  property->flag = XS_INTERNAL_FLAG;
1299
2.29M
  property->kind = XS_INTEGER_KIND;
1300
2.29M
  property->value.integer = XS_CODE_START_GENERATOR;
1301
  
1302
2.29M
  return instance;
1303
2.29M
}
1304
1305
void fxNewGeneratorResult(txMachine* the, txBoolean done)
1306
28.8k
{
1307
28.8k
  txSlot* value = the->stack;
1308
28.8k
  txSlot* slot;
1309
28.8k
  mxPush(mxObjectPrototype);
1310
28.8k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
1311
28.8k
  slot = fxNextSlotProperty(the, slot, value, mxID(_value), XS_DONT_DELETE_FLAG | XS_DONT_SET_FLAG);
1312
28.8k
  slot = fxNextBooleanProperty(the, slot, done, mxID(_done), XS_DONT_DELETE_FLAG | XS_DONT_SET_FLAG);
1313
28.8k
  mxPullSlot(value);
1314
28.8k
}
1315
1316
void fx_Generator(txMachine* the)
1317
0
{
1318
0
  if (mxHasTarget)
1319
0
    mxTypeError("new: Generator");
1320
0
}
1321
1322
void fx_Generator_prototype_aux(txMachine* the, txFlag status)
1323
197k
{
1324
197k
  txSlot* generator = fxCheckGeneratorInstance(the, mxThis);
1325
197k
  txSlot* stack = generator->next;
1326
197k
  txSlot* state = stack->next;
1327
1328
197k
  if (state->value.integer == XS_NO_CODE)
1329
3
    mxTypeError("generator is running");
1330
197k
  if ((state->value.integer == XS_CODE_START_GENERATOR) && (status != XS_NO_STATUS))
1331
28
    state->value.integer = XS_CODE_END;
1332
197k
  if (mxArgc > 0)
1333
9
    mxPushSlot(mxArgv(0));
1334
197k
  else
1335
197k
    mxPushUndefined();
1336
197k
  if (state->value.integer == XS_CODE_END) {
1337
75
    if (status == XS_THROW_STATUS) {
1338
2
      mxException.kind = the->stack->kind;
1339
2
      mxException.value = the->stack->value;
1340
2
      fxJump(the);
1341
2
    }
1342
73
    if (status == XS_NO_STATUS)
1343
17
      the->stack->kind = XS_UNDEFINED_KIND;
1344
73
    fxNewGeneratorResult(the, 1);
1345
73
    mxPullSlot(mxResult);
1346
73
  }
1347
197k
  else {
1348
197k
    mxTry(the) {
1349
197k
      the->scratch.kind = the->stack->kind;
1350
197k
      the->scratch.value = the->stack->value;
1351
197k
      the->status = status;
1352
197k
      state->value.integer = XS_NO_CODE;
1353
197k
      fxRunID(the, generator, XS_NO_ID);
1354
197k
      if (state->value.integer == XS_NO_CODE) {
1355
28.7k
        state->value.integer = XS_CODE_END;
1356
28.7k
        fxNewGeneratorResult(the, 1);
1357
28.7k
      }
1358
197k
      mxPullSlot(mxResult);
1359
197k
    }
1360
197k
    mxCatch(the) {
1361
14
      state->value.integer = XS_CODE_END;
1362
14
      fxJump(the);
1363
14
    }
1364
197k
  }
1365
197k
}
1366
1367
void fx_Generator_prototype_next(txMachine* the)
1368
197k
{
1369
197k
  fx_Generator_prototype_aux(the, XS_NO_STATUS);
1370
197k
}
1371
1372
void fx_Generator_prototype_return(txMachine* the)
1373
80
{
1374
80
  fx_Generator_prototype_aux(the, XS_RETURN_STATUS);
1375
80
}
1376
1377
void fx_Generator_prototype_throw(txMachine* the)
1378
11
{
1379
11
  fx_Generator_prototype_aux(the, XS_THROW_STATUS);
1380
11
}
1381
1382
txSlot* fxNewGeneratorFunctionInstance(txMachine* the, txID name)
1383
40.7k
{
1384
40.7k
  txSlot* instance;
1385
40.7k
  txSlot* property;
1386
1387
40.7k
  instance = fxNewFunctionInstance(the, name);
1388
40.7k
  property = fxLastProperty(the, instance);
1389
40.7k
  mxPush(mxGeneratorPrototype);
1390
40.7k
  fxNewObjectInstance(the);
1391
40.7k
  fxNextSlotProperty(the, property, the->stack, mxID(_prototype), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG);
1392
40.7k
  mxPop();
1393
  
1394
40.7k
  return instance;
1395
40.7k
}
1396
1397
void fx_GeneratorFunction(txMachine* the)
1398
25
{ 
1399
25
  txInteger c, i;
1400
25
  txStringStream stream;
1401
25
  txSlot* module = mxFunctionInstanceHome(mxFunction->value.reference)->value.home.module;
1402
25
  if (!module) module = mxProgram.value.reference;
1403
  
1404
25
  c = mxArgc;
1405
25
  i = 0;
1406
25
  mxPushStringX("(function* anonymous(");
1407
46
  while (c > 1) {
1408
21
    fxToString(the, mxArgv(i));
1409
21
    fxConcatString(the, the->stack, mxArgv(i));
1410
21
    if (c > 2)
1411
11
      fxConcatStringC(the, the->stack, ", ");
1412
21
    c--;
1413
21
    i++;
1414
21
  }
1415
25
  fxConcatStringC(the, the->stack, "\n){");
1416
25
  if (c > 0) {
1417
16
    fxToString(the, mxArgv(i));
1418
16
    fxConcatString(the, the->stack, mxArgv(i));
1419
16
  }
1420
25
  fxConcatStringC(the, the->stack, "\n})");
1421
25
  stream.slot = the->stack;
1422
25
  stream.offset = 0;
1423
25
  stream.size = mxStringLength(the->stack->value.string);
1424
25
  fxRunScript(the, fxParseScript(the, &stream, fxStringGetter, mxProgramFlag | mxGeneratorFlag), C_NULL, C_NULL, C_NULL, C_NULL, module);
1425
25
  mxPullSlot(mxResult);
1426
25
  if (mxHasTarget && !fxIsSameSlot(the, mxTarget, mxFunction)) {
1427
0
    mxPushSlot(mxTarget);
1428
0
    fxGetPrototypeFromConstructor(the, &mxGeneratorFunctionPrototype);
1429
0
    mxResult->value.reference->value.instance.prototype = the->stack->value.reference;
1430
0
    mxPop();
1431
0
  }
1432
25
}
1433
1434
void fx_Enumerator(txMachine* the)
1435
386k
{
1436
386k
  txSlot* iterator;
1437
386k
  txSlot* result;
1438
386k
  txSlot* slot;
1439
386k
  txSlot* keys;
1440
386k
  txSlot* visited;
1441
  
1442
386k
  mxPush(mxEnumeratorFunction);
1443
386k
  mxGetID(mxID(_prototype));
1444
386k
  iterator = fxNewObjectInstance(the);
1445
386k
  mxPullSlot(mxResult);
1446
386k
  mxPush(mxObjectPrototype);
1447
386k
  result = fxNewObjectInstance(the);
1448
386k
  slot = fxNextUndefinedProperty(the, result, mxID(_value), XS_DONT_DELETE_FLAG | XS_DONT_SET_FLAG);
1449
386k
  slot = fxNextBooleanProperty(the, slot, 0, mxID(_done), XS_DONT_DELETE_FLAG | XS_DONT_SET_FLAG);
1450
386k
  slot = fxNextSlotProperty(the, iterator, the->stack, mxID(_result), XS_GET_ONLY);
1451
386k
  mxPop();
1452
  
1453
386k
  slot = slot->next = fxNewSlot(the);
1454
386k
  slot->flag = XS_GET_ONLY;
1455
386k
  slot->ID = mxID(_iterable);
1456
386k
  slot->kind = mxThis->kind;
1457
386k
  slot->value = mxThis->value;
1458
386k
  if (mxIsUndefined(slot) || mxIsNull(slot))
1459
34.5k
    return;
1460
352k
  fxToInstance(the, slot);
1461
    
1462
352k
  keys = fxNewInstance(the);
1463
352k
  mxBehaviorOwnKeys(the, slot->value.reference, XS_EACH_NAME_FLAG, keys);
1464
352k
  slot = slot->next = fxNewSlot(the);
1465
352k
  slot->flag = XS_GET_ONLY;
1466
352k
  slot->kind = XS_REFERENCE_KIND;
1467
352k
  slot->value.reference = keys;
1468
352k
  mxPop();
1469
  
1470
352k
  visited = fxNewInstance(the);
1471
352k
  slot = slot->next = fxNewSlot(the);
1472
352k
  slot->flag = XS_GET_ONLY;
1473
352k
  slot->kind = XS_REFERENCE_KIND;
1474
352k
  slot->value.reference = visited;
1475
352k
  mxPop();
1476
352k
}
1477
1478
void fx_Enumerator_prototype_next(txMachine* the)
1479
8.23M
{
1480
8.23M
  txSlot* iterator = fxGetInstance(the, mxThis);
1481
8.23M
  txSlot* result = iterator->next;
1482
8.23M
  txSlot* iterable = result->next;
1483
8.23M
  txSlot* at = C_NULL;
1484
8.23M
  if (mxIsReference(iterable)) {
1485
8.20M
    txSlot* instance = iterable->value.reference;
1486
8.20M
    txSlot* keys = iterable->next;
1487
8.20M
    txSlot* visited = keys->next;
1488
8.20M
    txSlot* slot;
1489
8.20M
    txSlot* former;
1490
  
1491
8.20M
    keys = keys->value.reference;
1492
8.20M
    visited = visited->value.reference;
1493
  
1494
8.20M
    mxPushUndefined();
1495
8.20M
    slot = the->stack;
1496
8.91M
  again:  
1497
18.8M
    while ((at = keys->next)) {
1498
17.7M
      if (mxBehaviorGetOwnProperty(the, instance, at->value.at.id, at->value.at.index, slot)) {
1499
17.7M
        txSlot** address = &(visited->next);
1500
2.95G
        while ((former = *address)) {
1501
2.94G
          if ((at->value.at.id == former->value.at.id) && (at->value.at.index == former->value.at.index))
1502
1.17M
            break;
1503
2.93G
          address = &(former->next);
1504
2.93G
        }
1505
17.7M
        if (!former) {
1506
16.5M
          *address = at;
1507
16.5M
          keys->next = at->next;
1508
16.5M
          at->next = NULL;
1509
16.5M
          if (!(slot->flag & XS_DONT_ENUM_FLAG)) {
1510
7.85M
            fxKeyAt(the, at->value.at.id, at->value.at.index, result->value.reference->next);
1511
7.85M
            break;
1512
7.85M
          }
1513
16.5M
        }
1514
1.17M
        else
1515
1.17M
          keys->next = at->next;
1516
17.7M
      }
1517
1
      else
1518
1
        keys->next = at->next;
1519
17.7M
    }
1520
8.91M
    if (!at) {
1521
1.06M
      if (mxBehaviorGetPrototype(the, instance, slot)) {
1522
714k
        iterable->value.reference = instance = slot->value.reference;
1523
714k
        mxBehaviorOwnKeys(the, instance, XS_EACH_NAME_FLAG, keys);
1524
714k
        goto again;
1525
714k
      }
1526
1.06M
    }
1527
8.20M
    mxPop();
1528
8.20M
  }
1529
8.23M
  if (!at) {
1530
384k
    result->value.reference->next->kind = XS_UNDEFINED_KIND;
1531
384k
    result->value.reference->next->next->value.boolean = 1;
1532
384k
  }
1533
8.23M
  mxResult->kind = result->kind;
1534
8.23M
  mxResult->value = result->value;
1535
8.23M
}
1536
1537
void fx_AsyncIterator_prototype_asyncDispose(txMachine* the)
1538
2
{ 
1539
2
  mxTry(the) {
1540
2
    mxPushUndefined();
1541
2
    mxPush(mxPromiseConstructor);
1542
2
    mxPushSlot(mxThis);
1543
2
    mxDub();
1544
2
    mxGetID(mxID(_return));
1545
2
    if (mxIsUndefined(the->stack)) {
1546
1
      mxPop();
1547
1
      the->stack->kind = XS_UNDEFINED_KIND;
1548
1
    }
1549
1
    else {
1550
1
      mxCall();
1551
1
      mxRunCount(0);    
1552
1
    }
1553
2
    fx_Promise_resolveAux(the);
1554
2
    mxPop();
1555
2
    mxPop();
1556
2
    mxPullSlot(mxResult);
1557
2
  }
1558
2
  mxCatch(the) {
1559
0
    txSlot* resolveFunction;
1560
0
    txSlot* rejectFunction;
1561
0
    mxTemporary(resolveFunction);
1562
0
    mxTemporary(rejectFunction);
1563
0
    mxPush(mxPromiseConstructor);
1564
0
    fxNewPromiseCapability(the, resolveFunction, rejectFunction);
1565
0
    mxPullSlot(mxResult);
1566
0
    fxRejectException(the, rejectFunction);
1567
0
  }
1568
2
}
1569
1570
void fx_AsyncIterator_prototype_asyncIterator(txMachine* the)
1571
13
{
1572
13
  *mxResult = *mxThis;
1573
13
}
1574
1575
void fxAsyncGeneratorRejectAwait(txMachine* the)
1576
1
{
1577
1
  txSlot* slot = mxFunctionInstanceHome(mxFunction->value.reference);
1578
1
  txSlot* generator = slot->value.home.object;
1579
1
  the->scratch.kind = mxArgv(0)->kind;
1580
1
  the->scratch.value = mxArgv(0)->value;
1581
1
  fxAsyncGeneratorStep(the, generator, XS_THROW_STATUS);
1582
1
}
1583
1584
void fxAsyncGeneratorRejectYield(txMachine* the)
1585
14
{
1586
14
  txSlot* home = mxFunctionInstanceHome(mxFunction->value.reference);
1587
14
  txSlot* generator = home->value.home.object;
1588
14
  txSlot* stack = generator->next;
1589
14
  txSlot* state = stack->next;
1590
14
  if (state->value.integer == XS_CODE_END) {
1591
13
    txSlot* queue = state->next;
1592
13
    txSlot* current = queue->value.list.first;
1593
13
    txSlot* resolveFunction = current->value.reference->next;
1594
13
    txSlot* rejectFunction = resolveFunction->next;
1595
1596
13
    mxPushUndefined();
1597
13
    mxPushSlot(rejectFunction);
1598
13
    mxCall();
1599
13
    mxPushSlot(mxArgv(0));
1600
  
1601
13
    queue->value.list.first = current = current->next;
1602
13
    if (current == C_NULL)
1603
9
      queue->value.list.last = C_NULL;
1604
  
1605
13
    mxRunCount(1);
1606
13
    mxPop();
1607
  
1608
13
    if (current) {
1609
4
      txSlot* resolveFunction = current->value.reference->next;
1610
4
      txSlot* rejectFunction = resolveFunction->next;
1611
4
      txSlot* status = rejectFunction->next;
1612
4
      txSlot* value = status->next;
1613
4
      the->scratch.kind = value->kind;
1614
4
      the->scratch.value = value->value;
1615
4
      fxAsyncGeneratorStep(the, generator, status->value.integer);
1616
4
    }
1617
13
  }
1618
1
  else {
1619
1
    mxPushSlot(mxArgv(0));
1620
1
    mxPull(the->scratch);
1621
1
    fxAsyncGeneratorStep(the, generator, XS_THROW_STATUS);
1622
1
  }
1623
14
}
1624
1625
void fxAsyncGeneratorResolveAwait(txMachine* the)
1626
6
{
1627
6
  txSlot* slot = mxFunctionInstanceHome(mxFunction->value.reference);
1628
6
  txSlot* generator = slot->value.home.object;
1629
6
  the->scratch.kind = mxArgv(0)->kind;
1630
6
  the->scratch.value = mxArgv(0)->value;
1631
6
  fxAsyncGeneratorStep(the, generator, XS_NO_STATUS);
1632
6
}
1633
1634
void fxAsyncGeneratorResolveYield(txMachine* the)
1635
27
{
1636
27
  txSlot* home = mxFunctionInstanceHome(mxFunction->value.reference);
1637
27
  txSlot* generator = home->value.home.object;
1638
27
  txSlot* stack = generator->next;
1639
27
  txSlot* state = stack->next;
1640
27
  txSlot* queue = state->next;
1641
27
  txSlot* current = queue->value.list.first;
1642
27
  if (current) {
1643
27
    txSlot* resolveFunction = current->value.reference->next;
1644
  
1645
27
    mxPushUndefined();
1646
27
    mxPushSlot(resolveFunction);
1647
27
    mxCall();
1648
27
    mxPushSlot(mxArgv(0));
1649
27
    fxNewGeneratorResult(the, (state->value.integer == XS_CODE_END) ? 1 : 0);
1650
  
1651
27
    queue->value.list.first = current = current->next;
1652
27
    if (current == C_NULL)
1653
21
      queue->value.list.last = C_NULL;
1654
  
1655
27
    mxRunCount(1);
1656
27
    mxPop();
1657
27
  }
1658
  
1659
27
  if (current) {
1660
6
    txSlot* resolveFunction = current->value.reference->next;
1661
6
    txSlot* rejectFunction = resolveFunction->next;
1662
6
    txSlot* status = rejectFunction->next;
1663
6
    txSlot* value = status->next;
1664
6
    the->scratch.kind = value->kind;
1665
6
    the->scratch.value = value->value;
1666
6
    fxAsyncGeneratorStep(the, generator, status->value.integer);
1667
6
  }
1668
27
}
1669
1670
void fxAsyncGeneratorStep(txMachine* the, txSlot* generator, txFlag status)
1671
2.93k
{
1672
2.93k
  txSlot* stack = generator->next;
1673
2.93k
  txSlot* state = stack->next;
1674
2.93k
  txSlot* queue = state->next;
1675
2.93k
  txSlot* resolveAwaitFunction = queue->next;
1676
2.93k
  txSlot* rejectAwaitFunction = resolveAwaitFunction->next;
1677
2.93k
  txSlot* resolveYieldFunction = rejectAwaitFunction->next;
1678
2.93k
  txSlot* rejectYieldFunction = resolveYieldFunction->next;
1679
2.93k
  txSlot* resolveFunction;
1680
2.93k
  txSlot* rejectFunction;
1681
2.93k
  txSlot* value;
1682
  
1683
2.93k
  mxTry(the) {
1684
2.93k
    if (state->value.integer == XS_CODE_END) {
1685
16
      mxPush(the->scratch);
1686
16
      value = the->stack;
1687
16
      mxTemporary(resolveFunction);
1688
16
      mxTemporary(rejectFunction);
1689
16
      mxPush(mxPromiseConstructor);
1690
16
      fxNewPromiseCapability(the, resolveFunction, rejectFunction);
1691
16
            fxPromiseThen(the, the->stack->value.reference, resolveYieldFunction, rejectYieldFunction, C_NULL, C_NULL);
1692
      /* THIS */
1693
16
      mxPushUndefined();
1694
      /* FUNCTION */
1695
16
      if (status == XS_THROW_STATUS)
1696
1
        mxPushSlot(rejectFunction);
1697
15
      else
1698
15
        mxPushSlot(resolveFunction);
1699
16
      mxCall();
1700
      /* ARGUMENTS */
1701
16
      mxPushSlot(value);
1702
16
      mxRunCount(1);
1703
16
      mxPop();
1704
16
    }
1705
2.92k
    else {
1706
2.92k
      the->status = status;
1707
2.92k
      status = XS_NO_STATUS;
1708
2.92k
      state->value.integer = XS_NO_CODE;
1709
2.92k
      fxRunID(the, generator, XS_NO_ID);
1710
2.92k
      if (state->value.integer == XS_NO_CODE)
1711
7
        state->value.integer = XS_CODE_END;
1712
2.92k
      value = the->stack;
1713
2.92k
      if (state->value.integer == XS_CODE_END) {
1714
7
        txSlot* current = queue->value.list.first;
1715
7
        if (current) {
1716
7
          if (value->kind == XS_UNINITIALIZED_KIND)
1717
6
            value->kind = XS_UNDEFINED_KIND;
1718
7
          mxPushUndefined();
1719
7
          if (status == XS_THROW_STATUS)
1720
0
            mxPushSlot(rejectYieldFunction);
1721
7
          else
1722
7
            mxPushSlot(resolveYieldFunction);
1723
7
          mxCall();
1724
7
          mxPushSlot(value);
1725
7
          mxRunCount(1);
1726
7
          mxPop();
1727
7
        }
1728
7
      }
1729
2.91k
      else if (state->value.integer == XS_CODE_AWAIT) {
1730
9
        mxPushUndefined();
1731
9
        mxPush(mxPromiseConstructor);
1732
9
        mxPushSlot(value);
1733
9
        fx_Promise_resolveAux(the);
1734
9
        mxPop();
1735
9
        mxPop();
1736
9
        fxPromiseThen(the, the->stack->value.reference, resolveAwaitFunction, rejectAwaitFunction, C_NULL, C_NULL);
1737
9
      }
1738
2.90k
      else if (state->value.integer == XS_CODE_YIELD) {
1739
8
        mxPushUndefined();
1740
8
        mxPush(mxPromiseConstructor);
1741
8
        mxPushSlot(value);
1742
8
        fx_Promise_resolveAux(the);
1743
8
        mxPop();
1744
8
        mxPop();
1745
8
        fxPromiseThen(the, the->stack->value.reference, resolveYieldFunction, rejectYieldFunction, C_NULL, C_NULL);
1746
8
      }
1747
2.89k
      else if (state->value.integer == XS_CODE_YIELD_STAR) {
1748
1
        txSlot* current = queue->value.list.first;
1749
1
        if (current) {
1750
1
          mxPushUndefined();
1751
1
          mxPushSlot(resolveYieldFunction);
1752
1
          mxCall();
1753
1
          mxPushSlot(value);
1754
1
          mxRunCount(1);
1755
1
          mxPop();
1756
1
        }
1757
1
      }
1758
2.92k
    }
1759
2.93k
    mxPop();
1760
2.93k
  }
1761
2.93k
  mxCatch(the) {
1762
16
    mxTemporary(resolveFunction);
1763
16
    mxTemporary(rejectFunction);
1764
16
    mxPush(mxPromiseConstructor);
1765
16
    fxNewPromiseCapability(the, resolveFunction, rejectFunction);
1766
16
        if (state->value.integer == XS_CODE_AWAIT) {
1767
0
            fxPromiseThen(the, the->stack->value.reference, resolveAwaitFunction, rejectAwaitFunction, C_NULL, C_NULL);
1768
0
        }
1769
16
        else {
1770
16
      state->value.integer = XS_CODE_END;
1771
16
            fxPromiseThen(the, the->stack->value.reference, resolveYieldFunction, rejectYieldFunction, C_NULL, C_NULL);
1772
16
        }
1773
16
        fxRejectException(the, rejectFunction);
1774
16
  }
1775
2.93k
}
1776
1777
txSlot* fxCheckAsyncGeneratorInstance(txMachine* the, txSlot* slot)
1778
2.97k
{
1779
2.97k
  if (slot->kind == XS_REFERENCE_KIND) {
1780
2.96k
    txSlot* instance = slot->value.reference;
1781
2.96k
    slot = instance->next;
1782
2.96k
    if (slot && (slot->flag & XS_INTERNAL_FLAG) && (slot->kind == XS_STACK_KIND)) {
1783
2.93k
      slot = slot->next;
1784
2.93k
      if (slot && (slot->flag & XS_INTERNAL_FLAG) && (slot->kind == XS_INTEGER_KIND)) {
1785
2.93k
        slot = slot->next;
1786
2.93k
        if (slot && (slot->flag & XS_INTERNAL_FLAG) && (slot->kind == XS_LIST_KIND)) {
1787
2.93k
          return instance;
1788
2.93k
        }
1789
2.93k
      }
1790
2.93k
    }
1791
2.96k
  }
1792
2.97k
  mxTypeError("this: not an AsyncGenerator instance");
1793
0
  return C_NULL;
1794
2.97k
}
1795
1796
txSlot* fxNewAsyncGeneratorInstance(txMachine* the)
1797
11.3k
{
1798
11.3k
  txSlot* prototype;
1799
11.3k
  txSlot* instance;
1800
11.3k
  txSlot* property;
1801
11.3k
  txSlot* function;
1802
11.3k
  txSlot* home;
1803
1804
11.3k
  prototype = (the->stack->kind == XS_REFERENCE_KIND) ? the->stack->value.reference : mxAsyncGeneratorPrototype.value.reference;
1805
1806
11.3k
  instance = fxNewSlot(the);
1807
11.3k
  instance->kind = XS_INSTANCE_KIND;
1808
11.3k
  instance->value.instance.garbage = C_NULL;
1809
11.3k
  instance->value.instance.prototype = prototype;
1810
11.3k
  the->stack->value.reference = instance;
1811
11.3k
  the->stack->kind = XS_REFERENCE_KIND;
1812
1813
11.3k
  property = instance->next = fxNewSlot(the);
1814
11.3k
  property->flag = XS_INTERNAL_FLAG;
1815
11.3k
  property->kind = XS_STACK_KIND;
1816
11.3k
  property->ID = XS_NO_ID;
1817
11.3k
    property->value.stack.length = 0;
1818
11.3k
    property->value.stack.address = C_NULL;
1819
  
1820
11.3k
    property = property->next = fxNewSlot(the);
1821
11.3k
  property->flag = XS_INTERNAL_FLAG;
1822
11.3k
  property->kind = XS_INTEGER_KIND;
1823
11.3k
  property->value.integer = XS_CODE_START_ASYNC_GENERATOR;
1824
  
1825
11.3k
    property = property->next = fxNewSlot(the);
1826
11.3k
  property->flag = XS_INTERNAL_FLAG;
1827
11.3k
  property->kind = XS_LIST_KIND;
1828
11.3k
  property->value.list.first = C_NULL;
1829
11.3k
  property->value.list.last = C_NULL;
1830
  
1831
11.3k
  function = fxNewHostFunction(the, fxAsyncGeneratorResolveAwait, 1, XS_NO_ID, mxAsyncGeneratorResolveAwaitProfileID);
1832
11.3k
  home = mxFunctionInstanceHome(function);
1833
11.3k
  home->value.home.object = instance;
1834
11.3k
    property = fxNextSlotProperty(the, property, the->stack, XS_NO_ID, XS_INTERNAL_FLAG);
1835
11.3k
  mxPop();
1836
  
1837
11.3k
  function = fxNewHostFunction(the, fxAsyncGeneratorRejectAwait, 1, XS_NO_ID, mxAsyncGeneratorRejectAwaitProfileID);
1838
11.3k
  home = mxFunctionInstanceHome(function);
1839
11.3k
  home->value.home.object = instance;
1840
11.3k
    property = fxNextSlotProperty(the, property, the->stack, XS_NO_ID, XS_INTERNAL_FLAG);
1841
11.3k
  mxPop();
1842
  
1843
11.3k
  function = fxNewHostFunction(the, fxAsyncGeneratorResolveYield, 1, XS_NO_ID, mxAsyncGeneratorResolveYieldProfileID);
1844
11.3k
  home = mxFunctionInstanceHome(function);
1845
11.3k
  home->value.home.object = instance;
1846
11.3k
    property = fxNextSlotProperty(the, property, the->stack, XS_NO_ID, XS_INTERNAL_FLAG);
1847
11.3k
  mxPop();
1848
  
1849
11.3k
  function = fxNewHostFunction(the, fxAsyncGeneratorRejectYield, 1, XS_NO_ID, mxAsyncGeneratorRejectYieldProfileID);
1850
11.3k
  home = mxFunctionInstanceHome(function);
1851
11.3k
  home->value.home.object = instance;
1852
11.3k
    property = fxNextSlotProperty(the, property, the->stack, XS_NO_ID, XS_INTERNAL_FLAG);
1853
11.3k
  mxPop();
1854
  
1855
11.3k
  return instance;
1856
11.3k
}
1857
1858
1859
void fx_AsyncGenerator(txMachine* the)
1860
0
{
1861
0
  if (mxHasTarget)
1862
0
    mxTypeError("new: AsyncGenerator");
1863
0
}
1864
1865
void fx_AsyncGenerator_prototype_aux(txMachine* the, txFlag status)
1866
2.97k
{
1867
2.97k
  txSlot* stack = the->stack;
1868
2.97k
  txSlot* resolveFunction;
1869
2.97k
  txSlot* rejectFunction;
1870
2.97k
  txSlot* slot;
1871
2.97k
  txSlot* generator;
1872
2.97k
  txSlot* state;
1873
2.97k
  txSlot* queue;
1874
2.97k
  txSlot* instance;
1875
2.97k
  txSlot* property;
1876
  
1877
2.97k
  mxTemporary(resolveFunction);
1878
2.97k
  mxTemporary(rejectFunction);
1879
2.97k
  mxPush(mxPromiseConstructor);
1880
2.97k
  fxNewPromiseCapability(the, resolveFunction, rejectFunction);
1881
2.97k
  mxPullSlot(mxResult);
1882
#ifdef mxPromisePrint
1883
  fprintf(stderr, "fx_AsyncGenerator_prototype_aux %d\n", mxResult->value.reference->next->ID);
1884
#endif
1885
2.97k
  {
1886
2.97k
    mxTry(the) {
1887
2.97k
      generator = fxCheckAsyncGeneratorInstance(the, mxThis);
1888
2.97k
      state = generator->next->next;
1889
2.97k
      if (((status == XS_RETURN_STATUS) || (status == XS_THROW_STATUS)) && (state->value.integer == XS_CODE_START_ASYNC_GENERATOR))
1890
6
        state->value.integer = XS_CODE_END;
1891
2.97k
      instance = property = fxNewInstance(the);
1892
2.97k
      property = fxNextSlotProperty(the, property, resolveFunction, XS_NO_ID, XS_INTERNAL_FLAG);
1893
2.97k
      property = fxNextSlotProperty(the, property, rejectFunction, XS_NO_ID, XS_INTERNAL_FLAG);
1894
2.97k
      property = fxNextIntegerProperty(the, property, status, XS_NO_ID, XS_INTERNAL_FLAG);
1895
2.97k
      if (mxArgc > 0)
1896
8
        property = fxNextSlotProperty(the, property, mxArgv(0), XS_NO_ID, XS_INTERNAL_FLAG);
1897
2.96k
      else
1898
2.96k
        property = fxNextUndefinedProperty(the, property, XS_NO_ID, XS_INTERNAL_FLAG);
1899
2.97k
      slot = fxNewSlot(the);
1900
2.97k
      slot->kind = XS_REFERENCE_KIND;
1901
2.97k
      slot->value.reference = instance;
1902
2.97k
      queue = state->next;
1903
2.97k
      if (queue->value.list.first) {
1904
12
        queue->value.list.last->next = slot;
1905
12
        queue->value.list.last = slot;
1906
12
      }
1907
2.96k
      else {
1908
2.96k
        queue->value.list.first = slot;
1909
2.96k
        queue->value.list.last = slot;
1910
2.96k
        if (state->value.integer != XS_CODE_AWAIT) {
1911
2.92k
          the->scratch.kind = property->kind;
1912
2.92k
          the->scratch.value = property->value;
1913
2.92k
          fxAsyncGeneratorStep(the, generator, status);
1914
2.92k
        }
1915
2.96k
      }
1916
2.97k
    }
1917
2.97k
    mxCatch(the) {
1918
41
      fxRejectException(the, rejectFunction);
1919
41
    }
1920
2.97k
  }
1921
2.97k
  the->stack = stack;
1922
2.97k
}
1923
1924
void fx_AsyncGenerator_prototype_next(txMachine* the)
1925
2.94k
{
1926
2.94k
  fx_AsyncGenerator_prototype_aux(the, XS_NO_STATUS);
1927
2.94k
}
1928
1929
void fx_AsyncGenerator_prototype_return(txMachine* the)
1930
18
{
1931
18
  fx_AsyncGenerator_prototype_aux(the, XS_RETURN_STATUS);
1932
18
}
1933
1934
void fx_AsyncGenerator_prototype_throw(txMachine* the)
1935
12
{
1936
12
  fx_AsyncGenerator_prototype_aux(the, XS_THROW_STATUS);
1937
12
}
1938
1939
txSlot* fxNewAsyncGeneratorFunctionInstance(txMachine* the, txID name)
1940
2.21k
{
1941
2.21k
  txSlot* instance;
1942
2.21k
  txSlot* property;
1943
1944
2.21k
  instance = fxNewFunctionInstance(the, name);
1945
2.21k
  property = fxLastProperty(the, instance);
1946
2.21k
  mxPush(mxAsyncGeneratorPrototype);
1947
2.21k
  fxNewObjectInstance(the);
1948
2.21k
  fxNextSlotProperty(the, property, the->stack, mxID(_prototype), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG);
1949
2.21k
  mxPop();
1950
  
1951
2.21k
  return instance;
1952
2.21k
}
1953
1954
void fx_AsyncGeneratorFunction(txMachine* the)
1955
21
{ 
1956
21
  txInteger c, i;
1957
21
  txStringStream stream;
1958
21
  txSlot* module = mxFunctionInstanceHome(mxFunction->value.reference)->value.home.module;
1959
21
  if (!module) module = mxProgram.value.reference;
1960
  
1961
21
  c = mxArgc;
1962
21
  i = 0;
1963
21
  mxPushStringX("(async function* anonymous(");
1964
38
  while (c > 1) {
1965
17
    fxToString(the, mxArgv(i));
1966
17
    fxConcatString(the, the->stack, mxArgv(i));
1967
17
    if (c > 2)
1968
7
      fxConcatStringC(the, the->stack, ", ");
1969
17
    c--;
1970
17
    i++;
1971
17
  }
1972
21
  fxConcatStringC(the, the->stack, "\n){");
1973
21
  if (c > 0) {
1974
15
    fxToString(the, mxArgv(i));
1975
15
    fxConcatString(the, the->stack, mxArgv(i));
1976
15
  }
1977
21
  fxConcatStringC(the, the->stack, "\n})");
1978
21
  stream.slot = the->stack;
1979
21
  stream.offset = 0;
1980
21
  stream.size = mxStringLength(the->stack->value.string);
1981
21
  fxRunScript(the, fxParseScript(the, &stream, fxStringGetter, mxProgramFlag | mxGeneratorFlag), C_NULL, C_NULL, C_NULL, C_NULL, module);
1982
21
  mxPullSlot(mxResult);
1983
21
  if (mxHasTarget && !fxIsSameSlot(the, mxTarget, mxFunction)) {
1984
0
    mxPushSlot(mxTarget);
1985
0
    fxGetPrototypeFromConstructor(the, &mxAsyncGeneratorFunctionPrototype);
1986
0
    mxResult->value.reference->value.instance.prototype = the->stack->value.reference;
1987
0
    mxPop();
1988
0
  }
1989
21
}
1990
1991
void fxAsyncFromSyncIteratorDone(txMachine* the)
1992
4
{
1993
4
  txSlot* slot = mxFunctionInstanceHome(mxFunction->value.reference);
1994
4
  txSlot* instance = slot->value.home.object;
1995
4
  txSlot* iterator = instance->next;
1996
4
  txSlot* nextFunction = iterator->next;
1997
4
  txSlot* doneFunction = nextFunction->next;
1998
4
  txSlot* doneFlag = doneFunction->next;
1999
4
  mxPushSlot(mxArgv(0));
2000
4
  fxNewGeneratorResult(the, doneFlag->value.boolean);
2001
4
  mxPullSlot(mxResult);
2002
4
}
2003
2004
void fxAsyncFromSyncIteratorFailed(txMachine* the)
2005
0
{
2006
0
  txSlot* slot = mxFunctionInstanceHome(mxFunction->value.reference);
2007
0
  txSlot* instance = slot->value.home.object;
2008
0
  txSlot* iterator = instance->next;
2009
0
  mxTry(the) {
2010
0
    mxPushSlot(iterator);
2011
0
    mxPushSlot(iterator);
2012
0
    mxGetID(mxID(_return));
2013
0
    if (!mxIsUndefined(the->stack) && !mxIsNull(the->stack)) {
2014
0
      mxCall();
2015
0
      mxRunCount(0);
2016
0
    }
2017
0
    mxPop();
2018
0
  }
2019
0
  mxCatch(the) {
2020
0
  }
2021
0
  mxException.kind = mxArgv(0)->kind;
2022
0
  mxException.value = mxArgv(0)->value;
2023
0
  fxThrow(the, NULL, 0);
2024
0
}
2025
2026
txSlot* fxCheckAsyncFromSyncIteratorInstance(txMachine* the, txSlot* slot)
2027
8
{
2028
8
  if (slot->kind == XS_REFERENCE_KIND) {
2029
8
    txSlot* instance = slot->value.reference;
2030
8
    slot = instance->next;
2031
8
    if (slot && (slot->flag & XS_INTERNAL_FLAG) && (slot->ID == mxID(_iterator)))
2032
8
      return instance;
2033
8
  }
2034
8
  mxTypeError("this: not an AsyncFromSyncIterator instance");
2035
0
  return C_NULL;
2036
8
}
2037
2038
txSlot* fxNewAsyncFromSyncIteratorInstance(txMachine* the)
2039
7
{
2040
7
  txSlot* iterator = the->stack;
2041
7
  txSlot* instance;
2042
7
  txSlot* slot;
2043
7
  txSlot* function;
2044
7
  txSlot* home;
2045
7
  mxPush(mxAsyncFromSyncIteratorPrototype);
2046
7
  instance = fxNewObjectInstance(the);
2047
7
  slot = fxLastProperty(the, instance);
2048
  
2049
7
  slot = fxNextSlotProperty(the, slot, iterator, mxID(_iterator), XS_INTERNAL_FLAG);
2050
2051
7
  mxPushSlot(iterator);
2052
7
  mxGetID(mxID(_next));
2053
7
  slot = fxNextSlotProperty(the, slot, the->stack, XS_NO_ID, XS_INTERNAL_FLAG);
2054
7
  mxPop();
2055
  
2056
7
  function = fxNewHostFunction(the, fxAsyncFromSyncIteratorDone, 1, XS_NO_ID, mxAsyncFromSyncIteratorDoneProfileID);
2057
7
  home = mxFunctionInstanceHome(function);
2058
7
  home->value.home.object = instance;
2059
7
    slot = fxNextSlotProperty(the, slot, the->stack, XS_NO_ID, XS_INTERNAL_FLAG);
2060
7
  mxPop();
2061
  
2062
7
    slot = fxNextBooleanProperty(the, slot, 0, XS_NO_ID, XS_INTERNAL_FLAG);
2063
    
2064
7
  function = fxNewHostFunction(the, fxAsyncFromSyncIteratorFailed, 1, XS_NO_ID, mxAsyncFromSyncIteratorDoneProfileID);
2065
7
  home = mxFunctionInstanceHome(function);
2066
7
  home->value.home.object = instance;
2067
7
    slot = fxNextSlotProperty(the, slot, the->stack, XS_NO_ID, XS_INTERNAL_FLAG);
2068
7
  mxPop();
2069
2070
7
  mxPullSlot(iterator);
2071
7
  return instance;
2072
7
}
2073
2074
void fx_AsyncFromSyncIterator_prototype_aux(txMachine* the, txFlag status, txSlot* iterator, txBoolean* flag)
2075
8
{
2076
8
  txSlot* stack = the->stack;
2077
8
  txSlot* resolveFunction;
2078
8
    txSlot* rejectFunction;
2079
8
  txSlot* slot;
2080
8
  txSlot* stepFunction = C_NULL;
2081
  
2082
8
  mxTemporary(resolveFunction);
2083
8
  mxTemporary(rejectFunction);
2084
8
  mxPush(mxPromiseConstructor);
2085
8
  fxNewPromiseCapability(the, resolveFunction, rejectFunction);
2086
8
  mxPullSlot(mxResult);
2087
#ifdef mxPromisePrint
2088
  fprintf(stderr, "fx_AsyncFromSyncIterator_prototype_aux %d %d\n", mxResult->value.reference->next->ID, status);
2089
#endif
2090
8
    {
2091
8
    mxTry(the) {
2092
8
      if (status == XS_NO_STATUS) {
2093
7
        stepFunction = iterator->next;
2094
7
      }
2095
1
      else if (status == XS_RETURN_STATUS) {
2096
1
        mxPushSlot(iterator);
2097
1
        mxGetID(mxID(_return));
2098
1
        if (mxIsUndefined(the->stack) || mxIsNull(the->stack)) {
2099
0
          mxPushUndefined();
2100
0
          mxPushSlot(resolveFunction);
2101
0
          mxCall();
2102
0
          mxPushUndefined();
2103
0
          fxNewGeneratorResult(the, 1);
2104
0
          mxRunCount(1);
2105
0
        }
2106
1
        else
2107
1
          stepFunction = the->stack;
2108
1
      }
2109
0
      else {
2110
0
        mxPushSlot(iterator);
2111
0
        mxGetID(mxID(_throw));
2112
0
        if (mxIsUndefined(the->stack) || mxIsNull(the->stack)) {
2113
0
          *flag = 0;
2114
0
          fxIteratorReturn(the, iterator, 0);
2115
0
          mxTypeError("no throw");
2116
0
        }
2117
0
        else
2118
0
          stepFunction = the->stack;
2119
0
      }
2120
8
      if (stepFunction) {
2121
8
        txSlot* doneFunction = iterator->next->next;
2122
8
        txSlot* doneFlag = doneFunction->next;
2123
8
        txSlot* failedFunction = doneFlag->next;
2124
8
        mxPushSlot(iterator);
2125
8
        mxPushSlot(stepFunction);
2126
8
        mxCall();
2127
8
        if (mxArgc == 0)
2128
3
          mxRunCount(0);
2129
5
        else {
2130
5
          mxPushSlot(mxArgv(0));
2131
5
          mxRunCount(1);
2132
5
        }
2133
8
        slot = the->stack;
2134
8
                if (!mxIsReference(slot)) {
2135
0
                    mxTypeError("iterator result: not an object");
2136
0
                }
2137
2138
8
        mxPushSlot(slot);
2139
8
        mxGetID(mxID(_done));
2140
8
        doneFlag->value.boolean = fxToBoolean(the, the->stack);
2141
2142
8
        mxPushUndefined();
2143
8
        mxPush(mxPromiseConstructor);
2144
8
        mxPushSlot(slot);
2145
8
        mxGetID(mxID(_value));
2146
8
        fx_Promise_resolveAux(the);
2147
8
        mxPop();
2148
8
        mxPop();
2149
8
        fxPromiseThen(the, the->stack->value.reference, doneFunction, failedFunction, resolveFunction, rejectFunction);
2150
8
      }
2151
8
    }
2152
8
    mxCatch(the) {
2153
1
      if (*flag)
2154
1
        fxIteratorReturn(the, iterator, 1);
2155
1
      fxRejectException(the, rejectFunction);
2156
1
    }
2157
8
    }
2158
8
  the->stack = stack;
2159
8
}
2160
2161
void fx_AsyncFromSyncIterator_prototype_next(txMachine* the)
2162
7
{
2163
7
  txBoolean flag = 1;
2164
7
  txSlot* instance = fxCheckAsyncFromSyncIteratorInstance(the, mxThis);
2165
7
  fx_AsyncFromSyncIterator_prototype_aux(the, XS_NO_STATUS, instance->next, &flag);
2166
7
}
2167
2168
void fx_AsyncFromSyncIterator_prototype_return(txMachine* the)
2169
1
{
2170
1
  txBoolean flag = 1;
2171
1
  txSlot* instance = fxCheckAsyncFromSyncIteratorInstance(the, mxThis);
2172
1
  fx_AsyncFromSyncIterator_prototype_aux(the, XS_RETURN_STATUS, instance->next, &flag);
2173
1
}
2174
2175
void fx_AsyncFromSyncIterator_prototype_throw(txMachine* the)
2176
0
{
2177
0
  txBoolean flag = 1;
2178
0
  txSlot* instance = fxCheckAsyncFromSyncIteratorInstance(the, mxThis);
2179
0
  fx_AsyncFromSyncIterator_prototype_aux(the, XS_THROW_STATUS, instance->next, &flag);
2180
0
}
2181
2182