Coverage Report

Created: 2025-10-28 07:21

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