Coverage Report

Created: 2025-06-13 06:17

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