@mirascript/mirascript 0.1.12 → 0.1.14

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 (74) hide show
  1. package/dist/chunk-55FKP56O.js +2317 -0
  2. package/dist/chunk-55FKP56O.js.map +6 -0
  3. package/dist/{chunk-IKSSUVRE.js → chunk-Q74RKZ7O.js} +73 -1250
  4. package/dist/chunk-Q74RKZ7O.js.map +6 -0
  5. package/dist/cli/index.js +8 -7
  6. package/dist/cli/index.js.map +1 -1
  7. package/dist/compiler/emit.d.ts.map +1 -1
  8. package/dist/compiler/worker.js +1 -1
  9. package/dist/helpers/serialize.d.ts +1 -1
  10. package/dist/helpers/serialize.d.ts.map +1 -1
  11. package/dist/index.js +15 -9
  12. package/dist/subtle.d.ts +1 -1
  13. package/dist/subtle.d.ts.map +1 -1
  14. package/dist/subtle.js +7 -7
  15. package/dist/vm/lib/global/debug.d.ts +1 -1
  16. package/dist/vm/lib/global/json.d.ts +2 -2
  17. package/dist/vm/lib/global/json.d.ts.map +1 -1
  18. package/dist/vm/lib/global/mod/matrix.d.ts +1 -1
  19. package/dist/vm/lib/global/mod/matrix.d.ts.map +1 -1
  20. package/dist/vm/lib/global/sequence/all-any.d.ts +2 -2
  21. package/dist/vm/lib/global/sequence/entries.d.ts +4 -4
  22. package/dist/vm/lib/global/sequence/find.d.ts +2 -2
  23. package/dist/vm/lib/global/sequence/repeat.d.ts +1 -1
  24. package/dist/vm/lib/global/sequence/with.d.ts +1 -1
  25. package/dist/vm/lib/global/sequence/with.d.ts.map +1 -1
  26. package/dist/vm/lib/global/sequence/zip.d.ts +1 -1
  27. package/dist/vm/operations.d.ts +2 -0
  28. package/dist/vm/operations.d.ts.map +1 -1
  29. package/dist/vm/types/any.d.ts +10 -0
  30. package/dist/vm/types/any.d.ts.map +1 -0
  31. package/dist/vm/types/array.d.ts +12 -0
  32. package/dist/vm/types/array.d.ts.map +1 -0
  33. package/dist/vm/types/callable.d.ts +5 -0
  34. package/dist/vm/types/callable.d.ts.map +1 -0
  35. package/dist/vm/types/const.d.ts +15 -0
  36. package/dist/vm/types/const.d.ts.map +1 -0
  37. package/dist/vm/types/context.d.ts.map +1 -1
  38. package/dist/vm/types/extern.d.ts +1 -1
  39. package/dist/vm/types/extern.d.ts.map +1 -1
  40. package/dist/vm/types/immutable.d.ts +15 -0
  41. package/dist/vm/types/immutable.d.ts.map +1 -0
  42. package/dist/vm/types/index.d.ts +17 -47
  43. package/dist/vm/types/index.d.ts.map +1 -1
  44. package/dist/vm/types/primitive.d.ts +7 -0
  45. package/dist/vm/types/primitive.d.ts.map +1 -0
  46. package/dist/vm/types/record.d.ts +20 -0
  47. package/dist/vm/types/record.d.ts.map +1 -0
  48. package/dist/vm/types/value.d.ts +14 -0
  49. package/dist/vm/types/value.d.ts.map +1 -0
  50. package/dist/vm/types/wrapper.d.ts +1 -1
  51. package/dist/vm/types/wrapper.d.ts.map +1 -1
  52. package/package.json +2 -2
  53. package/src/compiler/compile-fast.ts +1 -1
  54. package/src/compiler/emit.ts +131 -17
  55. package/src/helpers/serialize.ts +34 -14
  56. package/src/subtle.ts +1 -1
  57. package/src/vm/operations.ts +5 -5
  58. package/src/vm/types/any.ts +33 -0
  59. package/src/vm/types/array.ts +19 -0
  60. package/src/vm/types/callable.ts +10 -0
  61. package/src/vm/types/{checker.ts → const.ts} +7 -55
  62. package/src/vm/types/context.ts +5 -1
  63. package/src/vm/types/extern.ts +19 -5
  64. package/src/vm/types/immutable.ts +22 -0
  65. package/src/vm/types/index.ts +31 -83
  66. package/src/vm/types/primitive.ts +14 -0
  67. package/src/vm/types/record.ts +53 -0
  68. package/src/vm/types/value.ts +22 -0
  69. package/src/vm/types/wrapper.ts +1 -1
  70. package/dist/chunk-AGIXQM52.js +0 -916
  71. package/dist/chunk-AGIXQM52.js.map +0 -6
  72. package/dist/chunk-IKSSUVRE.js.map +0 -6
  73. package/dist/vm/types/checker.d.ts +0 -30
  74. package/dist/vm/types/checker.d.ts.map +0 -1
@@ -0,0 +1,2317 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+
7
+ // src/vm/error.ts
8
+ var VmError = class _VmError extends Error {
9
+ constructor(message, recovered) {
10
+ super(message);
11
+ this.recovered = recovered;
12
+ this.name = "VmError";
13
+ }
14
+ /** 从其他错误构造 */
15
+ static from(prefix, error, recovered) {
16
+ if (prefix) {
17
+ if (prefix.endsWith(":")) {
18
+ prefix += " ";
19
+ } else if (!prefix.endsWith(": ")) {
20
+ prefix += ": ";
21
+ }
22
+ }
23
+ let vmError;
24
+ if (error instanceof Error) {
25
+ vmError = new _VmError(`${prefix}${error.message}`, recovered);
26
+ vmError.stack = error.stack;
27
+ } else {
28
+ vmError = new _VmError(`${prefix}${String(error)}`, recovered);
29
+ }
30
+ vmError.cause = error;
31
+ return vmError;
32
+ }
33
+ };
34
+
35
+ // src/vm/operations.ts
36
+ var operations_exports = {};
37
+ __export(operations_exports, {
38
+ $Add: () => $Add,
39
+ $Aeq: () => $Aeq,
40
+ $And: () => $And,
41
+ $ArraySpread: () => $ArraySpread,
42
+ $AssertInit: () => $AssertInit,
43
+ $AssertNonNil: () => $AssertNonNil,
44
+ $Call: () => $Call,
45
+ $Concat: () => $Concat,
46
+ $Div: () => $Div,
47
+ $Eq: () => $Eq,
48
+ $Format: () => $Format,
49
+ $Get: () => $Get,
50
+ $Gt: () => $Gt,
51
+ $Gte: () => $Gte,
52
+ $Has: () => $Has,
53
+ $In: () => $In,
54
+ $InnerToString: () => $InnerToString,
55
+ $IsArray: () => $IsArray,
56
+ $IsBoolean: () => $IsBoolean,
57
+ $IsNumber: () => $IsNumber,
58
+ $IsRecord: () => $IsRecord,
59
+ $IsString: () => $IsString,
60
+ $Iterable: () => $Iterable,
61
+ $Length: () => $Length,
62
+ $Lt: () => $Lt,
63
+ $Lte: () => $Lte,
64
+ $Mod: () => $Mod,
65
+ $Mul: () => $Mul,
66
+ $Naeq: () => $Naeq,
67
+ $Neg: () => $Neg,
68
+ $Neq: () => $Neq,
69
+ $Not: () => $Not,
70
+ $Nsame: () => $Nsame,
71
+ $Omit: () => $Omit,
72
+ $Or: () => $Or,
73
+ $Pick: () => $Pick,
74
+ $Pos: () => $Pos,
75
+ $Pow: () => $Pow,
76
+ $RecordSpread: () => $RecordSpread,
77
+ $Same: () => $Same,
78
+ $Set: () => $Set,
79
+ $Slice: () => $Slice,
80
+ $SliceExclusive: () => $SliceExclusive,
81
+ $Sub: () => $Sub,
82
+ $ToBoolean: () => $ToBoolean,
83
+ $ToNumber: () => $ToNumber,
84
+ $ToString: () => $ToString,
85
+ $Type: () => $Type
86
+ });
87
+
88
+ // src/helpers/utils.ts
89
+ var { isArray } = Array;
90
+ var { isFinite, isNaN, isInteger, isSafeInteger } = Number;
91
+ var { hasOwn, keys, values, entries, create, getPrototypeOf, fromEntries, defineProperty } = Object;
92
+ var { apply } = Reflect;
93
+ var hasOwnEnumerable = Function.call.bind(
94
+ // eslint-disable-next-line @typescript-eslint/unbound-method
95
+ Object.prototype.propertyIsEnumerable
96
+ );
97
+
98
+ // src/vm/helpers.ts
99
+ var helpers_exports = {};
100
+ __export(helpers_exports, {
101
+ ArrayRange: () => ArrayRange,
102
+ ArrayRangeExclusive: () => ArrayRangeExclusive,
103
+ Cp: () => Cp,
104
+ CpEnter: () => CpEnter,
105
+ CpExit: () => CpExit,
106
+ Element: () => Element,
107
+ ElementOpt: () => ElementOpt,
108
+ Function: () => Function2,
109
+ GlobalFallback: () => GlobalFallback,
110
+ Upvalue: () => Upvalue,
111
+ Vargs: () => Vargs,
112
+ configCheckpoint: () => configCheckpoint
113
+ });
114
+
115
+ // src/vm/types/context.ts
116
+ var kVmContext = Symbol.for("mirascript.vm.context");
117
+ var VmSharedContext = create(null);
118
+ var VmSharedContextKeys = null;
119
+ function defineVmContextValue(name, value, override = false) {
120
+ if (!override && name in VmSharedContext) throw new Error(`Global variable '${name}' is already defined.`);
121
+ let v;
122
+ if (typeof value == "function") {
123
+ v = VmFunction(value, {
124
+ isLib: true,
125
+ fullName: `global.${name}`
126
+ });
127
+ } else {
128
+ v = value;
129
+ }
130
+ VmSharedContext[name] = v ?? null;
131
+ VmSharedContextKeys = null;
132
+ }
133
+ var DefaultVmContext = Object.freeze({
134
+ [kVmContext]: true,
135
+ /** @inheritdoc */
136
+ keys() {
137
+ VmSharedContextKeys ??= Object.freeze(keys(VmSharedContext));
138
+ return VmSharedContextKeys;
139
+ },
140
+ /** @inheritdoc */
141
+ get(key) {
142
+ return VmSharedContext[key] ?? null;
143
+ },
144
+ /** @inheritdoc */
145
+ has(key) {
146
+ return key in VmSharedContext;
147
+ }
148
+ });
149
+ var _a;
150
+ _a = kVmContext;
151
+ var ValueVmContext = class {
152
+ constructor(env, describe) {
153
+ this.env = env;
154
+ this.describe = describe;
155
+ this[_a] = true;
156
+ this.cachedKeys = null;
157
+ }
158
+ /** @inheritdoc */
159
+ keys() {
160
+ this.cachedKeys ??= keys(this.env);
161
+ return [...this.cachedKeys, ...DefaultVmContext.keys()];
162
+ }
163
+ /** @inheritdoc */
164
+ get(key) {
165
+ return this.env[key] ?? null;
166
+ }
167
+ /** @inheritdoc */
168
+ has(key) {
169
+ return key in this.env;
170
+ }
171
+ };
172
+ var _a2;
173
+ _a2 = kVmContext;
174
+ var FactoryVmContext = class {
175
+ constructor(getter, enumerator, describe) {
176
+ this.getter = getter;
177
+ this.enumerator = enumerator;
178
+ this.describe = describe;
179
+ this[_a2] = true;
180
+ }
181
+ /** @inheritdoc */
182
+ keys() {
183
+ if (!this.enumerator) return DefaultVmContext.keys();
184
+ return [...this.enumerator(), ...DefaultVmContext.keys()];
185
+ }
186
+ /** @inheritdoc */
187
+ get(key) {
188
+ const value = this.getter(key);
189
+ if (value !== void 0) return value;
190
+ return DefaultVmContext.get(key);
191
+ }
192
+ /** @inheritdoc */
193
+ has(key) {
194
+ return this.getter(key) !== void 0 || DefaultVmContext.has(key);
195
+ }
196
+ };
197
+ function createVmContext(...args) {
198
+ if (args[0] == null && args[1] == null) {
199
+ return { ...DefaultVmContext };
200
+ }
201
+ if (typeof args[0] == "function") {
202
+ const [getter, enumerator, describer2] = args;
203
+ return new FactoryVmContext(getter, enumerator ?? void 0, describer2 ?? void 0);
204
+ }
205
+ const [vmValues, externValues, describer] = args;
206
+ const env = create(VmSharedContext);
207
+ if (vmValues) {
208
+ for (const [key, value] of entries(vmValues)) {
209
+ if (!isVmAny(value, false)) continue;
210
+ env[key] = value ?? null;
211
+ }
212
+ }
213
+ if (externValues) {
214
+ for (const [key, value] of entries(externValues)) {
215
+ env[key] = value == null ? null : wrapToVmValue(value, null);
216
+ }
217
+ }
218
+ return new ValueVmContext(env, describer ?? void 0);
219
+ }
220
+ function isVmContext(context) {
221
+ if (context == null || typeof context != "object") return false;
222
+ return context[kVmContext] === true;
223
+ }
224
+
225
+ // src/vm/helpers.ts
226
+ var Vargs = (varags) => {
227
+ for (let i = 0, l = varags.length; i < l; i++) {
228
+ const el = varags[i];
229
+ if (!isVmConst(el)) {
230
+ varags[i] = null;
231
+ }
232
+ }
233
+ return varags;
234
+ };
235
+ var Element = (value) => {
236
+ $AssertInit(value);
237
+ if (!isVmConst(value)) return null;
238
+ return value;
239
+ };
240
+ var ElementOpt = (key, value) => {
241
+ $AssertInit(value);
242
+ if (value == null || !isVmConst(value)) return {};
243
+ return { [key]: value };
244
+ };
245
+ var Function2 = (fn) => {
246
+ return VmFunction(fn, { isLib: false, injectCp: false });
247
+ };
248
+ var Upvalue = (value) => {
249
+ $AssertInit(value);
250
+ return value;
251
+ };
252
+ var assertArrayLength = (start, end) => {
253
+ if (end - start > VM_ARRAY_MAX_LENGTH) {
254
+ throw new RangeError(`Array length exceeds maximum limit of ${VM_ARRAY_MAX_LENGTH}`);
255
+ }
256
+ };
257
+ var isEmptyRange = (start, end) => {
258
+ return !isFinite(start) || !isFinite(end) || start > end;
259
+ };
260
+ var ArrayRange = (start, end) => {
261
+ const s = $ToNumber(start);
262
+ const e = $ToNumber(end);
263
+ if (isEmptyRange(s, e)) return [];
264
+ assertArrayLength(s, e);
265
+ const arr = [];
266
+ for (let i = s; i <= e; i++) {
267
+ arr.push(i);
268
+ }
269
+ return arr;
270
+ };
271
+ var ArrayRangeExclusive = (start, end) => {
272
+ const s = $ToNumber(start);
273
+ const e = $ToNumber(end);
274
+ if (isEmptyRange(s, e)) return [];
275
+ assertArrayLength(s, e);
276
+ const arr = [];
277
+ for (let i = s; i < e; i++) {
278
+ arr.push(i);
279
+ }
280
+ return arr;
281
+ };
282
+ var MAX_DEPTH = 128;
283
+ var cpDepth = 0;
284
+ var cp = Number.NaN;
285
+ var cpTimeout = 100;
286
+ function Cp() {
287
+ if (!cp) {
288
+ cp = Date.now();
289
+ } else if (Date.now() - cp > cpTimeout) {
290
+ throw new RangeError("Execution timeout");
291
+ }
292
+ }
293
+ function CpEnter() {
294
+ cpDepth++;
295
+ if (cpDepth <= 1) {
296
+ cp = Date.now();
297
+ cpDepth = 1;
298
+ } else if (cpDepth > MAX_DEPTH) {
299
+ throw new RangeError("Maximum call depth exceeded");
300
+ } else {
301
+ Cp();
302
+ }
303
+ }
304
+ function CpExit() {
305
+ cpDepth--;
306
+ if (cpDepth < 1) {
307
+ cp = Number.NaN;
308
+ cpDepth = 0;
309
+ } else {
310
+ Cp();
311
+ }
312
+ }
313
+ function configCheckpoint(timeout = 100) {
314
+ if (typeof timeout !== "number" || timeout <= 0 || Number.isNaN(timeout)) {
315
+ throw new RangeError("Invalid timeout value");
316
+ }
317
+ cpTimeout = timeout;
318
+ }
319
+ function GlobalFallback() {
320
+ return DefaultVmContext;
321
+ }
322
+
323
+ // src/vm/types/function.ts
324
+ var kVmFunction = Symbol.for("mirascript.vm.function");
325
+ function isVmFunction(value) {
326
+ return getVmFunctionInfo(value) != null;
327
+ }
328
+ function getVmFunctionInfo(value) {
329
+ if (typeof value != "function") return void 0;
330
+ return value[kVmFunction];
331
+ }
332
+ function VmFunction(fn, option = {}) {
333
+ if (typeof fn != "function") {
334
+ throw new TypeError("Invalid function");
335
+ }
336
+ const exists = fromVmFunctionProxy(fn);
337
+ if (exists) return exists;
338
+ const info = {
339
+ fullName: option.fullName ?? fn.name,
340
+ isLib: option.isLib ?? false,
341
+ summary: option.summary || void 0,
342
+ params: option.params,
343
+ paramsType: option.paramsType,
344
+ returns: option.returns || void 0,
345
+ returnsType: option.returnsType || void 0,
346
+ examples: option.examples?.length ? option.examples : void 0
347
+ };
348
+ if (option.injectCp) {
349
+ const original = fn;
350
+ info.original = original;
351
+ fn = ((...args) => {
352
+ try {
353
+ CpEnter();
354
+ const ret = original(...args);
355
+ return ret;
356
+ } finally {
357
+ CpExit();
358
+ }
359
+ });
360
+ defineProperty(fn, "name", {
361
+ value: original.name,
362
+ configurable: true
363
+ });
364
+ }
365
+ defineProperty(fn, kVmFunction, {
366
+ value: Object.freeze(info)
367
+ });
368
+ return fn;
369
+ }
370
+
371
+ // src/vm/types/wrapper.ts
372
+ var VmWrapper = class {
373
+ constructor(value) {
374
+ this.value = value;
375
+ }
376
+ /** Convert the object to JSON */
377
+ toJSON() {
378
+ return void 0;
379
+ }
380
+ /** 转为字符串 */
381
+ toString(useBraces) {
382
+ const { type, describe } = this;
383
+ if (!describe) return `<${type}>`;
384
+ return `<${type} ${describe}>`;
385
+ }
386
+ };
387
+ var kVmWrapper = Symbol.for("mirascript.vm.wrapper");
388
+ Object.defineProperty(VmWrapper.prototype, kVmWrapper, { value: true });
389
+ function isVmWrapper(value) {
390
+ return value != null && typeof value == "object" && kVmWrapper in value;
391
+ }
392
+
393
+ // src/vm/types/extern.ts
394
+ var ObjectPrototype = Object.prototype;
395
+ var ObjectToString = ObjectPrototype.toString;
396
+ var FunctionToString = Function.prototype.toString;
397
+ var ArrayToString = Array.prototype.toString;
398
+ var ArrayMap = Array.prototype.map;
399
+ var VmExtern = class extends VmWrapper {
400
+ constructor(value, thisArg = null) {
401
+ super(value);
402
+ this.thisArg = thisArg;
403
+ }
404
+ /** Check if the object has a property */
405
+ access(key, read) {
406
+ if (key.startsWith("_")) return false;
407
+ if (typeof this.value == "function" && (key === "prototype" || key === "arguments" || key === "caller"))
408
+ return false;
409
+ if (hasOwn(this.value, key)) return true;
410
+ if (!read) return true;
411
+ if (!(key in this.value)) return false;
412
+ if (key === "constructor") return false;
413
+ const prop = this.value[key];
414
+ if (key in Function.prototype && prop === Function.prototype[key]) return false;
415
+ if (key in Array.prototype && prop === Array.prototype[key]) return false;
416
+ if (key in Object.prototype && prop === Object.prototype[key]) return false;
417
+ return true;
418
+ }
419
+ /** 决定是否对属性进行包装 */
420
+ assumeVmValue(value, key) {
421
+ return false;
422
+ }
423
+ /** @inheritdoc */
424
+ has(key) {
425
+ return this.access(key, true);
426
+ }
427
+ /** @inheritdoc */
428
+ get(key) {
429
+ if (!this.has(key)) return void 0;
430
+ const prop = this.value[key];
431
+ return wrapToVmValue(prop, this, (v) => this.assumeVmValue(v, key));
432
+ }
433
+ /** Set a property on the object */
434
+ set(key, value) {
435
+ if (!this.access(key, false)) return false;
436
+ const prop = unwrapFromVmValue(value);
437
+ this.value[key] = prop;
438
+ return true;
439
+ }
440
+ /** Call extern value */
441
+ call(args) {
442
+ const { value } = this;
443
+ if (typeof value != "function") {
444
+ throw VmError.from(`Not a callable extern`, null, null);
445
+ }
446
+ const caller = this.thisArg?.value ?? null;
447
+ const unwrappedArgs = args.map(unwrapFromVmValue);
448
+ let ret;
449
+ try {
450
+ ret = apply(value, caller, unwrappedArgs);
451
+ } catch (ex) {
452
+ throw VmError.from(`Callable extern`, ex, null);
453
+ }
454
+ return wrapToVmValue(ret, null, (obj) => this.assumeVmValue(obj, void 0));
455
+ }
456
+ /** @inheritdoc */
457
+ keys() {
458
+ const keys2 = [];
459
+ for (const key in this.value) {
460
+ if (this.has(key)) keys2.push(key);
461
+ }
462
+ return keys2;
463
+ }
464
+ /** @inheritdoc */
465
+ same(other) {
466
+ if (!isVmExtern(other)) return false;
467
+ return this.value === other.value && this.thisArg === other.thisArg;
468
+ }
469
+ /** @inheritdoc */
470
+ toString(useBraces) {
471
+ const { toString } = this.value;
472
+ if (typeof toString != "function" || toString === ObjectToString || toString === FunctionToString) {
473
+ return super.toString(useBraces);
474
+ }
475
+ if (toString === ArrayToString && isArray(this.value)) {
476
+ const mapped = ArrayMap.call(this.value, (item) => {
477
+ if (item === void 0) return "";
478
+ return $InnerToString(wrapToVmValue(item ?? null, null), true);
479
+ });
480
+ const str = mapped.join(", ");
481
+ if (useBraces) return `[${str}]`;
482
+ return str;
483
+ }
484
+ try {
485
+ return String(this.value);
486
+ } catch {
487
+ return super.toString(useBraces);
488
+ }
489
+ }
490
+ /** @inheritdoc */
491
+ get type() {
492
+ return "extern";
493
+ }
494
+ /** @inheritdoc */
495
+ get describe() {
496
+ const tag = ObjectToString.call(this.value).slice(8, -1);
497
+ if (isArray(this.value)) {
498
+ return `${tag}(${this.value.length})`;
499
+ } else if (tag === "Object") {
500
+ const proto = getPrototypeOf(this.value);
501
+ if (proto === ObjectPrototype) {
502
+ return "Object";
503
+ }
504
+ if (proto == null) {
505
+ return "Object: null prototype";
506
+ }
507
+ if (typeof proto.constructor === "function" && proto.constructor.name) {
508
+ return proto.constructor.name;
509
+ }
510
+ } else if (tag === "Function" && "prototype" in this.value && typeof this.value.prototype == "object") {
511
+ const { name } = this.value;
512
+ return `class ${name || "<anonymous>"}`;
513
+ } else if (tag === "Function") {
514
+ const { name } = this.value;
515
+ return `function ${name || "<anonymous>"}()`;
516
+ } else if (tag === "AsyncFunction") {
517
+ const { name } = this.value;
518
+ return `async function ${name || "<anonymous>"}()`;
519
+ } else if (tag === "GeneratorFunction") {
520
+ const { name } = this.value;
521
+ return `function* ${name || "<anonymous>"}()`;
522
+ } else if (tag === "AsyncGeneratorFunction") {
523
+ const { name } = this.value;
524
+ return `async function* ${name || "<anonymous>"}()`;
525
+ }
526
+ return tag;
527
+ }
528
+ };
529
+ var kVmExtern = Symbol.for("mirascript.vm.extern");
530
+ Object.defineProperty(VmExtern.prototype, kVmExtern, { value: true });
531
+ function isVmExtern(value) {
532
+ return value != null && typeof value == "object" && kVmExtern in value;
533
+ }
534
+
535
+ // src/vm/types/boundary.ts
536
+ var kProxy = Symbol.for("mirascript.vm.function.proxy");
537
+ function toVmFunctionProxy(fn) {
538
+ if (!isVmFunction(fn)) return fn;
539
+ const cached = fn[kProxy];
540
+ if (cached != null) return cached;
541
+ const proxy = (...args) => {
542
+ const ret = $Call(
543
+ fn,
544
+ // 作为函数参数传入的值一定丢失了它的 this
545
+ args.map((v) => wrapToVmValue(v, null))
546
+ );
547
+ return unwrapFromVmValue(ret);
548
+ };
549
+ defineProperty(fn, kProxy, { value: proxy });
550
+ defineProperty(proxy, kProxy, { value: fn });
551
+ defineProperty(proxy, "name", {
552
+ value: fn.name,
553
+ configurable: true
554
+ });
555
+ return proxy;
556
+ }
557
+ function fromVmFunctionProxy(fn) {
558
+ if (isVmFunction(fn)) return fn;
559
+ const original = fn[kProxy];
560
+ if (original && isVmFunction(original)) return original;
561
+ return void 0;
562
+ }
563
+ function wrapToVmValue(value, thisArg = null, assumeVmValue) {
564
+ if (value == null) return null;
565
+ switch (typeof value) {
566
+ case "function": {
567
+ const unwrapped = fromVmFunctionProxy(value);
568
+ if (unwrapped) return unwrapped;
569
+ return new VmExtern(value, thisArg);
570
+ }
571
+ case "object": {
572
+ if (isVmWrapper(value)) return value;
573
+ if (value instanceof Date) return value.valueOf();
574
+ if (assumeVmValue?.(value)) return value;
575
+ return new VmExtern(value);
576
+ }
577
+ case "string":
578
+ case "number":
579
+ case "boolean":
580
+ return value;
581
+ case "bigint":
582
+ return Number(value);
583
+ case "symbol":
584
+ case "undefined":
585
+ default:
586
+ return null;
587
+ }
588
+ }
589
+ function unwrapFromVmValue(value) {
590
+ if (typeof value == "function") {
591
+ return toVmFunctionProxy(value);
592
+ }
593
+ if (value == null || typeof value != "object") return value;
594
+ if (!isVmExtern(value)) return value;
595
+ if (value.thisArg == null || typeof value.value != "function") {
596
+ return value.value;
597
+ }
598
+ const f = value;
599
+ const caller = f.thisArg.value;
600
+ return new Proxy(f.value, {
601
+ apply(target, thisArg, args) {
602
+ return apply(target, caller, args);
603
+ }
604
+ });
605
+ }
606
+
607
+ // src/vm/types/script.ts
608
+ var kVmScript = Symbol.for("mirascript.vm.script");
609
+ function isVmScript(value) {
610
+ return typeof value === "function" && value[kVmScript] === true;
611
+ }
612
+
613
+ // src/vm/types/callable.ts
614
+ function isVmCallable(value) {
615
+ return isVmFunction(value) || isVmExtern(value) && typeof value.value == "function";
616
+ }
617
+
618
+ // src/vm/types/array.ts
619
+ var VM_ARRAY_MAX_LENGTH = 2 ** 31 - 1;
620
+ function isVmArray(value) {
621
+ if (!isArray(value)) return false;
622
+ value;
623
+ return true;
624
+ }
625
+
626
+ // src/vm/types/record.ts
627
+ function isVmRecord(value) {
628
+ if (value == null || typeof value !== "object") return false;
629
+ if (isVmWrapper(value)) return false;
630
+ if (isVmArray(value)) return false;
631
+ value;
632
+ return true;
633
+ }
634
+ function isVmArrayLikeRecordByEntires(entries2) {
635
+ const { length } = entries2;
636
+ if (length === 0) return true;
637
+ if (length > VM_ARRAY_MAX_LENGTH) return false;
638
+ const firstKey = entries2[0][0];
639
+ if (firstKey !== "0") return false;
640
+ const lastKey = entries2[length - 1][0];
641
+ if (lastKey !== String(length - 1)) return false;
642
+ return true;
643
+ }
644
+ function isVmArrayLikeRecordByKeys(keys2) {
645
+ const { length } = keys2;
646
+ if (length === 0) return true;
647
+ if (length > VM_ARRAY_MAX_LENGTH) return false;
648
+ const firstKey = keys2[0];
649
+ if (firstKey !== "0") return false;
650
+ const lastKey = keys2[length - 1];
651
+ if (lastKey !== String(length - 1)) return false;
652
+ return true;
653
+ }
654
+ function isVmArrayLikeRecord(value) {
655
+ return isVmArrayLikeRecordByKeys(keys(value));
656
+ }
657
+
658
+ // src/vm/types/primitive.ts
659
+ function isVmPrimitive(value) {
660
+ if (value === null || typeof value == "number" || typeof value == "string" || typeof value == "boolean") {
661
+ value;
662
+ value;
663
+ return true;
664
+ }
665
+ return false;
666
+ }
667
+
668
+ // src/vm/types/const.ts
669
+ var MAX_DEPTH2 = 32;
670
+ function isVmArrayDeep(value, depth) {
671
+ const proto1 = getPrototypeOf(value);
672
+ if (!isArray(proto1)) return false;
673
+ if (!depth) return true;
674
+ return value.every((item) => isVmConstInner(item, depth));
675
+ }
676
+ function isVmRecordDeep(value, depth) {
677
+ let isRecord;
678
+ const proto1 = getPrototypeOf(value);
679
+ if (proto1 == null) {
680
+ isRecord = true;
681
+ } else {
682
+ const proto2 = getPrototypeOf(proto1);
683
+ if (proto2 != null) {
684
+ isRecord = false;
685
+ } else {
686
+ isRecord = "hasOwnProperty" in value;
687
+ }
688
+ }
689
+ if (!isRecord) return false;
690
+ if (!depth) return true;
691
+ return values(value).every((value2) => isVmConstInner(value2, depth));
692
+ }
693
+ function isVmConstInner(value, depth) {
694
+ if (depth++ >= MAX_DEPTH2) return false;
695
+ switch (typeof value) {
696
+ case "string":
697
+ case "number":
698
+ case "boolean":
699
+ case "undefined":
700
+ return true;
701
+ case "object":
702
+ if (value == null) return true;
703
+ if (isVmWrapper(value)) return false;
704
+ if (isArray(value)) {
705
+ return isVmArrayDeep(value, depth);
706
+ } else {
707
+ return isVmRecordDeep(value, depth);
708
+ }
709
+ case "function":
710
+ case "bigint":
711
+ case "symbol":
712
+ default:
713
+ return false;
714
+ }
715
+ }
716
+ function isVmConst(value, checkDeep = false) {
717
+ switch (typeof value) {
718
+ case "string":
719
+ case "number":
720
+ case "boolean":
721
+ return true;
722
+ case "object":
723
+ if (value == null) return true;
724
+ if (isVmWrapper(value)) return false;
725
+ if (!checkDeep) {
726
+ if (isArray(value)) {
727
+ return isVmArrayDeep(value, 0);
728
+ } else {
729
+ return isVmRecordDeep(value, 0);
730
+ }
731
+ } else {
732
+ return isVmConstInner(value, 1);
733
+ }
734
+ case "undefined":
735
+ case "function":
736
+ case "bigint":
737
+ case "symbol":
738
+ default:
739
+ return false;
740
+ }
741
+ }
742
+
743
+ // src/vm/types/module.ts
744
+ var VmModule = class extends VmWrapper {
745
+ constructor(name, value) {
746
+ super(value);
747
+ this.name = name;
748
+ }
749
+ /** @inheritdoc */
750
+ has(key) {
751
+ return hasOwnEnumerable(this.value, key);
752
+ }
753
+ /** @inheritdoc */
754
+ get(key) {
755
+ if (!this.has(key)) return void 0;
756
+ return this.value[key] ?? null;
757
+ }
758
+ /** @inheritdoc */
759
+ keys() {
760
+ return keys(this.value);
761
+ }
762
+ /** @inheritdoc */
763
+ same(other) {
764
+ return this === other;
765
+ }
766
+ /** @inheritdoc */
767
+ get type() {
768
+ return "module";
769
+ }
770
+ /** @inheritdoc */
771
+ get describe() {
772
+ return this.name;
773
+ }
774
+ };
775
+ var kVmModule = Symbol.for("mirascript.vm.module");
776
+ Object.defineProperty(VmModule.prototype, kVmModule, { value: true });
777
+ function isVmModule(value) {
778
+ return value != null && typeof value == "object" && kVmModule in value;
779
+ }
780
+
781
+ // src/vm/types/immutable.ts
782
+ function isVmImmutable(value, checkDeep = false) {
783
+ return isVmModule(value) || isVmFunction(value) || isVmConst(value, checkDeep);
784
+ }
785
+
786
+ // src/vm/types/any.ts
787
+ function isVmAny(value, checkDeep) {
788
+ switch (typeof value) {
789
+ case "string":
790
+ case "number":
791
+ case "boolean":
792
+ case "undefined":
793
+ return true;
794
+ case "object":
795
+ if (value == null) return true;
796
+ if (isVmWrapper(value)) return true;
797
+ return isVmConst(value, checkDeep);
798
+ case "function":
799
+ return isVmFunction(value);
800
+ case "bigint":
801
+ case "symbol":
802
+ default:
803
+ return false;
804
+ }
805
+ }
806
+
807
+ // src/vm/types/value.ts
808
+ function isVmValue(value, checkDeep = false) {
809
+ if (value === void 0) return false;
810
+ return isVmAny(value, checkDeep);
811
+ }
812
+
813
+ // src/vm/operations.ts
814
+ var { abs, min, trunc, ceil } = Math;
815
+ var { slice, at } = Array.prototype;
816
+ var { POSITIVE_INFINITY, NEGATIVE_INFINITY } = Number;
817
+ var isSame = (a, b) => {
818
+ if (typeof a == "number" && typeof b == "number") return a === b || isNaN(a) && isNaN(b);
819
+ if (a === b) return true;
820
+ if (a == null || typeof a != "object" || b == null || typeof b != "object") return false;
821
+ if (isVmWrapper(a)) return a.same(b);
822
+ if (isVmWrapper(b)) return b.same(a);
823
+ if (isVmArray(a) && isVmArray(b)) {
824
+ const len = a.length;
825
+ if (len !== b.length) {
826
+ return false;
827
+ }
828
+ for (let i = 0; i < len; i++) {
829
+ if (!isSame(a[i] ?? null, b[i] ?? null)) {
830
+ return false;
831
+ }
832
+ }
833
+ return true;
834
+ }
835
+ if (!isVmArray(a) && !isVmArray(b)) {
836
+ const aKeys = keys(a);
837
+ const bKeys = keys(b);
838
+ if (aKeys.length !== bKeys.length) {
839
+ return false;
840
+ }
841
+ for (const key of aKeys) {
842
+ if (!hasOwnEnumerable(b, key)) {
843
+ return false;
844
+ }
845
+ if (!isSame(a[key] ?? null, b[key] ?? null)) {
846
+ return false;
847
+ }
848
+ }
849
+ return true;
850
+ }
851
+ return false;
852
+ };
853
+ var overloadNumberString = (a, b) => {
854
+ if (typeof a == "number" || typeof b == "number") return true;
855
+ if (typeof a == "string" || typeof b == "string") return false;
856
+ return true;
857
+ };
858
+ var $Add = (a, b) => {
859
+ return $ToNumber(a) + $ToNumber(b);
860
+ };
861
+ var $Sub = (a, b) => {
862
+ return $ToNumber(a) - $ToNumber(b);
863
+ };
864
+ var $Mul = (a, b) => {
865
+ return $ToNumber(a) * $ToNumber(b);
866
+ };
867
+ var $Div = (a, b) => {
868
+ return $ToNumber(a) / $ToNumber(b);
869
+ };
870
+ var $Mod = (a, b) => {
871
+ return $ToNumber(a) % $ToNumber(b);
872
+ };
873
+ var $Pow = (a, b) => {
874
+ return $ToNumber(a) ** $ToNumber(b);
875
+ };
876
+ var $And = (a, b) => {
877
+ return $ToBoolean(a) && $ToBoolean(b);
878
+ };
879
+ var $Or = (a, b) => {
880
+ return $ToBoolean(a) || $ToBoolean(b);
881
+ };
882
+ var $Gt = (a, b) => {
883
+ if (overloadNumberString(a, b)) {
884
+ return $ToNumber(a) > $ToNumber(b);
885
+ } else {
886
+ return $ToString(a) > $ToString(b);
887
+ }
888
+ };
889
+ var $Gte = (a, b) => {
890
+ if (overloadNumberString(a, b)) {
891
+ return $ToNumber(a) >= $ToNumber(b);
892
+ } else {
893
+ return $ToString(a) >= $ToString(b);
894
+ }
895
+ };
896
+ var $Lt = (a, b) => {
897
+ if (overloadNumberString(a, b)) {
898
+ return $ToNumber(a) < $ToNumber(b);
899
+ } else {
900
+ return $ToString(a) < $ToString(b);
901
+ }
902
+ };
903
+ var $Lte = (a, b) => {
904
+ if (overloadNumberString(a, b)) {
905
+ return $ToNumber(a) <= $ToNumber(b);
906
+ } else {
907
+ return $ToString(a) <= $ToString(b);
908
+ }
909
+ };
910
+ var $Eq = (a, b) => {
911
+ $AssertInit(a);
912
+ $AssertInit(b);
913
+ if (typeof a == "number" && typeof b == "number") return a === b;
914
+ return isSame(a, b);
915
+ };
916
+ var $Neq = (a, b) => {
917
+ return !$Eq(a, b);
918
+ };
919
+ var $Aeq = (a, b) => {
920
+ if (overloadNumberString(a, b)) {
921
+ const an = $ToNumber(a);
922
+ const bn = $ToNumber(b);
923
+ const EPS = 1e-15;
924
+ if (isNaN(an) || isNaN(bn)) return false;
925
+ if (an === bn) return true;
926
+ const absoluteDifference = abs(an - bn);
927
+ if (absoluteDifference < EPS) return true;
928
+ const base = min(abs(an), abs(bn));
929
+ return absoluteDifference < base * EPS;
930
+ } else {
931
+ const as = $ToString(a);
932
+ const bs = $ToString(b);
933
+ if (as === bs) return true;
934
+ const ai = as.toLowerCase();
935
+ const bi = bs.toLowerCase();
936
+ if (ai === bi) return true;
937
+ const an = ai.normalize("NFC");
938
+ const bn = bi.normalize("NFC");
939
+ return an === bn;
940
+ }
941
+ };
942
+ var $Naeq = (a, b) => {
943
+ return !$Aeq(a, b);
944
+ };
945
+ var $Same = (a, b) => {
946
+ $AssertInit(a);
947
+ $AssertInit(b);
948
+ return isSame(a, b);
949
+ };
950
+ var $Nsame = (a, b) => {
951
+ return !$Same(a, b);
952
+ };
953
+ var $In = (value, iterable) => {
954
+ $AssertInit(value);
955
+ $AssertInit(iterable);
956
+ if (iterable == null) return false;
957
+ if (isVmArray(iterable)) {
958
+ if (value == null) {
959
+ for (const item of iterable) {
960
+ if (item == null) return true;
961
+ }
962
+ return false;
963
+ }
964
+ if (isVmPrimitive(value)) return iterable.includes(value);
965
+ value;
966
+ return iterable.some((item = null) => isSame(item, value));
967
+ }
968
+ if (isVmWrapper(iterable)) return iterable.has($ToString(value));
969
+ if (typeof iterable == "object") return hasOwnEnumerable(iterable, $ToString(value));
970
+ iterable;
971
+ return false;
972
+ };
973
+ var $Concat = (...args) => {
974
+ return args.map($Format).join("");
975
+ };
976
+ var $Pos = (a) => {
977
+ return $ToNumber(a);
978
+ };
979
+ var $Neg = (a) => {
980
+ return -$ToNumber(a);
981
+ };
982
+ var $Not = (a) => {
983
+ return !$ToBoolean(a);
984
+ };
985
+ var $Length = (value) => {
986
+ $AssertInit(value);
987
+ if (isVmArray(value)) return value.length;
988
+ if (isVmRecord(value)) return keys(value).length;
989
+ if (isVmWrapper(value)) {
990
+ return value.keys().length;
991
+ }
992
+ return Number.NaN;
993
+ };
994
+ var $Omit = (value, omitted) => {
995
+ $AssertInit(value);
996
+ if (value == null || !isVmRecord(value)) return {};
997
+ const result = {};
998
+ const valueKeys = keys(value);
999
+ const omittedSet = new Set(omitted.map($ToString));
1000
+ for (const key of valueKeys) {
1001
+ if (!omittedSet.has(key)) {
1002
+ result[key] = value[key] ?? null;
1003
+ }
1004
+ }
1005
+ return result;
1006
+ };
1007
+ var $Pick = (value, picked) => {
1008
+ $AssertInit(value);
1009
+ if (value == null || !isVmRecord(value)) return {};
1010
+ const result = {};
1011
+ for (const key of picked) {
1012
+ const k = $ToString(key);
1013
+ if (hasOwnEnumerable(value, k)) {
1014
+ result[k] = value[k] ?? null;
1015
+ }
1016
+ }
1017
+ return result;
1018
+ };
1019
+ var sliceCore = (value, start, end, exclusive) => {
1020
+ const { length } = value;
1021
+ if (isNaN(start)) start = 0;
1022
+ else if (start < 0) start = length + start;
1023
+ if (isNaN(end)) end = exclusive ? length : length - 1;
1024
+ else if (end < 0) end = length + end;
1025
+ start = ceil(start);
1026
+ if (exclusive || !isSafeInteger(end)) {
1027
+ end = ceil(end);
1028
+ } else {
1029
+ end = end + 1;
1030
+ }
1031
+ return slice.call(value, start, end);
1032
+ };
1033
+ var $Slice = (value, start, end) => {
1034
+ $AssertInit(value);
1035
+ if (!isVmArray(value)) throw new VmError(`Expected array, got ${$Type(value)}`, []);
1036
+ const s = start != null ? $ToNumber(start) : 0;
1037
+ const e = end != null ? $ToNumber(end) : value.length - 1;
1038
+ return sliceCore(value, s, e, false);
1039
+ };
1040
+ var $SliceExclusive = (value, start, end) => {
1041
+ $AssertInit(value);
1042
+ if (!isVmArray(value)) throw new VmError(`Expected array, got ${$Type(value)}`, []);
1043
+ const s = start != null ? $ToNumber(start) : 0;
1044
+ const e = end != null ? $ToNumber(end) : value.length;
1045
+ return sliceCore(value, s, e, true);
1046
+ };
1047
+ var $AssertInit = (value) => {
1048
+ if (value === void 0) throw new VmError(`Uninitialized value`, null);
1049
+ };
1050
+ var $Call = (func, args) => {
1051
+ for (const a of args) {
1052
+ $AssertInit(a);
1053
+ }
1054
+ if (isVmExtern(func)) {
1055
+ return func.call(args) ?? null;
1056
+ }
1057
+ if (isVmFunction(func)) {
1058
+ return func(...args) ?? null;
1059
+ }
1060
+ throw new VmError(`Expected callable, got ${$Type(func)}`, null);
1061
+ };
1062
+ var $Type = (value) => {
1063
+ if (value === void 0 || value === null) return "nil";
1064
+ if (isVmExtern(value)) return "extern";
1065
+ if (isVmModule(value)) return "module";
1066
+ if (isVmArray(value)) return "array";
1067
+ if (typeof value == "object") return "record";
1068
+ return typeof value;
1069
+ };
1070
+ var $ToBoolean = (value) => {
1071
+ $AssertInit(value);
1072
+ return value != null && value !== false;
1073
+ };
1074
+ function numberToString(value) {
1075
+ if (isNaN(value)) return "nan";
1076
+ if (value === Infinity) return "inf";
1077
+ if (value === -Infinity) return "-inf";
1078
+ return String(value);
1079
+ }
1080
+ function $InnerToString(value, useBraces) {
1081
+ if (value == null) return "nil";
1082
+ if (isVmWrapper(value)) return value.toString(useBraces);
1083
+ if (typeof value == "function") {
1084
+ const name = getVmFunctionInfo(value)?.fullName;
1085
+ return name ? `<function ${name}>` : `<function>`;
1086
+ }
1087
+ if (isVmArray(value)) {
1088
+ const strings = [];
1089
+ for (const item of value) {
1090
+ strings.push($InnerToString(item, true));
1091
+ }
1092
+ const results = strings.join(", ");
1093
+ if (!useBraces) return results;
1094
+ return `[${results}]`;
1095
+ }
1096
+ if (typeof value == "object") {
1097
+ const entries2 = keys(value).map((key) => `${key}: ${$InnerToString(value[key], true)}`).join(", ");
1098
+ if (!useBraces) return entries2;
1099
+ return `(${entries2})`;
1100
+ }
1101
+ if (typeof value == "number") {
1102
+ return numberToString(value);
1103
+ }
1104
+ return String(value);
1105
+ }
1106
+ var $ToString = (value) => {
1107
+ $AssertInit(value);
1108
+ if (typeof value == "string") return value;
1109
+ if (value === null) return "";
1110
+ return $InnerToString(value, false);
1111
+ };
1112
+ var $ToNumber = (value) => {
1113
+ $AssertInit(value);
1114
+ if (typeof value == "number") return value;
1115
+ if (value == null) return 0;
1116
+ if (typeof value == "string") {
1117
+ value = value.trim();
1118
+ if (value === "") return 0;
1119
+ if (value === "inf" || value === "+inf" || value === "Infinity" || value === "+Infinity") {
1120
+ return POSITIVE_INFINITY;
1121
+ }
1122
+ if (value === "-inf" || value === "-Infinity") {
1123
+ return NEGATIVE_INFINITY;
1124
+ }
1125
+ return Number(value);
1126
+ }
1127
+ if (typeof value == "boolean") return value ? 1 : 0;
1128
+ return Number.NaN;
1129
+ };
1130
+ var $IsBoolean = (value) => {
1131
+ $AssertInit(value);
1132
+ return typeof value == "boolean";
1133
+ };
1134
+ var $IsNumber = (value) => {
1135
+ $AssertInit(value);
1136
+ return typeof value == "number";
1137
+ };
1138
+ var $IsString = (value) => {
1139
+ $AssertInit(value);
1140
+ return typeof value == "string";
1141
+ };
1142
+ var $IsRecord = (value) => {
1143
+ $AssertInit(value);
1144
+ return isVmRecord(value);
1145
+ };
1146
+ var $IsArray = (value) => {
1147
+ $AssertInit(value);
1148
+ return isVmArray(value);
1149
+ };
1150
+ var $AssertNonNil = (value) => {
1151
+ $AssertInit(value);
1152
+ if (value !== null) return;
1153
+ throw new VmError("Expected non-nil value", null);
1154
+ };
1155
+ var $Has = (obj, key) => {
1156
+ $AssertInit(obj);
1157
+ const pk = $ToString(key);
1158
+ if (obj == null || typeof obj != "object") return false;
1159
+ if (isVmWrapper(obj)) return obj.has(pk);
1160
+ return hasOwnEnumerable(obj, pk);
1161
+ };
1162
+ var $Get = (obj, key) => {
1163
+ $AssertInit(obj);
1164
+ if (isVmArray(obj)) {
1165
+ const index = $ToNumber(key);
1166
+ if (isNaN(index)) return null;
1167
+ return at.call(obj, trunc(index)) ?? null;
1168
+ }
1169
+ const pk = $ToString(key);
1170
+ if (obj == null || typeof obj != "object") return null;
1171
+ if (isVmWrapper(obj)) return obj.get(pk) ?? null;
1172
+ if (!hasOwnEnumerable(obj, pk)) return null;
1173
+ return obj[pk] ?? null;
1174
+ };
1175
+ var $Set = (obj, key, value) => {
1176
+ $AssertInit(obj);
1177
+ $AssertInit(value);
1178
+ const pk = $ToString(key);
1179
+ if (obj == null) return;
1180
+ if (!isVmExtern(obj)) throw new VmError(`Expected extern, got ${$Type(obj)}`, void 0);
1181
+ obj.set(pk, value);
1182
+ };
1183
+ var $Iterable = (value) => {
1184
+ $AssertInit(value);
1185
+ if (isVmWrapper(value)) return value.keys();
1186
+ if (isVmArray(value)) return value;
1187
+ if (value != null && typeof value == "object") return keys(value);
1188
+ throw new VmError(`Value is not iterable`, isVmFunction(value) ? [] : [value]);
1189
+ };
1190
+ var $RecordSpread = (record) => {
1191
+ $AssertInit(record);
1192
+ if (record == null || isVmRecord(record)) return record;
1193
+ if (isVmArray(record)) {
1194
+ const result = {};
1195
+ const len = record.length;
1196
+ for (let i = 0; i < len; i++) {
1197
+ const item = record[i];
1198
+ result[i] = item ?? null;
1199
+ }
1200
+ return result;
1201
+ }
1202
+ if (isVmExtern(record)) {
1203
+ const result = create(null);
1204
+ for (const key of record.keys()) {
1205
+ const value = record.get(key) ?? null;
1206
+ if (isVmPrimitive(value)) {
1207
+ result[key] = value;
1208
+ }
1209
+ }
1210
+ return result;
1211
+ }
1212
+ throw new VmError(`Expected record, array, extern or nil, got ${$Type(record)}`, null);
1213
+ };
1214
+ var $ArraySpread = (array) => {
1215
+ $AssertInit(array);
1216
+ if (array == null) return [];
1217
+ if (isVmArray(array)) return array;
1218
+ if (isVmExtern(array) && typeof array.value[Symbol.iterator] == "function") {
1219
+ const result = [];
1220
+ for (const item of array.value) {
1221
+ if (isVmPrimitive(item)) {
1222
+ result.push(item);
1223
+ } else {
1224
+ result.push(null);
1225
+ }
1226
+ }
1227
+ return result;
1228
+ }
1229
+ throw new VmError(`Expected array, iterable extern or nil, got ${$Type(array)}`, []);
1230
+ };
1231
+ function formatNumber(value) {
1232
+ if (!Number.isFinite(value)) return numberToString(value);
1233
+ if (value === 0) return "0";
1234
+ const s = value.toString();
1235
+ let ps;
1236
+ const abs2 = Math.abs(value);
1237
+ if (abs2 >= 1e3 || abs2 < 1e-3) {
1238
+ const ps1 = value.toExponential();
1239
+ const ps2 = value.toExponential(5);
1240
+ ps = ps1.length < ps2.length ? ps1 : ps2;
1241
+ } else {
1242
+ ps = value.toPrecision(6);
1243
+ }
1244
+ return ps.length < s.length ? ps : s;
1245
+ }
1246
+ var $Format = (value, format) => {
1247
+ $AssertInit(value);
1248
+ const f = format == null ? "" : typeof format == "string" ? format.trim() : $ToString(format);
1249
+ if (typeof value == "number") {
1250
+ if (/^\.\d+$/.test(f)) {
1251
+ let digits = Math.trunc(Number(f.slice(1)));
1252
+ if (!(digits <= 100)) digits = 100;
1253
+ return value.toFixed(digits);
1254
+ } else {
1255
+ return formatNumber(value);
1256
+ }
1257
+ }
1258
+ return $ToString(value);
1259
+ };
1260
+
1261
+ // src/compiler/diagnostic.ts
1262
+ import { DiagnosticCode, getModule } from "@mirascript/bindings";
1263
+ var diagnosticMessages = /* @__PURE__ */ new Map();
1264
+ function getDiagnosticMessage(code) {
1265
+ if (!isSafeInteger(code) || code < 0 || code >= 65535) {
1266
+ throw new RangeError(`Invalid DiagnosticCode: ${code}`);
1267
+ }
1268
+ if (diagnosticMessages.has(code)) {
1269
+ return diagnosticMessages.get(code) || null;
1270
+ }
1271
+ const mod = getModule();
1272
+ const msg = mod.getDiagnosticMessage(code);
1273
+ diagnosticMessages.set(code, msg);
1274
+ return msg;
1275
+ }
1276
+ function parseDiagnostics(source, diagnostics, filter) {
1277
+ const parsed = [];
1278
+ const bufLen = diagnostics.length;
1279
+ for (let i = 0; i < bufLen; i += 5) {
1280
+ const code = diagnostics[i + 4];
1281
+ if (filter && !filter(code)) {
1282
+ continue;
1283
+ }
1284
+ const startLineNumber = diagnostics[i];
1285
+ const startColumn = diagnostics[i + 1];
1286
+ const endLineNumber = diagnostics[i + 2];
1287
+ const endColumn = diagnostics[i + 3];
1288
+ parsed.push({
1289
+ code,
1290
+ range: {
1291
+ startLineNumber,
1292
+ startColumn,
1293
+ endLineNumber,
1294
+ endColumn
1295
+ }
1296
+ });
1297
+ }
1298
+ const _errors = [];
1299
+ const _warnings = [];
1300
+ const _infos = [];
1301
+ const _hints = [];
1302
+ const _tags = [];
1303
+ const _references = [];
1304
+ const _tagsReferences = [];
1305
+ const _sourcemaps = [];
1306
+ for (let i = 0; i < parsed.length; i++) {
1307
+ const diagnostic = parsed[i];
1308
+ const { code } = diagnostic;
1309
+ if (code > DiagnosticCode.ErrorStart && code < DiagnosticCode.ErrorEnd) {
1310
+ _errors.push(diagnostic);
1311
+ } else if (code > DiagnosticCode.WarningStart && code < DiagnosticCode.WarningEnd) {
1312
+ _warnings.push(diagnostic);
1313
+ } else if (code > DiagnosticCode.InfoStart && code < DiagnosticCode.InfoEnd) {
1314
+ _infos.push(diagnostic);
1315
+ } else if (code > DiagnosticCode.HintStart && code < DiagnosticCode.HintEnd) {
1316
+ _hints.push(diagnostic);
1317
+ } else if (code > DiagnosticCode.TagStart && code < DiagnosticCode.TagEnd) {
1318
+ _tags.push(diagnostic);
1319
+ } else if (code === DiagnosticCode.SourceMap) {
1320
+ _sourcemaps.push(diagnostic.range);
1321
+ continue;
1322
+ } else {
1323
+ continue;
1324
+ }
1325
+ diagnostic.references = [];
1326
+ while (i + 1 < parsed.length) {
1327
+ const ref = parsed[i + 1];
1328
+ let isRef = false;
1329
+ if (ref.code > DiagnosticCode.TagRefStart && ref.code < DiagnosticCode.TagRefEnd) {
1330
+ isRef = true;
1331
+ _tagsReferences.push(ref);
1332
+ }
1333
+ if (ref.code > DiagnosticCode.ReferenceStart && ref.code < DiagnosticCode.ReferenceEnd) {
1334
+ isRef = true;
1335
+ _references.push(ref);
1336
+ }
1337
+ if (!isRef) {
1338
+ break;
1339
+ }
1340
+ i++;
1341
+ ref.diagnostic = diagnostic;
1342
+ diagnostic.references.push(ref);
1343
+ }
1344
+ }
1345
+ return {
1346
+ errors: _errors,
1347
+ warnings: _warnings,
1348
+ infos: _infos,
1349
+ hints: _hints,
1350
+ tags: _tags,
1351
+ references: _references,
1352
+ tagsReferences: _tagsReferences,
1353
+ sourcemaps: _sourcemaps
1354
+ };
1355
+ }
1356
+ function formatRange(range) {
1357
+ if (range.startLineNumber === range.endLineNumber) {
1358
+ if (range.startColumn === range.endColumn) {
1359
+ return `${range.startLineNumber}:${range.startColumn}`;
1360
+ }
1361
+ return `${range.startLineNumber}:${range.startColumn}-${range.endColumn}`;
1362
+ }
1363
+ return `${range.startLineNumber}:${range.startColumn}-${range.endLineNumber}:${range.endColumn}`;
1364
+ }
1365
+ function formatDiagnostic(diagnostic) {
1366
+ const range = formatRange(diagnostic.range);
1367
+ const codeName = DiagnosticCode[diagnostic.code] || `Unknown(${diagnostic.code})`;
1368
+ let message = getDiagnosticMessage(diagnostic.code);
1369
+ for (const ref of diagnostic.references) {
1370
+ const refRange = formatRange(ref.range);
1371
+ message += `
1372
+ (${refRange}): ${getDiagnosticMessage(ref.code)}`;
1373
+ }
1374
+ return ` ${codeName}(${range}): ${message}`;
1375
+ }
1376
+
1377
+ // src/compiler/emit.ts
1378
+ import { OpCode } from "@mirascript/bindings";
1379
+ import { SourceMapGenerator } from "source-map-js";
1380
+ function emit(source, chunk, sourcemaps, options) {
1381
+ const gen = new Emitter(source, chunk, sourcemaps, options);
1382
+ gen.read();
1383
+ const code = gen.codeLines.join("\n");
1384
+ return code;
1385
+ }
1386
+ function readConst(reader, offset) {
1387
+ const type = reader.getUint8(offset);
1388
+ switch (type) {
1389
+ /* c8 ignore next 2 */
1390
+ case 0:
1391
+ return [null, 1];
1392
+ case 1:
1393
+ return [true, 1];
1394
+ case 2:
1395
+ return [false, 1];
1396
+ case 3: {
1397
+ const ordinal = reader.getInt32(offset + 1, true);
1398
+ return [ordinal, 5];
1399
+ }
1400
+ case 4: {
1401
+ const num = reader.getFloat64(offset + 1, true);
1402
+ return [num, 9];
1403
+ }
1404
+ case 5: {
1405
+ const len = reader.getUint32(offset + 1, true);
1406
+ const str = new TextDecoder().decode(new Uint8Array(reader.buffer, reader.byteOffset + offset + 5, len));
1407
+ return [str, 5 + len];
1408
+ }
1409
+ /* c8 ignore next 2 */
1410
+ default:
1411
+ throw new Error(`Unknown constant type: ${type}`);
1412
+ }
1413
+ }
1414
+ function toJavascript(value) {
1415
+ if (value === null) return "null";
1416
+ if (value === void 0) return "undefined";
1417
+ if (typeof value == "object" || typeof value == "string") {
1418
+ return JSON.stringify(value);
1419
+ }
1420
+ if (value === 0) {
1421
+ if (1 / value === -Infinity) return "-0";
1422
+ return "0";
1423
+ }
1424
+ return String(value);
1425
+ }
1426
+ var ORIGIN = `mira://MiraScript/`;
1427
+ var sourceId = 1;
1428
+ function createArray(length, fn) {
1429
+ const result = [];
1430
+ for (let i = 0; i < length; i++) {
1431
+ result.push(fn(i));
1432
+ }
1433
+ return result;
1434
+ }
1435
+ var SCRIPT_PREFIX = `'use strict'; return ((global = GlobalFallback()) => { try { CpEnter();`;
1436
+ var GLOBAL_HINT = `/* globals */`;
1437
+ var Emitter = class {
1438
+ constructor(source, chunk, sourcemaps, options) {
1439
+ this.source = source;
1440
+ this.chunk = chunk;
1441
+ this.sourcemaps = sourcemaps;
1442
+ this.options = options;
1443
+ this.constVals = [];
1444
+ this.constLits = [];
1445
+ this.codeOffset = 0;
1446
+ this.closureCounter = 0;
1447
+ this.identCounter = 0;
1448
+ this.globals = /* @__PURE__ */ new Map();
1449
+ this.codeLines = [];
1450
+ this.pretty = options.pretty ?? false;
1451
+ const reader = new DataView(chunk.buffer, chunk.byteOffset, chunk.byteLength);
1452
+ this.chunkSize = reader.getUint32(0, true);
1453
+ this.codeSize = reader.getUint32(4, true);
1454
+ this.constSize = reader.getUint32(8 + this.codeSize, true);
1455
+ this.codeReader = new DataView(chunk.buffer, chunk.byteOffset + 8, this.codeSize);
1456
+ this.constReader = new DataView(chunk.buffer, chunk.byteOffset + 12 + this.codeSize, this.constSize);
1457
+ }
1458
+ /** 读取常量表 */
1459
+ readConsts() {
1460
+ for (let i = 0, index = 0; i < this.constSize; index++) {
1461
+ const [constant, size] = readConst(this.constReader, i);
1462
+ this.constVals.push(constant);
1463
+ this.constLits.push(toJavascript(constant));
1464
+ i += size;
1465
+ }
1466
+ }
1467
+ /** 制造缩进 */
1468
+ ident(len = 0) {
1469
+ if (!this.pretty) return "";
1470
+ return " ".repeat(this.identCounter + len);
1471
+ }
1472
+ /** 读取全局变量 */
1473
+ rg(constIdx, eager) {
1474
+ const cached = this.globals.get(constIdx);
1475
+ if (cached != null) {
1476
+ if (eager && !cached[2]) {
1477
+ cached[2] = true;
1478
+ cached[3] = cached[0];
1479
+ }
1480
+ return cached[3];
1481
+ }
1482
+ const constName = this.constVals[constIdx];
1483
+ const name = $ToString(constName);
1484
+ const lit = typeof constName == "string" ? this.constLits[constIdx] : JSON.stringify(name);
1485
+ const val = `g${this.globals.size + 1}`;
1486
+ const expr = eager ? val : `(${val} === undefined ? (${val} = global.get(${lit})) : ${val})`;
1487
+ this.globals.set(constIdx, [val, lit, eager, expr, name]);
1488
+ return expr;
1489
+ }
1490
+ /** Read variable */
1491
+ rv(i, level = 0) {
1492
+ if (!i) return "null";
1493
+ const c = this.closureCounter - level;
1494
+ return `var_${c}_${i}`;
1495
+ }
1496
+ /** Write variable */
1497
+ wv(i, level = 0) {
1498
+ if (!i) return "_";
1499
+ return this.rv(i, level);
1500
+ }
1501
+ /** 读取 code param */
1502
+ readParam(wide) {
1503
+ const value = wide ? this.codeReader.getUint32(this.codeOffset, true) : this.codeReader.getUint8(this.codeOffset);
1504
+ this.codeOffset += wide ? 4 : 1;
1505
+ return value;
1506
+ }
1507
+ /** 读取 code param */
1508
+ readIndex(wide) {
1509
+ const value = wide ? this.codeReader.getInt32(this.codeOffset, true) : this.codeReader.getInt8(this.codeOffset);
1510
+ this.codeOffset += wide ? 4 : 1;
1511
+ return value;
1512
+ }
1513
+ /** 读取闭包 */
1514
+ readClosure() {
1515
+ this.closureCounter++;
1516
+ this.identCounter++;
1517
+ while (this.codeOffset < this.codeSize) {
1518
+ const opcode_raw = this.codeReader.getUint8(this.codeOffset);
1519
+ const opcode = opcode_raw & 127;
1520
+ if (opcode !== OpCode.FuncEnd) {
1521
+ this.readCode();
1522
+ continue;
1523
+ }
1524
+ this.codeOffset++;
1525
+ const body = this.ident(-1) + `} finally { CpExit(); } });`;
1526
+ this.codeLines.push(body);
1527
+ this.closureCounter--;
1528
+ this.identCounter--;
1529
+ break;
1530
+ }
1531
+ }
1532
+ /** 读取块结束 */
1533
+ readBlockEnd(end) {
1534
+ while (this.codeOffset < this.codeSize) {
1535
+ const opcode_raw = this.codeReader.getUint8(this.codeOffset);
1536
+ const opcode = opcode_raw & 127;
1537
+ if (opcode !== end) {
1538
+ this.readCode();
1539
+ continue;
1540
+ }
1541
+ this.codeOffset++;
1542
+ this.identCounter--;
1543
+ if (end === OpCode.LoopEnd) {
1544
+ this.closureCounter--;
1545
+ }
1546
+ const body = this.ident() + `};`;
1547
+ this.codeLines.push(body);
1548
+ break;
1549
+ }
1550
+ }
1551
+ /** 读取 if else 或 if 结束 */
1552
+ readIfElse() {
1553
+ this.identCounter++;
1554
+ while (this.codeOffset < this.codeSize) {
1555
+ const opcode_raw = this.codeReader.getUint8(this.codeOffset);
1556
+ const opcode = opcode_raw & 127;
1557
+ if (opcode === OpCode.IfEnd) {
1558
+ return this.readBlockEnd(OpCode.IfEnd);
1559
+ }
1560
+ if (opcode === OpCode.Else) {
1561
+ this.codeOffset++;
1562
+ const body = this.ident(-1) + `} else {`;
1563
+ this.codeLines.push(body);
1564
+ break;
1565
+ }
1566
+ if (opcode === OpCode.ElIf) {
1567
+ this.codeOffset++;
1568
+ const body = this.ident(-1) + `} else `;
1569
+ this.codeLines.push(body);
1570
+ return this.readCode();
1571
+ }
1572
+ this.readCode();
1573
+ }
1574
+ return this.readBlockEnd(OpCode.IfEnd);
1575
+ }
1576
+ /** 读取 record */
1577
+ readRecord(obj) {
1578
+ this.identCounter++;
1579
+ while (this.codeOffset < this.codeSize) {
1580
+ const opcode_raw = this.codeReader.getUint8(this.codeOffset++);
1581
+ const opcode = opcode_raw & 127;
1582
+ const wide = opcode_raw >= 128;
1583
+ const read = () => this.readParam(wide);
1584
+ let code = "";
1585
+ switch (opcode) {
1586
+ case OpCode.FieldOpt:
1587
+ case OpCode.Field: {
1588
+ const field = read();
1589
+ const field_name = this.constLits[field];
1590
+ if (!field_name) {
1591
+ throw new Error(`Unknown field ${field}`);
1592
+ }
1593
+ const value = read();
1594
+ const opt = opcode === OpCode.FieldOpt;
1595
+ code = opt ? `...ElementOpt(${field_name}, ${this.rv(value)}),` : `[${field_name}]: Element(${this.rv(value)}),`;
1596
+ break;
1597
+ }
1598
+ case OpCode.FieldOptDyn:
1599
+ case OpCode.FieldDyn: {
1600
+ const field = read();
1601
+ const value = read();
1602
+ const opt = opcode === OpCode.FieldOptDyn;
1603
+ code = opt ? `...ElementOpt(${this.rv(field)}, ${this.rv(value)}),` : `[${this.rv(field)}]: Element(${this.rv(value)}),`;
1604
+ break;
1605
+ }
1606
+ case OpCode.FieldOptIndex:
1607
+ case OpCode.FieldIndex: {
1608
+ const field = this.readIndex(wide);
1609
+ const value = read();
1610
+ const opt = opcode === OpCode.FieldOptIndex;
1611
+ code = opt ? `...ElementOpt(${field}, ${this.rv(value)}),` : `[${field}]: Element(${this.rv(value)}),`;
1612
+ break;
1613
+ }
1614
+ case OpCode.Spread: {
1615
+ const value = read();
1616
+ code = `...$RecordSpread(${this.rv(value)}),`;
1617
+ break;
1618
+ }
1619
+ case OpCode.Freeze: {
1620
+ this.identCounter--;
1621
+ code = `});`;
1622
+ break;
1623
+ }
1624
+ default: {
1625
+ code = `// ?${OpCode[opcode] ?? opcode}`;
1626
+ break;
1627
+ }
1628
+ }
1629
+ const ident = this.ident();
1630
+ this.codeLines.push(ident + code);
1631
+ if (opcode === OpCode.Freeze) {
1632
+ return;
1633
+ }
1634
+ }
1635
+ }
1636
+ /** 读取 array */
1637
+ readArray(arr) {
1638
+ this.identCounter++;
1639
+ while (this.codeOffset < this.codeSize) {
1640
+ const opcode_raw = this.codeReader.getUint8(this.codeOffset++);
1641
+ const opcode = opcode_raw & 127;
1642
+ const wide = opcode_raw >= 128;
1643
+ const read = () => this.readParam(wide);
1644
+ let code = "";
1645
+ switch (opcode) {
1646
+ case OpCode.Item: {
1647
+ const value = read();
1648
+ code = `Element(${this.rv(value)}),`;
1649
+ break;
1650
+ }
1651
+ case OpCode.ItemRange: {
1652
+ const start = this.readIndex(wide);
1653
+ const end = this.readIndex(wide);
1654
+ code = `...ArrayRange(${start}, ${end}),`;
1655
+ break;
1656
+ }
1657
+ case OpCode.ItemRangeDyn: {
1658
+ const start = read();
1659
+ const end = read();
1660
+ code = `...ArrayRange(${this.rv(start)}, ${this.rv(end)}),`;
1661
+ break;
1662
+ }
1663
+ case OpCode.ItemRangeExclusiveDyn: {
1664
+ const start = read();
1665
+ const end = read();
1666
+ code = `...ArrayRangeExclusive(${this.rv(start)}, ${this.rv(end)}),`;
1667
+ break;
1668
+ }
1669
+ case OpCode.Spread: {
1670
+ const value = read();
1671
+ code = `...$ArraySpread(${this.rv(value)}),`;
1672
+ break;
1673
+ }
1674
+ case OpCode.Freeze: {
1675
+ this.identCounter--;
1676
+ code = `]);`;
1677
+ break;
1678
+ }
1679
+ default: {
1680
+ code = `// ?${OpCode[opcode] ?? opcode}`;
1681
+ break;
1682
+ }
1683
+ }
1684
+ const ident = this.ident();
1685
+ this.codeLines.push(ident + code);
1686
+ if (opcode === OpCode.Freeze) {
1687
+ return;
1688
+ }
1689
+ }
1690
+ }
1691
+ /** 读取代码 */
1692
+ readCode() {
1693
+ const opcode_raw = this.codeReader.getUint8(this.codeOffset++);
1694
+ const opcode = opcode_raw & 127;
1695
+ const wide = opcode_raw >= 128;
1696
+ const read = () => this.readParam(wide);
1697
+ const readIndex = () => this.readIndex(wide);
1698
+ const ident = this.ident();
1699
+ let code = "";
1700
+ let reg = 0;
1701
+ switch (opcode) {
1702
+ case OpCode.FuncVarg:
1703
+ case OpCode.Func: {
1704
+ const startFunc = this.codeOffset === 1;
1705
+ reg = read();
1706
+ const varg = opcode === OpCode.FuncVarg;
1707
+ const argn = read();
1708
+ const regn = read();
1709
+ const args = createArray(argn, (i) => {
1710
+ const wv = this.wv(i + 1, -1);
1711
+ if (varg && i === argn - 1) {
1712
+ return `...vargs`;
1713
+ }
1714
+ return `${wv} = null`;
1715
+ });
1716
+ const regs = createArray(regn - argn + 1, (i) => i ? this.wv(i + argn, -1) : this.wv(0, -1)).join(
1717
+ ", "
1718
+ );
1719
+ const script = startFunc && !varg && argn === 0;
1720
+ if (script) {
1721
+ code = `${SCRIPT_PREFIX} var ${regs};`;
1722
+ } else {
1723
+ code = `${this.wv(reg)} = Function((${args.join(", ")}) => { try { CpEnter(); var ${regs};`;
1724
+ }
1725
+ if (varg) {
1726
+ code += ` var ${this.wv(argn, -1)} = Vargs(vargs);`;
1727
+ }
1728
+ break;
1729
+ }
1730
+ case OpCode.Constant: {
1731
+ reg = read();
1732
+ const i = read();
1733
+ const c = this.constLits[i];
1734
+ code = `${this.wv(reg)} = ${c};`;
1735
+ break;
1736
+ }
1737
+ case OpCode.Uninit: {
1738
+ reg = read();
1739
+ code = `${this.wv(reg)} = undefined;`;
1740
+ break;
1741
+ }
1742
+ case OpCode.Return: {
1743
+ reg = read();
1744
+ code = `return ${this.rv(reg)};`;
1745
+ break;
1746
+ }
1747
+ case OpCode.Add:
1748
+ case OpCode.Sub:
1749
+ case OpCode.Mul:
1750
+ case OpCode.Div:
1751
+ case OpCode.Mod:
1752
+ case OpCode.Pow:
1753
+ case OpCode.Gt:
1754
+ case OpCode.Gte:
1755
+ case OpCode.Lt:
1756
+ case OpCode.Lte:
1757
+ case OpCode.Eq:
1758
+ case OpCode.Neq:
1759
+ case OpCode.Aeq:
1760
+ case OpCode.Naeq:
1761
+ case OpCode.Same:
1762
+ case OpCode.Nsame:
1763
+ case OpCode.In:
1764
+ case OpCode.And:
1765
+ case OpCode.Or:
1766
+ case OpCode.Format: {
1767
+ reg = read();
1768
+ const left = read();
1769
+ const right = read();
1770
+ code = `${this.wv(reg)} = $${OpCode[opcode]}(${this.rv(left)}, ${this.rv(right)});`;
1771
+ break;
1772
+ }
1773
+ case OpCode.InGlobal: {
1774
+ reg = read();
1775
+ const left = read();
1776
+ code = `${this.wv(reg)} = global.has($ToString(${this.rv(left)}));`;
1777
+ break;
1778
+ }
1779
+ case OpCode.Concat: {
1780
+ reg = read();
1781
+ const n = read();
1782
+ const args = createArray(n, () => read());
1783
+ code = `${this.wv(reg)} = $${OpCode[opcode]}(${args.map((a) => this.rv(a)).join(", ")});`;
1784
+ break;
1785
+ }
1786
+ case OpCode.Omit:
1787
+ case OpCode.Pick: {
1788
+ reg = read();
1789
+ const value = read();
1790
+ const n = read();
1791
+ const args = createArray(n, () => this.constLits[read()]);
1792
+ code = `${this.wv(reg)} = $${OpCode[opcode]}(${this.rv(value)}, [${args.join(", ")}]);`;
1793
+ break;
1794
+ }
1795
+ case OpCode.Call:
1796
+ case OpCode.CallDyn: {
1797
+ reg = read();
1798
+ const func = read();
1799
+ const n = read();
1800
+ const args = createArray(n, () => read());
1801
+ const ns = read();
1802
+ const spreads = createArray(ns, () => read());
1803
+ const callTarget = opcode === OpCode.Call ? this.rg(func, this.identCounter <= 1) : this.rv(func);
1804
+ code = `${this.wv(reg)} = $Call(${callTarget}, [${args.map((a, i) => {
1805
+ if (spreads.includes(i)) return `...$ArraySpread(${this.rv(a)})`;
1806
+ else return this.rv(a);
1807
+ }).join(", ")}]);`;
1808
+ break;
1809
+ }
1810
+ case OpCode.Assign: {
1811
+ reg = read();
1812
+ const value = read();
1813
+ code = `${this.wv(reg)} = ${this.rv(value)};`;
1814
+ break;
1815
+ }
1816
+ case OpCode.Pos:
1817
+ case OpCode.Neg:
1818
+ case OpCode.Not:
1819
+ case OpCode.Type:
1820
+ case OpCode.ToBoolean:
1821
+ case OpCode.ToNumber:
1822
+ case OpCode.ToString:
1823
+ case OpCode.IsBoolean:
1824
+ case OpCode.IsNumber:
1825
+ case OpCode.IsString:
1826
+ case OpCode.IsRecord:
1827
+ case OpCode.IsArray:
1828
+ case OpCode.Length: {
1829
+ reg = read();
1830
+ const value = read();
1831
+ code = `${this.wv(reg)} = $${OpCode[opcode]}(${this.rv(value)});`;
1832
+ break;
1833
+ }
1834
+ case OpCode.AssertInit:
1835
+ case OpCode.AssertNonNil: {
1836
+ reg = read();
1837
+ code = `$${OpCode[opcode]}(${this.rv(reg)})`;
1838
+ break;
1839
+ }
1840
+ case OpCode.Get: {
1841
+ reg = read();
1842
+ const obj = read();
1843
+ const prop = this.constLits[read()];
1844
+ code = `${this.wv(reg)} = $Get(${this.rv(obj)}, ${prop});`;
1845
+ break;
1846
+ }
1847
+ case OpCode.GetIndex: {
1848
+ reg = read();
1849
+ const obj = read();
1850
+ const index = readIndex();
1851
+ code = `${this.wv(reg)} = $Get(${this.rv(obj)}, ${index});`;
1852
+ break;
1853
+ }
1854
+ case OpCode.GetDyn: {
1855
+ reg = read();
1856
+ const obj = read();
1857
+ const index = read();
1858
+ code = `${this.wv(reg)} = $Get(${this.rv(obj)}, ${this.rv(index)});`;
1859
+ break;
1860
+ }
1861
+ case OpCode.Has: {
1862
+ reg = read();
1863
+ const obj = read();
1864
+ const prop = this.constLits[read()];
1865
+ code = `${this.wv(reg)} = $Has(${this.rv(obj)}, ${prop});`;
1866
+ break;
1867
+ }
1868
+ case OpCode.HasIndex: {
1869
+ reg = read();
1870
+ const obj = read();
1871
+ const index = readIndex();
1872
+ code = `${this.wv(reg)} = $Has(${this.rv(obj)}, ${index});`;
1873
+ break;
1874
+ }
1875
+ case OpCode.HasDyn: {
1876
+ reg = read();
1877
+ const obj = read();
1878
+ const index = read();
1879
+ code = `${this.wv(reg)} = $Has(${this.rv(obj)}, ${this.rv(index)});`;
1880
+ break;
1881
+ }
1882
+ case OpCode.Set: {
1883
+ reg = read();
1884
+ const obj = read();
1885
+ const prop = this.constLits[read()];
1886
+ code = `$Set(${this.rv(obj)}, ${prop}, ${this.rv(reg)});`;
1887
+ break;
1888
+ }
1889
+ case OpCode.SetIndex: {
1890
+ reg = read();
1891
+ const obj = read();
1892
+ const index = readIndex();
1893
+ code = `$Set(${this.rv(obj)}, ${index}, ${this.rv(reg)});`;
1894
+ break;
1895
+ }
1896
+ case OpCode.SetDyn: {
1897
+ reg = read();
1898
+ const obj = read();
1899
+ const index = read();
1900
+ code = `$Set(${this.rv(obj)}, ${this.rv(index)}, ${this.rv(reg)});`;
1901
+ break;
1902
+ }
1903
+ case OpCode.GetGlobal: {
1904
+ reg = read();
1905
+ const i = read();
1906
+ code = `${this.wv(reg)} = ${this.rg(i, this.identCounter <= 1)};`;
1907
+ break;
1908
+ }
1909
+ case OpCode.GetGlobalDyn: {
1910
+ reg = read();
1911
+ const name = read();
1912
+ code = `${this.wv(reg)} = global.get($ToString(${this.rv(name)}));`;
1913
+ break;
1914
+ }
1915
+ case OpCode.GetUpvalue: {
1916
+ reg = read();
1917
+ const level = read();
1918
+ const up = read();
1919
+ code = `${this.wv(reg)} = Upvalue(${this.rv(up, level)});`;
1920
+ break;
1921
+ }
1922
+ case OpCode.SetUpvalue: {
1923
+ reg = read();
1924
+ const level = read();
1925
+ const up = read();
1926
+ code = `${this.wv(up, level)} = ${this.rv(reg)};`;
1927
+ break;
1928
+ }
1929
+ case OpCode.Slice: {
1930
+ reg = read();
1931
+ const obj = read();
1932
+ const start = readIndex();
1933
+ const end = readIndex();
1934
+ code = `${this.wv(reg)} = $Slice(${this.rv(obj)}, ${start}, ${end});`;
1935
+ break;
1936
+ }
1937
+ case OpCode.SliceStart: {
1938
+ reg = read();
1939
+ const obj = read();
1940
+ const end = readIndex();
1941
+ code = `${this.wv(reg)} = $Slice(${this.rv(obj)}, null, ${end});`;
1942
+ break;
1943
+ }
1944
+ case OpCode.SliceEnd: {
1945
+ reg = read();
1946
+ const obj = read();
1947
+ const start = readIndex();
1948
+ code = `${this.wv(reg)} = $Slice(${this.rv(obj)}, ${start}, null);`;
1949
+ break;
1950
+ }
1951
+ case OpCode.SliceDyn: {
1952
+ reg = read();
1953
+ const obj = read();
1954
+ const start = read();
1955
+ const end = read();
1956
+ code = `${this.wv(reg)} = $Slice(${this.rv(obj)}, ${this.rv(start)}, ${this.rv(end)});`;
1957
+ break;
1958
+ }
1959
+ case OpCode.SliceExclusiveDyn: {
1960
+ reg = read();
1961
+ const obj = read();
1962
+ const start = read();
1963
+ const end = read();
1964
+ code = `${this.wv(reg)} = $SliceExclusive(${this.rv(obj)}, ${this.rv(start)}, ${this.rv(end)});`;
1965
+ break;
1966
+ }
1967
+ case OpCode.Record: {
1968
+ reg = read();
1969
+ code = `${this.wv(reg)} = ({`;
1970
+ break;
1971
+ }
1972
+ case OpCode.Array: {
1973
+ reg = read();
1974
+ code = `${this.wv(reg)} = ([`;
1975
+ break;
1976
+ }
1977
+ case OpCode.If: {
1978
+ const cond = read();
1979
+ code = `if (${this.rv(cond)} !== false && $ToBoolean(${this.rv(cond)}) !== false) {`;
1980
+ break;
1981
+ }
1982
+ case OpCode.IfNot: {
1983
+ const cond = read();
1984
+ code = `if (${this.rv(cond)} !== true && $ToBoolean(${this.rv(cond)}) !== true) {`;
1985
+ break;
1986
+ }
1987
+ case OpCode.IfInit: {
1988
+ const cond = read();
1989
+ code = `if (${this.rv(cond)} !== undefined) {`;
1990
+ break;
1991
+ }
1992
+ case OpCode.IfNotInit: {
1993
+ const cond = read();
1994
+ code = `if (${this.rv(cond)} === undefined) {`;
1995
+ break;
1996
+ }
1997
+ case OpCode.IfNil: {
1998
+ const cond = read();
1999
+ code = `if (${this.rv(cond)} === null) {`;
2000
+ break;
2001
+ }
2002
+ case OpCode.IfNotNil: {
2003
+ const cond = read();
2004
+ code = `if (${this.rv(cond)} !== null) {`;
2005
+ break;
2006
+ }
2007
+ case OpCode.LoopFor: {
2008
+ const nreg = read();
2009
+ const iterable = read();
2010
+ const regs = createArray(nreg - 1, (i) => this.wv(i + 2, -1));
2011
+ regs.unshift("_");
2012
+ const ir = this.wv(1, -1);
2013
+ code = `for (let ${ir} of $Iterable(${this.rv(iterable)})) { ${ir} ??= null; Cp(); let ${regs.join(", ")};`;
2014
+ break;
2015
+ }
2016
+ case OpCode.LoopRange:
2017
+ case OpCode.LoopRangeExclusive: {
2018
+ const nreg = read();
2019
+ const start = read();
2020
+ const end = read();
2021
+ const exclusive = opcode === OpCode.LoopRangeExclusive;
2022
+ const regs = createArray(nreg - 1, (i2) => this.wv(i2 + 2, -1));
2023
+ regs.unshift("_");
2024
+ const i = this.wv(1, -1);
2025
+ code = `for (let start = $ToNumber(${this.rv(start)}), end = $ToNumber(${this.rv(end)}), ${i} = start; ${i} ${exclusive ? "<" : "<="} end; ${i} += 1) { Cp(); let ${regs.join(", ")};`;
2026
+ break;
2027
+ }
2028
+ case OpCode.Loop: {
2029
+ const nreg = read();
2030
+ const regs = createArray(nreg, (i) => this.wv(i + 1, -1));
2031
+ regs.unshift("_");
2032
+ code = `while (true) { Cp(); let ${regs.join(", ")};`;
2033
+ break;
2034
+ }
2035
+ case OpCode.Break: {
2036
+ code = `break;`;
2037
+ break;
2038
+ }
2039
+ case OpCode.Continue: {
2040
+ code = `continue;`;
2041
+ break;
2042
+ }
2043
+ case OpCode.Noop: {
2044
+ return;
2045
+ }
2046
+ default: {
2047
+ code = `; // ${OpCode[opcode] ?? opcode}`;
2048
+ break;
2049
+ }
2050
+ }
2051
+ this.codeLines.push(ident + code);
2052
+ switch (opcode) {
2053
+ case OpCode.FuncVarg:
2054
+ case OpCode.Func: {
2055
+ this.readClosure();
2056
+ break;
2057
+ }
2058
+ case OpCode.If:
2059
+ case OpCode.IfNot:
2060
+ case OpCode.IfNil:
2061
+ case OpCode.IfNotNil:
2062
+ case OpCode.IfInit:
2063
+ case OpCode.IfNotInit: {
2064
+ this.readIfElse();
2065
+ break;
2066
+ }
2067
+ case OpCode.Loop:
2068
+ case OpCode.LoopFor:
2069
+ case OpCode.LoopRange:
2070
+ case OpCode.LoopRangeExclusive: {
2071
+ this.identCounter++;
2072
+ this.closureCounter++;
2073
+ this.readBlockEnd(OpCode.LoopEnd);
2074
+ break;
2075
+ }
2076
+ case OpCode.Record: {
2077
+ this.readRecord(reg);
2078
+ break;
2079
+ }
2080
+ case OpCode.Array: {
2081
+ this.readArray(reg);
2082
+ break;
2083
+ }
2084
+ }
2085
+ }
2086
+ /** 读取 chunk */
2087
+ read() {
2088
+ this.readConsts();
2089
+ this.readCode();
2090
+ if (this.globals.size > 0) {
2091
+ let globalsInit = "";
2092
+ for (const [val, lit, eager] of this.globals.values()) {
2093
+ const expr = eager ? `${val} = global.get(${lit})` : val;
2094
+ globalsInit += globalsInit ? `, ${expr}` : `var ${GLOBAL_HINT} ${expr}`;
2095
+ }
2096
+ this.codeLines[0] += globalsInit + ";";
2097
+ }
2098
+ this.addSourceMap();
2099
+ }
2100
+ /** 添加源映射 */
2101
+ addSourceMap() {
2102
+ if (!this.options.sourceMap) return;
2103
+ let fileName = (this.options.fileName ?? "").trim();
2104
+ const hasSchema = /^\w+:/.test(fileName);
2105
+ if (!hasSchema) {
2106
+ if (fileName.startsWith("/")) {
2107
+ fileName = fileName.replace(/^\/+\s*/, "");
2108
+ }
2109
+ if (!fileName) {
2110
+ fileName = `${sourceId++}.${this.options.input_mode === "Template" ? "miratpl" : "mira"}`;
2111
+ }
2112
+ }
2113
+ const map = new SourceMapGenerator({
2114
+ file: fileName + ".js"
2115
+ });
2116
+ if (typeof this.source === "string") {
2117
+ map.setSourceContent(fileName, this.source);
2118
+ }
2119
+ let hasStartMap = false;
2120
+ for (let i = 1; i < this.sourcemaps.length; i++) {
2121
+ const range = this.sourcemaps[i];
2122
+ if (!range) break;
2123
+ if (!hasStartMap && range.startLineNumber === 1 && range.startColumn === 1) {
2124
+ hasStartMap = true;
2125
+ }
2126
+ map.addMapping({
2127
+ generated: {
2128
+ // 前两行固定为:
2129
+ // (function anonymous($Add,$Aeq, ...
2130
+ // ) {
2131
+ line: i + 3,
2132
+ column: 0
2133
+ },
2134
+ original: {
2135
+ line: range.startLineNumber,
2136
+ column: range.startColumn - 1
2137
+ },
2138
+ source: fileName
2139
+ });
2140
+ }
2141
+ if (!hasStartMap) {
2142
+ map.addMapping({
2143
+ generated: {
2144
+ line: 3,
2145
+ column: SCRIPT_PREFIX.length - "CpEnter();".length
2146
+ },
2147
+ original: {
2148
+ line: 1,
2149
+ column: 0
2150
+ },
2151
+ source: fileName
2152
+ });
2153
+ }
2154
+ {
2155
+ const line0 = this.codeLines[0];
2156
+ const file = `${fileName} <globals>`;
2157
+ let globals = `global;
2158
+ `;
2159
+ map.addMapping({
2160
+ generated: {
2161
+ line: 3,
2162
+ column: line0.indexOf(`global = `)
2163
+ },
2164
+ original: {
2165
+ line: 1,
2166
+ column: 0
2167
+ },
2168
+ source: file,
2169
+ name: "global"
2170
+ });
2171
+ map.addMapping({
2172
+ generated: {
2173
+ line: 3,
2174
+ column: SCRIPT_PREFIX.length
2175
+ },
2176
+ original: {
2177
+ line: 1,
2178
+ column: 7
2179
+ },
2180
+ source: file,
2181
+ name: ""
2182
+ });
2183
+ let i = 1;
2184
+ let pos = line0.indexOf(GLOBAL_HINT, SCRIPT_PREFIX.length) + GLOBAL_HINT.length;
2185
+ for (const p of this.globals.values()) {
2186
+ i++;
2187
+ if (pos < 0) break;
2188
+ const val = p[0];
2189
+ pos = line0.indexOf(val, pos);
2190
+ if (pos < 0) break;
2191
+ const name = p[4];
2192
+ map.addMapping({
2193
+ generated: {
2194
+ line: 3,
2195
+ column: pos
2196
+ },
2197
+ original: {
2198
+ line: i,
2199
+ column: 0
2200
+ },
2201
+ source: file,
2202
+ name
2203
+ });
2204
+ globals += `${name};
2205
+ `;
2206
+ }
2207
+ map.addMapping({
2208
+ generated: {
2209
+ line: 3,
2210
+ column: pos
2211
+ },
2212
+ original: {
2213
+ line: i,
2214
+ column: 0
2215
+ },
2216
+ source: file,
2217
+ name: ""
2218
+ });
2219
+ map.setSourceContent(file, globals);
2220
+ }
2221
+ const prefix = "//# ";
2222
+ const sourceURL = hasSchema ? fileName : `${ORIGIN}${fileName}`;
2223
+ this.codeLines.push(
2224
+ // Prevent source map from being recognized as of this file
2225
+ `${prefix}sourceURL=${sourceURL}.js`,
2226
+ `${prefix}sourceMappingURL=data:application/json,${encodeURIComponent(map.toString())}`
2227
+ );
2228
+ }
2229
+ };
2230
+
2231
+ // src/compiler/generate-bytecode.ts
2232
+ import { getModule as getModule2, loadModule } from "@mirascript/bindings";
2233
+ function generateBytecodeSync(script, options) {
2234
+ const module = getModule2();
2235
+ const result = module.compileSync(script, options);
2236
+ return [result.chunk, result.diagnostics];
2237
+ }
2238
+ async function generateBytecode(script, options) {
2239
+ if (options == null) {
2240
+ throw new TypeError("options must be provided");
2241
+ }
2242
+ const module = await loadModule();
2243
+ const result = "compile" in module ? await module.compile(script, options) : module.compileSync(script, options);
2244
+ return [result.chunk, result.diagnostics];
2245
+ }
2246
+
2247
+ export {
2248
+ __export,
2249
+ isArray,
2250
+ isFinite,
2251
+ isNaN,
2252
+ isInteger,
2253
+ isSafeInteger,
2254
+ hasOwn,
2255
+ keys,
2256
+ values,
2257
+ entries,
2258
+ create,
2259
+ fromEntries,
2260
+ defineProperty,
2261
+ VmError,
2262
+ $Add,
2263
+ $Sub,
2264
+ $Mul,
2265
+ $Div,
2266
+ $Same,
2267
+ $Call,
2268
+ $Type,
2269
+ $ToBoolean,
2270
+ $ToString,
2271
+ $ToNumber,
2272
+ $Format,
2273
+ operations_exports,
2274
+ VmSharedContext,
2275
+ defineVmContextValue,
2276
+ DefaultVmContext,
2277
+ createVmContext,
2278
+ isVmContext,
2279
+ Element,
2280
+ Cp,
2281
+ configCheckpoint,
2282
+ GlobalFallback,
2283
+ helpers_exports,
2284
+ isVmFunction,
2285
+ getVmFunctionInfo,
2286
+ VmFunction,
2287
+ isVmWrapper,
2288
+ VmExtern,
2289
+ isVmExtern,
2290
+ toVmFunctionProxy,
2291
+ fromVmFunctionProxy,
2292
+ wrapToVmValue,
2293
+ unwrapFromVmValue,
2294
+ isVmScript,
2295
+ isVmCallable,
2296
+ VM_ARRAY_MAX_LENGTH,
2297
+ isVmArray,
2298
+ isVmRecord,
2299
+ isVmArrayLikeRecordByEntires,
2300
+ isVmArrayLikeRecordByKeys,
2301
+ isVmArrayLikeRecord,
2302
+ isVmPrimitive,
2303
+ isVmConst,
2304
+ VmModule,
2305
+ isVmModule,
2306
+ isVmImmutable,
2307
+ isVmAny,
2308
+ isVmValue,
2309
+ DiagnosticCode,
2310
+ getDiagnosticMessage,
2311
+ parseDiagnostics,
2312
+ formatDiagnostic,
2313
+ emit,
2314
+ generateBytecodeSync,
2315
+ generateBytecode
2316
+ };
2317
+ //# sourceMappingURL=chunk-55FKP56O.js.map