Coverage Report

Created: 2026-07-16 06:43

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
31.9k
{
74
31.9k
  txSlot* slot;
75
31.9k
  txSlot* prototype;
76
31.9k
  txSlot* instance;
77
31.9k
#if mxExplicitResourceManagement
78
31.9k
  txSlot* property;
79
31.9k
#endif
80
  
81
31.9k
  mxPush(mxObjectPrototype);
82
31.9k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
83
31.9k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Error_toString), 0, mxID(_toString), XS_DONT_ENUM_FLAG);
84
31.9k
  slot = fxNextStringXProperty(the, slot, (txString)gxErrorNames[XS_UNKNOWN_ERROR], mxID(_name), XS_DONT_ENUM_FLAG);
85
31.9k
  slot = fxNextStringXProperty(the, slot, "", mxID(_message), XS_DONT_ENUM_FLAG);
86
31.9k
  slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_Error_prototype_get_stack), mxCallback(fx_Error_prototype_set_stack), mxID(_stack), XS_DONT_ENUM_FLAG);
87
31.9k
  mxErrorPrototype = *the->stack;
88
31.9k
  prototype = fxBuildHostConstructor(the, mxCallback(fx_Error), 1, mxID(_Error));
89
31.9k
  mxErrorConstructor = *the->stack;
90
31.9k
#if mxErrorIsError
91
31.9k
  slot = fxLastProperty(the, prototype);
92
31.9k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Error_isError), 1, mxID(_isError), XS_DONT_ENUM_FLAG);
93
31.9k
#endif
94
31.9k
  mxPop();
95
31.9k
  mxPush(mxErrorPrototype);
96
31.9k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
97
31.9k
  slot = fxNextStringXProperty(the, slot, (txString)gxErrorNames[XS_AGGREGATE_ERROR], mxID(_name), XS_DONT_ENUM_FLAG);
98
31.9k
  slot = fxNextStringXProperty(the, slot, "", mxID(_message), XS_DONT_ENUM_FLAG);
99
31.9k
  mxAggregateErrorPrototype = *the->stack;
100
31.9k
  instance = fxBuildHostConstructor(the, mxCallback(fx_AggregateError), 2, mxID(_AggregateError));
101
31.9k
  instance->value.instance.prototype = prototype;
102
31.9k
  mxAggregateErrorConstructor = *the->stack;
103
31.9k
  mxPop();
104
31.9k
  mxPush(mxErrorPrototype);
105
31.9k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
106
31.9k
  slot = fxNextStringXProperty(the, slot, (txString)gxErrorNames[XS_EVAL_ERROR], mxID(_name), XS_DONT_ENUM_FLAG);
107
31.9k
  slot = fxNextStringXProperty(the, slot, "", mxID(_message), XS_DONT_ENUM_FLAG);
108
31.9k
  mxEvalErrorPrototype = *the->stack;
109
31.9k
  instance = fxBuildHostConstructor(the, mxCallback(fx_EvalError), 1, mxID(_EvalError));
110
31.9k
  instance->value.instance.prototype = prototype;
111
31.9k
  mxEvalErrorConstructor = *the->stack;
112
31.9k
  mxPop();
113
31.9k
  mxPush(mxErrorPrototype);
114
31.9k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
115
31.9k
  slot = fxNextStringXProperty(the, slot, (txString)gxErrorNames[XS_RANGE_ERROR], mxID(_name), XS_DONT_ENUM_FLAG);
116
31.9k
  slot = fxNextStringXProperty(the, slot, "", mxID(_message), XS_DONT_ENUM_FLAG);
117
31.9k
  mxRangeErrorPrototype = *the->stack;
118
31.9k
  instance = fxBuildHostConstructor(the, mxCallback(fx_RangeError), 1, mxID(_RangeError));
119
31.9k
  instance->value.instance.prototype = prototype;
120
31.9k
  mxRangeErrorConstructor = *the->stack;
121
31.9k
  mxPop();
122
31.9k
  mxPush(mxErrorPrototype);
123
31.9k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
124
31.9k
  slot = fxNextStringXProperty(the, slot, (txString)gxErrorNames[XS_REFERENCE_ERROR], mxID(_name), XS_DONT_ENUM_FLAG);
125
31.9k
  slot = fxNextStringXProperty(the, slot, "", mxID(_message), XS_DONT_ENUM_FLAG);
126
31.9k
  mxReferenceErrorPrototype = *the->stack;
127
31.9k
  instance = fxBuildHostConstructor(the, mxCallback(fx_ReferenceError), 1, mxID(_ReferenceError));
128
31.9k
  instance->value.instance.prototype = prototype;
129
31.9k
  mxReferenceErrorConstructor = *the->stack;
130
31.9k
  mxPop();
131
31.9k
  mxPush(mxErrorPrototype);
132
31.9k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
133
31.9k
  slot = fxNextStringXProperty(the, slot, (txString)gxErrorNames[XS_SYNTAX_ERROR], mxID(_name), XS_DONT_ENUM_FLAG);
134
31.9k
  slot = fxNextStringXProperty(the, slot, "", mxID(_message), XS_DONT_ENUM_FLAG);
135
31.9k
  mxSyntaxErrorPrototype = *the->stack;
136
31.9k
  instance = fxBuildHostConstructor(the, mxCallback(fx_SyntaxError), 1, mxID(_SyntaxError));
137
31.9k
  instance->value.instance.prototype = prototype;
138
31.9k
  mxSyntaxErrorConstructor = *the->stack;
139
31.9k
  mxPop();
140
31.9k
  mxPush(mxErrorPrototype);
141
31.9k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
142
31.9k
  slot = fxNextStringXProperty(the, slot, (txString)gxErrorNames[XS_TYPE_ERROR], mxID(_name), XS_DONT_ENUM_FLAG);
143
31.9k
  slot = fxNextStringXProperty(the, slot, "", mxID(_message), XS_DONT_ENUM_FLAG);
144
31.9k
  mxTypeErrorPrototype = *the->stack;
145
31.9k
  instance = fxBuildHostConstructor(the, mxCallback(fx_TypeError), 1, mxID(_TypeError));
146
31.9k
  instance->value.instance.prototype = prototype;
147
31.9k
  mxTypeErrorConstructor = *the->stack;
148
31.9k
  mxPop();
149
31.9k
  mxPush(mxErrorPrototype);
150
31.9k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
151
31.9k
  slot = fxNextStringXProperty(the, slot, (txString)gxErrorNames[XS_URI_ERROR], mxID(_name), XS_DONT_ENUM_FLAG);
152
31.9k
  slot = fxNextStringXProperty(the, slot, "", mxID(_message), XS_DONT_ENUM_FLAG);
153
31.9k
  mxURIErrorPrototype = *the->stack;
154
31.9k
  instance = fxBuildHostConstructor(the, mxCallback(fx_URIError), 1, mxID(_URIError));
155
31.9k
  instance->value.instance.prototype = prototype;
156
31.9k
  mxURIErrorConstructor = *the->stack;
157
31.9k
  mxPop();
158
159
31.9k
#if mxExplicitResourceManagement
160
31.9k
  mxPush(mxErrorPrototype);
161
31.9k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
162
31.9k
  slot = fxNextStringXProperty(the, slot, (txString)gxErrorNames[XS_SUPPRESSED_ERROR], mxID(_name), XS_DONT_ENUM_FLAG);
163
31.9k
  slot = fxNextStringXProperty(the, slot, "", mxID(_message), XS_DONT_ENUM_FLAG);
164
31.9k
  mxSuppressedErrorPrototype = *the->stack;
165
31.9k
  instance = fxBuildHostConstructor(the, mxCallback(fx_SuppressedError), 3, mxID(_SuppressedError));
166
31.9k
  instance->value.instance.prototype = prototype;
167
31.9k
  mxSuppressedErrorConstructor = *the->stack;
168
31.9k
  mxPop();
169
170
31.9k
  mxPush(mxObjectPrototype);
171
31.9k
    slot = fxLastProperty(the, fxNewObjectInstance(the));
172
31.9k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Error_toString), 0, mxID(_toString), XS_DONT_ENUM_FLAG);
173
31.9k
  slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_DisposableStack_prototype_get_disposed), C_NULL, mxID(_disposed), XS_DONT_ENUM_FLAG);
174
31.9k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DisposableStack_prototype_adopt), 2, mxID(_adopt), XS_DONT_ENUM_FLAG);
175
31.9k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DisposableStack_prototype_defer), 1, mxID(_defer), XS_DONT_ENUM_FLAG);
176
31.9k
  property = slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DisposableStack_prototype_dispose), 0, mxID(_dispose), XS_DONT_ENUM_FLAG);
177
31.9k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DisposableStack_prototype_move), 0, mxID(_move), XS_DONT_ENUM_FLAG);
178
31.9k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DisposableStack_prototype_use), 1, mxID(_use), XS_DONT_ENUM_FLAG);
179
31.9k
  slot = fxNextSlotProperty(the, slot, property, mxID(_Symbol_dispose), XS_DONT_ENUM_FLAG);
180
31.9k
  slot = fxNextStringXProperty(the, slot, "DisposableStack", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
181
31.9k
  mxDisposableStackPrototype = *the->stack;
182
31.9k
  slot = fxBuildHostConstructor(the, mxCallback(fx_DisposableStack), 0, mxID(_DisposableStack));
183
31.9k
  mxDisposableStackConstructor = *the->stack;
184
31.9k
  mxPop();
185
  
186
31.9k
  mxPush(mxObjectPrototype);
187
31.9k
    slot = fxLastProperty(the, fxNewObjectInstance(the));
188
31.9k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Error_toString), 0, mxID(_toString), XS_DONT_ENUM_FLAG);
189
31.9k
  slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_AsyncDisposableStack_prototype_get_disposed), C_NULL, mxID(_disposed), XS_DONT_ENUM_FLAG);
190
31.9k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_AsyncDisposableStack_prototype_adopt), 2, mxID(_adopt), XS_DONT_ENUM_FLAG);
191
31.9k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_AsyncDisposableStack_prototype_defer), 1, mxID(_defer), XS_DONT_ENUM_FLAG);
192
31.9k
  property = slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_AsyncDisposableStack_prototype_disposeAsync), 0, mxID(_disposeAsync), XS_DONT_ENUM_FLAG);
193
31.9k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_AsyncDisposableStack_prototype_move), 0, mxID(_move), XS_DONT_ENUM_FLAG);
194
31.9k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_AsyncDisposableStack_prototype_use), 1, mxID(_use), XS_DONT_ENUM_FLAG);
195
31.9k
  slot = fxNextSlotProperty(the, slot, property, mxID(_Symbol_asyncDispose), XS_DONT_ENUM_FLAG);
196
31.9k
  slot = fxNextStringXProperty(the, slot, "AsyncDisposableStack", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
197
31.9k
  mxAsyncDisposableStackPrototype = *the->stack;
198
31.9k
  slot = fxBuildHostConstructor(the, mxCallback(fx_AsyncDisposableStack), 0, mxID(_AsyncDisposableStack));
199
31.9k
  mxAsyncDisposableStackConstructor = *the->stack;
200
31.9k
  mxPop();
201
31.9k
#endif
202
31.9k
}
203
204
void fxCaptureErrorStack(txMachine* the, txSlot* internal, txSlot* frame)
205
2.38M
{
206
2.38M
  txSlot* slot = internal->value.reference = fxNewSlot(the);
207
2.38M
  slot->kind = XS_INSTANCE_KIND;
208
2.38M
  slot->value.instance.garbage = C_NULL;
209
2.38M
  slot->value.instance.prototype = C_NULL;
210
18.5M
  while (frame->next) {
211
16.1M
    txSlot* environment = mxFrameToEnvironment(frame);
212
16.1M
    txSlot* function = frame + 2;
213
16.1M
    if (function->kind == XS_REFERENCE_KIND) {
214
16.0M
      function = function->value.reference;
215
16.0M
      if (mxIsFunction(function)) {
216
16.0M
        txSlot* name = mxBehaviorGetProperty(the, function, mxID(_name), 0, XS_OWN);
217
16.0M
        slot = slot->next = fxNewSlot(the);
218
16.0M
        slot->flag = XS_GET_ONLY;
219
16.0M
        slot->kind = XS_KEY_KIND;
220
16.0M
        slot->ID = environment->ID;
221
16.0M
        slot->value.key.string = C_NULL;
222
16.0M
        slot->value.key.sum = environment->value.environment.line;
223
16.0M
        if (name && ((name->kind == XS_STRING_KIND) || (name->kind == XS_STRING_X_KIND))) {
224
16.0M
          if (name->kind == XS_STRING_X_KIND)
225
0
            slot->kind = XS_KEY_X_KIND;
226
16.0M
          slot->value.key.string = name->value.string;
227
16.0M
        }
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
16.0M
      }
247
16.0M
    }
248
16.1M
    frame = frame->next;
249
16.1M
  }
250
2.38M
}
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
392
{
259
392
  mxResult->kind = XS_BOOLEAN_KIND;
260
392
  mxResult->value.boolean = 0;
261
392
  if (mxArgc > 0) {
262
230
    txSlot* instance = fxGetInstance(the, mxArgv(0));
263
230
    if (instance) {
264
56
      txSlot* internal = instance->next;
265
56
      if (internal && (internal->kind == XS_ERROR_KIND)) {
266
30
        mxResult->value.boolean = 1;
267
30
      }
268
56
    }
269
230
  }
270
392
}
271
272
txSlot* fx_Error_aux(txMachine* the, txError error, txInteger i)
273
550k
{
274
550k
  txSlot* instance;
275
550k
  txSlot* slot;
276
550k
  if (!mxHasTarget)
277
823
    mxPushSlot(mxFunction);
278
549k
  else
279
549k
    mxPushSlot(mxTarget);
280
550k
  fxGetPrototypeFromConstructor(the, &mxErrorPrototypes(error));
281
550k
  instance = fxNewObjectInstance(the);
282
550k
  mxPullSlot(mxResult);
283
550k
  slot = instance->next = fxNewSlot(the);
284
550k
  slot->flag = XS_INTERNAL_FLAG;
285
550k
  slot->kind = XS_ERROR_KIND;
286
550k
  slot->value.error.info = C_NULL;
287
550k
  slot->value.error.which = error;
288
550k
  if (gxDefaults.captureErrorStack)
289
550k
    gxDefaults.captureErrorStack(the, slot, the->frame->next);
290
550k
  if ((mxArgc > i) && (mxArgv(i)->kind != XS_UNDEFINED_KIND)) {
291
549k
    fxToString(the, mxArgv(i));
292
549k
    slot = fxNextSlotProperty(the, slot, mxArgv(i), mxID(_message), XS_DONT_ENUM_FLAG);
293
549k
  }
294
550k
  i++;
295
550k
  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
550k
  return slot;
304
550k
}
305
306
void fx_Error_toString(txMachine* the)
307
2.22k
{
308
2.22k
  txSlot* name;
309
2.22k
  txSlot* message;
310
2.22k
  if (mxThis->kind != XS_REFERENCE_KIND)
311
9
    mxTypeError("this: not an object");
312
2.21k
  mxPushSlot(mxThis);
313
2.21k
  mxGetID(mxID(_name));
314
2.21k
  if (the->stack->kind == XS_UNDEFINED_KIND) 
315
1.41k
    fxStringX(the, the->stack, "Error");
316
796
  else  
317
796
    fxToString(the, the->stack);
318
2.21k
  name = the->stack;
319
2.21k
  mxPushSlot(mxThis);
320
2.21k
  mxGetID(mxID(_message));
321
2.21k
  if (the->stack->kind == XS_UNDEFINED_KIND) 
322
1.41k
    *the->stack = mxEmptyString;
323
797
  else  
324
797
    fxToString(the, the->stack);
325
2.21k
  message = the->stack;
326
2.21k
  if (c_isEmpty(name->value.string))
327
3
    *mxResult = *message;
328
2.20k
  else if (c_isEmpty(message->value.string))
329
2.04k
    *mxResult = *name;
330
169
  else {
331
169
    fxStringX(the, mxResult, "");
332
169
    fxConcatString(the, mxResult, name);
333
169
    fxConcatStringC(the, mxResult, ": ");
334
169
    fxConcatString(the, mxResult, message);
335
169
  }
336
2.21k
  the->stack += 2;
337
2.21k
}
338
339
void fx_AggregateError(txMachine* the)
340
162
{
341
162
  txSlot* stack = the->stack;
342
162
  txSlot* property = fx_Error_aux(the, XS_AGGREGATE_ERROR, 1);
343
162
  txSlot* array;
344
162
  txSlot** address;
345
162
  txIndex length = 0;
346
162
  txSlot* iterator;
347
162
  txSlot* next;
348
162
  txSlot* value;
349
162
  txSlot* slot;
350
  
351
162
  mxPush(mxArrayPrototype);
352
162
  array = fxNewArrayInstance(the);
353
162
  fxNextSlotProperty(the, property, the->stack, mxID(_errors), XS_DONT_ENUM_FLAG);
354
162
  address = &array->next->next;
355
162
  mxTemporary(iterator);
356
162
  mxTemporary(next);
357
162
  fxGetIterator(the, mxArgv(0), iterator, next, 0);
358
162
  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
162
  array->next->value.array.length = length;
373
162
  fxCacheArray(the, array);
374
  
375
162
  the->stack = stack;
376
162
}
377
378
void fx_EvalError(txMachine* the)
379
10
{
380
10
  fx_Error_aux(the, XS_EVAL_ERROR, 0);
381
10
}
382
383
void fx_RangeError(txMachine* the)
384
135
{
385
135
  fx_Error_aux(the, XS_RANGE_ERROR, 0);
386
135
}
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
483k
{
395
483k
  fx_Error_aux(the, XS_SYNTAX_ERROR, 0);
396
483k
}
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.1k
{
410
36.1k
  txSlot* slot;
411
36.1k
  if (mxThis->kind != XS_REFERENCE_KIND)
412
22
    mxTypeError("this: not an object");
413
36.1k
  slot = mxThis->value.reference->next;
414
36.1k
  if (slot && (slot->kind == XS_ERROR_KIND)) {
415
1
    fxStringX(the, mxResult, "");
416
1
    mxPushSlot(mxThis);
417
1
    mxGetID(mxID(_name));
418
1
    if (the->stack->kind != XS_UNDEFINED_KIND)  {
419
1
      fxToString(the, the->stack);
420
1
      fxConcatString(the, mxResult, the->stack);
421
1
    }
422
0
    else
423
0
      fxConcatStringC(the, mxResult, "Error");
424
1
    mxPop();
425
1
    mxPushSlot(mxThis);
426
1
    mxGetID(mxID(_message));
427
1
    if (the->stack->kind != XS_UNDEFINED_KIND) {
428
1
      fxToString(the, the->stack);
429
1
      if (!c_isEmpty(the->stack->value.string)) {
430
0
        fxConcatStringC(the, mxResult, ": ");
431
0
        fxConcatString(the, mxResult, the->stack);
432
0
      }
433
1
    }
434
1
    mxPop();
435
1
    slot = slot->value.reference;
436
1
    if (slot) {
437
1
      slot = slot->next;
438
2
      while (slot) {
439
1
        fxConcatStringC(the, mxResult, "\n at");
440
1
        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
1
        fxConcatStringC(the, mxResult, " (");
445
1
        if (slot->ID != XS_NO_ID) {
446
1
          fxIDToString(the, slot->ID, the->nameBuffer, sizeof(the->nameBuffer));
447
1
          fxConcatStringC(the, mxResult, the->nameBuffer);
448
1
          fxConcatStringC(the, mxResult, ":");
449
1
          fxIntegerToString(the, (txInteger)slot->value.key.sum, the->nameBuffer, sizeof(the->nameBuffer));
450
1
          fxConcatStringC(the, mxResult, the->nameBuffer);
451
1
        }
452
1
        fxConcatStringC(the, mxResult, ")");
453
1
        slot = slot->next;
454
1
      }
455
1
    }
456
1
  }
457
36.1k
}
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
437
{
497
437
  txSlot* property = fx_Error_aux(the, XS_SUPPRESSED_ERROR, 2);
498
437
  property = fxNextSlotProperty(the, property, mxArgv(0), mxID(_error), XS_DONT_ENUM_FLAG);
499
437
  property = fxNextSlotProperty(the, property, mxArgv(1), mxID(_suppressed), XS_DONT_ENUM_FLAG);
500
437
}
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
275
{
507
275
  if (slot->kind == XS_REFERENCE_KIND) {
508
193
    txSlot* instance = slot->value.reference;
509
193
    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
193
  }
517
275
  mxTypeError("this: not a DisposableStack instance");
518
0
  return C_NULL;
519
275
}
520
521
void fx_DisposableStack(txMachine* the)
522
116k
{
523
116k
  txSlot* instance;
524
116k
  txSlot* property;
525
116k
  if (!mxHasTarget)
526
1
    mxTypeError("call: DisposableStack");
527
116k
  mxPushSlot(mxTarget);
528
116k
  fxGetPrototypeFromConstructor(the, &mxDisposableStackPrototype);
529
116k
  instance = fxNewSlot(the);
530
116k
  instance->kind = XS_INSTANCE_KIND;
531
116k
  instance->value.instance.garbage = C_NULL;
532
116k
  instance->value.instance.prototype = the->stack->value.reference;
533
116k
  the->stack->kind = XS_REFERENCE_KIND;
534
116k
  the->stack->value.reference = instance;
535
116k
  mxPullSlot(mxResult);
536
116k
  property = instance->next = fxNewSlot(the);
537
116k
  property->flag = XS_INTERNAL_FLAG;
538
116k
  property->kind = XS_DISPOSABLE_STACK_KIND;
539
116k
  property->value.disposableStack.stack = C_NULL;
540
116k
  property->value.disposableStack.disposed = 0;
541
116k
}
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
55
{
553
55
  txSlot* instance = fxCheckDisposableStackInstance(the, mxThis, 1, 1);
554
55
  txSlot* property = instance->next;
555
55
  if (mxArgc > 0) 
556
36
    mxPushSlot(mxArgv(0));
557
19
  else
558
19
    mxPushUndefined();
559
55
  if (mxArgc > 1) 
560
35
    mxPushSlot(mxArgv(1));
561
20
  else
562
20
    mxPushUndefined();
563
55
  fxDisposableStackPush(the, property);
564
55
  property->value.disposableStack.stack->flag |= XS_BASE_FLAG;
565
55
  mxPop();
566
55
  mxPullSlot(mxResult);
567
55
}
568
569
void fx_DisposableStack_prototype_defer(txMachine* the)
570
51
{
571
51
  txSlot* instance = fxCheckDisposableStackInstance(the, mxThis, 1, 1);
572
51
  txSlot* property = instance->next;
573
51
  mxPushUndefined();
574
51
  if (mxArgc > 0) 
575
30
    mxPushSlot(mxArgv(0));
576
21
  else
577
21
    mxPushUndefined();
578
51
  fxDisposableStackPush(the, property);
579
51
  mxPop();
580
51
  mxPop();
581
51
}  
582
583
void fx_DisposableStack_prototype_dispose(txMachine* the)
584
50
{
585
50
  txSlot* instance = fxCheckDisposableStackInstance(the, mxThis, 1, 0);
586
50
  txSlot* property = instance->next;
587
50
  txSlot* exception;
588
50
  txBoolean selector = 1;
589
50
  txSlot* slot;
590
50
  if (property->value.disposableStack.disposed)
591
3
    return;
592
47
  property->value.disposableStack.disposed = 1;
593
47
  mxTemporary(exception);
594
47
  slot = property->value.disposableStack.stack;
595
69
  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
47
  if (selector == 0) {
633
4
    mxException.kind = exception->kind;
634
4
    mxException.value = exception->value;
635
4
    fxJump(the);
636
4
  }
637
47
}
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
67
{
665
67
  txSlot* instance = fxCheckDisposableStackInstance(the, mxThis, 1, 1);
666
67
  txSlot* property = instance->next;
667
67
  txSlot* resource;
668
67
  if (mxArgc > 0)
669
28
    mxPushSlot(mxArgv(0));
670
39
  else
671
39
    mxPushUndefined();
672
67
  resource = the->stack;
673
67
  if (!mxIsNull(resource) && !mxIsUndefined(resource)) {
674
23
    mxPushSlot(resource);
675
23
    mxGetID(mxID(_Symbol_dispose));
676
23
    fxDisposableStackPush(the, property);
677
23
    mxPop();
678
23
  }
679
67
  mxPullSlot(mxResult);
680
67
}
681
682
void fxDisposableStackPush(txMachine* the, txSlot* property)
683
89
{
684
89
  txSlot* dispose = the->stack;
685
89
  txSlot* resource = dispose + 1;
686
89
  txSlot** address = &property->value.disposableStack.stack;
687
89
  txSlot* slot;
688
89
  if (!fxIsCallable(the, dispose))
689
50
    mxTypeError("dispose: not a function");
690
    
691
39
  slot = fxNewSlot(the);
692
39
  slot->next = *address;
693
39
  slot->kind = resource->kind;
694
39
  slot->value = resource->value;
695
39
  *address = slot;
696
  
697
39
  slot = fxNewSlot(the);
698
39
  slot->next = *address;
699
39
  slot->kind = dispose->kind;
700
39
  slot->value = dispose->value;
701
39
  *address = slot;
702
39
}
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
256
{
711
256
  if (slot->kind == XS_REFERENCE_KIND) {
712
200
    txSlot* instance = slot->value.reference;
713
200
    if (((slot = instance->next)) && (slot->flag & XS_INTERNAL_FLAG) && (slot->kind == XS_ASYNC_DISPOSABLE_STACK_KIND)) {
714
137
      if (mutable && (slot->flag & XS_DONT_SET_FLAG))
715
0
        mxTypeError("this: read-only AsyncDisposableStack instance");
716
137
      if (disposable && slot->value.disposableStack.disposed)
717
19
        mxReferenceError("this: disposed AsyncDisposableStack instance");
718
118
      return instance;
719
137
    }
720
200
  }
721
256
  mxTypeError("this: not a AsyncDisposableStack instance");
722
0
  return C_NULL;
723
256
}
724
void fx_AsyncDisposableStack(txMachine* the)
725
1.45k
{
726
1.45k
  txSlot* instance;
727
1.45k
  txSlot* property;
728
1.45k
  txSlot* function;
729
1.45k
  txSlot* home;
730
1.45k
  if (!mxHasTarget)
731
1
    mxTypeError("call: AsyncDisposableStack");
732
1.45k
  mxPushSlot(mxTarget);
733
1.45k
  fxGetPrototypeFromConstructor(the, &mxAsyncDisposableStackPrototype);
734
1.45k
  instance = fxNewSlot(the);
735
1.45k
  instance->kind = XS_INSTANCE_KIND;
736
1.45k
  instance->value.instance.garbage = C_NULL;
737
1.45k
  instance->value.instance.prototype = the->stack->value.reference;
738
1.45k
  the->stack->kind = XS_REFERENCE_KIND;
739
1.45k
  the->stack->value.reference = instance;
740
1.45k
  mxPullSlot(mxResult);
741
1.45k
  property = instance->next = fxNewSlot(the);
742
1.45k
  property->flag = XS_INTERNAL_FLAG;
743
1.45k
  property->kind = XS_ASYNC_DISPOSABLE_STACK_KIND;
744
1.45k
  property->value.disposableStack.stack = C_NULL;
745
1.45k
  property->value.disposableStack.disposed = 0;
746
  
747
1.45k
    property = fxNextUndefinedProperty(the, property, XS_NO_ID, XS_INTERNAL_FLAG);
748
1.45k
  function = fxNewHostFunction(the, fxAsyncDisposableStackResolve, 1, XS_NO_ID, mxAsyncGeneratorResolveYieldProfileID);
749
1.45k
  home = mxFunctionInstanceHome(function);
750
1.45k
  home->value.home.object = instance;
751
1.45k
    property = fxNextSlotProperty(the, property, the->stack, XS_NO_ID, XS_INTERNAL_FLAG);
752
1.45k
  mxPop();
753
1.45k
  function = fxNewHostFunction(the, fxAsyncDisposableStackReject, 1, XS_NO_ID, mxAsyncGeneratorRejectYieldProfileID);
754
1.45k
  home = mxFunctionInstanceHome(function);
755
1.45k
  home->value.home.object = instance;
756
1.45k
    property = fxNextSlotProperty(the, property, the->stack, XS_NO_ID, XS_INTERNAL_FLAG);
757
1.45k
  mxPop();
758
1.45k
    property = fxNextUndefinedProperty(the, property, XS_NO_ID, XS_INTERNAL_FLAG);
759
1.45k
    property = fxNextUndefinedProperty(the, property, XS_NO_ID, XS_INTERNAL_FLAG);
760
1.45k
}
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
8
{
804
8
  txSlot* promise;
805
8
  txSlot* resolveFunction;
806
8
  txSlot* rejectFunction;
807
808
8
  mxPush(mxPromisePrototype);
809
8
  promise = fxNewPromiseInstance(the);
810
8
  mxPullSlot(mxResult);
811
8
  mxPromiseStatus(promise)->value.integer = mxPendingStatus;
812
8
  fxPushPromiseFunctions(the, promise);
813
8
  resolveFunction = the->stack + 1;
814
8
  rejectFunction = the->stack;
815
8
  mxTry(the) {
816
8
    txSlot* instance = fxCheckAsyncDisposableStackInstance(the, mxThis, 1, 0);
817
8
    txSlot* property = instance->next;
818
8
    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
8
    else {
827
8
      txSlot* exception = property->next;
828
8
      txSlot* resolveStepFunction = exception->next;
829
8
      txSlot* rejectStepFunction = resolveStepFunction->next;
830
8
      property->value.disposableStack.disposed = 1;
831
8
      property = rejectStepFunction->next;
832
8
      property->kind = resolveFunction->kind;
833
8
      property->value = resolveFunction->value;
834
8
      property = property->next;
835
8
      property->kind = rejectFunction->kind;
836
8
      property->value = rejectFunction->value;
837
8
      mxPushUndefined();
838
8
      mxPushSlot(resolveStepFunction);
839
8
      mxCall();
840
8
      mxPushUndefined();
841
8
      mxRunCount(1);
842
8
      mxPop();
843
8
    }
844
8
  }
845
8
  mxCatch(the) {
846
0
    fxRejectException(the, rejectFunction);
847
0
  }
848
8
}
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
74
{
893
74
  txSlot* instance = fxCheckAsyncDisposableStackInstance(the, mxThis, 1, 1);
894
74
  txSlot* property = instance->next;
895
74
  txSlot* resource;
896
74
  if (mxArgc > 0)
897
18
    mxPushSlot(mxArgv(0));
898
56
  else
899
56
    mxPushUndefined();
900
74
  resource = the->stack;
901
74
  if (!mxIsNull(resource) && !mxIsUndefined(resource)) {
902
15
    mxPushSlot(resource);
903
15
    mxGetID(mxID(_Symbol_asyncDispose));
904
15
    if (!fxIsCallable(the, the->stack)) {
905
10
      mxPop();
906
10
      mxPushSlot(resource);
907
10
      mxGetID(mxID(_Symbol_dispose));
908
10
    }
909
15
    fxAsyncDisposableStackPush(the, property);
910
15
    mxPop();
911
15
  }
912
59
  else {
913
59
    txSlot** address = &property->value.disposableStack.stack;
914
59
    txSlot* slot;
915
    
916
59
    slot = fxNewSlot(the);
917
59
    slot->next = *address;
918
59
    *address = slot;
919
    
920
59
    slot = fxNewSlot(the);
921
59
    slot->next = *address;
922
59
    *address = slot;
923
59
  }
924
74
  mxPullSlot(mxResult);
925
74
}
926
927
void fxAsyncDisposableStackPush(txMachine* the, txSlot* property)
928
81
{
929
81
  txSlot* dispose = the->stack;
930
81
  txSlot* resource = dispose + 1;
931
81
  txSlot** address = &property->value.disposableStack.stack;
932
81
  txSlot* slot;
933
81
  if (!fxIsCallable(the, dispose))
934
49
    mxTypeError("dispose: no a function");
935
    
936
32
  slot = fxNewSlot(the);
937
32
  slot->next = *address;
938
32
  slot->kind = resource->kind;
939
32
  slot->value = resource->value;
940
32
  *address = slot;
941
  
942
32
  slot = fxNewSlot(the);
943
32
  slot->next = *address;
944
32
  slot->kind = dispose->kind;
945
32
  slot->value = dispose->value;
946
32
  *address = slot;
947
32
}
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
8
{
973
8
  txSlot* slot = mxFunctionInstanceHome(mxFunction->value.reference);
974
8
  txSlot* instance = slot->value.home.object;
975
8
  txSlot* property = instance->next;
976
8
  txSlot* exception = property->next;
977
8
  txSlot* resolveStepFunction = exception->next;
978
8
  txSlot* rejectStepFunction = resolveStepFunction->next;
979
8
  txSlot* resolveFunction = rejectStepFunction->next;
980
8
  txSlot* rejectFunction = resolveFunction->next;
981
982
8
  slot = property->value.disposableStack.stack;
983
8
  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
8
  else {
1024
8
    if (mxIsUndefined(exception)) {
1025
8
      mxPushUndefined();
1026
8
      mxPushSlot(resolveFunction);
1027
8
      mxCall();
1028
8
      mxPushUndefined();
1029
8
      mxRunCount(1);
1030
8
      mxPop();
1031
8
    }
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
8
  }
1041
8
}
1042
1043
#endif
1044
1045
1046
1047