Coverage Report

Created: 2025-11-24 06:36

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/moddable/xs/sources/xsError.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2016-2025  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
static txSlot* fx_Error_aux(txMachine* the, txError error, txInteger i);
41
42
const int gxErrorWhichPrototypeStackIndex[XS_ERROR_COUNT] ICACHE_FLASH_ATTR = {
43
  mxErrorPrototypeStackIndex,
44
  mxErrorPrototypeStackIndex,
45
  mxEvalErrorPrototypeStackIndex,
46
  mxRangeErrorPrototypeStackIndex,
47
  mxReferenceErrorPrototypeStackIndex,
48
  mxSyntaxErrorPrototypeStackIndex,
49
  mxTypeErrorPrototypeStackIndex,
50
  mxURIErrorPrototypeStackIndex,
51
  mxAggregateErrorPrototypeStackIndex,
52
#if mxExplicitResourceManagement
53
  mxSuppressedErrorPrototypeStackIndex,
54
#else
55
  mxErrorPrototypeStackIndex,
56
#endif
57
};
58
59
const char *const gxErrorNames[XS_ERROR_COUNT] ICACHE_FLASH_ATTR = {
60
  "no error",
61
  "Error",
62
  "EvalError",
63
  "RangeError",
64
  "ReferenceError",
65
  "SyntaxError",
66
  "TypeError",
67
  "URIError",
68
  "AggregateError",
69
  "SuppressedError"
70
};
71
72
void fxBuildError(txMachine* the)
73
6.38k
{
74
6.38k
  txSlot* slot;
75
6.38k
  txSlot* prototype;
76
6.38k
  txSlot* instance;
77
6.38k
#if mxExplicitResourceManagement
78
6.38k
  txSlot* property;
79
6.38k
#endif
80
  
81
6.38k
  mxPush(mxObjectPrototype);
82
6.38k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
83
6.38k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Error_toString), 0, mxID(_toString), XS_DONT_ENUM_FLAG);
84
6.38k
  slot = fxNextStringXProperty(the, slot, (txString)gxErrorNames[XS_UNKNOWN_ERROR], mxID(_name), XS_DONT_ENUM_FLAG);
85
6.38k
  slot = fxNextStringXProperty(the, slot, "", mxID(_message), XS_DONT_ENUM_FLAG);
86
6.38k
  slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_Error_prototype_get_stack), mxCallback(fx_Error_prototype_set_stack), mxID(_stack), XS_DONT_ENUM_FLAG);
87
6.38k
  mxErrorPrototype = *the->stack;
88
6.38k
  prototype = fxBuildHostConstructor(the, mxCallback(fx_Error), 1, mxID(_Error));
89
6.38k
  mxErrorConstructor = *the->stack;
90
6.38k
#if mxErrorIsError
91
6.38k
  slot = fxLastProperty(the, prototype);
92
6.38k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Error_isError), 1, mxID(_isError), XS_DONT_ENUM_FLAG);
93
6.38k
#endif
94
6.38k
  mxPop();
95
6.38k
  mxPush(mxErrorPrototype);
96
6.38k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
97
6.38k
  slot = fxNextStringXProperty(the, slot, (txString)gxErrorNames[XS_AGGREGATE_ERROR], mxID(_name), XS_DONT_ENUM_FLAG);
98
6.38k
  slot = fxNextStringXProperty(the, slot, "", mxID(_message), XS_DONT_ENUM_FLAG);
99
6.38k
  mxAggregateErrorPrototype = *the->stack;
100
6.38k
  instance = fxBuildHostConstructor(the, mxCallback(fx_AggregateError), 2, mxID(_AggregateError));
101
6.38k
  instance->value.instance.prototype = prototype;
102
6.38k
  mxAggregateErrorConstructor = *the->stack;
103
6.38k
  mxPop();
104
6.38k
  mxPush(mxErrorPrototype);
105
6.38k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
106
6.38k
  slot = fxNextStringXProperty(the, slot, (txString)gxErrorNames[XS_EVAL_ERROR], mxID(_name), XS_DONT_ENUM_FLAG);
107
6.38k
  slot = fxNextStringXProperty(the, slot, "", mxID(_message), XS_DONT_ENUM_FLAG);
108
6.38k
  mxEvalErrorPrototype = *the->stack;
109
6.38k
  instance = fxBuildHostConstructor(the, mxCallback(fx_EvalError), 1, mxID(_EvalError));
110
6.38k
  instance->value.instance.prototype = prototype;
111
6.38k
  mxEvalErrorConstructor = *the->stack;
112
6.38k
  mxPop();
113
6.38k
  mxPush(mxErrorPrototype);
114
6.38k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
115
6.38k
  slot = fxNextStringXProperty(the, slot, (txString)gxErrorNames[XS_RANGE_ERROR], mxID(_name), XS_DONT_ENUM_FLAG);
116
6.38k
  slot = fxNextStringXProperty(the, slot, "", mxID(_message), XS_DONT_ENUM_FLAG);
117
6.38k
  mxRangeErrorPrototype = *the->stack;
118
6.38k
  instance = fxBuildHostConstructor(the, mxCallback(fx_RangeError), 1, mxID(_RangeError));
119
6.38k
  instance->value.instance.prototype = prototype;
120
6.38k
  mxRangeErrorConstructor = *the->stack;
121
6.38k
  mxPop();
122
6.38k
  mxPush(mxErrorPrototype);
123
6.38k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
124
6.38k
  slot = fxNextStringXProperty(the, slot, (txString)gxErrorNames[XS_REFERENCE_ERROR], mxID(_name), XS_DONT_ENUM_FLAG);
125
6.38k
  slot = fxNextStringXProperty(the, slot, "", mxID(_message), XS_DONT_ENUM_FLAG);
126
6.38k
  mxReferenceErrorPrototype = *the->stack;
127
6.38k
  instance = fxBuildHostConstructor(the, mxCallback(fx_ReferenceError), 1, mxID(_ReferenceError));
128
6.38k
  instance->value.instance.prototype = prototype;
129
6.38k
  mxReferenceErrorConstructor = *the->stack;
130
6.38k
  mxPop();
131
6.38k
  mxPush(mxErrorPrototype);
132
6.38k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
133
6.38k
  slot = fxNextStringXProperty(the, slot, (txString)gxErrorNames[XS_SYNTAX_ERROR], mxID(_name), XS_DONT_ENUM_FLAG);
134
6.38k
  slot = fxNextStringXProperty(the, slot, "", mxID(_message), XS_DONT_ENUM_FLAG);
135
6.38k
  mxSyntaxErrorPrototype = *the->stack;
136
6.38k
  instance = fxBuildHostConstructor(the, mxCallback(fx_SyntaxError), 1, mxID(_SyntaxError));
137
6.38k
  instance->value.instance.prototype = prototype;
138
6.38k
  mxSyntaxErrorConstructor = *the->stack;
139
6.38k
  mxPop();
140
6.38k
  mxPush(mxErrorPrototype);
141
6.38k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
142
6.38k
  slot = fxNextStringXProperty(the, slot, (txString)gxErrorNames[XS_TYPE_ERROR], mxID(_name), XS_DONT_ENUM_FLAG);
143
6.38k
  slot = fxNextStringXProperty(the, slot, "", mxID(_message), XS_DONT_ENUM_FLAG);
144
6.38k
  mxTypeErrorPrototype = *the->stack;
145
6.38k
  instance = fxBuildHostConstructor(the, mxCallback(fx_TypeError), 1, mxID(_TypeError));
146
6.38k
  instance->value.instance.prototype = prototype;
147
6.38k
  mxTypeErrorConstructor = *the->stack;
148
6.38k
  mxPop();
149
6.38k
  mxPush(mxErrorPrototype);
150
6.38k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
151
6.38k
  slot = fxNextStringXProperty(the, slot, (txString)gxErrorNames[XS_URI_ERROR], mxID(_name), XS_DONT_ENUM_FLAG);
152
6.38k
  slot = fxNextStringXProperty(the, slot, "", mxID(_message), XS_DONT_ENUM_FLAG);
153
6.38k
  mxURIErrorPrototype = *the->stack;
154
6.38k
  instance = fxBuildHostConstructor(the, mxCallback(fx_URIError), 1, mxID(_URIError));
155
6.38k
  instance->value.instance.prototype = prototype;
156
6.38k
  mxURIErrorConstructor = *the->stack;
157
6.38k
  mxPop();
158
159
6.38k
#if mxExplicitResourceManagement
160
6.38k
  mxPush(mxErrorPrototype);
161
6.38k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
162
6.38k
  slot = fxNextStringXProperty(the, slot, (txString)gxErrorNames[XS_SUPPRESSED_ERROR], mxID(_name), XS_DONT_ENUM_FLAG);
163
6.38k
  slot = fxNextStringXProperty(the, slot, "", mxID(_message), XS_DONT_ENUM_FLAG);
164
6.38k
  mxSuppressedErrorPrototype = *the->stack;
165
6.38k
  instance = fxBuildHostConstructor(the, mxCallback(fx_SuppressedError), 3, mxID(_SuppressedError));
166
6.38k
  instance->value.instance.prototype = prototype;
167
6.38k
  mxSuppressedErrorConstructor = *the->stack;
168
6.38k
  mxPop();
169
170
6.38k
  mxPush(mxObjectPrototype);
171
6.38k
    slot = fxLastProperty(the, fxNewObjectInstance(the));
172
6.38k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Error_toString), 0, mxID(_toString), XS_DONT_ENUM_FLAG);
173
6.38k
  slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_DisposableStack_prototype_get_disposed), C_NULL, mxID(_disposed), XS_DONT_ENUM_FLAG);
174
6.38k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DisposableStack_prototype_adopt), 2, mxID(_adopt), XS_DONT_ENUM_FLAG);
175
6.38k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DisposableStack_prototype_defer), 1, mxID(_defer), XS_DONT_ENUM_FLAG);
176
6.38k
  property = slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DisposableStack_prototype_dispose), 0, mxID(_dispose), XS_DONT_ENUM_FLAG);
177
6.38k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DisposableStack_prototype_move), 0, mxID(_move), XS_DONT_ENUM_FLAG);
178
6.38k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DisposableStack_prototype_use), 1, mxID(_use), XS_DONT_ENUM_FLAG);
179
6.38k
  slot = fxNextSlotProperty(the, slot, property, mxID(_Symbol_dispose), XS_DONT_ENUM_FLAG);
180
6.38k
  slot = fxNextStringXProperty(the, slot, "DisposableStack", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
181
6.38k
  mxDisposableStackPrototype = *the->stack;
182
6.38k
  slot = fxBuildHostConstructor(the, mxCallback(fx_DisposableStack), 0, mxID(_DisposableStack));
183
6.38k
  mxDisposableStackConstructor = *the->stack;
184
6.38k
  mxPop();
185
  
186
6.38k
  mxPush(mxObjectPrototype);
187
6.38k
    slot = fxLastProperty(the, fxNewObjectInstance(the));
188
6.38k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Error_toString), 0, mxID(_toString), XS_DONT_ENUM_FLAG);
189
6.38k
  slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_AsyncDisposableStack_prototype_get_disposed), C_NULL, mxID(_disposed), XS_DONT_ENUM_FLAG);
190
6.38k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_AsyncDisposableStack_prototype_adopt), 2, mxID(_adopt), XS_DONT_ENUM_FLAG);
191
6.38k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_AsyncDisposableStack_prototype_defer), 1, mxID(_defer), XS_DONT_ENUM_FLAG);
192
6.38k
  property = slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_AsyncDisposableStack_prototype_disposeAsync), 0, mxID(_disposeAsync), XS_DONT_ENUM_FLAG);
193
6.38k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_AsyncDisposableStack_prototype_move), 0, mxID(_move), XS_DONT_ENUM_FLAG);
194
6.38k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_AsyncDisposableStack_prototype_use), 1, mxID(_use), XS_DONT_ENUM_FLAG);
195
6.38k
  slot = fxNextSlotProperty(the, slot, property, mxID(_Symbol_asyncDispose), XS_DONT_ENUM_FLAG);
196
6.38k
  slot = fxNextStringXProperty(the, slot, "AsyncDisposableStack", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
197
6.38k
  mxAsyncDisposableStackPrototype = *the->stack;
198
6.38k
  slot = fxBuildHostConstructor(the, mxCallback(fx_AsyncDisposableStack), 0, mxID(_AsyncDisposableStack));
199
6.38k
  mxAsyncDisposableStackConstructor = *the->stack;
200
6.38k
  mxPop();
201
6.38k
#endif
202
6.38k
}
203
204
void fxCaptureErrorStack(txMachine* the, txSlot* internal, txSlot* frame)
205
4.75k
{
206
4.75k
  txSlot* slot = internal->value.reference = fxNewSlot(the);
207
4.75k
  slot->kind = XS_INSTANCE_KIND;
208
4.75k
  slot->value.instance.garbage = C_NULL;
209
4.75k
  slot->value.instance.prototype = C_NULL;
210
9.51k
  while (frame->next) {
211
4.75k
    txSlot* environment = mxFrameToEnvironment(frame);
212
4.75k
    txSlot* function = frame + 3; 
213
4.75k
    if (function->kind == XS_REFERENCE_KIND) {
214
4.75k
      function = function->value.reference;
215
4.75k
      if (mxIsFunction(function)) {
216
4.75k
        txSlot* name = mxBehaviorGetProperty(the, function, mxID(_name), 0, XS_OWN);
217
4.75k
        slot = slot->next = fxNewSlot(the);
218
4.75k
        slot->flag = XS_GET_ONLY;
219
4.75k
        slot->kind = XS_KEY_KIND;
220
4.75k
        slot->ID = environment->ID;
221
4.75k
        slot->value.key.string = C_NULL;
222
4.75k
        slot->value.key.sum = environment->value.environment.line;
223
4.75k
        if (name && ((name->kind == XS_STRING_KIND) || (name->kind == XS_STRING_X_KIND))) {
224
4.75k
          if (name->kind == XS_STRING_X_KIND)
225
0
            slot->kind = XS_KEY_X_KIND;
226
4.75k
          slot->value.key.string = name->value.string;
227
4.75k
        }
228
0
        else {
229
0
          txSlot* code = mxFunctionInstanceCode(function);
230
0
          if (code->ID != XS_NO_ID) {
231
0
            txSlot* key = fxGetKey(the, code->ID);
232
0
            if ((key->kind == XS_KEY_KIND) || (key->kind == XS_KEY_X_KIND)) {
233
0
              slot->value.key.string = key->value.key.string;
234
0
              slot->kind = key->kind;
235
0
            }
236
0
            else if (key->kind == XS_REFERENCE_KIND) {
237
0
              name = key->value.reference->next->next;
238
0
              if (name && ((name->kind == XS_STRING_KIND) || (name->kind == XS_STRING_X_KIND))) {
239
0
                if (name->kind == XS_STRING_X_KIND)
240
0
                  slot->kind = XS_KEY_X_KIND;
241
0
                slot->value.key.string = name->value.string;
242
0
              }
243
0
            }
244
0
          }
245
0
        }
246
4.75k
      }
247
4.75k
    }
248
4.75k
    frame = frame->next;
249
4.75k
  }
250
4.75k
}
251
252
void fx_Error(txMachine* the)
253
0
{
254
0
  fx_Error_aux(the, XS_UNKNOWN_ERROR, 0);
255
0
}
256
257
void fx_Error_isError(txMachine* the)
258
0
{
259
0
  mxResult->kind = XS_BOOLEAN_KIND;
260
0
  mxResult->value.boolean = 0;
261
0
  if (mxArgc > 0) {
262
0
    txSlot* instance = fxGetInstance(the, mxArgv(0));
263
0
    if (instance) {
264
0
      txSlot* internal = instance->next;
265
0
      if (internal && (internal->kind == XS_ERROR_KIND)) {
266
0
        mxResult->value.boolean = 1;
267
0
      }
268
0
    }
269
0
  }
270
0
}
271
272
txSlot* fx_Error_aux(txMachine* the, txError error, txInteger i)
273
0
{
274
0
  txSlot* instance;
275
0
  txSlot* slot;
276
0
  if (mxIsUndefined(mxTarget))
277
0
    mxPushSlot(mxFunction);
278
0
  else
279
0
    mxPushSlot(mxTarget);
280
0
  fxGetPrototypeFromConstructor(the, &mxErrorPrototypes(error));
281
0
  instance = fxNewObjectInstance(the);
282
0
  mxPullSlot(mxResult);
283
0
  slot = instance->next = fxNewSlot(the);
284
0
  slot->flag = XS_INTERNAL_FLAG;
285
0
  slot->kind = XS_ERROR_KIND;
286
0
  slot->value.error.info = C_NULL;
287
0
  slot->value.error.which = error;
288
0
  if (gxDefaults.captureErrorStack)
289
0
    gxDefaults.captureErrorStack(the, slot, the->frame->next);
290
0
  if ((mxArgc > i) && (mxArgv(i)->kind != XS_UNDEFINED_KIND)) {
291
0
    fxToString(the, mxArgv(i));
292
0
    slot = fxNextSlotProperty(the, slot, mxArgv(i), mxID(_message), XS_DONT_ENUM_FLAG);
293
0
  }
294
0
  i++;
295
0
  if ((mxArgc > i) && (mxArgv(i)->kind == XS_REFERENCE_KIND)) {
296
0
    if (mxBehaviorHasProperty(the, mxArgv(i)->value.reference, mxID(_cause), 0)) {
297
0
      mxPushSlot(mxArgv(i));
298
0
      mxGetID(mxID(_cause));
299
0
      slot = fxNextSlotProperty(the, slot, the->stack, mxID(_cause), XS_DONT_ENUM_FLAG);
300
0
      mxPop();
301
0
    }
302
0
  }
303
0
  return slot;
304
0
}
305
306
void fx_Error_toString(txMachine* the)
307
0
{
308
0
  txSlot* name;
309
0
  txSlot* message;
310
0
  if (mxThis->kind != XS_REFERENCE_KIND)
311
0
    mxTypeError("this: not an object");
312
0
  mxPushSlot(mxThis);
313
0
  mxGetID(mxID(_name));
314
0
  if (the->stack->kind == XS_UNDEFINED_KIND) 
315
0
    fxStringX(the, the->stack, "Error");
316
0
  else  
317
0
    fxToString(the, the->stack);
318
0
  name = the->stack;
319
0
  mxPushSlot(mxThis);
320
0
  mxGetID(mxID(_message));
321
0
  if (the->stack->kind == XS_UNDEFINED_KIND) 
322
0
    *the->stack = mxEmptyString;
323
0
  else  
324
0
    fxToString(the, the->stack);
325
0
  message = the->stack;
326
0
  if (c_isEmpty(name->value.string))
327
0
    *mxResult = *message;
328
0
  else if (c_isEmpty(message->value.string))
329
0
    *mxResult = *name;
330
0
  else {
331
0
    fxStringX(the, mxResult, "");
332
0
    fxConcatString(the, mxResult, name);
333
0
    fxConcatStringC(the, mxResult, ": ");
334
0
    fxConcatString(the, mxResult, message);
335
0
  }
336
0
  the->stack += 2;
337
0
}
338
339
void fx_AggregateError(txMachine* the)
340
0
{
341
0
  txSlot* stack = the->stack;
342
0
  txSlot* property = fx_Error_aux(the, XS_AGGREGATE_ERROR, 1);
343
0
  txSlot* array;
344
0
  txSlot** address;
345
0
  txIndex length = 0;
346
0
  txSlot* iterator;
347
0
  txSlot* next;
348
0
  txSlot* value;
349
0
  txSlot* slot;
350
  
351
0
  mxPush(mxArrayPrototype);
352
0
  array = fxNewArrayInstance(the);
353
0
  fxNextSlotProperty(the, property, the->stack, mxID(_errors), XS_DONT_ENUM_FLAG);
354
0
  address = &array->next->next;
355
0
  mxTemporary(iterator);
356
0
  mxTemporary(next);
357
0
  fxGetIterator(the, mxArgv(0), iterator, next, 0);
358
0
  mxTemporary(value);
359
0
  while (fxIteratorNext(the, iterator, next, value)) {
360
0
    mxTry(the) {
361
0
      *address = slot = fxNewSlot(the);
362
0
      slot->kind = value->kind;
363
0
      slot->value = value->value;
364
0
      address = &slot->next;
365
0
      length++;
366
0
    }
367
0
    mxCatch(the) {
368
0
      fxIteratorReturn(the, iterator, 1);
369
0
      fxJump(the);
370
0
    }
371
0
  }
372
0
  array->next->value.array.length = length;
373
0
  fxCacheArray(the, array);
374
  
375
0
  the->stack = stack;
376
0
}
377
378
void fx_EvalError(txMachine* the)
379
0
{
380
0
  fx_Error_aux(the, XS_EVAL_ERROR, 0);
381
0
}
382
383
void fx_RangeError(txMachine* the)
384
0
{
385
0
  fx_Error_aux(the, XS_RANGE_ERROR, 0);
386
0
}
387
388
void fx_ReferenceError(txMachine* the)
389
0
{
390
0
  fx_Error_aux(the, XS_REFERENCE_ERROR, 0);
391
0
}
392
393
void fx_SyntaxError(txMachine* the)
394
0
{
395
0
  fx_Error_aux(the, XS_SYNTAX_ERROR, 0);
396
0
}
397
398
void fx_TypeError(txMachine* the)
399
0
{
400
0
  fx_Error_aux(the, XS_TYPE_ERROR, 0);
401
0
}
402
403
void fx_URIError(txMachine* the)
404
0
{
405
0
  fx_Error_aux(the, XS_URI_ERROR, 0);
406
0
}
407
408
void fx_Error_prototype_get_stack(txMachine* the)
409
0
{
410
0
  txSlot* slot;
411
0
  if (mxThis->kind != XS_REFERENCE_KIND)
412
0
    mxTypeError("this: not an object");
413
0
  slot = mxThis->value.reference->next;
414
0
  if (slot && (slot->kind == XS_ERROR_KIND)) {
415
0
    fxStringX(the, mxResult, "");
416
0
    mxPushSlot(mxThis);
417
0
    mxGetID(mxID(_name));
418
0
    if (the->stack->kind != XS_UNDEFINED_KIND)  {
419
0
      fxToString(the, the->stack);
420
0
      fxConcatString(the, mxResult, the->stack);
421
0
    }
422
0
    else
423
0
      fxConcatStringC(the, mxResult, "Error");
424
0
    mxPop();
425
0
    mxPushSlot(mxThis);
426
0
    mxGetID(mxID(_message));
427
0
    if (the->stack->kind != XS_UNDEFINED_KIND) {
428
0
      fxToString(the, the->stack);
429
0
      if (!c_isEmpty(the->stack->value.string)) {
430
0
        fxConcatStringC(the, mxResult, ": ");
431
0
        fxConcatString(the, mxResult, the->stack);
432
0
      }
433
0
    }
434
0
    mxPop();
435
0
    slot = slot->value.reference;
436
0
    if (slot) {
437
0
      slot = slot->next;
438
0
      while (slot) {
439
0
        fxConcatStringC(the, mxResult, "\n at");
440
0
        if ((slot->value.key.string != C_NULL) && (mxStringLength(slot->value.key.string))) {
441
0
          fxConcatStringC(the, mxResult, " ");
442
0
          fxConcatString(the, mxResult, slot);
443
0
        }
444
0
        fxConcatStringC(the, mxResult, " (");
445
0
        if (slot->ID != XS_NO_ID) {
446
0
          fxIDToString(the, slot->ID, the->nameBuffer, sizeof(the->nameBuffer));
447
0
          fxConcatStringC(the, mxResult, the->nameBuffer);
448
0
          fxConcatStringC(the, mxResult, ":");
449
0
          fxIntegerToString(the, (txInteger)slot->value.key.sum, the->nameBuffer, sizeof(the->nameBuffer));
450
0
          fxConcatStringC(the, mxResult, the->nameBuffer);
451
0
        }
452
0
        fxConcatStringC(the, mxResult, ")");
453
0
        slot = slot->next;
454
0
      }
455
0
    }
456
0
  }
457
0
}
458
459
void fx_Error_prototype_set_stack(txMachine* the)
460
0
{
461
0
  if (mxThis->kind != XS_REFERENCE_KIND)
462
0
    mxTypeError("this: not an object");
463
0
  if (mxArgc < 1)
464
0
    mxTypeError("no value");
465
0
  mxPushSlot(mxArgv(0));
466
0
  mxPushSlot(mxThis);
467
0
  mxDefineID(mxID(_stack), XS_NO_FLAG, XS_GET_ONLY);
468
0
  mxPop();
469
0
}
470
471
static const txString gXSAbortStrings[] = {
472
  "debugger",
473
  "memory full",
474
  "JavaScript stack overflow",
475
  "fatal",
476
  "dead strip",
477
  "unhandled exception",
478
  "not enough keys",
479
  "too much computation",
480
  "unhandled rejection",
481
  "native stack overflow",
482
};
483
484
txString fxAbortString(int status)
485
0
{
486
0
  if ((status < 0) || (status >= (int)(sizeof(gXSAbortStrings) / sizeof(txString))))
487
0
    return "unknown";
488
489
0
  return gXSAbortStrings[status];
490
0
}
491
492
#if mxExplicitResourceManagement
493
494
void fx_SuppressedError(txMachine* the)
495
0
{
496
0
  txSlot* property = fx_Error_aux(the, XS_SUPPRESSED_ERROR, 2);
497
0
  property = fxNextSlotProperty(the, property, mxArgv(0), mxID(_error), XS_DONT_ENUM_FLAG);
498
0
  property = fxNextSlotProperty(the, property, mxArgv(1), mxID(_suppressed), XS_DONT_ENUM_FLAG);
499
0
}
500
501
static txSlot* fxCheckDisposableStackInstance(txMachine* the, txSlot* slot, txBoolean mutable, txBoolean disposable);
502
static void fxDisposableStackPush(txMachine* the, txSlot* property);
503
504
txSlot* fxCheckDisposableStackInstance(txMachine* the, txSlot* slot, txBoolean mutable, txBoolean disposable)
505
0
{
506
0
  if (slot->kind == XS_REFERENCE_KIND) {
507
0
    txSlot* instance = slot->value.reference;
508
0
    if (((slot = instance->next)) && (slot->flag & XS_INTERNAL_FLAG) && (slot->kind == XS_DISPOSABLE_STACK_KIND)) {
509
0
      if (mutable && (slot->flag & XS_DONT_SET_FLAG))
510
0
        mxTypeError("this: read-only DisposableStack instance");
511
0
      if (disposable && slot->value.disposableStack.disposed)
512
0
        mxReferenceError("this: disposed DisposableStack instance");
513
0
      return instance;
514
0
    }
515
0
  }
516
0
  mxTypeError("this: not a DisposableStack instance");
517
0
  return C_NULL;
518
0
}
519
520
void fx_DisposableStack(txMachine* the)
521
0
{
522
0
  txSlot* instance;
523
0
  txSlot* property;
524
0
  if (mxIsUndefined(mxTarget))
525
0
    mxTypeError("call: DisposableStack");
526
0
  mxPushSlot(mxTarget);
527
0
  fxGetPrototypeFromConstructor(the, &mxDisposableStackPrototype);
528
0
  instance = fxNewSlot(the);
529
0
  instance->kind = XS_INSTANCE_KIND;
530
0
  instance->value.instance.garbage = C_NULL;
531
0
  instance->value.instance.prototype = the->stack->value.reference;
532
0
  the->stack->kind = XS_REFERENCE_KIND;
533
0
  the->stack->value.reference = instance;
534
0
  mxPullSlot(mxResult);
535
0
  property = instance->next = fxNewSlot(the);
536
0
  property->flag = XS_INTERNAL_FLAG;
537
0
  property->kind = XS_DISPOSABLE_STACK_KIND;
538
0
  property->value.disposableStack.stack = C_NULL;
539
0
  property->value.disposableStack.disposed = 0;
540
0
}
541
542
void fx_DisposableStack_prototype_get_disposed(txMachine* the)
543
0
{
544
0
  txSlot* instance = fxCheckDisposableStackInstance(the, mxThis, 0, 0);
545
0
  txSlot* property = instance->next;
546
0
  mxResult->value.boolean = property->value.disposableStack.disposed;
547
0
  mxResult->kind = XS_BOOLEAN_KIND;
548
0
}
549
550
void fx_DisposableStack_prototype_adopt(txMachine* the)
551
0
{
552
0
  txSlot* instance = fxCheckDisposableStackInstance(the, mxThis, 1, 1);
553
0
  txSlot* property = instance->next;
554
0
  if (mxArgc > 0) 
555
0
    mxPushSlot(mxArgv(0));
556
0
  else
557
0
    mxPushUndefined();
558
0
  if (mxArgc > 1) 
559
0
    mxPushSlot(mxArgv(1));
560
0
  else
561
0
    mxPushUndefined();
562
0
  fxDisposableStackPush(the, property);
563
0
  property->value.disposableStack.stack->flag |= XS_BASE_FLAG;
564
0
  mxPop();
565
0
  mxPullSlot(mxResult);
566
0
}
567
568
void fx_DisposableStack_prototype_defer(txMachine* the)
569
0
{
570
0
  txSlot* instance = fxCheckDisposableStackInstance(the, mxThis, 1, 1);
571
0
  txSlot* property = instance->next;
572
0
  mxPushUndefined();
573
0
  if (mxArgc > 0) 
574
0
    mxPushSlot(mxArgv(0));
575
0
  else
576
0
    mxPushUndefined();
577
0
  fxDisposableStackPush(the, property);
578
0
  mxPop();
579
0
  mxPop();
580
0
}  
581
582
void fx_DisposableStack_prototype_dispose(txMachine* the)
583
0
{
584
0
  txSlot* instance = fxCheckDisposableStackInstance(the, mxThis, 1, 0);
585
0
  txSlot* property = instance->next;
586
0
  txSlot* exception;
587
0
  txBoolean selector = 1;
588
0
  txSlot* slot;
589
0
  if (property->value.disposableStack.disposed)
590
0
    return;
591
0
  property->value.disposableStack.disposed = 1;
592
0
  mxTemporary(exception);
593
0
  slot = property->value.disposableStack.stack;
594
0
  while (slot) {
595
0
    txSlot* dispose = slot;
596
0
    txSlot* resource = slot->next;
597
0
    mxTry(the) {
598
0
      if (dispose->flag & XS_BASE_FLAG) {
599
0
        mxPushUndefined();
600
0
        mxPushSlot(dispose);
601
0
        mxCall();
602
0
        mxPushSlot(resource);
603
0
        mxRunCount(1);
604
0
        mxPop();
605
0
      }
606
0
      else {
607
0
        mxPushSlot(resource);
608
0
        mxPushSlot(dispose);
609
0
        mxCall();
610
0
        mxRunCount(0);
611
0
        mxPop();
612
0
      }
613
0
    }
614
0
    mxCatch(the) {
615
0
      if (selector == 0) {
616
0
        mxPush(mxSuppressedErrorConstructor);
617
0
        mxNew();
618
0
        mxPush(mxException);
619
0
        mxPushSlot(exception);
620
0
        mxRunCount(2);
621
0
        mxPullSlot(exception);
622
0
      }
623
0
      else {
624
0
        *exception = mxException;
625
0
        selector = 0;
626
0
      }
627
0
      mxException = mxUndefined;
628
0
    }
629
0
    slot = resource->next;
630
0
  }
631
0
  if (selector == 0) {
632
0
    mxException.kind = exception->kind;
633
0
    mxException.value = exception->value;
634
0
    fxJump(the);
635
0
  }
636
0
}
637
638
void fx_DisposableStack_prototype_move(txMachine* the)
639
0
{
640
0
  txSlot* instance = fxCheckDisposableStackInstance(the, mxThis, 1, 1);
641
0
  txSlot* property = instance->next;
642
0
  txSlot* resultInstance;
643
0
  txSlot* resultProperty;
644
0
  mxPush(mxDisposableStackConstructor);
645
0
  fxGetPrototypeFromConstructor(the, &mxDisposableStackPrototype);
646
0
  resultInstance = fxNewSlot(the);
647
0
  resultInstance->kind = XS_INSTANCE_KIND;
648
0
  resultInstance->value.instance.garbage = C_NULL;
649
0
  resultInstance->value.instance.prototype = the->stack->value.reference;
650
0
  the->stack->kind = XS_REFERENCE_KIND;
651
0
  the->stack->value.reference = resultInstance;
652
0
  mxPullSlot(mxResult);
653
0
  resultProperty = resultInstance->next = fxNewSlot(the);
654
0
  resultProperty->flag = XS_INTERNAL_FLAG;
655
0
  resultProperty->kind = XS_DISPOSABLE_STACK_KIND;
656
0
  resultProperty->value.disposableStack.stack = property->value.disposableStack.stack;
657
0
  resultProperty->value.disposableStack.disposed = 0;
658
0
  property->value.disposableStack.stack = C_NULL;
659
0
  property->value.disposableStack.disposed = 1;
660
0
}
661
662
void fx_DisposableStack_prototype_use(txMachine* the)
663
0
{
664
0
  txSlot* instance = fxCheckDisposableStackInstance(the, mxThis, 1, 1);
665
0
  txSlot* property = instance->next;
666
0
  txSlot* resource;
667
0
  if (mxArgc > 0)
668
0
    mxPushSlot(mxArgv(0));
669
0
  else
670
0
    mxPushUndefined();
671
0
  resource = the->stack;
672
0
  if (!mxIsNull(resource) && !mxIsUndefined(resource)) {
673
0
    mxPushSlot(resource);
674
0
    mxGetID(mxID(_Symbol_dispose));
675
0
    fxDisposableStackPush(the, property);
676
0
    mxPop();
677
0
  }
678
0
  mxPullSlot(mxResult);
679
0
}
680
681
void fxDisposableStackPush(txMachine* the, txSlot* property)
682
0
{
683
0
  txSlot* dispose = the->stack;
684
0
  txSlot* resource = dispose + 1;
685
0
  txSlot** address = &property->value.disposableStack.stack;
686
0
  txSlot* slot;
687
0
  if (!fxIsCallable(the, dispose))
688
0
    mxTypeError("dispose: not a function");
689
    
690
0
  slot = fxNewSlot(the);
691
0
  slot->next = *address;
692
0
  slot->kind = resource->kind;
693
0
  slot->value = resource->value;
694
0
  *address = slot;
695
  
696
0
  slot = fxNewSlot(the);
697
0
  slot->next = *address;
698
0
  slot->kind = dispose->kind;
699
0
  slot->value = dispose->value;
700
0
  *address = slot;
701
0
}
702
703
static txSlot* fxCheckAsyncDisposableStackInstance(txMachine* the, txSlot* slot, txBoolean mutable, txBoolean disposable);
704
static void fxAsyncDisposableStackPush(txMachine* the, txSlot* property);
705
static void fxAsyncDisposableStackReject(txMachine* the);
706
static void fxAsyncDisposableStackResolve(txMachine* the);
707
708
txSlot* fxCheckAsyncDisposableStackInstance(txMachine* the, txSlot* slot, txBoolean mutable, txBoolean disposable)
709
0
{
710
0
  if (slot->kind == XS_REFERENCE_KIND) {
711
0
    txSlot* instance = slot->value.reference;
712
0
    if (((slot = instance->next)) && (slot->flag & XS_INTERNAL_FLAG) && (slot->kind == XS_ASYNC_DISPOSABLE_STACK_KIND)) {
713
0
      if (mutable && (slot->flag & XS_DONT_SET_FLAG))
714
0
        mxTypeError("this: read-only AsyncDisposableStack instance");
715
0
      if (disposable && slot->value.disposableStack.disposed)
716
0
        mxReferenceError("this: disposed AsyncDisposableStack instance");
717
0
      return instance;
718
0
    }
719
0
  }
720
0
  mxTypeError("this: not a AsyncDisposableStack instance");
721
0
  return C_NULL;
722
0
}
723
void fx_AsyncDisposableStack(txMachine* the)
724
0
{
725
0
  txSlot* instance;
726
0
  txSlot* property;
727
0
  txSlot* function;
728
0
  txSlot* home;
729
0
  if (mxIsUndefined(mxTarget))
730
0
    mxTypeError("call: AsyncDisposableStack");
731
0
  mxPushSlot(mxTarget);
732
0
  fxGetPrototypeFromConstructor(the, &mxAsyncDisposableStackPrototype);
733
0
  instance = fxNewSlot(the);
734
0
  instance->kind = XS_INSTANCE_KIND;
735
0
  instance->value.instance.garbage = C_NULL;
736
0
  instance->value.instance.prototype = the->stack->value.reference;
737
0
  the->stack->kind = XS_REFERENCE_KIND;
738
0
  the->stack->value.reference = instance;
739
0
  mxPullSlot(mxResult);
740
0
  property = instance->next = fxNewSlot(the);
741
0
  property->flag = XS_INTERNAL_FLAG;
742
0
  property->kind = XS_ASYNC_DISPOSABLE_STACK_KIND;
743
0
  property->value.disposableStack.stack = C_NULL;
744
0
  property->value.disposableStack.disposed = 0;
745
  
746
0
    property = fxNextUndefinedProperty(the, property, XS_NO_ID, XS_INTERNAL_FLAG);
747
0
  function = fxNewHostFunction(the, fxAsyncDisposableStackResolve, 1, XS_NO_ID, mxAsyncGeneratorResolveYieldProfileID);
748
0
  home = mxFunctionInstanceHome(function);
749
0
  home->value.home.object = instance;
750
0
    property = fxNextSlotProperty(the, property, the->stack, XS_NO_ID, XS_INTERNAL_FLAG);
751
0
  mxPop();
752
0
  function = fxNewHostFunction(the, fxAsyncDisposableStackReject, 1, XS_NO_ID, mxAsyncGeneratorRejectYieldProfileID);
753
0
  home = mxFunctionInstanceHome(function);
754
0
  home->value.home.object = instance;
755
0
    property = fxNextSlotProperty(the, property, the->stack, XS_NO_ID, XS_INTERNAL_FLAG);
756
0
  mxPop();
757
0
    property = fxNextUndefinedProperty(the, property, XS_NO_ID, XS_INTERNAL_FLAG);
758
0
    property = fxNextUndefinedProperty(the, property, XS_NO_ID, XS_INTERNAL_FLAG);
759
0
}
760
761
void fx_AsyncDisposableStack_prototype_get_disposed(txMachine* the)
762
0
{
763
0
  txSlot* instance = fxCheckAsyncDisposableStackInstance(the, mxThis, 0, 0);
764
0
  txSlot* property = instance->next;
765
0
  mxResult->value.boolean = property->value.disposableStack.disposed;
766
0
  mxResult->kind = XS_BOOLEAN_KIND;
767
0
}
768
769
void fx_AsyncDisposableStack_prototype_adopt(txMachine* the)
770
0
{
771
0
  txSlot* instance = fxCheckAsyncDisposableStackInstance(the, mxThis, 1, 1);
772
0
  txSlot* property = instance->next;
773
0
  if (mxArgc > 0) 
774
0
    mxPushSlot(mxArgv(0));
775
0
  else
776
0
    mxPushUndefined();
777
0
  if (mxArgc > 1) 
778
0
    mxPushSlot(mxArgv(1));
779
0
  else
780
0
    mxPushUndefined();
781
0
  fxAsyncDisposableStackPush(the, property);
782
0
  property->value.disposableStack.stack->flag |= XS_BASE_FLAG;
783
0
  mxPop();
784
0
  mxPullSlot(mxResult);
785
0
}
786
787
void fx_AsyncDisposableStack_prototype_defer(txMachine* the)
788
0
{
789
0
  txSlot* instance = fxCheckAsyncDisposableStackInstance(the, mxThis, 1, 1);
790
0
  txSlot* property = instance->next;
791
0
  mxPushUndefined();
792
0
  if (mxArgc > 0) 
793
0
    mxPushSlot(mxArgv(0));
794
0
  else
795
0
    mxPushUndefined();
796
0
  fxAsyncDisposableStackPush(the, property);
797
0
  mxPop();
798
0
  mxPop();
799
0
}  
800
801
void fx_AsyncDisposableStack_prototype_disposeAsync(txMachine* the)
802
0
{
803
0
  txSlot* promise;
804
0
  txSlot* resolveFunction;
805
0
  txSlot* rejectFunction;
806
807
0
  mxPush(mxPromisePrototype);
808
0
  promise = fxNewPromiseInstance(the);
809
0
  mxPullSlot(mxResult);
810
0
  mxPromiseStatus(promise)->value.integer = mxPendingStatus;
811
0
  fxPushPromiseFunctions(the, promise);
812
0
  resolveFunction = the->stack + 1;
813
0
  rejectFunction = the->stack;
814
0
  mxTry(the) {
815
0
    txSlot* instance = fxCheckAsyncDisposableStackInstance(the, mxThis, 1, 0);
816
0
    txSlot* property = instance->next;
817
0
    if (property->value.disposableStack.disposed) {
818
0
      mxPushUndefined();
819
0
      mxPushSlot(resolveFunction);
820
0
      mxCall();
821
0
      mxPushUndefined();
822
0
      mxRunCount(1);
823
0
      mxPop();
824
0
    }
825
0
    else {
826
0
      txSlot* exception = property->next;
827
0
      txSlot* resolveStepFunction = exception->next;
828
0
      txSlot* rejectStepFunction = resolveStepFunction->next;
829
0
      property->value.disposableStack.disposed = 1;
830
0
      property = rejectStepFunction->next;
831
0
      property->kind = resolveFunction->kind;
832
0
      property->value = resolveFunction->value;
833
0
      property = property->next;
834
0
      property->kind = rejectFunction->kind;
835
0
      property->value = rejectFunction->value;
836
0
      mxPushUndefined();
837
0
      mxPushSlot(resolveStepFunction);
838
0
      mxCall();
839
0
      mxPushUndefined();
840
0
      mxRunCount(1);
841
0
      mxPop();
842
0
    }
843
0
  }
844
0
  mxCatch(the) {
845
0
    fxRejectException(the, rejectFunction);
846
0
  }
847
0
}
848
849
void fx_AsyncDisposableStack_prototype_move(txMachine* the)
850
0
{
851
0
  txSlot* instance = fxCheckAsyncDisposableStackInstance(the, mxThis, 1, 1);
852
0
  txSlot* property = instance->next;
853
0
  txSlot* resultInstance;
854
0
  txSlot* resultProperty;
855
0
  txSlot* function;
856
0
  txSlot* home;
857
0
  mxPush(mxAsyncDisposableStackConstructor);
858
0
  fxGetPrototypeFromConstructor(the, &mxAsyncDisposableStackPrototype);
859
0
  resultInstance = fxNewSlot(the);
860
0
  resultInstance->kind = XS_INSTANCE_KIND;
861
0
  resultInstance->value.instance.garbage = C_NULL;
862
0
  resultInstance->value.instance.prototype = the->stack->value.reference;
863
0
  the->stack->kind = XS_REFERENCE_KIND;
864
0
  the->stack->value.reference = resultInstance;
865
0
  mxPullSlot(mxResult);
866
0
  resultProperty = resultInstance->next = fxNewSlot(the);
867
0
  resultProperty->flag = XS_INTERNAL_FLAG;
868
0
  resultProperty->kind = XS_ASYNC_DISPOSABLE_STACK_KIND;
869
0
  resultProperty->value.disposableStack.stack = property->value.disposableStack.stack;
870
0
  resultProperty->value.disposableStack.disposed = 0;
871
  
872
0
    resultProperty = fxNextUndefinedProperty(the, resultProperty, XS_NO_ID, XS_INTERNAL_FLAG);
873
0
  function = fxNewHostFunction(the, fxAsyncDisposableStackResolve, 1, XS_NO_ID, mxAsyncGeneratorResolveYieldProfileID);
874
0
  home = mxFunctionInstanceHome(function);
875
0
  home->value.home.object = resultInstance;
876
0
    resultProperty = fxNextSlotProperty(the, resultProperty, the->stack, XS_NO_ID, XS_INTERNAL_FLAG);
877
0
  mxPop();
878
0
  function = fxNewHostFunction(the, fxAsyncDisposableStackReject, 1, XS_NO_ID, mxAsyncGeneratorRejectYieldProfileID);
879
0
  home = mxFunctionInstanceHome(function);
880
0
  home->value.home.object = resultInstance;
881
0
    resultProperty = fxNextSlotProperty(the, resultProperty, the->stack, XS_NO_ID, XS_INTERNAL_FLAG);
882
0
  mxPop();
883
0
    resultProperty = fxNextUndefinedProperty(the, resultProperty, XS_NO_ID, XS_INTERNAL_FLAG);
884
0
    resultProperty = fxNextUndefinedProperty(the, resultProperty, XS_NO_ID, XS_INTERNAL_FLAG);
885
  
886
0
  property->value.disposableStack.stack = C_NULL;
887
0
  property->value.disposableStack.disposed = 1;
888
0
}
889
890
void fx_AsyncDisposableStack_prototype_use(txMachine* the)
891
0
{
892
0
  txSlot* instance = fxCheckAsyncDisposableStackInstance(the, mxThis, 1, 1);
893
0
  txSlot* property = instance->next;
894
0
  txSlot* resource;
895
0
  if (mxArgc > 0)
896
0
    mxPushSlot(mxArgv(0));
897
0
  else
898
0
    mxPushUndefined();
899
0
  resource = the->stack;
900
0
  if (!mxIsNull(resource) && !mxIsUndefined(resource)) {
901
0
    mxPushSlot(resource);
902
0
    mxGetID(mxID(_Symbol_asyncDispose));
903
0
    if (!fxIsCallable(the, the->stack)) {
904
0
      mxPop();
905
0
      mxPushSlot(resource);
906
0
      mxGetID(mxID(_Symbol_dispose));
907
0
    }
908
0
    fxAsyncDisposableStackPush(the, property);
909
0
    mxPop();
910
0
  }
911
0
  mxPullSlot(mxResult);
912
0
}
913
914
void fxAsyncDisposableStackPush(txMachine* the, txSlot* property)
915
0
{
916
0
  txSlot* dispose = the->stack;
917
0
  txSlot* resource = dispose + 1;
918
0
  txSlot** address = &property->value.disposableStack.stack;
919
0
  txSlot* slot;
920
0
  if (!fxIsCallable(the, dispose))
921
0
    mxTypeError("dispose: no a function");
922
    
923
0
  slot = fxNewSlot(the);
924
0
  slot->next = *address;
925
0
  slot->kind = resource->kind;
926
0
  slot->value = resource->value;
927
0
  *address = slot;
928
  
929
0
  slot = fxNewSlot(the);
930
0
  slot->next = *address;
931
0
  slot->kind = dispose->kind;
932
0
  slot->value = dispose->value;
933
0
  *address = slot;
934
0
}
935
936
void fxAsyncDisposableStackReject(txMachine* the)
937
0
{
938
0
  txSlot* slot = mxFunctionInstanceHome(mxFunction->value.reference);
939
0
  txSlot* instance = slot->value.home.object;
940
0
  txSlot* property = instance->next;
941
0
  txSlot* exception = property->next;
942
  
943
0
  if (mxIsUndefined(exception)) {
944
0
    mxPushSlot(mxArgv(0));
945
0
    mxPullSlot(exception);
946
0
  }
947
0
  else {
948
0
    mxPush(mxSuppressedErrorConstructor);
949
0
    mxNew();
950
0
    mxPushSlot(mxArgv(0));
951
0
    mxPushSlot(exception);
952
0
    mxRunCount(2);
953
0
    mxPullSlot(exception);
954
0
  }
955
0
  fxAsyncDisposableStackResolve(the);
956
0
}
957
958
void fxAsyncDisposableStackResolve(txMachine* the)
959
0
{
960
0
  txSlot* slot = mxFunctionInstanceHome(mxFunction->value.reference);
961
0
  txSlot* instance = slot->value.home.object;
962
0
  txSlot* property = instance->next;
963
0
  txSlot* exception = property->next;
964
0
  txSlot* resolveStepFunction = exception->next;
965
0
  txSlot* rejectStepFunction = resolveStepFunction->next;
966
0
  txSlot* resolveFunction = rejectStepFunction->next;
967
0
  txSlot* rejectFunction = resolveFunction->next;
968
969
0
  slot = property->value.disposableStack.stack;
970
0
  if (slot) {
971
0
    txSlot* dispose = slot;
972
0
    txSlot* resource = slot->next;
973
0
    property->value.disposableStack.stack = resource->next;
974
0
    mxTry(the) {
975
0
      mxPushUndefined();
976
0
      mxPush(mxPromiseConstructor);
977
0
      if (dispose->flag & XS_BASE_FLAG) {
978
0
        mxPushUndefined();
979
0
        mxPushSlot(dispose);
980
0
        mxCall();
981
0
        mxPushSlot(resource);
982
0
        mxRunCount(1);
983
0
      }
984
0
      else {
985
0
        mxPushSlot(resource);
986
0
        mxPushSlot(dispose);
987
0
        mxCall();
988
0
        mxRunCount(0);
989
0
      }
990
0
      fx_Promise_resolveAux(the);
991
0
      mxPop();
992
0
      mxPop();
993
0
      fxPromiseThen(the, the->stack->value.reference, resolveStepFunction, rejectStepFunction, C_NULL, C_NULL);
994
0
      mxPop();
995
0
    }
996
0
    mxCatch(the) {
997
0
      mxPushUndefined();
998
0
      mxPushSlot(rejectStepFunction);
999
0
      mxCall();
1000
0
      mxPush(mxException);
1001
0
      mxException = mxUndefined;
1002
0
      mxRunCount(1);
1003
0
      mxPop();
1004
0
    }
1005
0
  }
1006
0
  else {
1007
0
    if (mxIsUndefined(exception)) {
1008
0
      mxPushUndefined();
1009
0
      mxPushSlot(resolveFunction);
1010
0
      mxCall();
1011
0
      mxPushUndefined();
1012
0
      mxRunCount(1);
1013
0
      mxPop();
1014
0
    }
1015
0
    else {
1016
0
      mxPushUndefined();
1017
0
      mxPushSlot(rejectFunction);
1018
0
      mxCall();
1019
0
      mxPushSlot(exception);
1020
0
      mxRunCount(1);
1021
0
      mxPop();
1022
0
    }
1023
0
  }
1024
0
}
1025
1026
#endif
1027
1028
1029
1030