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,721 @@
1
+ /*
2
+ * Runtime adapter for the compiled tier (src/jit.ts).
3
+ *
4
+ * This is the ONLY module that generated code talks to, and the only
5
+ * place where the compiled tier touches engine internals. Generated code
6
+ * receives one `JitRuntime` instance per context as `$RT`, plus a few
7
+ * host intrinsics and engine tables as factory parameters (see
8
+ * JIT_FACTORY_PARAMS).
9
+ *
10
+ * Conventions:
11
+ * - every helper either returns a guest value or `throw`s a guest value
12
+ * (the engine's JS_EXCEPTION/current_exception convention is converted
13
+ * here by `check()`/`throw_pending()`);
14
+ * - `DONE` is a sentinel returned by the iteration helpers;
15
+ * - the direct entry of a guest function (js_direct) uses the explicit
16
+ * convention `direct($this, $new_target, ...args)`; compiled code calls
17
+ * it when it has an explicit `this` or new.target, and calls guest
18
+ * functions natively otherwise.
19
+ */
20
+ import { JS_EXCEPTION, JS_UNINITIALIZED, JS_IsException, JS_IsObject, JS_GetException, js_take_exception, js_host_exception_to_guest, JS_ThrowTypeError, JS_ThrowReferenceError, JS_ThrowInternalError, JS_ThrowStackOverflow, JS_ThrowTypeErrorReadOnly, JS_ThrowSyntaxErrorAtom, JS_ThrowReferenceErrorUninitialized, JS_ThrowReferenceErrorNotDefined, JS_ThrowReferenceErrorUninitialized2, JS_ThrowTypeErrorNotAnObject, JS_GetProperty, JS_GetPropertyInternal, JS_GetPropertyValue, JS_SetPropertyInternal, JS_SetPropertyValue, JS_DefinePropertyValue, JS_DefinePropertyValueValue, JS_DefinePropertyValueUint32, JS_DefineProperty, JS_DeleteProperty, JS_HasProperty, JS_GetPrototype, JS_SetPrototypeInternal, JS_NewObject, JS_NewObjectProto, JS_NewObjectProtoClass, JS_NewArrayFrom, JS_ValueToAtom, JS_AtomToValue, JS_AtomToKey, JS_NewSymbolFromAtom, JS_ToObject, JS_ToPropertyKey, JS_ToNumericFree, JS_IsInstanceOf, js_operator_in, js_unary_arith_slow, JS_GetIterator, JS_IteratorClose, build_for_in_iterator, js_for_in_next, JS_CopyDataProperties, JS_Call, JS_CallConstructorInternal, JS_CallConstructor2, js_create_from_ctor, JS_CheckGlobalVar, JS_GetGlobalVar, JS_SetGlobalVar, JS_CheckDefineGlobalVar, JS_DefineGlobalVar, JS_DefineGlobalFunction, JS_GetGlobalVarRef, hooks, js_meta, js_direct, JS_GetFunctionData, js_new_host_function, js_init_host_function, JS_ATOM_NULL, JS_ATOM_return, JS_ATOM_throw, JS_ATOM_length, JS_ATOM_prototype, JS_ATOM_callee, JS_ATOM_Symbol_iterator, JS_ATOM_empty_string, JS_ATOM_TYPE_PRIVATE, JS_ATOM_constructor, JS_IsUncatchableError, JS_SetUncatchableError, } from "./quickjs.js";
21
+ import { JSFunctionData, JSObjectMeta, new_var_ref_cell, JS_PROP_C_W_E, JS_PROP_THROW, JS_PROP_CONFIGURABLE, JS_PROP_WRITABLE, JS_PROP_ENUMERABLE, JS_PROP_HAS_CONFIGURABLE, JS_PROP_HAS_ENUMERABLE, JS_PROP_HAS_VALUE, JS_PROP_HAS_WRITABLE, JS_PROP_HAS_GET, JS_PROP_HAS_SET, JS_CALL_FLAG_CONSTRUCTOR, } from "./values.js";
22
+ import { JS_CallInternal, js_closure_from_refs, js_function_set_properties, js_define_class, js_build_arguments_value, js_build_rest, JS_DefinePrivateField, JS_GetPrivateField, JS_SetPrivateField, JS_AddBrand, JS_CheckBrand, js_operator_private_in, js_method_set_home_object, js_method_set_properties, JS_DefineObjectName, JS_DefineObjectNameComputed, js_function_apply, js_for_of_start_value, js_for_of_next_value, js_append_enumerate_value, } from "./interpreter.js";
23
+ import { short_opcode_info } from "./opcodes.js";
24
+ import { OP_DEFINE_METHOD_ENUMERABLE, OP_DEFINE_METHOD_METHOD, OP_DEFINE_METHOD_GETTER, JS_THROW_VAR_RO, JS_THROW_VAR_REDECL, JS_THROW_VAR_UNINITIALIZED, JS_THROW_ERROR_DELETE_SUPER, JS_THROW_ERROR_ITERATOR_THROW } from "./opcodes.js";
25
+ /* parameters of the generated factory function, in order */
26
+ export const JIT_FACTORY_PARAMS = ['$RT', '$cpool', '$b', '$U', '$D', '$Obj', '$set', '$del', '$getproto', '$DIRECT', '$P', '$G', '$GV',
27
+ '$CALL', '$CONSTRUCT', '$C'];
28
+ export function jit_runtime_factory_args(RT, b) {
29
+ return [RT, b.cpool, b, JS_UNINITIALIZED, RT.DONE, RT.Obj, Reflect.set, Reflect.deleteProperty, Object.getPrototypeOf,
30
+ js_direct, RT.ctx.plain_object_proto, RT.ctx.global_obj, RT.ctx.global_var_obj, Function.prototype.call, Reflect.construct,
31
+ RT.ctx];
32
+ }
33
+ const runtimes = new WeakMap();
34
+ /* `compile(b)` returns the compiled form of `b` if it is (or should now be) compiled, else null */
35
+ export function make_jit_runtime(ctx, compile) {
36
+ let rt = runtimes.get(ctx);
37
+ if (!rt) {
38
+ rt = new JitRuntime(ctx, compile);
39
+ runtimes.set(ctx, rt);
40
+ }
41
+ return rt;
42
+ }
43
+ /* Call a compiled body through its private host-convention copy (`fd.priv`): the engine's
44
+ ordinary (non-construct) calls of compiled functions. */
45
+ export function jit_runtime_call_priv(ctx, priv, this_obj, argv) {
46
+ const rt = ctx.rt;
47
+ if (rt.stack_depth >= rt.max_stack_depth)
48
+ return JS_ThrowStackOverflow(ctx);
49
+ rt.stack_depth++;
50
+ const sf = rt.current_stack_frame;
51
+ try {
52
+ return priv.apply(this_obj, argv);
53
+ }
54
+ catch (e) {
55
+ return js_host_exception_to_guest(ctx, e);
56
+ }
57
+ finally {
58
+ rt.current_stack_frame = sf;
59
+ rt.stack_depth--;
60
+ }
61
+ }
62
+ /* ---------------------------------------------------------------------
63
+ Retargetable wrappers
64
+
65
+ The function object of a closure created by the interpreter (or by compiled code before the
66
+ function's bytecode is compiled) is a wrapper that calls the compiled body as soon as one
67
+ exists for the closure (JSFunctionData.priv for calls, .ctor for construct calls) and the
68
+ engine otherwise, so its identity survives tier-up. The wrappers are generated once per
69
+ (kind, arity) without rest parameters: a call is `fd.priv.call(this, a0, a1)`, which the host
70
+ inlines (measured: the same cost as calling the compiled function directly, also for `new`).
71
+ --------------------------------------------------------------------- */
72
+ /* the body reads `arguments` (or a rest parameter, or init_ctor's arguments): its wrapper must
73
+ forward the exact argument list. Cached on the bytecode. */
74
+ export function jit_bytecode_uses_args(b) {
75
+ if (b.uses_args >= 0)
76
+ return b.uses_args === 1;
77
+ const buf = b.byte_code_buf, len = b.byte_code_len;
78
+ let r = 0;
79
+ for (let pos = 0; pos < len;) {
80
+ const op = buf[pos];
81
+ if (op === 13 /* OP.rest */ || op === 44 /* OP.init_ctor */) {
82
+ r = 1;
83
+ break;
84
+ }
85
+ if (op === 12 /* OP.special_object */) {
86
+ const k = buf[pos + 1];
87
+ if (k === 0 /* OPSpecialObject.ARGUMENTS */ || k === 1 /* OPSpecialObject.MAPPED_ARGUMENTS */) {
88
+ r = 1;
89
+ break;
90
+ }
91
+ }
92
+ const oi = short_opcode_info(op);
93
+ if (!oi || oi.size <= 0) {
94
+ r = 1;
95
+ break;
96
+ }
97
+ pos += oi.size;
98
+ }
99
+ b.uses_args = r;
100
+ return r === 1;
101
+ }
102
+ const MAX_WRAPPER_ARITY = 12;
103
+ /* The wrapper code is generated once per function (bytecode), not once per arity: the call
104
+ `p.call(this, a0)` inside a wrapper shared by many functions sees many targets and the host
105
+ stops inlining it (measured in Bun: 1.75x the cost of a direct call, against 1x for a
106
+ per-function wrapper). Closures of the same function share their wrapper's code. */
107
+ function wrapper_factory(b, is_ctor) {
108
+ /* cached per kind (constructible or not): a function is normally wrapped as one kind only */
109
+ const slot = is_ctor ? 'f' : 'm';
110
+ if (b.wrapper_factory === null)
111
+ b.wrapper_factory = { f: undefined, m: undefined };
112
+ const cached = b.wrapper_factory[slot];
113
+ if (cached !== undefined)
114
+ return cached;
115
+ const arity = b.arg_count;
116
+ let use_args = jit_bytecode_uses_args(b);
117
+ if (arity > MAX_WRAPPER_ARITY)
118
+ use_args = true;
119
+ let f;
120
+ const params = use_args ? '' : Array.from({ length: arity }, (_, i) => `a${i}`).join(', ');
121
+ const call_p = use_args ? 'p.apply(this, arguments)' : `p.call(this${params ? ', ' + params : ''})`;
122
+ const call_c = use_args ? 'c(t, new.target, ...arguments)' : `c(t, new.target${params ? ', ' + params : ''})`;
123
+ const src = is_ctor
124
+ ? `"use strict"; return function (fd, slow) { return function $w(${params}) {
125
+ if (new.target === undefined) { const p = fd.priv; if (p !== null) return ${call_p}; }
126
+ else { const c = fd.ctor; if (c !== null) { const xp = new.target.prototype; const t = (typeof xp === 'object' ? xp !== null : typeof xp === 'function') ? this : undefined; return ${call_c}; } }
127
+ return slow($w, this, new.target, arguments);
128
+ }; };`
129
+ : `"use strict"; return function (fd, slow) { let w; const o = { $w(${params}) {
130
+ const p = fd.priv; if (p !== null) return ${call_p};
131
+ return slow(w, this, undefined, arguments);
132
+ } }; w = o.$w; return w; };`;
133
+ try {
134
+ f = new Function(src)();
135
+ }
136
+ catch {
137
+ f = null; /* code generation unavailable */
138
+ }
139
+ b.wrapper_factory[slot] = f;
140
+ return f;
141
+ }
142
+ const slow_calls = new WeakMap();
143
+ function slow_call(ctx) {
144
+ let s = slow_calls.get(ctx);
145
+ if (s === undefined) {
146
+ s = (w, t, nt, args) => {
147
+ const argv = new Array(args.length);
148
+ for (let i = 0; i < args.length; i++)
149
+ argv[i] = args[i];
150
+ const ret = nt !== undefined ? JS_CallInternal(ctx, w, nt, nt, argv, JS_CALL_FLAG_CONSTRUCTOR)
151
+ : JS_CallInternal(ctx, w, t, undefined, argv, 0);
152
+ if (ret === JS_EXCEPTION)
153
+ throw js_take_exception(ctx);
154
+ return ret;
155
+ };
156
+ slow_calls.set(ctx, s);
157
+ }
158
+ return s;
159
+ }
160
+ /* the function object of a closure of a normal function: a retargetable wrapper, or null when
161
+ wrappers cannot be generated (the engine then uses its generic wrapper) */
162
+ export function jit_runtime_make_wrapper(ctx, b, var_refs, proto, is_ctor) {
163
+ const fac = wrapper_factory(b, is_ctor);
164
+ if (fac === null)
165
+ return null;
166
+ const fd = new JSFunctionData(b, var_refs);
167
+ const slow = slow_call(ctx);
168
+ const w = fac(fd, slow);
169
+ /* a host `function` has an own `prototype` object with a host prototype chain */
170
+ if (is_ctor)
171
+ w.prototype = undefined;
172
+ const m = js_init_host_function(ctx, w, is_ctor, '', b.defined_arg_count, proto, func_kind_to_class_id(b.func_kind));
173
+ m.func = fd;
174
+ m.realm = b.realm ?? ctx;
175
+ js_direct.set(w, (t, nt, ...args) => {
176
+ if (nt === undefined) {
177
+ const p = fd.priv;
178
+ if (p !== null)
179
+ return p.apply(t, args);
180
+ }
181
+ return slow(w, t, nt, args);
182
+ });
183
+ return w;
184
+ }
185
+ /* Call the direct entry of a compiled function from the engine (JS_CallInternal). */
186
+ export function jit_runtime_call_compiled(ctx, direct, this_obj, new_target, argv, flags) {
187
+ const rt = ctx.rt;
188
+ if (rt.stack_depth >= rt.max_stack_depth)
189
+ return JS_ThrowStackOverflow(ctx);
190
+ rt.stack_depth++;
191
+ const sf = rt.current_stack_frame;
192
+ try {
193
+ /* construct call (JS_CallConstructorInternal passes new_target as this_obj, like C): the
194
+ callee creates `this`. The interpreter's legacy constructor path calls back with the flag
195
+ cleared, new_target set and `this` already created: the compiled prologue keeps it. */
196
+ if (flags & JS_CALL_FLAG_CONSTRUCTOR)
197
+ return direct(undefined, new_target, ...argv);
198
+ return direct(this_obj, new_target, ...argv);
199
+ }
200
+ catch (e) {
201
+ return js_host_exception_to_guest(ctx, e);
202
+ }
203
+ finally {
204
+ rt.current_stack_frame = sf;
205
+ rt.stack_depth--;
206
+ }
207
+ }
208
+ function func_kind_to_class_id(kind) {
209
+ switch (kind) {
210
+ case 1 /* JSFunctionKind.GENERATOR */: return 16 /* JSClassID.GENERATOR_FUNCTION */;
211
+ case 2 /* JSFunctionKind.ASYNC */: return 48 /* JSClassID.ASYNC_FUNCTION */;
212
+ case 3 /* JSFunctionKind.ASYNC_GENERATOR */: return 52 /* JSClassID.ASYNC_GENERATOR_FUNCTION */;
213
+ default: return 13 /* JSClassID.BYTECODE_FUNCTION */;
214
+ }
215
+ }
216
+ export class JitRuntime {
217
+ ctx;
218
+ compile;
219
+ /* sentinel returned by iteration helpers */
220
+ DONE = Symbol('jit.done');
221
+ /* host constructor whose .prototype is the guest Object.prototype: `new $Obj()` creates an
222
+ object literal (measured ~0.7 ns vs ~27 ns for `{__proto__: proto}`) */
223
+ Obj;
224
+ constructor(ctx, compile) {
225
+ this.ctx = ctx;
226
+ this.compile = compile;
227
+ const Obj = function () { };
228
+ Obj.prototype = ctx.class_proto[1 /* JSClassID.OBJECT */];
229
+ this.Obj = Obj;
230
+ }
231
+ /* --- exception plumbing --- */
232
+ throw_pending() {
233
+ throw js_take_exception(this.ctx);
234
+ }
235
+ check(v) {
236
+ if (v === JS_EXCEPTION)
237
+ this.throw_pending();
238
+ return v;
239
+ }
240
+ checkn(r) {
241
+ if (r < 0)
242
+ this.throw_pending();
243
+ }
244
+ /* host exception -> guest exception value (guest values pass through) */
245
+ to_guest_exception(e) {
246
+ if (!(e instanceof Error) && e !== JS_EXCEPTION)
247
+ return e;
248
+ js_host_exception_to_guest(this.ctx, e);
249
+ return js_take_exception(this.ctx);
250
+ }
251
+ /* a guest `catch` (or the handler that runs `finally`, or closes an iterator) takes the
252
+ exception, unless it is uncatchable (an interrupt): that one goes on unwinding, without
253
+ running handlers, as in the interpreter */
254
+ catchable(e) {
255
+ const v = this.to_guest_exception(e);
256
+ if (JS_IsUncatchableError(this.ctx, v))
257
+ throw v;
258
+ return v;
259
+ }
260
+ /* --- interrupts --- */
261
+ /* compiled code polls at every function entry and loop head, as the interpreter polls at
262
+ its jumps. Generated code decrements `ctx.interrupt_counter` inline and calls
263
+ poll_handler() when it runs out; poll() is the same check as a call. Every 10000 polls
264
+ the runtime's interrupt handler is asked, and a request to stop throws an uncatchable
265
+ InternalError */
266
+ poll() {
267
+ if (--this.ctx.interrupt_counter > 0)
268
+ return;
269
+ this.poll_handler();
270
+ }
271
+ poll_handler() {
272
+ const ctx = this.ctx;
273
+ ctx.interrupt_counter = 10000;
274
+ const rt = ctx.rt;
275
+ if (rt.interrupt_handler === null || !rt.interrupt_handler(rt, rt.interrupt_opaque))
276
+ return;
277
+ JS_ThrowInternalError(ctx, 'interrupted');
278
+ JS_SetUncatchableError(ctx, rt.current_exception, true);
279
+ this.throw_pending();
280
+ }
281
+ throw_type_error(msg) { JS_ThrowTypeError(this.ctx, msg); this.throw_pending(); }
282
+ throw_reference_error(msg) { JS_ThrowReferenceError(this.ctx, msg); this.throw_pending(); }
283
+ throw_internal_error(msg) { JS_ThrowInternalError(this.ctx, msg); this.throw_pending(); }
284
+ throw_not_a_constructor(_f) { this.throw_type_error('not a constructor'); }
285
+ throw_uninitialized(b, idx, is_ref) {
286
+ JS_ThrowReferenceErrorUninitialized2(this.ctx, b, idx, is_ref);
287
+ this.throw_pending();
288
+ }
289
+ throw_error(atom, type) {
290
+ const ctx = this.ctx;
291
+ if (type === JS_THROW_VAR_RO)
292
+ JS_ThrowTypeErrorReadOnly(ctx, JS_PROP_THROW, atom);
293
+ else if (type === JS_THROW_VAR_REDECL)
294
+ JS_ThrowSyntaxErrorAtom(ctx, "redeclaration of '%s'", atom);
295
+ else if (type === JS_THROW_VAR_UNINITIALIZED)
296
+ JS_ThrowReferenceErrorUninitialized(ctx, atom);
297
+ else if (type === JS_THROW_ERROR_DELETE_SUPER)
298
+ JS_ThrowReferenceError(ctx, "unsupported reference to 'super'");
299
+ else if (type === JS_THROW_ERROR_ITERATOR_THROW)
300
+ JS_ThrowTypeError(ctx, 'iterator does not have a throw method');
301
+ else
302
+ JS_ThrowInternalError(ctx, 'invalid throw var type ' + type);
303
+ this.throw_pending();
304
+ }
305
+ /* --- values --- */
306
+ new_cell(v) { return new_var_ref_cell(v); }
307
+ new_object() { return this.check(JS_NewObject(this.ctx)); }
308
+ new_object_null() { return this.check(JS_NewObjectProto(this.ctx, null)); }
309
+ /* array literal: takes ownership of the host array and re-prototypes it */
310
+ array(elems) { return JS_NewArrayFrom(this.ctx, elems); }
311
+ atom_value(atom) { return JS_AtomToValue(this.ctx, atom); }
312
+ private_symbol(atom) { return JS_NewSymbolFromAtom(this.ctx, atom, JS_ATOM_TYPE_PRIVATE); }
313
+ sloppy_this(t) {
314
+ if (JS_IsObject(t))
315
+ return t;
316
+ if (t === undefined || t === null)
317
+ return this.ctx.global_obj;
318
+ return this.check(JS_ToObject(this.ctx, t));
319
+ }
320
+ regexp(pattern, flags) {
321
+ if (!hooks.js_regexp_constructor_internal)
322
+ this.throw_internal_error('RegExp is not available');
323
+ return this.check(hooks.js_regexp_constructor_internal(this.ctx, undefined, pattern, flags));
324
+ }
325
+ to_object(v) { return this.check(JS_ToObject(this.ctx, v)); }
326
+ to_propkey(v) { return this.check(JS_ToPropertyKey(this.ctx, v)); }
327
+ to_numeric(v) { return this.check(JS_ToNumericFree(this.ctx, v)); }
328
+ inc(v) { return this.check(js_unary_arith_slow(this.ctx, 2 /* JSUnaryOp.INC */, v)); }
329
+ dec(v) { return this.check(js_unary_arith_slow(this.ctx, 3 /* JSUnaryOp.DEC */, v)); }
330
+ in(k, o) {
331
+ const r = js_operator_in(this.ctx, k, o);
332
+ if (r < 0)
333
+ this.throw_pending();
334
+ return r !== 0;
335
+ }
336
+ instanceof(v, c) {
337
+ const r = JS_IsInstanceOf(this.ctx, v, c);
338
+ if (r < 0)
339
+ this.throw_pending();
340
+ return r !== 0;
341
+ }
342
+ get_prototype(o) { return this.check(JS_GetPrototype(this.ctx, o)); }
343
+ /* --- calls --- */
344
+ /* call with an explicit this when the callee has no direct entry (not a guest function) */
345
+ call_slow(f, thisv, args) {
346
+ return this.check(JS_CallInternal(this.ctx, f, thisv, undefined, args, 0));
347
+ }
348
+ construct_slow(f, new_target, args) {
349
+ return this.check(JS_CallConstructorInternal(this.ctx, f, new_target, args, 0));
350
+ }
351
+ /* method call on a primitive receiver (looked up on the guest prototype of its type) */
352
+ call_method_prim(o, atom, args) {
353
+ const f = this.check(JS_GetProperty(this.ctx, o, atom));
354
+ return this.check(JS_CallInternal(this.ctx, f, o, undefined, args, 0));
355
+ }
356
+ call_method_prim_key(o, key, args) {
357
+ const f = this.check(JS_GetPropertyValue(this.ctx, o, key));
358
+ return this.check(JS_CallInternal(this.ctx, f, o, undefined, args, 0));
359
+ }
360
+ apply(f, thisv, arr, magic) {
361
+ return this.check(js_function_apply(this.ctx, f, [thisv, arr], magic));
362
+ }
363
+ create_this(new_target) {
364
+ /* fast path: an ordinary guest function with an object `prototype` (the property read is
365
+ native, as the host does for `new`) */
366
+ if (typeof new_target === 'function' && js_meta.get(new_target)?.class_id !== 44 /* JSClassID.PROXY */) {
367
+ const p = new_target.prototype;
368
+ if (typeof p === 'object' && p !== null)
369
+ return Object.create(p);
370
+ }
371
+ return this.check(js_create_from_ctor(this.ctx, new_target, 1 /* JSClassID.OBJECT */));
372
+ }
373
+ /* `off` is the index of the first guest argument in the host `arguments` object (2 for the
374
+ direct convention, 0 for the natural one) */
375
+ init_ctor(self, new_target, args, off) {
376
+ if (new_target === undefined)
377
+ this.throw_type_error("class constructors must be invoked with 'new'");
378
+ const sup = this.check(JS_GetPrototype(this.ctx, self));
379
+ return this.check(JS_CallConstructor2(this.ctx, sup, new_target, Array.prototype.slice.call(args, off)));
380
+ }
381
+ arguments(args, off) {
382
+ return this.check(js_build_arguments_value(this.ctx, Array.prototype.slice.call(args, off)));
383
+ }
384
+ /* legacy arguments object aliasing the argument cells through accessor properties */
385
+ mapped_arguments(args, off, cells, self) {
386
+ const ctx = this.ctx;
387
+ const argv = Array.prototype.slice.call(args, off);
388
+ const argc = argv.length;
389
+ const val = this.check(JS_NewObjectProtoClass(ctx, ctx.class_proto[1 /* JSClassID.OBJECT */], 9 /* JSClassID.MAPPED_ARGUMENTS */));
390
+ JS_DefinePropertyValue(ctx, val, JS_ATOM_length, argc, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE);
391
+ const n = Math.min(argc, cells.length);
392
+ for (let i = 0; i < n; i++) {
393
+ const cell = cells[i];
394
+ const getter = js_new_host_function(ctx, () => cell.get(), false, '', 0, ctx.function_proto, 12 /* JSClassID.C_FUNCTION */);
395
+ const setter = js_new_host_function(ctx, (_t, _nt, a) => { cell.set(a[0]); return undefined; }, false, '', 1, ctx.function_proto, 12 /* JSClassID.C_FUNCTION */);
396
+ Reflect.defineProperty(val, i, { get: getter, set: setter, enumerable: true, configurable: true });
397
+ }
398
+ for (let i = n; i < argc; i++)
399
+ this.checkn(JS_DefinePropertyValueUint32(ctx, val, i, argv[i], JS_PROP_C_W_E));
400
+ JS_DefinePropertyValue(ctx, val, JS_ATOM_Symbol_iterator, ctx.array_proto_values, JS_PROP_CONFIGURABLE | JS_PROP_WRITABLE);
401
+ JS_DefinePropertyValue(ctx, val, JS_ATOM_callee, self, JS_PROP_CONFIGURABLE | JS_PROP_WRITABLE);
402
+ return val;
403
+ }
404
+ rest(args, off, first) {
405
+ const argv = Array.prototype.slice.call(args, off);
406
+ return this.check(js_build_rest(this.ctx, first, argv.length, argv));
407
+ }
408
+ home_object(self) {
409
+ return JS_GetFunctionData(self)?.home_object ?? undefined;
410
+ }
411
+ /* --- closures and classes --- */
412
+ /* guest function object for bytecode `b` with the given variable references (fclosure).
413
+ When `b` is compiled the object is the generated forwarder, else an interpreter wrapper
414
+ that the call hook tiers up later. */
415
+ closure(b, var_refs, _parent) {
416
+ const ctx = this.ctx;
417
+ const class_id = func_kind_to_class_id(b.func_kind);
418
+ const proto = ctx.class_proto[class_id] ?? ctx.function_proto;
419
+ let fo = null;
420
+ if (b.func_kind === 0 /* JSFunctionKind.NORMAL */ && !b.no_jit) {
421
+ const c = this.compile(b);
422
+ if (c) {
423
+ const [f, direct, mkpriv] = c.make(var_refs);
424
+ const m = new JSObjectMeta(13 /* JSClassID.BYTECODE_FUNCTION */);
425
+ m.func = new JSFunctionData(b, var_refs);
426
+ m.func.compiled = direct;
427
+ m.func.mkpriv = mkpriv;
428
+ m.is_constructor = b.has_prototype;
429
+ m.realm = b.realm ?? ctx;
430
+ js_meta.set(f, m);
431
+ js_direct.set(f, direct);
432
+ Object.setPrototypeOf(f, proto);
433
+ /* a host `function` has an own `prototype` object with a host prototype chain */
434
+ if (Object.prototype.hasOwnProperty.call(f, 'prototype'))
435
+ f.prototype = undefined;
436
+ fo = f;
437
+ }
438
+ }
439
+ if (fo === null)
440
+ fo = this.check(js_closure_from_refs(ctx, b, var_refs, proto, b.has_prototype));
441
+ let name_atom = b.func_name;
442
+ if (name_atom === JS_ATOM_NULL)
443
+ name_atom = JS_ATOM_empty_string;
444
+ js_function_set_properties(ctx, fo, name_atom, b.defined_arg_count);
445
+ if (b.func_kind & 1 /* JSFunctionKind.GENERATOR */) {
446
+ const proto_class_id = (b.func_kind === 3 /* JSFunctionKind.ASYNC_GENERATOR */) ? 53 /* JSClassID.ASYNC_GENERATOR */ : 43 /* JSClassID.GENERATOR */;
447
+ const gproto = this.check(JS_NewObjectProto(ctx, ctx.class_proto[proto_class_id]));
448
+ JS_DefinePropertyValue(ctx, fo, JS_ATOM_prototype, gproto, JS_PROP_WRITABLE);
449
+ }
450
+ else if (b.has_prototype) {
451
+ const pobj = this.check(JS_NewObject(ctx));
452
+ this.checkn(JS_DefinePropertyValue(ctx, pobj, JS_ATOM_constructor, fo, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE));
453
+ this.checkn(JS_DefinePropertyValue(ctx, fo, JS_ATOM_prototype, pobj, JS_PROP_WRITABLE));
454
+ }
455
+ return fo;
456
+ }
457
+ define_class(name, parent_class, b, class_flags, var_refs, is_computed_name) {
458
+ const r = js_define_class(this.ctx, is_computed_name ? JS_ATOM_NULL : name, class_flags, parent_class, b, var_refs, is_computed_name, is_computed_name ? name : undefined);
459
+ if (r === null)
460
+ this.throw_pending();
461
+ return r;
462
+ }
463
+ set_home_object(f, home) { js_method_set_home_object(this.ctx, f, home); }
464
+ set_name(f, atom) { this.checkn(JS_DefineObjectName(this.ctx, f, atom, JS_PROP_CONFIGURABLE)); }
465
+ set_name_computed(f, name) { this.checkn(JS_DefineObjectNameComputed(this.ctx, f, name, JS_PROP_CONFIGURABLE)); }
466
+ define_method(obj, key, fn, op_flags, computed) {
467
+ const ctx = this.ctx;
468
+ let atom;
469
+ if (computed) {
470
+ atom = JS_ValueToAtom(ctx, key);
471
+ if (atom === JS_ATOM_NULL)
472
+ this.throw_pending();
473
+ }
474
+ else {
475
+ atom = key;
476
+ }
477
+ let fl = JS_PROP_HAS_CONFIGURABLE | JS_PROP_CONFIGURABLE | JS_PROP_HAS_ENUMERABLE | JS_PROP_THROW;
478
+ if (op_flags & OP_DEFINE_METHOD_ENUMERABLE)
479
+ fl |= JS_PROP_ENUMERABLE;
480
+ op_flags &= 3;
481
+ let value = undefined, getter = undefined, setter = undefined;
482
+ if (op_flags === OP_DEFINE_METHOD_METHOD) {
483
+ value = fn;
484
+ fl |= JS_PROP_HAS_VALUE | JS_PROP_HAS_WRITABLE | JS_PROP_WRITABLE;
485
+ }
486
+ else if (op_flags === OP_DEFINE_METHOD_GETTER) {
487
+ getter = fn;
488
+ fl |= JS_PROP_HAS_GET;
489
+ }
490
+ else {
491
+ setter = fn;
492
+ fl |= JS_PROP_HAS_SET;
493
+ }
494
+ this.checkn(js_method_set_properties(ctx, fn, atom, fl, obj));
495
+ this.checkn(JS_DefineProperty(ctx, obj, atom, value, getter, setter, fl));
496
+ }
497
+ set_proto(o, proto) {
498
+ if (JS_IsObject(proto) || proto === null)
499
+ this.checkn(JS_SetPrototypeInternal(this.ctx, o, proto, true));
500
+ }
501
+ check_brand(o, f) {
502
+ const r = JS_CheckBrand(this.ctx, o, f);
503
+ if (r < 0)
504
+ this.throw_pending();
505
+ if (!r)
506
+ this.throw_type_error('invalid brand on object');
507
+ }
508
+ add_brand(o, f) { this.checkn(JS_AddBrand(this.ctx, o, f)); }
509
+ get_private_field(o, name) { return this.check(JS_GetPrivateField(this.ctx, o, name)); }
510
+ put_private_field(o, name, v) { this.checkn(JS_SetPrivateField(this.ctx, o, name, v)); }
511
+ define_private_field(o, name, v) { this.checkn(JS_DefinePrivateField(this.ctx, o, name, v)); }
512
+ private_in(o, name) {
513
+ const r = js_operator_private_in(this.ctx, o, name);
514
+ if (r < 0)
515
+ this.throw_pending();
516
+ return r !== 0;
517
+ }
518
+ /* --- globals --- */
519
+ check_var(atom) {
520
+ const r = JS_CheckGlobalVar(this.ctx, atom);
521
+ if (r < 0)
522
+ this.throw_pending();
523
+ return r !== 0;
524
+ }
525
+ get_global(atom, throw_ref_error) {
526
+ return this.check(JS_GetGlobalVar(this.ctx, atom, throw_ref_error ? 1 : 0));
527
+ }
528
+ /* JS_SetGlobalVar with an explicit strict flag (the engine's version reads the strictness
529
+ from the current interpreter frame, which does not exist for compiled code) */
530
+ put_global(atom, v, flag, strict) {
531
+ const ctx = this.ctx;
532
+ if (flag === 1 || !strict || (JS_AtomToKey(ctx, atom) in ctx.global_var_obj)) {
533
+ this.checkn(JS_SetGlobalVar(ctx, atom, v, flag));
534
+ return;
535
+ }
536
+ const ret = JS_HasProperty(ctx, ctx.global_obj, atom);
537
+ if (ret < 0)
538
+ this.throw_pending();
539
+ if (!ret) {
540
+ JS_ThrowReferenceErrorNotDefined(ctx, atom);
541
+ this.throw_pending();
542
+ }
543
+ this.checkn(JS_SetPropertyInternal(ctx, ctx.global_obj, atom, v, ctx.global_obj, JS_PROP_THROW));
544
+ }
545
+ put_global_strict(atom, defined, v) {
546
+ const ctx = this.ctx;
547
+ if (!defined) {
548
+ JS_ThrowReferenceErrorNotDefined(ctx, atom);
549
+ this.throw_pending();
550
+ }
551
+ if (JS_AtomToKey(ctx, atom) in ctx.global_var_obj) {
552
+ this.checkn(JS_SetGlobalVar(ctx, atom, v, 2));
553
+ return;
554
+ }
555
+ this.checkn(JS_SetPropertyInternal(ctx, ctx.global_obj, atom, v, ctx.global_obj, JS_PROP_THROW));
556
+ }
557
+ check_define_var(atom, flags) { if (JS_CheckDefineGlobalVar(this.ctx, atom, flags))
558
+ this.throw_pending(); }
559
+ define_var(atom, flags) { this.checkn(JS_DefineGlobalVar(this.ctx, atom, flags)); }
560
+ define_func(atom, v, flags) { this.checkn(JS_DefineGlobalFunction(this.ctx, atom, v, flags)); }
561
+ get_global_ref(atom) {
562
+ const r = JS_GetGlobalVarRef(this.ctx, atom);
563
+ if (!r)
564
+ this.throw_pending();
565
+ return r;
566
+ }
567
+ delete_global(atom) {
568
+ const r = JS_DeleteProperty(this.ctx, this.ctx.global_obj, atom, 0);
569
+ if (r < 0)
570
+ this.throw_pending();
571
+ return r !== 0;
572
+ }
573
+ /* --- properties (slow paths: primitive bases and runtime-dependent semantics) --- */
574
+ get_field(o, atom) { return this.check(JS_GetProperty(this.ctx, o, atom)); }
575
+ get_field_str(o, name) {
576
+ return this.check(JS_GetProperty(this.ctx, o, this.ctx.rt.atoms.newAtomStr(name)));
577
+ }
578
+ get_length(o) { return this.check(JS_GetProperty(this.ctx, o, JS_ATOM_length)); }
579
+ get_el(o, k) { return this.check(JS_GetPropertyValue(this.ctx, o, k)); }
580
+ put_field(o, atom, v, strict) {
581
+ this.checkn(JS_SetPropertyInternal(this.ctx, o, atom, v, o, strict ? JS_PROP_THROW : 0));
582
+ }
583
+ put_el(o, k, v, strict) {
584
+ this.checkn(JS_SetPropertyValue(this.ctx, o, k, v, strict ? JS_PROP_THROW : 0));
585
+ }
586
+ delete(o, k, strict) {
587
+ const atom = JS_ValueToAtom(this.ctx, k);
588
+ if (atom === JS_ATOM_NULL)
589
+ this.throw_pending();
590
+ const r = JS_DeleteProperty(this.ctx, o, atom, strict ? JS_PROP_THROW : 0);
591
+ if (r < 0)
592
+ this.throw_pending();
593
+ return r !== 0;
594
+ }
595
+ define_field(o, atom, v) {
596
+ this.checkn(JS_DefinePropertyValue(this.ctx, o, atom, v, JS_PROP_C_W_E | JS_PROP_THROW));
597
+ }
598
+ define_array_el(arr, pos, v) {
599
+ this.checkn(JS_DefinePropertyValueValue(this.ctx, arr, pos, v, JS_PROP_C_W_E | JS_PROP_THROW));
600
+ }
601
+ append(arr, pos, src) {
602
+ if (typeof pos !== 'number')
603
+ this.throw_internal_error('invalid index for append');
604
+ const r = js_append_enumerate_value(this.ctx, arr, pos, src);
605
+ if (r < 0)
606
+ this.throw_pending();
607
+ return r;
608
+ }
609
+ copy_data_properties(target, source, excluded) {
610
+ if (JS_CopyDataProperties(this.ctx, target, source, excluded, false))
611
+ this.throw_pending();
612
+ }
613
+ get_ref_value(o, k, strict) {
614
+ const ctx = this.ctx;
615
+ const atom = JS_ValueToAtom(ctx, k);
616
+ if (atom === JS_ATOM_NULL)
617
+ this.throw_pending();
618
+ if (o === undefined) {
619
+ JS_ThrowReferenceErrorNotDefined(ctx, atom);
620
+ this.throw_pending();
621
+ }
622
+ const r = JS_HasProperty(ctx, o, atom);
623
+ if (r < 0)
624
+ this.throw_pending();
625
+ if (!r) {
626
+ if (strict) {
627
+ JS_ThrowReferenceErrorNotDefined(ctx, atom);
628
+ this.throw_pending();
629
+ }
630
+ return undefined;
631
+ }
632
+ return this.check(JS_GetProperty(ctx, o, atom));
633
+ }
634
+ put_ref_value(o, k, v, strict) {
635
+ const ctx = this.ctx;
636
+ const atom = JS_ValueToAtom(ctx, k);
637
+ if (atom === JS_ATOM_NULL)
638
+ this.throw_pending();
639
+ if (o === undefined) {
640
+ if (strict) {
641
+ JS_ThrowReferenceErrorNotDefined(ctx, atom);
642
+ this.throw_pending();
643
+ }
644
+ o = ctx.global_obj;
645
+ }
646
+ const r = JS_HasProperty(ctx, o, atom);
647
+ if (r < 0)
648
+ this.throw_pending();
649
+ if (!r && strict) {
650
+ JS_ThrowReferenceErrorNotDefined(ctx, atom);
651
+ this.throw_pending();
652
+ }
653
+ this.checkn(JS_SetPropertyInternal(ctx, o, atom, v, o, strict ? JS_PROP_THROW : 0));
654
+ }
655
+ get_super_value(thisv, o, k) {
656
+ const atom = JS_ValueToAtom(this.ctx, k);
657
+ if (atom === JS_ATOM_NULL)
658
+ this.throw_pending();
659
+ return this.check(JS_GetPropertyInternal(this.ctx, o, atom, thisv, false));
660
+ }
661
+ put_super_value(thisv, o, k, v) {
662
+ if (!JS_IsObject(o)) {
663
+ JS_ThrowTypeErrorNotAnObject(this.ctx);
664
+ this.throw_pending();
665
+ }
666
+ const atom = JS_ValueToAtom(this.ctx, k);
667
+ if (atom === JS_ATOM_NULL)
668
+ this.throw_pending();
669
+ this.checkn(JS_SetPropertyInternal(this.ctx, o, atom, v, thisv, JS_PROP_THROW));
670
+ }
671
+ /* --- iteration --- */
672
+ for_in_start(o) { return this.check(build_for_in_iterator(this.ctx, o)); }
673
+ for_in_next(it) {
674
+ const pdone = { done: 0 };
675
+ const v = this.check(js_for_in_next(this.ctx, it, pdone));
676
+ return pdone.done ? this.DONE : v;
677
+ }
678
+ get_iterator(o) { return this.check(JS_GetIterator(this.ctx, o, false)); }
679
+ for_of_start(o) {
680
+ const r = js_for_of_start_value(this.ctx, o, false);
681
+ if (r === null)
682
+ this.throw_pending();
683
+ return r;
684
+ }
685
+ for_of_next(iter, next) {
686
+ if (iter === undefined)
687
+ return this.DONE;
688
+ const r = js_for_of_next_value(this.ctx, iter, next);
689
+ if (r === null)
690
+ this.throw_pending();
691
+ return r.done ? this.DONE : r.value;
692
+ }
693
+ iterator_close(iter) {
694
+ if (JS_IteratorClose(this.ctx, iter, false) < 0)
695
+ this.throw_pending();
696
+ }
697
+ /* close an iterator while an exception is propagating: errors from return() are ignored */
698
+ iterator_close_exc(iter) {
699
+ if (iter === undefined)
700
+ return;
701
+ const ctx = this.ctx;
702
+ const method = JS_GetProperty(ctx, iter, JS_ATOM_return);
703
+ if (JS_IsException(method)) {
704
+ JS_GetException(ctx);
705
+ return;
706
+ }
707
+ if (method === undefined || method === null)
708
+ return;
709
+ const r = JS_Call(ctx, method, iter, []);
710
+ if (JS_IsException(r))
711
+ JS_GetException(ctx);
712
+ }
713
+ iterator_call(iter, val, flags) {
714
+ const ctx = this.ctx;
715
+ const method = this.check(JS_GetProperty(ctx, iter, (flags & 1) ? JS_ATOM_throw : JS_ATOM_return));
716
+ if (method === undefined || method === null)
717
+ return this.DONE;
718
+ return this.check(JS_Call(ctx, method, iter, (flags & 2) ? [] : [val]));
719
+ }
720
+ }
721
+ //# sourceMappingURL=jit_runtime.js.map