Coverage Report

Created: 2026-08-14 06:19

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