Coverage Report

Created: 2026-08-31 06:30

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