Coverage Report

Created: 2026-01-29 06:33

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
27.5k
{
74
27.5k
  txSlot* slot;
75
27.5k
  txSlot* prototype;
76
27.5k
  txSlot* instance;
77
27.5k
#if mxExplicitResourceManagement
78
27.5k
  txSlot* property;
79
27.5k
#endif
80
  
81
27.5k
  mxPush(mxObjectPrototype);
82
27.5k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
83
27.5k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Error_toString), 0, mxID(_toString), XS_DONT_ENUM_FLAG);
84
27.5k
  slot = fxNextStringXProperty(the, slot, (txString)gxErrorNames[XS_UNKNOWN_ERROR], mxID(_name), XS_DONT_ENUM_FLAG);
85
27.5k
  slot = fxNextStringXProperty(the, slot, "", mxID(_message), XS_DONT_ENUM_FLAG);
86
27.5k
  slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_Error_prototype_get_stack), mxCallback(fx_Error_prototype_set_stack), mxID(_stack), XS_DONT_ENUM_FLAG);
87
27.5k
  mxErrorPrototype = *the->stack;
88
27.5k
  prototype = fxBuildHostConstructor(the, mxCallback(fx_Error), 1, mxID(_Error));
89
27.5k
  mxErrorConstructor = *the->stack;
90
27.5k
#if mxErrorIsError
91
27.5k
  slot = fxLastProperty(the, prototype);
92
27.5k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Error_isError), 1, mxID(_isError), XS_DONT_ENUM_FLAG);
93
27.5k
#endif
94
27.5k
  mxPop();
95
27.5k
  mxPush(mxErrorPrototype);
96
27.5k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
97
27.5k
  slot = fxNextStringXProperty(the, slot, (txString)gxErrorNames[XS_AGGREGATE_ERROR], mxID(_name), XS_DONT_ENUM_FLAG);
98
27.5k
  slot = fxNextStringXProperty(the, slot, "", mxID(_message), XS_DONT_ENUM_FLAG);
99
27.5k
  mxAggregateErrorPrototype = *the->stack;
100
27.5k
  instance = fxBuildHostConstructor(the, mxCallback(fx_AggregateError), 2, mxID(_AggregateError));
101
27.5k
  instance->value.instance.prototype = prototype;
102
27.5k
  mxAggregateErrorConstructor = *the->stack;
103
27.5k
  mxPop();
104
27.5k
  mxPush(mxErrorPrototype);
105
27.5k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
106
27.5k
  slot = fxNextStringXProperty(the, slot, (txString)gxErrorNames[XS_EVAL_ERROR], mxID(_name), XS_DONT_ENUM_FLAG);
107
27.5k
  slot = fxNextStringXProperty(the, slot, "", mxID(_message), XS_DONT_ENUM_FLAG);
108
27.5k
  mxEvalErrorPrototype = *the->stack;
109
27.5k
  instance = fxBuildHostConstructor(the, mxCallback(fx_EvalError), 1, mxID(_EvalError));
110
27.5k
  instance->value.instance.prototype = prototype;
111
27.5k
  mxEvalErrorConstructor = *the->stack;
112
27.5k
  mxPop();
113
27.5k
  mxPush(mxErrorPrototype);
114
27.5k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
115
27.5k
  slot = fxNextStringXProperty(the, slot, (txString)gxErrorNames[XS_RANGE_ERROR], mxID(_name), XS_DONT_ENUM_FLAG);
116
27.5k
  slot = fxNextStringXProperty(the, slot, "", mxID(_message), XS_DONT_ENUM_FLAG);
117
27.5k
  mxRangeErrorPrototype = *the->stack;
118
27.5k
  instance = fxBuildHostConstructor(the, mxCallback(fx_RangeError), 1, mxID(_RangeError));
119
27.5k
  instance->value.instance.prototype = prototype;
120
27.5k
  mxRangeErrorConstructor = *the->stack;
121
27.5k
  mxPop();
122
27.5k
  mxPush(mxErrorPrototype);
123
27.5k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
124
27.5k
  slot = fxNextStringXProperty(the, slot, (txString)gxErrorNames[XS_REFERENCE_ERROR], mxID(_name), XS_DONT_ENUM_FLAG);
125
27.5k
  slot = fxNextStringXProperty(the, slot, "", mxID(_message), XS_DONT_ENUM_FLAG);
126
27.5k
  mxReferenceErrorPrototype = *the->stack;
127
27.5k
  instance = fxBuildHostConstructor(the, mxCallback(fx_ReferenceError), 1, mxID(_ReferenceError));
128
27.5k
  instance->value.instance.prototype = prototype;
129
27.5k
  mxReferenceErrorConstructor = *the->stack;
130
27.5k
  mxPop();
131
27.5k
  mxPush(mxErrorPrototype);
132
27.5k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
133
27.5k
  slot = fxNextStringXProperty(the, slot, (txString)gxErrorNames[XS_SYNTAX_ERROR], mxID(_name), XS_DONT_ENUM_FLAG);
134
27.5k
  slot = fxNextStringXProperty(the, slot, "", mxID(_message), XS_DONT_ENUM_FLAG);
135
27.5k
  mxSyntaxErrorPrototype = *the->stack;
136
27.5k
  instance = fxBuildHostConstructor(the, mxCallback(fx_SyntaxError), 1, mxID(_SyntaxError));
137
27.5k
  instance->value.instance.prototype = prototype;
138
27.5k
  mxSyntaxErrorConstructor = *the->stack;
139
27.5k
  mxPop();
140
27.5k
  mxPush(mxErrorPrototype);
141
27.5k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
142
27.5k
  slot = fxNextStringXProperty(the, slot, (txString)gxErrorNames[XS_TYPE_ERROR], mxID(_name), XS_DONT_ENUM_FLAG);
143
27.5k
  slot = fxNextStringXProperty(the, slot, "", mxID(_message), XS_DONT_ENUM_FLAG);
144
27.5k
  mxTypeErrorPrototype = *the->stack;
145
27.5k
  instance = fxBuildHostConstructor(the, mxCallback(fx_TypeError), 1, mxID(_TypeError));
146
27.5k
  instance->value.instance.prototype = prototype;
147
27.5k
  mxTypeErrorConstructor = *the->stack;
148
27.5k
  mxPop();
149
27.5k
  mxPush(mxErrorPrototype);
150
27.5k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
151
27.5k
  slot = fxNextStringXProperty(the, slot, (txString)gxErrorNames[XS_URI_ERROR], mxID(_name), XS_DONT_ENUM_FLAG);
152
27.5k
  slot = fxNextStringXProperty(the, slot, "", mxID(_message), XS_DONT_ENUM_FLAG);
153
27.5k
  mxURIErrorPrototype = *the->stack;
154
27.5k
  instance = fxBuildHostConstructor(the, mxCallback(fx_URIError), 1, mxID(_URIError));
155
27.5k
  instance->value.instance.prototype = prototype;
156
27.5k
  mxURIErrorConstructor = *the->stack;
157
27.5k
  mxPop();
158
159
27.5k
#if mxExplicitResourceManagement
160
27.5k
  mxPush(mxErrorPrototype);
161
27.5k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
162
27.5k
  slot = fxNextStringXProperty(the, slot, (txString)gxErrorNames[XS_SUPPRESSED_ERROR], mxID(_name), XS_DONT_ENUM_FLAG);
163
27.5k
  slot = fxNextStringXProperty(the, slot, "", mxID(_message), XS_DONT_ENUM_FLAG);
164
27.5k
  mxSuppressedErrorPrototype = *the->stack;
165
27.5k
  instance = fxBuildHostConstructor(the, mxCallback(fx_SuppressedError), 3, mxID(_SuppressedError));
166
27.5k
  instance->value.instance.prototype = prototype;
167
27.5k
  mxSuppressedErrorConstructor = *the->stack;
168
27.5k
  mxPop();
169
170
27.5k
  mxPush(mxObjectPrototype);
171
27.5k
    slot = fxLastProperty(the, fxNewObjectInstance(the));
172
27.5k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Error_toString), 0, mxID(_toString), XS_DONT_ENUM_FLAG);
173
27.5k
  slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_DisposableStack_prototype_get_disposed), C_NULL, mxID(_disposed), XS_DONT_ENUM_FLAG);
174
27.5k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DisposableStack_prototype_adopt), 2, mxID(_adopt), XS_DONT_ENUM_FLAG);
175
27.5k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DisposableStack_prototype_defer), 1, mxID(_defer), XS_DONT_ENUM_FLAG);
176
27.5k
  property = slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DisposableStack_prototype_dispose), 0, mxID(_dispose), XS_DONT_ENUM_FLAG);
177
27.5k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DisposableStack_prototype_move), 0, mxID(_move), XS_DONT_ENUM_FLAG);
178
27.5k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DisposableStack_prototype_use), 1, mxID(_use), XS_DONT_ENUM_FLAG);
179
27.5k
  slot = fxNextSlotProperty(the, slot, property, mxID(_Symbol_dispose), XS_DONT_ENUM_FLAG);
180
27.5k
  slot = fxNextStringXProperty(the, slot, "DisposableStack", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
181
27.5k
  mxDisposableStackPrototype = *the->stack;
182
27.5k
  slot = fxBuildHostConstructor(the, mxCallback(fx_DisposableStack), 0, mxID(_DisposableStack));
183
27.5k
  mxDisposableStackConstructor = *the->stack;
184
27.5k
  mxPop();
185
  
186
27.5k
  mxPush(mxObjectPrototype);
187
27.5k
    slot = fxLastProperty(the, fxNewObjectInstance(the));
188
27.5k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Error_toString), 0, mxID(_toString), XS_DONT_ENUM_FLAG);
189
27.5k
  slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_AsyncDisposableStack_prototype_get_disposed), C_NULL, mxID(_disposed), XS_DONT_ENUM_FLAG);
190
27.5k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_AsyncDisposableStack_prototype_adopt), 2, mxID(_adopt), XS_DONT_ENUM_FLAG);
191
27.5k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_AsyncDisposableStack_prototype_defer), 1, mxID(_defer), XS_DONT_ENUM_FLAG);
192
27.5k
  property = slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_AsyncDisposableStack_prototype_disposeAsync), 0, mxID(_disposeAsync), XS_DONT_ENUM_FLAG);
193
27.5k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_AsyncDisposableStack_prototype_move), 0, mxID(_move), XS_DONT_ENUM_FLAG);
194
27.5k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_AsyncDisposableStack_prototype_use), 1, mxID(_use), XS_DONT_ENUM_FLAG);
195
27.5k
  slot = fxNextSlotProperty(the, slot, property, mxID(_Symbol_asyncDispose), XS_DONT_ENUM_FLAG);
196
27.5k
  slot = fxNextStringXProperty(the, slot, "AsyncDisposableStack", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
197
27.5k
  mxAsyncDisposableStackPrototype = *the->stack;
198
27.5k
  slot = fxBuildHostConstructor(the, mxCallback(fx_AsyncDisposableStack), 0, mxID(_AsyncDisposableStack));
199
27.5k
  mxAsyncDisposableStackConstructor = *the->stack;
200
27.5k
  mxPop();
201
27.5k
#endif
202
27.5k
}
203
204
void fxCaptureErrorStack(txMachine* the, txSlot* internal, txSlot* frame)
205
1.68M
{
206
1.68M
  txSlot* slot = internal->value.reference = fxNewSlot(the);
207
1.68M
  slot->kind = XS_INSTANCE_KIND;
208
1.68M
  slot->value.instance.garbage = C_NULL;
209
1.68M
  slot->value.instance.prototype = C_NULL;
210
30.1M
  while (frame->next) {
211
28.4M
    txSlot* environment = mxFrameToEnvironment(frame);
212
28.4M
    txSlot* function = frame + 3; 
213
28.4M
    if (function->kind == XS_REFERENCE_KIND) {
214
28.4M
      function = function->value.reference;
215
28.4M
      if (mxIsFunction(function)) {
216
28.4M
        txSlot* name = mxBehaviorGetProperty(the, function, mxID(_name), 0, XS_OWN);
217
28.4M
        slot = slot->next = fxNewSlot(the);
218
28.4M
        slot->flag = XS_GET_ONLY;
219
28.4M
        slot->kind = XS_KEY_KIND;
220
28.4M
        slot->ID = environment->ID;
221
28.4M
        slot->value.key.string = C_NULL;
222
28.4M
        slot->value.key.sum = environment->value.environment.line;
223
28.4M
        if (name && ((name->kind == XS_STRING_KIND) || (name->kind == XS_STRING_X_KIND))) {
224
28.4M
          if (name->kind == XS_STRING_X_KIND)
225
0
            slot->kind = XS_KEY_X_KIND;
226
28.4M
          slot->value.key.string = name->value.string;
227
28.4M
        }
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
28.4M
      }
247
28.4M
    }
248
28.4M
    frame = frame->next;
249
28.4M
  }
250
1.68M
}
251
252
void fx_Error(txMachine* the)
253
56.2k
{
254
56.2k
  fx_Error_aux(the, XS_UNKNOWN_ERROR, 0);
255
56.2k
}
256
257
void fx_Error_isError(txMachine* the)
258
268
{
259
268
  mxResult->kind = XS_BOOLEAN_KIND;
260
268
  mxResult->value.boolean = 0;
261
268
  if (mxArgc > 0) {
262
230
    txSlot* instance = fxGetInstance(the, mxArgv(0));
263
230
    if (instance) {
264
171
      txSlot* internal = instance->next;
265
171
      if (internal && (internal->kind == XS_ERROR_KIND)) {
266
142
        mxResult->value.boolean = 1;
267
142
      }
268
171
    }
269
230
  }
270
268
}
271
272
txSlot* fx_Error_aux(txMachine* the, txError error, txInteger i)
273
374k
{
274
374k
  txSlot* instance;
275
374k
  txSlot* slot;
276
374k
  if (mxIsUndefined(mxTarget))
277
222
    mxPushSlot(mxFunction);
278
373k
  else
279
373k
    mxPushSlot(mxTarget);
280
374k
  fxGetPrototypeFromConstructor(the, &mxErrorPrototypes(error));
281
374k
  instance = fxNewObjectInstance(the);
282
374k
  mxPullSlot(mxResult);
283
374k
  slot = instance->next = fxNewSlot(the);
284
374k
  slot->flag = XS_INTERNAL_FLAG;
285
374k
  slot->kind = XS_ERROR_KIND;
286
374k
  slot->value.error.info = C_NULL;
287
374k
  slot->value.error.which = error;
288
374k
  if (gxDefaults.captureErrorStack)
289
374k
    gxDefaults.captureErrorStack(the, slot, the->frame->next);
290
374k
  if ((mxArgc > i) && (mxArgv(i)->kind != XS_UNDEFINED_KIND)) {
291
350k
    fxToString(the, mxArgv(i));
292
350k
    slot = fxNextSlotProperty(the, slot, mxArgv(i), mxID(_message), XS_DONT_ENUM_FLAG);
293
350k
  }
294
374k
  i++;
295
374k
  if ((mxArgc > i) && (mxArgv(i)->kind == XS_REFERENCE_KIND)) {
296
32.5k
    if (mxBehaviorHasProperty(the, mxArgv(i)->value.reference, mxID(_cause), 0)) {
297
1
      mxPushSlot(mxArgv(i));
298
1
      mxGetID(mxID(_cause));
299
1
      slot = fxNextSlotProperty(the, slot, the->stack, mxID(_cause), XS_DONT_ENUM_FLAG);
300
1
      mxPop();
301
1
    }
302
32.5k
  }
303
374k
  return slot;
304
374k
}
305
306
void fx_Error_toString(txMachine* the)
307
185k
{
308
185k
  txSlot* name;
309
185k
  txSlot* message;
310
185k
  if (mxThis->kind != XS_REFERENCE_KIND)
311
9
    mxTypeError("this: not an object");
312
185k
  mxPushSlot(mxThis);
313
185k
  mxGetID(mxID(_name));
314
185k
  if (the->stack->kind == XS_UNDEFINED_KIND) 
315
185k
    fxStringX(the, the->stack, "Error");
316
118
  else  
317
118
    fxToString(the, the->stack);
318
185k
  name = the->stack;
319
185k
  mxPushSlot(mxThis);
320
185k
  mxGetID(mxID(_message));
321
185k
  if (the->stack->kind == XS_UNDEFINED_KIND) 
322
185k
    *the->stack = mxEmptyString;
323
119
  else  
324
119
    fxToString(the, the->stack);
325
185k
  message = the->stack;
326
185k
  if (c_isEmpty(name->value.string))
327
3
    *mxResult = *message;
328
185k
  else if (c_isEmpty(message->value.string))
329
185k
    *mxResult = *name;
330
93
  else {
331
93
    fxStringX(the, mxResult, "");
332
93
    fxConcatString(the, mxResult, name);
333
93
    fxConcatStringC(the, mxResult, ": ");
334
93
    fxConcatString(the, mxResult, message);
335
93
  }
336
185k
  the->stack += 2;
337
185k
}
338
339
void fx_AggregateError(txMachine* the)
340
101
{
341
101
  txSlot* stack = the->stack;
342
101
  txSlot* property = fx_Error_aux(the, XS_AGGREGATE_ERROR, 1);
343
101
  txSlot* array;
344
101
  txSlot** address;
345
101
  txIndex length = 0;
346
101
  txSlot* iterator;
347
101
  txSlot* next;
348
101
  txSlot* value;
349
101
  txSlot* slot;
350
  
351
101
  mxPush(mxArrayPrototype);
352
101
  array = fxNewArrayInstance(the);
353
101
  fxNextSlotProperty(the, property, the->stack, mxID(_errors), XS_DONT_ENUM_FLAG);
354
101
  address = &array->next->next;
355
101
  mxTemporary(iterator);
356
101
  mxTemporary(next);
357
101
  fxGetIterator(the, mxArgv(0), iterator, next, 0);
358
101
  mxTemporary(value);
359
39.7k
  while (fxIteratorNext(the, iterator, next, value)) {
360
39.6k
    mxTry(the) {
361
39.6k
      *address = slot = fxNewSlot(the);
362
39.6k
      slot->kind = value->kind;
363
39.6k
      slot->value = value->value;
364
39.6k
      address = &slot->next;
365
39.6k
      length++;
366
39.6k
    }
367
39.6k
    mxCatch(the) {
368
0
      fxIteratorReturn(the, iterator, 1);
369
0
      fxJump(the);
370
0
    }
371
39.6k
  }
372
101
  array->next->value.array.length = length;
373
101
  fxCacheArray(the, array);
374
  
375
101
  the->stack = stack;
376
101
}
377
378
void fx_EvalError(txMachine* the)
379
117
{
380
117
  fx_Error_aux(the, XS_EVAL_ERROR, 0);
381
117
}
382
383
void fx_RangeError(txMachine* the)
384
76
{
385
76
  fx_Error_aux(the, XS_RANGE_ERROR, 0);
386
76
}
387
388
void fx_ReferenceError(txMachine* the)
389
5
{
390
5
  fx_Error_aux(the, XS_REFERENCE_ERROR, 0);
391
5
}
392
393
void fx_SyntaxError(txMachine* the)
394
317k
{
395
317k
  fx_Error_aux(the, XS_SYNTAX_ERROR, 0);
396
317k
}
397
398
void fx_TypeError(txMachine* the)
399
99
{
400
99
  fx_Error_aux(the, XS_TYPE_ERROR, 0);
401
99
}
402
403
void fx_URIError(txMachine* the)
404
5
{
405
5
  fx_Error_aux(the, XS_URI_ERROR, 0);
406
5
}
407
408
void fx_Error_prototype_get_stack(txMachine* the)
409
2
{
410
2
  txSlot* slot;
411
2
  if (mxThis->kind != XS_REFERENCE_KIND)
412
0
    mxTypeError("this: not an object");
413
2
  slot = mxThis->value.reference->next;
414
2
  if (slot && (slot->kind == XS_ERROR_KIND)) {
415
2
    fxStringX(the, mxResult, "");
416
2
    mxPushSlot(mxThis);
417
2
    mxGetID(mxID(_name));
418
2
    if (the->stack->kind != XS_UNDEFINED_KIND)  {
419
2
      fxToString(the, the->stack);
420
2
      fxConcatString(the, mxResult, the->stack);
421
2
    }
422
0
    else
423
0
      fxConcatStringC(the, mxResult, "Error");
424
2
    mxPop();
425
2
    mxPushSlot(mxThis);
426
2
    mxGetID(mxID(_message));
427
2
    if (the->stack->kind != XS_UNDEFINED_KIND) {
428
2
      fxToString(the, the->stack);
429
2
      if (!c_isEmpty(the->stack->value.string)) {
430
1
        fxConcatStringC(the, mxResult, ": ");
431
1
        fxConcatString(the, mxResult, the->stack);
432
1
      }
433
2
    }
434
2
    mxPop();
435
2
    slot = slot->value.reference;
436
2
    if (slot) {
437
2
      slot = slot->next;
438
4
      while (slot) {
439
2
        fxConcatStringC(the, mxResult, "\n at");
440
2
        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
2
        fxConcatStringC(the, mxResult, " (");
445
2
        if (slot->ID != XS_NO_ID) {
446
2
          fxIDToString(the, slot->ID, the->nameBuffer, sizeof(the->nameBuffer));
447
2
          fxConcatStringC(the, mxResult, the->nameBuffer);
448
2
          fxConcatStringC(the, mxResult, ":");
449
2
          fxIntegerToString(the, (txInteger)slot->value.key.sum, the->nameBuffer, sizeof(the->nameBuffer));
450
2
          fxConcatStringC(the, mxResult, the->nameBuffer);
451
2
        }
452
2
        fxConcatStringC(the, mxResult, ")");
453
2
        slot = slot->next;
454
2
      }
455
2
    }
456
2
  }
457
2
}
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
18
{
496
18
  txSlot* property = fx_Error_aux(the, XS_SUPPRESSED_ERROR, 2);
497
18
  property = fxNextSlotProperty(the, property, mxArgv(0), mxID(_error), XS_DONT_ENUM_FLAG);
498
18
  property = fxNextSlotProperty(the, property, mxArgv(1), mxID(_suppressed), XS_DONT_ENUM_FLAG);
499
18
}
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
271
{
506
271
  if (slot->kind == XS_REFERENCE_KIND) {
507
201
    txSlot* instance = slot->value.reference;
508
201
    if (((slot = instance->next)) && (slot->flag & XS_INTERNAL_FLAG) && (slot->kind == XS_DISPOSABLE_STACK_KIND)) {
509
149
      if (mutable && (slot->flag & XS_DONT_SET_FLAG))
510
0
        mxTypeError("this: read-only DisposableStack instance");
511
149
      if (disposable && slot->value.disposableStack.disposed)
512
20
        mxReferenceError("this: disposed DisposableStack instance");
513
129
      return instance;
514
149
    }
515
201
  }
516
271
  mxTypeError("this: not a DisposableStack instance");
517
0
  return C_NULL;
518
271
}
519
520
void fx_DisposableStack(txMachine* the)
521
817
{
522
817
  txSlot* instance;
523
817
  txSlot* property;
524
817
  if (mxIsUndefined(mxTarget))
525
1
    mxTypeError("call: DisposableStack");
526
816
  mxPushSlot(mxTarget);
527
816
  fxGetPrototypeFromConstructor(the, &mxDisposableStackPrototype);
528
816
  instance = fxNewSlot(the);
529
816
  instance->kind = XS_INSTANCE_KIND;
530
816
  instance->value.instance.garbage = C_NULL;
531
816
  instance->value.instance.prototype = the->stack->value.reference;
532
816
  the->stack->kind = XS_REFERENCE_KIND;
533
816
  the->stack->value.reference = instance;
534
816
  mxPullSlot(mxResult);
535
816
  property = instance->next = fxNewSlot(the);
536
816
  property->flag = XS_INTERNAL_FLAG;
537
816
  property->kind = XS_DISPOSABLE_STACK_KIND;
538
816
  property->value.disposableStack.stack = C_NULL;
539
816
  property->value.disposableStack.disposed = 0;
540
816
}
541
542
void fx_DisposableStack_prototype_get_disposed(txMachine* the)
543
16
{
544
16
  txSlot* instance = fxCheckDisposableStackInstance(the, mxThis, 0, 0);
545
16
  txSlot* property = instance->next;
546
16
  mxResult->value.boolean = property->value.disposableStack.disposed;
547
16
  mxResult->kind = XS_BOOLEAN_KIND;
548
16
}
549
550
void fx_DisposableStack_prototype_adopt(txMachine* the)
551
62
{
552
62
  txSlot* instance = fxCheckDisposableStackInstance(the, mxThis, 1, 1);
553
62
  txSlot* property = instance->next;
554
62
  if (mxArgc > 0) 
555
42
    mxPushSlot(mxArgv(0));
556
20
  else
557
20
    mxPushUndefined();
558
62
  if (mxArgc > 1) 
559
41
    mxPushSlot(mxArgv(1));
560
21
  else
561
21
    mxPushUndefined();
562
62
  fxDisposableStackPush(the, property);
563
62
  property->value.disposableStack.stack->flag |= XS_BASE_FLAG;
564
62
  mxPop();
565
62
  mxPullSlot(mxResult);
566
62
}
567
568
void fx_DisposableStack_prototype_defer(txMachine* the)
569
55
{
570
55
  txSlot* instance = fxCheckDisposableStackInstance(the, mxThis, 1, 1);
571
55
  txSlot* property = instance->next;
572
55
  mxPushUndefined();
573
55
  if (mxArgc > 0) 
574
29
    mxPushSlot(mxArgv(0));
575
26
  else
576
26
    mxPushUndefined();
577
55
  fxDisposableStackPush(the, property);
578
55
  mxPop();
579
55
  mxPop();
580
55
}  
581
582
void fx_DisposableStack_prototype_dispose(txMachine* the)
583
52
{
584
52
  txSlot* instance = fxCheckDisposableStackInstance(the, mxThis, 1, 0);
585
52
  txSlot* property = instance->next;
586
52
  txSlot* exception;
587
52
  txBoolean selector = 1;
588
52
  txSlot* slot;
589
52
  if (property->value.disposableStack.disposed)
590
6
    return;
591
46
  property->value.disposableStack.disposed = 1;
592
46
  mxTemporary(exception);
593
46
  slot = property->value.disposableStack.stack;
594
62
  while (slot) {
595
16
    txSlot* dispose = slot;
596
16
    txSlot* resource = slot->next;
597
16
    mxTry(the) {
598
16
      if (dispose->flag & XS_BASE_FLAG) {
599
4
        mxPushUndefined();
600
4
        mxPushSlot(dispose);
601
4
        mxCall();
602
4
        mxPushSlot(resource);
603
4
        mxRunCount(1);
604
4
        mxPop();
605
4
      }
606
12
      else {
607
12
        mxPushSlot(resource);
608
12
        mxPushSlot(dispose);
609
12
        mxCall();
610
12
        mxRunCount(0);
611
12
        mxPop();
612
12
      }
613
16
    }
614
16
    mxCatch(the) {
615
5
      if (selector == 0) {
616
2
        mxPush(mxSuppressedErrorConstructor);
617
2
        mxNew();
618
2
        mxPush(mxException);
619
2
        mxPushSlot(exception);
620
2
        mxRunCount(2);
621
2
        mxPullSlot(exception);
622
2
      }
623
3
      else {
624
3
        *exception = mxException;
625
3
        selector = 0;
626
3
      }
627
5
      mxException = mxUndefined;
628
5
    }
629
16
    slot = resource->next;
630
16
  }
631
46
  if (selector == 0) {
632
3
    mxException.kind = exception->kind;
633
3
    mxException.value = exception->value;
634
3
    fxJump(the);
635
3
  }
636
46
}
637
638
void fx_DisposableStack_prototype_move(txMachine* the)
639
20
{
640
20
  txSlot* instance = fxCheckDisposableStackInstance(the, mxThis, 1, 1);
641
20
  txSlot* property = instance->next;
642
20
  txSlot* resultInstance;
643
20
  txSlot* resultProperty;
644
20
  mxPush(mxDisposableStackConstructor);
645
20
  fxGetPrototypeFromConstructor(the, &mxDisposableStackPrototype);
646
20
  resultInstance = fxNewSlot(the);
647
20
  resultInstance->kind = XS_INSTANCE_KIND;
648
20
  resultInstance->value.instance.garbage = C_NULL;
649
20
  resultInstance->value.instance.prototype = the->stack->value.reference;
650
20
  the->stack->kind = XS_REFERENCE_KIND;
651
20
  the->stack->value.reference = resultInstance;
652
20
  mxPullSlot(mxResult);
653
20
  resultProperty = resultInstance->next = fxNewSlot(the);
654
20
  resultProperty->flag = XS_INTERNAL_FLAG;
655
20
  resultProperty->kind = XS_DISPOSABLE_STACK_KIND;
656
20
  resultProperty->value.disposableStack.stack = property->value.disposableStack.stack;
657
20
  resultProperty->value.disposableStack.disposed = 0;
658
20
  property->value.disposableStack.stack = C_NULL;
659
20
  property->value.disposableStack.disposed = 1;
660
20
}
661
662
void fx_DisposableStack_prototype_use(txMachine* the)
663
66
{
664
66
  txSlot* instance = fxCheckDisposableStackInstance(the, mxThis, 1, 1);
665
66
  txSlot* property = instance->next;
666
66
  txSlot* resource;
667
66
  if (mxArgc > 0)
668
21
    mxPushSlot(mxArgv(0));
669
45
  else
670
45
    mxPushUndefined();
671
66
  resource = the->stack;
672
66
  if (!mxIsNull(resource) && !mxIsUndefined(resource)) {
673
16
    mxPushSlot(resource);
674
16
    mxGetID(mxID(_Symbol_dispose));
675
16
    fxDisposableStackPush(the, property);
676
16
    mxPop();
677
16
  }
678
66
  mxPullSlot(mxResult);
679
66
}
680
681
void fxDisposableStackPush(txMachine* the, txSlot* property)
682
88
{
683
88
  txSlot* dispose = the->stack;
684
88
  txSlot* resource = dispose + 1;
685
88
  txSlot** address = &property->value.disposableStack.stack;
686
88
  txSlot* slot;
687
88
  if (!fxIsCallable(the, dispose))
688
52
    mxTypeError("dispose: not a function");
689
    
690
36
  slot = fxNewSlot(the);
691
36
  slot->next = *address;
692
36
  slot->kind = resource->kind;
693
36
  slot->value = resource->value;
694
36
  *address = slot;
695
  
696
36
  slot = fxNewSlot(the);
697
36
  slot->next = *address;
698
36
  slot->kind = dispose->kind;
699
36
  slot->value = dispose->value;
700
36
  *address = slot;
701
36
}
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
104
{
710
104
  if (slot->kind == XS_REFERENCE_KIND) {
711
50
    txSlot* instance = slot->value.reference;
712
50
    if (((slot = instance->next)) && (slot->flag & XS_INTERNAL_FLAG) && (slot->kind == XS_ASYNC_DISPOSABLE_STACK_KIND)) {
713
12
      if (mutable && (slot->flag & XS_DONT_SET_FLAG))
714
0
        mxTypeError("this: read-only AsyncDisposableStack instance");
715
12
      if (disposable && slot->value.disposableStack.disposed)
716
0
        mxReferenceError("this: disposed AsyncDisposableStack instance");
717
12
      return instance;
718
12
    }
719
50
  }
720
104
  mxTypeError("this: not a AsyncDisposableStack instance");
721
0
  return C_NULL;
722
104
}
723
void fx_AsyncDisposableStack(txMachine* the)
724
185k
{
725
185k
  txSlot* instance;
726
185k
  txSlot* property;
727
185k
  txSlot* function;
728
185k
  txSlot* home;
729
185k
  if (mxIsUndefined(mxTarget))
730
3
    mxTypeError("call: AsyncDisposableStack");
731
185k
  mxPushSlot(mxTarget);
732
185k
  fxGetPrototypeFromConstructor(the, &mxAsyncDisposableStackPrototype);
733
185k
  instance = fxNewSlot(the);
734
185k
  instance->kind = XS_INSTANCE_KIND;
735
185k
  instance->value.instance.garbage = C_NULL;
736
185k
  instance->value.instance.prototype = the->stack->value.reference;
737
185k
  the->stack->kind = XS_REFERENCE_KIND;
738
185k
  the->stack->value.reference = instance;
739
185k
  mxPullSlot(mxResult);
740
185k
  property = instance->next = fxNewSlot(the);
741
185k
  property->flag = XS_INTERNAL_FLAG;
742
185k
  property->kind = XS_ASYNC_DISPOSABLE_STACK_KIND;
743
185k
  property->value.disposableStack.stack = C_NULL;
744
185k
  property->value.disposableStack.disposed = 0;
745
  
746
185k
    property = fxNextUndefinedProperty(the, property, XS_NO_ID, XS_INTERNAL_FLAG);
747
185k
  function = fxNewHostFunction(the, fxAsyncDisposableStackResolve, 1, XS_NO_ID, mxAsyncGeneratorResolveYieldProfileID);
748
185k
  home = mxFunctionInstanceHome(function);
749
185k
  home->value.home.object = instance;
750
185k
    property = fxNextSlotProperty(the, property, the->stack, XS_NO_ID, XS_INTERNAL_FLAG);
751
185k
  mxPop();
752
185k
  function = fxNewHostFunction(the, fxAsyncDisposableStackReject, 1, XS_NO_ID, mxAsyncGeneratorRejectYieldProfileID);
753
185k
  home = mxFunctionInstanceHome(function);
754
185k
  home->value.home.object = instance;
755
185k
    property = fxNextSlotProperty(the, property, the->stack, XS_NO_ID, XS_INTERNAL_FLAG);
756
185k
  mxPop();
757
185k
    property = fxNextUndefinedProperty(the, property, XS_NO_ID, XS_INTERNAL_FLAG);
758
185k
    property = fxNextUndefinedProperty(the, property, XS_NO_ID, XS_INTERNAL_FLAG);
759
185k
}
760
761
void fx_AsyncDisposableStack_prototype_get_disposed(txMachine* the)
762
10
{
763
10
  txSlot* instance = fxCheckAsyncDisposableStackInstance(the, mxThis, 0, 0);
764
10
  txSlot* property = instance->next;
765
10
  mxResult->value.boolean = property->value.disposableStack.disposed;
766
10
  mxResult->kind = XS_BOOLEAN_KIND;
767
10
}
768
769
void fx_AsyncDisposableStack_prototype_adopt(txMachine* the)
770
22
{
771
22
  txSlot* instance = fxCheckAsyncDisposableStackInstance(the, mxThis, 1, 1);
772
22
  txSlot* property = instance->next;
773
22
  if (mxArgc > 0) 
774
0
    mxPushSlot(mxArgv(0));
775
22
  else
776
22
    mxPushUndefined();
777
22
  if (mxArgc > 1) 
778
0
    mxPushSlot(mxArgv(1));
779
22
  else
780
22
    mxPushUndefined();
781
22
  fxAsyncDisposableStackPush(the, property);
782
22
  property->value.disposableStack.stack->flag |= XS_BASE_FLAG;
783
22
  mxPop();
784
22
  mxPullSlot(mxResult);
785
22
}
786
787
void fx_AsyncDisposableStack_prototype_defer(txMachine* the)
788
23
{
789
23
  txSlot* instance = fxCheckAsyncDisposableStackInstance(the, mxThis, 1, 1);
790
23
  txSlot* property = instance->next;
791
23
  mxPushUndefined();
792
23
  if (mxArgc > 0) 
793
0
    mxPushSlot(mxArgv(0));
794
23
  else
795
23
    mxPushUndefined();
796
23
  fxAsyncDisposableStackPush(the, property);
797
23
  mxPop();
798
23
  mxPop();
799
23
}  
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
21
{
851
21
  txSlot* instance = fxCheckAsyncDisposableStackInstance(the, mxThis, 1, 1);
852
21
  txSlot* property = instance->next;
853
21
  txSlot* resultInstance;
854
21
  txSlot* resultProperty;
855
21
  txSlot* function;
856
21
  txSlot* home;
857
21
  mxPush(mxAsyncDisposableStackConstructor);
858
21
  fxGetPrototypeFromConstructor(the, &mxAsyncDisposableStackPrototype);
859
21
  resultInstance = fxNewSlot(the);
860
21
  resultInstance->kind = XS_INSTANCE_KIND;
861
21
  resultInstance->value.instance.garbage = C_NULL;
862
21
  resultInstance->value.instance.prototype = the->stack->value.reference;
863
21
  the->stack->kind = XS_REFERENCE_KIND;
864
21
  the->stack->value.reference = resultInstance;
865
21
  mxPullSlot(mxResult);
866
21
  resultProperty = resultInstance->next = fxNewSlot(the);
867
21
  resultProperty->flag = XS_INTERNAL_FLAG;
868
21
  resultProperty->kind = XS_ASYNC_DISPOSABLE_STACK_KIND;
869
21
  resultProperty->value.disposableStack.stack = property->value.disposableStack.stack;
870
21
  resultProperty->value.disposableStack.disposed = 0;
871
  
872
21
    resultProperty = fxNextUndefinedProperty(the, resultProperty, XS_NO_ID, XS_INTERNAL_FLAG);
873
21
  function = fxNewHostFunction(the, fxAsyncDisposableStackResolve, 1, XS_NO_ID, mxAsyncGeneratorResolveYieldProfileID);
874
21
  home = mxFunctionInstanceHome(function);
875
21
  home->value.home.object = resultInstance;
876
21
    resultProperty = fxNextSlotProperty(the, resultProperty, the->stack, XS_NO_ID, XS_INTERNAL_FLAG);
877
21
  mxPop();
878
21
  function = fxNewHostFunction(the, fxAsyncDisposableStackReject, 1, XS_NO_ID, mxAsyncGeneratorRejectYieldProfileID);
879
21
  home = mxFunctionInstanceHome(function);
880
21
  home->value.home.object = resultInstance;
881
21
    resultProperty = fxNextSlotProperty(the, resultProperty, the->stack, XS_NO_ID, XS_INTERNAL_FLAG);
882
21
  mxPop();
883
21
    resultProperty = fxNextUndefinedProperty(the, resultProperty, XS_NO_ID, XS_INTERNAL_FLAG);
884
21
    resultProperty = fxNextUndefinedProperty(the, resultProperty, XS_NO_ID, XS_INTERNAL_FLAG);
885
  
886
21
  property->value.disposableStack.stack = C_NULL;
887
21
  property->value.disposableStack.disposed = 1;
888
21
}
889
890
void fx_AsyncDisposableStack_prototype_use(txMachine* the)
891
28
{
892
28
  txSlot* instance = fxCheckAsyncDisposableStackInstance(the, mxThis, 1, 1);
893
28
  txSlot* property = instance->next;
894
28
  txSlot* resource;
895
28
  if (mxArgc > 0)
896
11
    mxPushSlot(mxArgv(0));
897
17
  else
898
17
    mxPushUndefined();
899
28
  resource = the->stack;
900
28
  if (!mxIsNull(resource) && !mxIsUndefined(resource)) {
901
11
    mxPushSlot(resource);
902
11
    mxGetID(mxID(_Symbol_asyncDispose));
903
11
    if (!fxIsCallable(the, the->stack)) {
904
11
      mxPop();
905
11
      mxPushSlot(resource);
906
11
      mxGetID(mxID(_Symbol_dispose));
907
11
    }
908
11
    fxAsyncDisposableStackPush(the, property);
909
11
    mxPop();
910
11
  }
911
28
  mxPullSlot(mxResult);
912
28
}
913
914
void fxAsyncDisposableStackPush(txMachine* the, txSlot* property)
915
11
{
916
11
  txSlot* dispose = the->stack;
917
11
  txSlot* resource = dispose + 1;
918
11
  txSlot** address = &property->value.disposableStack.stack;
919
11
  txSlot* slot;
920
11
  if (!fxIsCallable(the, dispose))
921
11
    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