jseption 0.0.0-stage → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/LICENSE +26 -0
  2. package/README.md +191 -2
  3. package/dist/atoms.d.ts +255 -0
  4. package/dist/atoms.js +445 -0
  5. package/dist/atoms.js.map +1 -0
  6. package/dist/builtins/array.d.ts +3 -0
  7. package/dist/builtins/array.js +116 -0
  8. package/dist/builtins/array.js.map +1 -0
  9. package/dist/builtins/bigint.d.ts +3 -0
  10. package/dist/builtins/bigint.js +122 -0
  11. package/dist/builtins/bigint.js.map +1 -0
  12. package/dist/builtins/boolean.d.ts +2 -0
  13. package/dist/builtins/boolean.js +26 -0
  14. package/dist/builtins/boolean.js.map +1 -0
  15. package/dist/builtins/date.d.ts +3 -0
  16. package/dist/builtins/date.js +1046 -0
  17. package/dist/builtins/date.js.map +1 -0
  18. package/dist/builtins/error.d.ts +2 -0
  19. package/dist/builtins/error.js +154 -0
  20. package/dist/builtins/error.js.map +1 -0
  21. package/dist/builtins/function.d.ts +5 -0
  22. package/dist/builtins/function.js +164 -0
  23. package/dist/builtins/function.js.map +1 -0
  24. package/dist/builtins/global.d.ts +2 -0
  25. package/dist/builtins/global.js +29 -0
  26. package/dist/builtins/global.js.map +1 -0
  27. package/dist/builtins/index.d.ts +3 -0
  28. package/dist/builtins/index.js +139 -0
  29. package/dist/builtins/index.js.map +1 -0
  30. package/dist/builtins/json.d.ts +6 -0
  31. package/dist/builtins/json.js +984 -0
  32. package/dist/builtins/json.js.map +1 -0
  33. package/dist/builtins/mapset.d.ts +4 -0
  34. package/dist/builtins/mapset.js +234 -0
  35. package/dist/builtins/mapset.js.map +1 -0
  36. package/dist/builtins/math.d.ts +2 -0
  37. package/dist/builtins/math.js +62 -0
  38. package/dist/builtins/math.js.map +1 -0
  39. package/dist/builtins/native.d.ts +22 -0
  40. package/dist/builtins/native.js +250 -0
  41. package/dist/builtins/native.js.map +1 -0
  42. package/dist/builtins/number.d.ts +4 -0
  43. package/dist/builtins/number.js +76 -0
  44. package/dist/builtins/number.js.map +1 -0
  45. package/dist/builtins/object.d.ts +12 -0
  46. package/dist/builtins/object.js +575 -0
  47. package/dist/builtins/object.js.map +1 -0
  48. package/dist/builtins/promise.d.ts +13 -0
  49. package/dist/builtins/promise.js +582 -0
  50. package/dist/builtins/promise.js.map +1 -0
  51. package/dist/builtins/proxy.d.ts +3 -0
  52. package/dist/builtins/proxy.js +226 -0
  53. package/dist/builtins/proxy.js.map +1 -0
  54. package/dist/builtins/reflect.d.ts +2 -0
  55. package/dist/builtins/reflect.js +109 -0
  56. package/dist/builtins/reflect.js.map +1 -0
  57. package/dist/builtins/regexp.d.ts +2 -0
  58. package/dist/builtins/regexp.js +203 -0
  59. package/dist/builtins/regexp.js.map +1 -0
  60. package/dist/builtins/string.d.ts +4 -0
  61. package/dist/builtins/string.js +135 -0
  62. package/dist/builtins/string.js.map +1 -0
  63. package/dist/builtins/symbol.d.ts +3 -0
  64. package/dist/builtins/symbol.js +98 -0
  65. package/dist/builtins/symbol.js.map +1 -0
  66. package/dist/builtins/typedarray.d.ts +15 -0
  67. package/dist/builtins/typedarray.js +1838 -0
  68. package/dist/builtins/typedarray.js.map +1 -0
  69. package/dist/builtins/weakref.d.ts +18 -0
  70. package/dist/builtins/weakref.js +130 -0
  71. package/dist/builtins/weakref.js.map +1 -0
  72. package/dist/dump.d.ts +2 -0
  73. package/dist/dump.js +124 -0
  74. package/dist/dump.js.map +1 -0
  75. package/dist/embed.d.ts +18 -0
  76. package/dist/embed.js +286 -0
  77. package/dist/embed.js.map +1 -0
  78. package/dist/interpreter.d.ts +81 -0
  79. package/dist/interpreter.js +3768 -0
  80. package/dist/interpreter.js.map +1 -0
  81. package/dist/jit.d.ts +59 -0
  82. package/dist/jit.js +3440 -0
  83. package/dist/jit.js.map +1 -0
  84. package/dist/jit_hook.d.ts +21 -0
  85. package/dist/jit_hook.js +4 -0
  86. package/dist/jit_hook.js.map +1 -0
  87. package/dist/jit_runtime.d.ts +104 -0
  88. package/dist/jit_runtime.js +721 -0
  89. package/dist/jit_runtime.js.map +1 -0
  90. package/dist/jit_stack.d.ts +24 -0
  91. package/dist/jit_stack.js +227 -0
  92. package/dist/jit_stack.js.map +1 -0
  93. package/dist/jseption.d.ts +15 -0
  94. package/dist/jseption.js +61 -0
  95. package/dist/jseption.js.map +1 -0
  96. package/dist/opcodes.d.ts +347 -0
  97. package/dist/opcodes.js +322 -0
  98. package/dist/opcodes.js.map +1 -0
  99. package/dist/parser.d.ts +283 -0
  100. package/dist/parser.js +9752 -0
  101. package/dist/parser.js.map +1 -0
  102. package/dist/qjs.d.ts +2 -0
  103. package/dist/qjs.js +122 -0
  104. package/dist/qjs.js.map +1 -0
  105. package/dist/quickjs.d.ts +460 -0
  106. package/dist/quickjs.js +3408 -0
  107. package/dist/quickjs.js.map +1 -0
  108. package/dist/std.d.ts +4 -0
  109. package/dist/std.js +273 -0
  110. package/dist/std.js.map +1 -0
  111. package/dist/values.d.ts +447 -0
  112. package/dist/values.js +461 -0
  113. package/dist/values.js.map +1 -0
  114. package/package.json +59 -4
@@ -0,0 +1,13 @@
1
+ import { JSContext, JSValue, JSPromiseState } from '../quickjs.ts';
2
+ export declare function JS_PromiseState(ctx: JSContext, promise: JSValue): JSPromiseState | -1;
3
+ export declare function JS_PromiseResult(ctx: JSContext, promise: JSValue): JSValue;
4
+ export declare function check_function(ctx: JSContext, obj: JSValue): number;
5
+ export declare function js_create_resolving_functions(ctx: JSContext, resolving_funcs: [JSValue, JSValue], promise: JSValue): number;
6
+ export declare function js_promise_resolve_function_call(ctx: JSContext, func_obj: JSValue, resolution: JSValue): JSValue;
7
+ export declare function JS_NewPromiseCapability(ctx: JSContext, resolving_funcs: [JSValue, JSValue]): JSValue;
8
+ export declare function js_promise_resolve(ctx: JSContext, this_val: JSValue, argv: JSValue[], magic: number): JSValue;
9
+ export declare function JS_PromiseResolve(ctx: JSContext, ctor: JSValue, value: JSValue): JSValue;
10
+ export declare function perform_promise_then(ctx: JSContext, promise: JSValue, resolve_reject: [JSValue, JSValue], cap_resolving_funcs: [JSValue, JSValue]): number;
11
+ export declare function JS_SpeciesConstructor(ctx: JSContext, obj: JSValue, defaultConstructor: JSValue): JSValue;
12
+ export declare function js_promise_then(ctx: JSContext, this_val: JSValue, argv: JSValue[]): JSValue;
13
+ export declare function JS_AddIntrinsicPromise(ctx: JSContext): void;
@@ -0,0 +1,582 @@
1
+ /*
2
+ * jseption: TypeScript port of QuickJS
3
+ *
4
+ * Promise implementation (port of the Promise section of quickjs.c).
5
+ */
6
+ import * as Q from "../quickjs.js";
7
+ import { JS_EXCEPTION, JS_IsException, JS_IsUndefined, JS_IsObject, JSPromiseData, JSPromiseReactionData, JSPromiseFunctionData, JS_PROP_C_W_E, JS_PROP_CONFIGURABLE, JS_PROP_WRITABLE, JS_PROP_ENUMERABLE, JS_ATOM_then, JS_ATOM_constructor, JS_ATOM_resolve, JS_ATOM_reject, JS_ATOM_promise, JS_ATOM_next, JS_ATOM_status, JS_ATOM_reason, JS_ATOM_value, JS_ATOM_errors, JS_ATOM_Symbol_species, JS_ATOM_Symbol_toStringTag, JS_Throw, JS_GetException, JS_ThrowTypeError, JS_ThrowTypeErrorNotAnObject, JS_NewObject, JS_NewObjectProtoClass, JS_NewArray, JS_NewCFunctionData, JS_NewCFunction2, JS_GetProperty, JS_GetPropertyUint32, JS_SetPropertyUint32, JS_DefinePropertyValue, JS_DefinePropertyValueUint32, JS_Call, JS_CallConstructor, JS_Invoke, JS_IsFunction, JS_IsConstructor, JS_GetOpaque, JS_GetOpaque2, JS_SetOpaque, js_create_from_ctor, js_same_value, JS_ToBoolFree, JS_ToInt32Free, JS_GetIterator, JS_IteratorNext, JS_IteratorClose, JS_EnqueueJob, JS_SetPropertyFunctionList, JS_NewGlobalCConstructor2, JS_CFUNC_DEF, JS_CFUNC_MAGIC_DEF, JS_CGETSET_DEF, JS_PROP_STRING_DEF, } from "../quickjs.js";
8
+ /* ---------------------------------------------------------------------
9
+ Promise state
10
+ --------------------------------------------------------------------- */
11
+ export function JS_PromiseState(ctx, promise) {
12
+ const s = JS_GetOpaque(promise, 45 /* JSClassID.PROMISE */);
13
+ if (!s)
14
+ return -1;
15
+ return s.promise_state;
16
+ }
17
+ export function JS_PromiseResult(ctx, promise) {
18
+ const s = JS_GetOpaque(promise, 45 /* JSClassID.PROMISE */);
19
+ if (!s)
20
+ return undefined;
21
+ return s.promise_result;
22
+ }
23
+ export function check_function(ctx, obj) {
24
+ if (JS_IsFunction(ctx, obj))
25
+ return 0;
26
+ JS_ThrowTypeError(ctx, 'not a function');
27
+ return -1;
28
+ }
29
+ /* argv: [resolve, reject, handler, is_reject, arg] */
30
+ function promise_reaction_job(ctx, argv) {
31
+ const handler = argv[2];
32
+ let is_reject = JS_ToBoolFree(ctx, argv[3]);
33
+ const arg = argv[4];
34
+ let res;
35
+ if (JS_IsUndefined(handler)) {
36
+ if (is_reject)
37
+ res = JS_Throw(ctx, arg);
38
+ else
39
+ res = arg;
40
+ }
41
+ else {
42
+ res = JS_Call(ctx, handler, undefined, [arg]);
43
+ }
44
+ is_reject = JS_IsException(res);
45
+ if (is_reject)
46
+ res = JS_GetException(ctx);
47
+ const func = argv[is_reject ? 1 : 0];
48
+ /* as an extension, we support undefined as value to avoid creating a
49
+ dummy promise in the 'await' implementation of async functions */
50
+ if (!JS_IsUndefined(func))
51
+ return JS_Call(ctx, func, undefined, [res]);
52
+ return undefined;
53
+ }
54
+ function fulfill_or_reject_promise(ctx, promise, value, is_reject) {
55
+ const s = JS_GetOpaque(promise, 45 /* JSClassID.PROMISE */);
56
+ if (!s || s.promise_state !== 0 /* JSPromiseState.PENDING */)
57
+ return; /* should never happen */
58
+ s.promise_result = value;
59
+ s.promise_state = is_reject ? 2 /* JSPromiseState.REJECTED */ : 1 /* JSPromiseState.FULFILLED */;
60
+ if (s.promise_state === 2 /* JSPromiseState.REJECTED */ && !s.is_handled) {
61
+ const rt = ctx.rt;
62
+ if (rt.host_promise_rejection_tracker) {
63
+ rt.host_promise_rejection_tracker(ctx, promise, value, false, rt.host_promise_rejection_tracker_opaque);
64
+ }
65
+ }
66
+ const idx = is_reject ? 1 : 0;
67
+ for (const rd of s.promise_reactions[idx]) {
68
+ JS_EnqueueJob(ctx, promise_reaction_job, [rd.resolving_funcs[0], rd.resolving_funcs[1], rd.handler, is_reject, value]);
69
+ }
70
+ s.promise_reactions[0] = [];
71
+ s.promise_reactions[1] = [];
72
+ }
73
+ function reject_promise(ctx, promise, value) {
74
+ fulfill_or_reject_promise(ctx, promise, value, true);
75
+ }
76
+ /* argv: [promise, thenable, then] */
77
+ function js_promise_resolve_thenable_job(ctx, argv) {
78
+ const promise = argv[0], thenable = argv[1], then = argv[2];
79
+ const args = [undefined, undefined];
80
+ if (js_create_resolving_functions(ctx, args, promise) < 0)
81
+ return JS_EXCEPTION;
82
+ let res = JS_Call(ctx, then, thenable, [args[0], args[1]]);
83
+ if (JS_IsException(res)) {
84
+ const error = JS_GetException(ctx);
85
+ res = JS_Call(ctx, args[1], undefined, [error]);
86
+ }
87
+ return res;
88
+ }
89
+ export function js_create_resolving_functions(ctx, resolving_funcs, promise) {
90
+ const sr = { already_resolved: false }; /* must be shared between the two functions */
91
+ for (let i = 0; i < 2; i++) {
92
+ let fobj;
93
+ const impl = (_this_val, _new_target, args) => {
94
+ js_promise_resolve_function_call(ctx, fobj, args.length > 0 ? args[0] : undefined);
95
+ return undefined;
96
+ };
97
+ fobj = Q.js_new_host_function(ctx, impl, false, '', 1, ctx.function_proto, (46 /* JSClassID.PROMISE_RESOLVE_FUNCTION */ + i));
98
+ Q.js_meta.get(fobj).u = new JSPromiseFunctionData(promise, sr);
99
+ resolving_funcs[i] = fobj;
100
+ }
101
+ return 0;
102
+ }
103
+ export function js_promise_resolve_function_call(ctx, func_obj, resolution) {
104
+ const m = Q.js_get_meta(func_obj);
105
+ const s = m.u;
106
+ if (!s || s.presolved.already_resolved)
107
+ return undefined;
108
+ s.presolved.already_resolved = true;
109
+ const is_reject = m.class_id === 47 /* JSClassID.PROMISE_REJECT_FUNCTION */;
110
+ if (is_reject || !JS_IsObject(resolution)) {
111
+ fulfill_or_reject_promise(ctx, s.promise, resolution, is_reject);
112
+ return undefined;
113
+ }
114
+ if (js_same_value(ctx, resolution, s.promise)) {
115
+ JS_ThrowTypeError(ctx, 'promise self resolution');
116
+ const error = JS_GetException(ctx);
117
+ reject_promise(ctx, s.promise, error);
118
+ return undefined;
119
+ }
120
+ const then = JS_GetProperty(ctx, resolution, JS_ATOM_then);
121
+ if (JS_IsException(then)) {
122
+ const error = JS_GetException(ctx);
123
+ reject_promise(ctx, s.promise, error);
124
+ }
125
+ else if (!JS_IsFunction(ctx, then)) {
126
+ fulfill_or_reject_promise(ctx, s.promise, resolution, is_reject);
127
+ }
128
+ else {
129
+ JS_EnqueueJob(ctx, js_promise_resolve_thenable_job, [s.promise, resolution, then]);
130
+ }
131
+ return undefined;
132
+ }
133
+ /* ---------------------------------------------------------------------
134
+ Promise constructor and capabilities
135
+ --------------------------------------------------------------------- */
136
+ function js_promise_constructor(ctx, new_target, argv) {
137
+ const executor = argv[0];
138
+ if (check_function(ctx, executor))
139
+ return JS_EXCEPTION;
140
+ const obj = js_create_from_ctor(ctx, new_target, 45 /* JSClassID.PROMISE */);
141
+ if (JS_IsException(obj))
142
+ return JS_EXCEPTION;
143
+ const s = new JSPromiseData();
144
+ JS_SetOpaque(obj, s);
145
+ const args = [undefined, undefined];
146
+ if (js_create_resolving_functions(ctx, args, obj))
147
+ return JS_EXCEPTION;
148
+ const ret = JS_Call(ctx, executor, undefined, [args[0], args[1]]);
149
+ if (JS_IsException(ret)) {
150
+ const error = JS_GetException(ctx);
151
+ const ret2 = JS_Call(ctx, args[1], undefined, [error]);
152
+ if (JS_IsException(ret2))
153
+ return JS_EXCEPTION;
154
+ }
155
+ return obj;
156
+ }
157
+ function js_promise_executor(ctx, this_val, argv, magic, func_data) {
158
+ for (let i = 0; i < 2; i++) {
159
+ if (!JS_IsUndefined(func_data[i]))
160
+ return JS_ThrowTypeError(ctx, 'resolving function already set');
161
+ func_data[i] = argv[i];
162
+ }
163
+ return undefined;
164
+ }
165
+ function js_promise_executor_new(ctx) {
166
+ return JS_NewCFunctionData(ctx, js_promise_executor, 2, 0, [undefined, undefined]);
167
+ }
168
+ function js_new_promise_capability(ctx, resolving_funcs, ctor) {
169
+ const executor = js_promise_executor_new(ctx);
170
+ if (JS_IsException(executor))
171
+ return executor;
172
+ let result_promise;
173
+ if (JS_IsUndefined(ctor)) {
174
+ result_promise = js_promise_constructor(ctx, ctor, [executor]);
175
+ }
176
+ else {
177
+ result_promise = JS_CallConstructor(ctx, ctor, [executor]);
178
+ }
179
+ if (JS_IsException(result_promise))
180
+ return JS_EXCEPTION;
181
+ const s = JS_GetOpaque(executor, 15 /* JSClassID.C_FUNCTION_DATA */);
182
+ for (let i = 0; i < 2; i++) {
183
+ if (check_function(ctx, s.data[i]))
184
+ return JS_EXCEPTION;
185
+ }
186
+ resolving_funcs[0] = s.data[0];
187
+ resolving_funcs[1] = s.data[1];
188
+ return result_promise;
189
+ }
190
+ /* resolving_funcs receives [resolve, reject]; returns the promise */
191
+ export function JS_NewPromiseCapability(ctx, resolving_funcs) {
192
+ return js_new_promise_capability(ctx, resolving_funcs, undefined);
193
+ }
194
+ /* Promise.resolve / Promise.reject (magic = is_reject) with 'this_val' as constructor */
195
+ export function js_promise_resolve(ctx, this_val, argv, magic) {
196
+ const is_reject = magic !== 0;
197
+ if (!JS_IsObject(this_val))
198
+ return JS_ThrowTypeErrorNotAnObject(ctx);
199
+ if (!is_reject && JS_GetOpaque(argv[0], 45 /* JSClassID.PROMISE */)) {
200
+ const ctor = JS_GetProperty(ctx, argv[0], JS_ATOM_constructor);
201
+ if (JS_IsException(ctor))
202
+ return ctor;
203
+ if (js_same_value(ctx, ctor, this_val))
204
+ return argv[0];
205
+ }
206
+ const resolving_funcs = [undefined, undefined];
207
+ const result_promise = js_new_promise_capability(ctx, resolving_funcs, this_val);
208
+ if (JS_IsException(result_promise))
209
+ return result_promise;
210
+ const ret = JS_Call(ctx, resolving_funcs[is_reject ? 1 : 0], undefined, [argv[0]]);
211
+ if (JS_IsException(ret))
212
+ return ret;
213
+ return result_promise;
214
+ }
215
+ /* PromiseResolve(C, x) */
216
+ export function JS_PromiseResolve(ctx, ctor, value) {
217
+ return js_promise_resolve(ctx, ctor, [value], 0);
218
+ }
219
+ function js_promise_withResolvers(ctx, this_val, argv) {
220
+ if (!JS_IsObject(this_val))
221
+ return JS_ThrowTypeErrorNotAnObject(ctx);
222
+ const resolving_funcs = [undefined, undefined];
223
+ const result_promise = js_new_promise_capability(ctx, resolving_funcs, this_val);
224
+ if (JS_IsException(result_promise))
225
+ return result_promise;
226
+ const obj = JS_NewObject(ctx);
227
+ if (JS_IsException(obj))
228
+ return JS_EXCEPTION;
229
+ JS_DefinePropertyValue(ctx, obj, JS_ATOM_promise, result_promise, JS_PROP_C_W_E);
230
+ JS_DefinePropertyValue(ctx, obj, JS_ATOM_resolve, resolving_funcs[0], JS_PROP_C_W_E);
231
+ JS_DefinePropertyValue(ctx, obj, JS_ATOM_reject, resolving_funcs[1], JS_PROP_C_W_E);
232
+ return obj;
233
+ }
234
+ /* return -1 on exception, else 1 if the counter reached zero, 0 otherwise */
235
+ function remainingElementsCount_add(ctx, resolve_element_env, addend) {
236
+ const val = JS_GetPropertyUint32(ctx, resolve_element_env, 0);
237
+ if (JS_IsException(val))
238
+ return -1;
239
+ const n = JS_ToInt32Free(ctx, val);
240
+ if (JS_IsException(n))
241
+ return -1;
242
+ const remainingElementsCount = n + addend;
243
+ if (JS_SetPropertyUint32(ctx, resolve_element_env, 0, remainingElementsCount) < 0)
244
+ return -1;
245
+ return remainingElementsCount === 0 ? 1 : 0;
246
+ }
247
+ const PROMISE_MAGIC_all = 0;
248
+ const PROMISE_MAGIC_allSettled = 1;
249
+ const PROMISE_MAGIC_any = 2;
250
+ function js_aggregate_error_constructor(ctx, errors) {
251
+ const obj = JS_NewObjectProtoClass(ctx, ctx.native_error_proto[7 /* JSErrorEnum.AGGREGATE_ERROR */], 3 /* JSClassID.ERROR */);
252
+ if (JS_IsException(obj))
253
+ return obj;
254
+ JS_DefinePropertyValue(ctx, obj, JS_ATOM_errors, errors, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE);
255
+ return obj;
256
+ }
257
+ /* func_data: [alreadyCalled, index, values, resolve, resolve_element_env] */
258
+ function js_promise_all_resolve_element(ctx, this_val, argv, magic, func_data) {
259
+ const resolve_type = magic & 3;
260
+ const is_reject = (magic & 4) !== 0;
261
+ const alreadyCalled = JS_ToBoolFree(ctx, func_data[0]);
262
+ const values = func_data[2];
263
+ const resolve = func_data[3];
264
+ const resolve_element_env = func_data[4];
265
+ const idx = JS_ToInt32Free(ctx, func_data[1]);
266
+ if (JS_IsException(idx))
267
+ return JS_EXCEPTION;
268
+ if (alreadyCalled)
269
+ return undefined;
270
+ func_data[0] = true;
271
+ let obj;
272
+ if (resolve_type === PROMISE_MAGIC_allSettled) {
273
+ obj = JS_NewObject(ctx);
274
+ if (JS_IsException(obj))
275
+ return JS_EXCEPTION;
276
+ if (JS_DefinePropertyValue(ctx, obj, JS_ATOM_status, is_reject ? 'rejected' : 'fulfilled', JS_PROP_C_W_E) < 0)
277
+ return JS_EXCEPTION;
278
+ if (JS_DefinePropertyValue(ctx, obj, is_reject ? JS_ATOM_reason : JS_ATOM_value, argv[0], JS_PROP_C_W_E) < 0)
279
+ return JS_EXCEPTION;
280
+ }
281
+ else {
282
+ obj = argv[0];
283
+ }
284
+ if (JS_DefinePropertyValueUint32(ctx, values, idx, obj, JS_PROP_C_W_E) < 0)
285
+ return JS_EXCEPTION;
286
+ const is_zero = remainingElementsCount_add(ctx, resolve_element_env, -1);
287
+ if (is_zero < 0)
288
+ return JS_EXCEPTION;
289
+ if (is_zero) {
290
+ let ret;
291
+ if (resolve_type === PROMISE_MAGIC_any) {
292
+ const error = js_aggregate_error_constructor(ctx, values);
293
+ if (JS_IsException(error))
294
+ return JS_EXCEPTION;
295
+ ret = JS_Call(ctx, resolve, undefined, [error]);
296
+ }
297
+ else {
298
+ ret = JS_Call(ctx, resolve, undefined, [values]);
299
+ }
300
+ if (JS_IsException(ret))
301
+ return ret;
302
+ }
303
+ return undefined;
304
+ }
305
+ /* magic = 0: Promise.all 1: Promise.allSettled 2: Promise.any */
306
+ function js_promise_all(ctx, this_val, argv, magic) {
307
+ const is_promise_any = (magic === PROMISE_MAGIC_any);
308
+ if (!JS_IsObject(this_val))
309
+ return JS_ThrowTypeErrorNotAnObject(ctx);
310
+ const resolving_funcs = [undefined, undefined];
311
+ const result_promise = js_new_promise_capability(ctx, resolving_funcs, this_val);
312
+ if (JS_IsException(result_promise))
313
+ return result_promise;
314
+ const fail_reject = () => {
315
+ const error = JS_GetException(ctx);
316
+ const ret = JS_Call(ctx, resolving_funcs[1], undefined, [error]);
317
+ if (JS_IsException(ret))
318
+ return JS_EXCEPTION;
319
+ return result_promise;
320
+ };
321
+ const promise_resolve = JS_GetProperty(ctx, this_val, JS_ATOM_resolve);
322
+ if (JS_IsException(promise_resolve) || check_function(ctx, promise_resolve))
323
+ return fail_reject();
324
+ const iter = JS_GetIterator(ctx, argv[0], false);
325
+ if (JS_IsException(iter))
326
+ return fail_reject();
327
+ const next_method = JS_GetProperty(ctx, iter, JS_ATOM_next);
328
+ if (JS_IsException(next_method))
329
+ return fail_reject();
330
+ const values = JS_NewArray(ctx);
331
+ if (JS_IsException(values))
332
+ return fail_reject();
333
+ const resolve_element_env = JS_NewArray(ctx);
334
+ if (JS_IsException(resolve_element_env))
335
+ return fail_reject();
336
+ /* remainingElementsCount field */
337
+ if (JS_DefinePropertyValueUint32(ctx, resolve_element_env, 0, 1, JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE | JS_PROP_WRITABLE) < 0)
338
+ return fail_reject();
339
+ const fail_reject1 = () => {
340
+ JS_IteratorClose(ctx, iter, true);
341
+ return fail_reject();
342
+ };
343
+ let index = 0;
344
+ const pdone = { done: 0 };
345
+ for (;;) {
346
+ /* XXX: conformance: should close the iterator if error on 'done'
347
+ access, but not on 'value' access */
348
+ const item = JS_IteratorNext(ctx, iter, next_method, [], pdone);
349
+ if (JS_IsException(item))
350
+ return fail_reject();
351
+ if (pdone.done)
352
+ break;
353
+ const next_promise = JS_Call(ctx, promise_resolve, this_val, [item]);
354
+ if (JS_IsException(next_promise))
355
+ return fail_reject1();
356
+ const resolve_element_data = [false, index, values, resolving_funcs[is_promise_any ? 1 : 0], resolve_element_env];
357
+ let resolve_element = JS_NewCFunctionData(ctx, js_promise_all_resolve_element, 1, magic, resolve_element_data);
358
+ if (JS_IsException(resolve_element))
359
+ return fail_reject1();
360
+ /* the data array must be shared between the resolve and reject functions */
361
+ const shared_data = JS_GetOpaque(resolve_element, 15 /* JSClassID.C_FUNCTION_DATA */).data;
362
+ let reject_element;
363
+ if (magic === PROMISE_MAGIC_allSettled) {
364
+ reject_element = JS_NewCFunctionData(ctx, js_promise_all_resolve_element, 1, magic | 4, shared_data);
365
+ if (JS_IsException(reject_element))
366
+ return fail_reject1();
367
+ JS_GetOpaque(reject_element, 15 /* JSClassID.C_FUNCTION_DATA */).data = shared_data;
368
+ }
369
+ else if (magic === PROMISE_MAGIC_any) {
370
+ if (JS_DefinePropertyValueUint32(ctx, values, index, undefined, JS_PROP_C_W_E) < 0)
371
+ return fail_reject1();
372
+ reject_element = resolve_element;
373
+ resolve_element = resolving_funcs[0];
374
+ }
375
+ else {
376
+ reject_element = resolving_funcs[1];
377
+ }
378
+ if (remainingElementsCount_add(ctx, resolve_element_env, 1) < 0)
379
+ return fail_reject1();
380
+ const ret = JS_Invoke(ctx, next_promise, JS_ATOM_then, [resolve_element, reject_element]);
381
+ if (JS_IsException(ret))
382
+ return fail_reject1();
383
+ index++;
384
+ }
385
+ const is_zero = remainingElementsCount_add(ctx, resolve_element_env, -1);
386
+ if (is_zero < 0)
387
+ return fail_reject();
388
+ if (is_zero) {
389
+ let vals = values;
390
+ if (magic === PROMISE_MAGIC_any) {
391
+ const error = js_aggregate_error_constructor(ctx, values);
392
+ if (JS_IsException(error))
393
+ return fail_reject();
394
+ vals = error;
395
+ }
396
+ const ret = JS_Call(ctx, resolving_funcs[is_promise_any ? 1 : 0], undefined, [vals]);
397
+ if (JS_IsException(ret))
398
+ return fail_reject();
399
+ }
400
+ return result_promise;
401
+ }
402
+ function js_promise_race(ctx, this_val, argv) {
403
+ if (!JS_IsObject(this_val))
404
+ return JS_ThrowTypeErrorNotAnObject(ctx);
405
+ const resolving_funcs = [undefined, undefined];
406
+ const result_promise = js_new_promise_capability(ctx, resolving_funcs, this_val);
407
+ if (JS_IsException(result_promise))
408
+ return result_promise;
409
+ const fail_reject = () => {
410
+ const error = JS_GetException(ctx);
411
+ const ret = JS_Call(ctx, resolving_funcs[1], undefined, [error]);
412
+ if (JS_IsException(ret))
413
+ return JS_EXCEPTION;
414
+ return result_promise;
415
+ };
416
+ const promise_resolve = JS_GetProperty(ctx, this_val, JS_ATOM_resolve);
417
+ if (JS_IsException(promise_resolve) || check_function(ctx, promise_resolve))
418
+ return fail_reject();
419
+ const iter = JS_GetIterator(ctx, argv[0], false);
420
+ if (JS_IsException(iter))
421
+ return fail_reject();
422
+ const next_method = JS_GetProperty(ctx, iter, JS_ATOM_next);
423
+ if (JS_IsException(next_method))
424
+ return fail_reject();
425
+ const pdone = { done: 0 };
426
+ for (;;) {
427
+ const item = JS_IteratorNext(ctx, iter, next_method, [], pdone);
428
+ if (JS_IsException(item))
429
+ return fail_reject();
430
+ if (pdone.done)
431
+ break;
432
+ const next_promise = JS_Call(ctx, promise_resolve, this_val, [item]);
433
+ if (JS_IsException(next_promise)) {
434
+ JS_IteratorClose(ctx, iter, true);
435
+ return fail_reject();
436
+ }
437
+ const ret = JS_Invoke(ctx, next_promise, JS_ATOM_then, [resolving_funcs[0], resolving_funcs[1]]);
438
+ if (JS_IsException(ret)) {
439
+ JS_IteratorClose(ctx, iter, true);
440
+ return fail_reject();
441
+ }
442
+ }
443
+ return result_promise;
444
+ }
445
+ /* PerformPromiseThen: resolve_reject = [onFulfilled, onRejected],
446
+ cap_resolving_funcs = [resolve, reject] of the derived promise (may be undefined) */
447
+ export function perform_promise_then(ctx, promise, resolve_reject, cap_resolving_funcs) {
448
+ const s = JS_GetOpaque(promise, 45 /* JSClassID.PROMISE */);
449
+ const rd_array = [];
450
+ for (let i = 0; i < 2; i++) {
451
+ let handler = resolve_reject[i];
452
+ if (!JS_IsFunction(ctx, handler))
453
+ handler = undefined;
454
+ rd_array.push(new JSPromiseReactionData([cap_resolving_funcs[0], cap_resolving_funcs[1]], handler));
455
+ }
456
+ if (s.promise_state === 0 /* JSPromiseState.PENDING */) {
457
+ s.promise_reactions[0].push(rd_array[0]);
458
+ s.promise_reactions[1].push(rd_array[1]);
459
+ }
460
+ else {
461
+ if (s.promise_state === 2 /* JSPromiseState.REJECTED */ && !s.is_handled) {
462
+ const rt = ctx.rt;
463
+ if (rt.host_promise_rejection_tracker) {
464
+ rt.host_promise_rejection_tracker(ctx, promise, s.promise_result, true, rt.host_promise_rejection_tracker_opaque);
465
+ }
466
+ }
467
+ const i = s.promise_state === 2 /* JSPromiseState.REJECTED */ ? 1 : 0;
468
+ const rd = rd_array[i];
469
+ JS_EnqueueJob(ctx, promise_reaction_job, [rd.resolving_funcs[0], rd.resolving_funcs[1], rd.handler, i !== 0, s.promise_result]);
470
+ }
471
+ s.is_handled = true;
472
+ return 0;
473
+ }
474
+ export function JS_SpeciesConstructor(ctx, obj, defaultConstructor) {
475
+ if (!JS_IsObject(obj))
476
+ return JS_ThrowTypeErrorNotAnObject(ctx);
477
+ const ctor = JS_GetProperty(ctx, obj, JS_ATOM_constructor);
478
+ if (JS_IsException(ctor))
479
+ return ctor;
480
+ if (JS_IsUndefined(ctor))
481
+ return defaultConstructor;
482
+ if (!JS_IsObject(ctor))
483
+ return JS_ThrowTypeErrorNotAnObject(ctx);
484
+ const species = JS_GetProperty(ctx, ctor, JS_ATOM_Symbol_species);
485
+ if (JS_IsException(species))
486
+ return species;
487
+ if (species === undefined || species === null)
488
+ return defaultConstructor;
489
+ if (!JS_IsConstructor(ctx, species))
490
+ return JS_ThrowTypeError(ctx, 'not a constructor');
491
+ return species;
492
+ }
493
+ export function js_promise_then(ctx, this_val, argv) {
494
+ const s = JS_GetOpaque2(ctx, this_val, 45 /* JSClassID.PROMISE */);
495
+ if (!s)
496
+ return JS_EXCEPTION;
497
+ const ctor = JS_SpeciesConstructor(ctx, this_val, ctx.promise_ctor ?? undefined);
498
+ if (JS_IsException(ctor))
499
+ return ctor;
500
+ const resolving_funcs = [undefined, undefined];
501
+ const result_promise = js_new_promise_capability(ctx, resolving_funcs, ctor);
502
+ if (JS_IsException(result_promise))
503
+ return result_promise;
504
+ if (perform_promise_then(ctx, this_val, [argv[0], argv[1]], resolving_funcs))
505
+ return JS_EXCEPTION;
506
+ return result_promise;
507
+ }
508
+ function js_promise_catch(ctx, this_val, argv) {
509
+ return JS_Invoke(ctx, this_val, JS_ATOM_then, [undefined, argv[0]]);
510
+ }
511
+ function js_promise_finally_value_thunk(ctx, this_val, argv, magic, func_data) {
512
+ return func_data[0];
513
+ }
514
+ function js_promise_finally_thrower(ctx, this_val, argv, magic, func_data) {
515
+ return JS_Throw(ctx, func_data[0]);
516
+ }
517
+ function js_promise_then_finally_func(ctx, this_val, argv, magic, func_data) {
518
+ const ctor = func_data[0];
519
+ const onFinally = func_data[1];
520
+ const res = JS_Call(ctx, onFinally, undefined, []);
521
+ if (JS_IsException(res))
522
+ return res;
523
+ const promise = js_promise_resolve(ctx, ctor, [res], 0);
524
+ if (JS_IsException(promise))
525
+ return promise;
526
+ let then_func;
527
+ if (magic === 0)
528
+ then_func = JS_NewCFunctionData(ctx, js_promise_finally_value_thunk, 0, 0, [argv[0]]);
529
+ else
530
+ then_func = JS_NewCFunctionData(ctx, js_promise_finally_thrower, 0, 0, [argv[0]]);
531
+ if (JS_IsException(then_func))
532
+ return then_func;
533
+ return JS_Invoke(ctx, promise, JS_ATOM_then, [then_func]);
534
+ }
535
+ function js_promise_finally(ctx, this_val, argv) {
536
+ const onFinally = argv[0];
537
+ const ctor = JS_SpeciesConstructor(ctx, this_val, ctx.promise_ctor ?? undefined);
538
+ if (JS_IsException(ctor))
539
+ return ctor;
540
+ const then_funcs = [];
541
+ if (!JS_IsFunction(ctx, onFinally)) {
542
+ then_funcs.push(onFinally, onFinally);
543
+ }
544
+ else {
545
+ for (let i = 0; i < 2; i++) {
546
+ const f = JS_NewCFunctionData(ctx, js_promise_then_finally_func, 1, i, [ctor, onFinally]);
547
+ if (JS_IsException(f))
548
+ return JS_EXCEPTION;
549
+ then_funcs.push(f);
550
+ }
551
+ }
552
+ return JS_Invoke(ctx, this_val, JS_ATOM_then, then_funcs);
553
+ }
554
+ function js_get_this(ctx, this_val) { return this_val; }
555
+ const js_promise_funcs = [
556
+ JS_CFUNC_MAGIC_DEF('resolve', 1, js_promise_resolve, 0),
557
+ JS_CFUNC_MAGIC_DEF('reject', 1, js_promise_resolve, 1),
558
+ JS_CFUNC_MAGIC_DEF('all', 1, js_promise_all, PROMISE_MAGIC_all),
559
+ JS_CFUNC_MAGIC_DEF('allSettled', 1, js_promise_all, PROMISE_MAGIC_allSettled),
560
+ JS_CFUNC_MAGIC_DEF('any', 1, js_promise_all, PROMISE_MAGIC_any),
561
+ JS_CFUNC_DEF('race', 1, js_promise_race),
562
+ JS_CFUNC_DEF('withResolvers', 0, js_promise_withResolvers),
563
+ JS_CGETSET_DEF(JS_ATOM_Symbol_species, js_get_this, null),
564
+ ];
565
+ const js_promise_proto_funcs = [
566
+ JS_CFUNC_DEF('then', 2, js_promise_then),
567
+ JS_CFUNC_DEF('catch', 1, js_promise_catch),
568
+ JS_CFUNC_DEF('finally', 1, js_promise_finally),
569
+ JS_PROP_STRING_DEF(JS_ATOM_Symbol_toStringTag, 'Promise', JS_PROP_CONFIGURABLE),
570
+ ];
571
+ /* Promise constructor and prototype (the AsyncFunction / AsyncGenerator
572
+ prototypes are installed by the interpreter module) */
573
+ export function JS_AddIntrinsicPromise(ctx) {
574
+ const proto = JS_NewObject(ctx);
575
+ ctx.class_proto[45 /* JSClassID.PROMISE */] = proto;
576
+ JS_SetPropertyFunctionList(ctx, proto, js_promise_proto_funcs);
577
+ const obj1 = JS_NewCFunction2(ctx, js_promise_constructor, 'Promise', 1, 2 /* JSCFunctionEnum.constructor */, 0);
578
+ ctx.promise_ctor = obj1;
579
+ JS_SetPropertyFunctionList(ctx, obj1, js_promise_funcs);
580
+ JS_NewGlobalCConstructor2(ctx, obj1, 'Promise', proto);
581
+ }
582
+ //# sourceMappingURL=promise.js.map