Coverage Report

Created: 2026-01-17 06:27

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