@mirascript/mirascript 0.1.15 → 0.1.17
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.
- package/dist/chunk-JG3D67GF.js +1625 -0
- package/dist/chunk-JG3D67GF.js.map +6 -0
- package/dist/chunk-RIT53WVY.js +1 -0
- package/dist/chunk-RLWIIOH5.js +12 -0
- package/dist/chunk-RLWIIOH5.js.map +6 -0
- package/dist/{chunk-NT235HY3.js → chunk-W2I5XPIE.js} +1490 -608
- package/dist/chunk-W2I5XPIE.js.map +6 -0
- package/dist/cli/index.js +11 -67
- package/dist/cli/index.js.map +2 -2
- package/dist/compiler/compile-fast.d.ts +1 -1
- package/dist/compiler/compile-fast.d.ts.map +1 -1
- package/dist/compiler/create-script.d.ts +10 -1
- package/dist/compiler/create-script.d.ts.map +1 -1
- package/dist/compiler/diagnostic.d.ts +1 -1
- package/dist/compiler/diagnostic.d.ts.map +1 -1
- package/dist/compiler/emit/constants.d.ts +3 -0
- package/dist/compiler/emit/constants.d.ts.map +1 -0
- package/dist/compiler/emit/consts.d.ts +6 -0
- package/dist/compiler/emit/consts.d.ts.map +1 -0
- package/dist/compiler/emit/globals.d.ts +17 -0
- package/dist/compiler/emit/globals.d.ts.map +1 -0
- package/dist/compiler/emit/index.d.ts +58 -0
- package/dist/compiler/emit/index.d.ts.map +1 -0
- package/dist/compiler/emit/sourcemap.d.ts +6 -0
- package/dist/compiler/emit/sourcemap.d.ts.map +1 -0
- package/dist/compiler/index.d.ts +3 -2
- package/dist/compiler/index.d.ts.map +1 -1
- package/dist/compiler/worker.js +1 -1
- package/dist/helpers/constants.d.ts +10 -0
- package/dist/helpers/constants.d.ts.map +1 -1
- package/dist/helpers/convert/index.d.ts +5 -0
- package/dist/helpers/convert/index.d.ts.map +1 -0
- package/dist/helpers/convert/to-boolean.d.ts +4 -0
- package/dist/helpers/convert/to-boolean.d.ts.map +1 -0
- package/dist/helpers/convert/to-format.d.ts +4 -0
- package/dist/helpers/convert/to-format.d.ts.map +1 -0
- package/dist/helpers/convert/to-number.d.ts +4 -0
- package/dist/helpers/convert/to-number.d.ts.map +1 -0
- package/dist/helpers/convert/to-string.d.ts +6 -0
- package/dist/helpers/convert/to-string.d.ts.map +1 -0
- package/dist/{vm → helpers}/error.d.ts +1 -1
- package/dist/helpers/error.d.ts.map +1 -0
- package/dist/helpers/serialize.d.ts +13 -4
- package/dist/helpers/serialize.d.ts.map +1 -1
- package/dist/helpers/types.d.ts +54 -0
- package/dist/helpers/types.d.ts.map +1 -0
- package/dist/index.js +11 -17
- package/dist/subtle.d.ts +4 -3
- package/dist/subtle.d.ts.map +1 -1
- package/dist/subtle.js +20 -16
- package/dist/vm/checkpoint.d.ts +9 -0
- package/dist/vm/checkpoint.d.ts.map +1 -0
- package/dist/vm/helpers.d.ts +4 -10
- package/dist/vm/helpers.d.ts.map +1 -1
- package/dist/vm/index.d.ts +3 -3
- package/dist/vm/index.d.ts.map +1 -1
- package/dist/vm/lib/global/bit.d.ts +7 -7
- package/dist/vm/lib/global/bit.d.ts.map +1 -1
- package/dist/vm/lib/global/debug.d.ts +2 -2
- package/dist/vm/lib/global/debug.d.ts.map +1 -1
- package/dist/vm/lib/global/index.d.ts +0 -1
- package/dist/vm/lib/global/index.d.ts.map +1 -1
- package/dist/vm/lib/global/json.d.ts +2 -2
- package/dist/vm/lib/global/json.d.ts.map +1 -1
- package/dist/vm/lib/global/math-additional.d.ts +1 -1
- package/dist/vm/lib/global/math-additional.d.ts.map +1 -1
- package/dist/vm/lib/global/math-arr.d.ts +5 -5
- package/dist/vm/lib/global/math-arr.d.ts.map +1 -1
- package/dist/vm/lib/global/math-unary.d.ts +26 -26
- package/dist/vm/lib/global/math-unary.d.ts.map +1 -1
- package/dist/vm/lib/global/math.d.ts +3 -3
- package/dist/vm/lib/global/math.d.ts.map +1 -1
- package/dist/vm/lib/global/sequence/all-any.d.ts +2 -2
- package/dist/vm/lib/global/sequence/all-any.d.ts.map +1 -1
- package/dist/vm/lib/global/sequence/entries.d.ts +5 -5
- package/dist/vm/lib/global/sequence/entries.d.ts.map +1 -1
- package/dist/vm/lib/global/sequence/find.d.ts +3 -3
- package/dist/vm/lib/global/sequence/find.d.ts.map +1 -1
- package/dist/vm/lib/global/sequence/flatten.d.ts +1 -1
- package/dist/vm/lib/global/sequence/flatten.d.ts.map +1 -1
- package/dist/vm/lib/global/sequence/len.d.ts +1 -1
- package/dist/vm/lib/global/sequence/len.d.ts.map +1 -1
- package/dist/vm/lib/global/sequence/map-filter.d.ts +3 -3
- package/dist/vm/lib/global/sequence/map-filter.d.ts.map +1 -1
- package/dist/vm/lib/global/sequence/repeat.d.ts +1 -1
- package/dist/vm/lib/global/sequence/repeat.d.ts.map +1 -1
- package/dist/vm/lib/global/sequence/reverse.d.ts +1 -1
- package/dist/vm/lib/global/sequence/reverse.d.ts.map +1 -1
- package/dist/vm/lib/global/sequence/sort.d.ts +2 -2
- package/dist/vm/lib/global/sequence/sort.d.ts.map +1 -1
- package/dist/vm/lib/global/sequence/with.d.ts +2 -2
- package/dist/vm/lib/global/sequence/with.d.ts.map +1 -1
- package/dist/vm/lib/global/sequence/zip.d.ts +1 -1
- package/dist/vm/lib/global/sequence/zip.d.ts.map +1 -1
- package/dist/vm/lib/global/string.d.ts +10 -10
- package/dist/vm/lib/global/string.d.ts.map +1 -1
- package/dist/vm/lib/global/time.d.ts +3 -13
- package/dist/vm/lib/global/time.d.ts.map +1 -1
- package/dist/vm/lib/global/to-primitive.d.ts +4 -4
- package/dist/vm/lib/global/to-primitive.d.ts.map +1 -1
- package/dist/vm/lib/helpers.d.ts +53 -0
- package/dist/vm/lib/helpers.d.ts.map +1 -0
- package/dist/vm/lib/index.d.ts +4 -0
- package/dist/vm/lib/index.d.ts.map +1 -0
- package/dist/vm/lib/{_loader.d.ts → loader.d.ts} +5 -5
- package/dist/vm/lib/loader.d.ts.map +1 -0
- package/dist/vm/lib/mod/index.d.ts +2 -0
- package/dist/vm/lib/mod/index.d.ts.map +1 -0
- package/dist/vm/lib/mod/matrix.d.ts +15 -0
- package/dist/vm/lib/mod/matrix.d.ts.map +1 -0
- package/dist/vm/operations.d.ts +2 -4
- package/dist/vm/operations.d.ts.map +1 -1
- package/dist/vm/types/boundary.d.ts +1 -1
- package/dist/vm/types/boundary.d.ts.map +1 -1
- package/dist/vm/types/context.d.ts +4 -17
- package/dist/vm/types/context.d.ts.map +1 -1
- package/dist/vm/types/extern.d.ts +1 -3
- package/dist/vm/types/extern.d.ts.map +1 -1
- package/dist/vm/types/function.d.ts +1 -6
- package/dist/vm/types/function.d.ts.map +1 -1
- package/dist/vm/types/index.d.ts +31 -17
- package/dist/vm/types/index.d.ts.map +1 -1
- package/dist/vm/types/module.d.ts +2 -4
- package/dist/vm/types/module.d.ts.map +1 -1
- package/dist/vm/types/wrapper.d.ts +0 -2
- package/dist/vm/types/wrapper.d.ts.map +1 -1
- package/package.json +7 -3
- package/src/cli/index.ts +1 -1
- package/src/compiler/compile-fast.ts +1 -2
- package/src/compiler/create-script.ts +12 -2
- package/src/compiler/diagnostic.ts +17 -8
- package/src/compiler/emit/constants.ts +2 -0
- package/src/compiler/emit/consts.ts +47 -0
- package/src/compiler/emit/globals.ts +39 -0
- package/src/compiler/{emit.ts → emit/index.ts} +16 -200
- package/src/compiler/emit/sourcemap.ts +168 -0
- package/src/compiler/index.ts +9 -9
- package/src/compiler/worker.ts +1 -1
- package/src/helpers/constants.ts +12 -0
- package/src/helpers/convert/index.ts +4 -0
- package/src/helpers/convert/to-boolean.ts +12 -0
- package/src/helpers/convert/to-format.ts +37 -0
- package/src/helpers/convert/to-number.ts +35 -0
- package/src/helpers/convert/to-string.ts +55 -0
- package/src/{vm → helpers}/error.ts +1 -1
- package/src/helpers/serialize.ts +72 -24
- package/src/helpers/types.ts +267 -0
- package/src/subtle.ts +4 -2
- package/src/vm/checkpoint.ts +42 -0
- package/src/vm/helpers.ts +9 -53
- package/src/vm/index.ts +3 -3
- package/src/vm/lib/global/bit.ts +8 -9
- package/src/vm/lib/global/debug.ts +5 -4
- package/src/vm/lib/global/index.ts +0 -1
- package/src/vm/lib/global/json.ts +2 -2
- package/src/vm/lib/global/math-additional.ts +2 -4
- package/src/vm/lib/global/math-arr.ts +1 -1
- package/src/vm/lib/global/math-unary.ts +2 -4
- package/src/vm/lib/global/math.ts +3 -4
- package/src/vm/lib/global/sequence/all-any.ts +11 -6
- package/src/vm/lib/global/sequence/entries.ts +1 -1
- package/src/vm/lib/global/sequence/find.ts +4 -3
- package/src/vm/lib/global/sequence/flatten.ts +2 -3
- package/src/vm/lib/global/sequence/len.ts +1 -1
- package/src/vm/lib/global/sequence/map-filter.ts +4 -3
- package/src/vm/lib/global/sequence/repeat.ts +2 -4
- package/src/vm/lib/global/sequence/reverse.ts +1 -1
- package/src/vm/lib/global/sequence/sort.ts +6 -5
- package/src/vm/lib/global/sequence/with.ts +21 -20
- package/src/vm/lib/global/sequence/zip.ts +3 -3
- package/src/vm/lib/global/string.ts +16 -27
- package/src/vm/lib/global/time.ts +59 -30
- package/src/vm/lib/global/to-primitive.ts +27 -18
- package/src/vm/lib/{_helpers.ts → helpers.ts} +132 -44
- package/src/vm/lib/index.ts +16 -0
- package/src/vm/lib/{_loader.ts → loader.ts} +3 -11
- package/src/vm/lib/mod/index.ts +1 -0
- package/src/vm/lib/{global/mod → mod}/matrix.ts +9 -7
- package/src/vm/operations.ts +41 -137
- package/src/vm/types/boundary.ts +10 -13
- package/src/vm/types/context.ts +31 -50
- package/src/vm/types/extern.ts +8 -15
- package/src/vm/types/function.ts +4 -19
- package/src/vm/types/index.ts +47 -25
- package/src/vm/types/module.ts +3 -7
- package/src/vm/types/wrapper.ts +1 -5
- package/dist/chunk-35JGBXRE.js +0 -1
- package/dist/chunk-JVFUK7AN.js +0 -2324
- package/dist/chunk-JVFUK7AN.js.map +0 -6
- package/dist/chunk-NT235HY3.js.map +0 -6
- package/dist/compiler/emit.d.ts +0 -5
- package/dist/compiler/emit.d.ts.map +0 -1
- package/dist/vm/error.d.ts.map +0 -1
- package/dist/vm/lib/_helpers.d.ts +0 -35
- package/dist/vm/lib/_helpers.d.ts.map +0 -1
- package/dist/vm/lib/_loader.d.ts.map +0 -1
- package/dist/vm/lib/global/mod/index.d.ts +0 -3
- package/dist/vm/lib/global/mod/index.d.ts.map +0 -1
- package/dist/vm/lib/global/mod/matrix.d.ts +0 -15
- package/dist/vm/lib/global/mod/matrix.d.ts.map +0 -1
- package/dist/vm/types/any.d.ts +0 -10
- package/dist/vm/types/any.d.ts.map +0 -1
- package/dist/vm/types/array.d.ts +0 -12
- package/dist/vm/types/array.d.ts.map +0 -1
- package/dist/vm/types/callable.d.ts +0 -5
- package/dist/vm/types/callable.d.ts.map +0 -1
- package/dist/vm/types/const.d.ts +0 -15
- package/dist/vm/types/const.d.ts.map +0 -1
- package/dist/vm/types/immutable.d.ts +0 -15
- package/dist/vm/types/immutable.d.ts.map +0 -1
- package/dist/vm/types/primitive.d.ts +0 -7
- package/dist/vm/types/primitive.d.ts.map +0 -1
- package/dist/vm/types/record.d.ts +0 -20
- package/dist/vm/types/record.d.ts.map +0 -1
- package/dist/vm/types/script.d.ts +0 -14
- package/dist/vm/types/script.d.ts.map +0 -1
- package/dist/vm/types/value.d.ts +0 -14
- package/dist/vm/types/value.d.ts.map +0 -1
- package/src/vm/lib/global/mod/index.ts +0 -4
- package/src/vm/types/any.ts +0 -33
- package/src/vm/types/array.ts +0 -19
- package/src/vm/types/callable.ts +0 -10
- package/src/vm/types/const.ts +0 -109
- package/src/vm/types/immutable.ts +0 -22
- package/src/vm/types/primitive.ts +0 -14
- package/src/vm/types/record.ts +0 -53
- package/src/vm/types/script.ts +0 -18
- package/src/vm/types/value.ts +0 -22
- /package/dist/{chunk-35JGBXRE.js.map → chunk-RIT53WVY.js.map} +0 -0
|
@@ -1,42 +1,31 @@
|
|
|
1
1
|
import {
|
|
2
|
-
$Add,
|
|
3
|
-
$Call,
|
|
4
|
-
$Div,
|
|
5
|
-
$Format,
|
|
6
|
-
$Mul,
|
|
7
|
-
$Same,
|
|
8
|
-
$Sub,
|
|
9
|
-
$ToBoolean,
|
|
10
|
-
$ToNumber,
|
|
11
|
-
$ToString,
|
|
12
|
-
$Type,
|
|
13
|
-
Cp,
|
|
14
2
|
DiagnosticCode,
|
|
15
|
-
Element,
|
|
16
|
-
GlobalFallback,
|
|
17
3
|
VM_ARRAY_MAX_LENGTH,
|
|
4
|
+
VM_FUNCTION_ANONYMOUS_NAME,
|
|
5
|
+
VM_SCRIPT_NAME,
|
|
18
6
|
VmError,
|
|
19
|
-
VmFunction,
|
|
20
|
-
VmModule,
|
|
21
|
-
VmSharedContext,
|
|
22
7
|
__export,
|
|
8
|
+
apply,
|
|
23
9
|
create,
|
|
24
10
|
defineProperty,
|
|
11
|
+
display,
|
|
25
12
|
emit,
|
|
26
13
|
entries,
|
|
27
|
-
|
|
14
|
+
formatDiagnostics,
|
|
28
15
|
fromEntries,
|
|
29
16
|
generateBytecode,
|
|
30
17
|
generateBytecodeSync,
|
|
18
|
+
getPrototypeOf,
|
|
31
19
|
hasOwn,
|
|
32
|
-
|
|
20
|
+
hasOwnEnumerable,
|
|
21
|
+
innerToString,
|
|
33
22
|
isArray,
|
|
34
23
|
isFinite,
|
|
35
24
|
isInteger,
|
|
36
25
|
isNaN,
|
|
37
26
|
isSafeInteger,
|
|
27
|
+
isVmAny,
|
|
38
28
|
isVmArray,
|
|
39
|
-
isVmArrayLikeRecordByEntires,
|
|
40
29
|
isVmCallable,
|
|
41
30
|
isVmConst,
|
|
42
31
|
isVmExtern,
|
|
@@ -44,40 +33,1242 @@ import {
|
|
|
44
33
|
isVmModule,
|
|
45
34
|
isVmPrimitive,
|
|
46
35
|
isVmRecord,
|
|
36
|
+
isVmWrapper,
|
|
37
|
+
kVmContext,
|
|
38
|
+
kVmExtern,
|
|
39
|
+
kVmFunction,
|
|
40
|
+
kVmFunctionProxy,
|
|
41
|
+
kVmModule,
|
|
42
|
+
kVmScript,
|
|
43
|
+
kVmWrapper,
|
|
47
44
|
keys,
|
|
48
|
-
operations_exports,
|
|
49
45
|
parseDiagnostics,
|
|
46
|
+
toString,
|
|
50
47
|
values
|
|
51
|
-
} from "./chunk-
|
|
48
|
+
} from "./chunk-JG3D67GF.js";
|
|
49
|
+
|
|
50
|
+
// src/helpers/convert/index.ts
|
|
51
|
+
var convert_exports = {};
|
|
52
|
+
__export(convert_exports, {
|
|
53
|
+
toBoolean: () => toBoolean,
|
|
54
|
+
toFormat: () => toFormat,
|
|
55
|
+
toNumber: () => toNumber,
|
|
56
|
+
toString: () => toString
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// src/helpers/convert/to-number.ts
|
|
60
|
+
var { POSITIVE_INFINITY, NEGATIVE_INFINITY } = Number;
|
|
61
|
+
function toNumber(value, fallback) {
|
|
62
|
+
if (typeof value === "number") {
|
|
63
|
+
return value;
|
|
64
|
+
}
|
|
65
|
+
if (typeof value == "boolean") {
|
|
66
|
+
return value ? 1 : 0;
|
|
67
|
+
}
|
|
68
|
+
if (typeof value == "string") {
|
|
69
|
+
value = value.trim();
|
|
70
|
+
if (value !== "") {
|
|
71
|
+
if (value === "inf" || value === "+inf" || value === "Infinity" || value === "+Infinity") {
|
|
72
|
+
return POSITIVE_INFINITY;
|
|
73
|
+
}
|
|
74
|
+
if (value === "-inf" || value === "-Infinity") {
|
|
75
|
+
return NEGATIVE_INFINITY;
|
|
76
|
+
}
|
|
77
|
+
if (value === "nan" || value === "NaN") {
|
|
78
|
+
return Number.NaN;
|
|
79
|
+
}
|
|
80
|
+
const num2 = Number(value);
|
|
81
|
+
if (!isNaN(num2)) return num2;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (fallback === void 0) {
|
|
85
|
+
throw new VmError(`Failed to convert value to number: ${display(value)}`, Number.NaN);
|
|
86
|
+
}
|
|
87
|
+
return fallback;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// src/helpers/convert/to-format.ts
|
|
91
|
+
function formatNumber(value) {
|
|
92
|
+
if (!isFinite(value)) return toString(value, void 0);
|
|
93
|
+
if (value === 0) return "0";
|
|
94
|
+
const s = value.toString();
|
|
95
|
+
let ps;
|
|
96
|
+
const abs3 = Math.abs(value);
|
|
97
|
+
if (abs3 >= 1e3 || abs3 < 1e-3) {
|
|
98
|
+
const ps1 = value.toExponential();
|
|
99
|
+
const ps2 = value.toExponential(5);
|
|
100
|
+
ps = ps1.length < ps2.length ? ps1 : ps2;
|
|
101
|
+
} else {
|
|
102
|
+
ps = value.toPrecision(6);
|
|
103
|
+
}
|
|
104
|
+
return ps.length < s.length ? ps : s;
|
|
105
|
+
}
|
|
106
|
+
function toFormat(value, format2) {
|
|
107
|
+
const f = format2 == null ? "" : format2.trim();
|
|
108
|
+
if (typeof value == "number") {
|
|
109
|
+
if (/^\.\d+$/.test(f)) {
|
|
110
|
+
let digits = Math.trunc(Number(f.slice(1)));
|
|
111
|
+
if (!(digits <= 100)) digits = 100;
|
|
112
|
+
return value.toFixed(digits);
|
|
113
|
+
} else {
|
|
114
|
+
return formatNumber(value);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return toString(value, void 0);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// src/helpers/convert/to-boolean.ts
|
|
121
|
+
function toBoolean(value, fallback) {
|
|
122
|
+
if (typeof value === "boolean") return value;
|
|
123
|
+
if (fallback === void 0) {
|
|
124
|
+
throw new VmError(`Failed to convert value to boolean: ${display(value)}`, false);
|
|
125
|
+
}
|
|
126
|
+
return fallback;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// src/vm/operations.ts
|
|
130
|
+
var operations_exports = {};
|
|
131
|
+
__export(operations_exports, {
|
|
132
|
+
$Add: () => $Add,
|
|
133
|
+
$Aeq: () => $Aeq,
|
|
134
|
+
$And: () => $And,
|
|
135
|
+
$ArraySpread: () => $ArraySpread,
|
|
136
|
+
$AssertInit: () => $AssertInit,
|
|
137
|
+
$AssertNonNil: () => $AssertNonNil,
|
|
138
|
+
$Call: () => $Call,
|
|
139
|
+
$Concat: () => $Concat,
|
|
140
|
+
$Div: () => $Div,
|
|
141
|
+
$Eq: () => $Eq,
|
|
142
|
+
$Format: () => $Format,
|
|
143
|
+
$Get: () => $Get,
|
|
144
|
+
$Gt: () => $Gt,
|
|
145
|
+
$Gte: () => $Gte,
|
|
146
|
+
$Has: () => $Has,
|
|
147
|
+
$In: () => $In,
|
|
148
|
+
$IsArray: () => $IsArray,
|
|
149
|
+
$IsBoolean: () => $IsBoolean,
|
|
150
|
+
$IsNumber: () => $IsNumber,
|
|
151
|
+
$IsRecord: () => $IsRecord,
|
|
152
|
+
$IsString: () => $IsString,
|
|
153
|
+
$Iterable: () => $Iterable,
|
|
154
|
+
$Length: () => $Length,
|
|
155
|
+
$Lt: () => $Lt,
|
|
156
|
+
$Lte: () => $Lte,
|
|
157
|
+
$Mod: () => $Mod,
|
|
158
|
+
$Mul: () => $Mul,
|
|
159
|
+
$Naeq: () => $Naeq,
|
|
160
|
+
$Neg: () => $Neg,
|
|
161
|
+
$Neq: () => $Neq,
|
|
162
|
+
$Not: () => $Not,
|
|
163
|
+
$Nsame: () => $Nsame,
|
|
164
|
+
$Omit: () => $Omit,
|
|
165
|
+
$Or: () => $Or,
|
|
166
|
+
$Pick: () => $Pick,
|
|
167
|
+
$Pos: () => $Pos,
|
|
168
|
+
$Pow: () => $Pow,
|
|
169
|
+
$RecordSpread: () => $RecordSpread,
|
|
170
|
+
$Same: () => $Same,
|
|
171
|
+
$Set: () => $Set,
|
|
172
|
+
$Slice: () => $Slice,
|
|
173
|
+
$SliceExclusive: () => $SliceExclusive,
|
|
174
|
+
$Sub: () => $Sub,
|
|
175
|
+
$ToBoolean: () => $ToBoolean,
|
|
176
|
+
$ToNumber: () => $ToNumber,
|
|
177
|
+
$ToString: () => $ToString,
|
|
178
|
+
$Type: () => $Type
|
|
179
|
+
});
|
|
180
|
+
var { abs, min, trunc, ceil } = Math;
|
|
181
|
+
var { slice, at } = Array.prototype;
|
|
182
|
+
var isSame = (a, b) => {
|
|
183
|
+
if (typeof a == "number" && typeof b == "number") return a === b || isNaN(a) && isNaN(b);
|
|
184
|
+
if (a === b) return true;
|
|
185
|
+
if (a == null || typeof a != "object" || b == null || typeof b != "object") return false;
|
|
186
|
+
if (isVmWrapper(a)) return a.same(b);
|
|
187
|
+
if (isVmWrapper(b)) return b.same(a);
|
|
188
|
+
if (isVmArray(a) && isVmArray(b)) {
|
|
189
|
+
const len2 = a.length;
|
|
190
|
+
if (len2 !== b.length) {
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
for (let i = 0; i < len2; i++) {
|
|
194
|
+
if (!isSame(a[i] ?? null, b[i] ?? null)) {
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
200
|
+
if (!isVmArray(a) && !isVmArray(b)) {
|
|
201
|
+
const aKeys = keys(a);
|
|
202
|
+
const bKeys = keys(b);
|
|
203
|
+
if (aKeys.length !== bKeys.length) {
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
for (const key of aKeys) {
|
|
207
|
+
if (!hasOwnEnumerable(b, key)) {
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
const av = a[key] ?? null;
|
|
211
|
+
const bv = b[key] ?? null;
|
|
212
|
+
if (!isSame(av, bv)) {
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return true;
|
|
217
|
+
}
|
|
218
|
+
return false;
|
|
219
|
+
};
|
|
220
|
+
var overloadNumberString = (a, b) => {
|
|
221
|
+
if (typeof a == "number" || typeof b == "number") return true;
|
|
222
|
+
if (typeof a == "string" || typeof b == "string") return false;
|
|
223
|
+
return true;
|
|
224
|
+
};
|
|
225
|
+
var $Add = (a, b) => {
|
|
226
|
+
return $ToNumber(a) + $ToNumber(b);
|
|
227
|
+
};
|
|
228
|
+
var $Sub = (a, b) => {
|
|
229
|
+
return $ToNumber(a) - $ToNumber(b);
|
|
230
|
+
};
|
|
231
|
+
var $Mul = (a, b) => {
|
|
232
|
+
return $ToNumber(a) * $ToNumber(b);
|
|
233
|
+
};
|
|
234
|
+
var $Div = (a, b) => {
|
|
235
|
+
return $ToNumber(a) / $ToNumber(b);
|
|
236
|
+
};
|
|
237
|
+
var $Mod = (a, b) => {
|
|
238
|
+
return $ToNumber(a) % $ToNumber(b);
|
|
239
|
+
};
|
|
240
|
+
var $Pow = (a, b) => {
|
|
241
|
+
return $ToNumber(a) ** $ToNumber(b);
|
|
242
|
+
};
|
|
243
|
+
var $And = (a, b) => {
|
|
244
|
+
return $ToBoolean(a) && $ToBoolean(b);
|
|
245
|
+
};
|
|
246
|
+
var $Or = (a, b) => {
|
|
247
|
+
return $ToBoolean(a) || $ToBoolean(b);
|
|
248
|
+
};
|
|
249
|
+
var $Gt = (a, b) => {
|
|
250
|
+
if (overloadNumberString(a, b)) {
|
|
251
|
+
return $ToNumber(a) > $ToNumber(b);
|
|
252
|
+
} else {
|
|
253
|
+
return $ToString(a) > $ToString(b);
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
var $Gte = (a, b) => {
|
|
257
|
+
if (overloadNumberString(a, b)) {
|
|
258
|
+
return $ToNumber(a) >= $ToNumber(b);
|
|
259
|
+
} else {
|
|
260
|
+
return $ToString(a) >= $ToString(b);
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
var $Lt = (a, b) => {
|
|
264
|
+
if (overloadNumberString(a, b)) {
|
|
265
|
+
return $ToNumber(a) < $ToNumber(b);
|
|
266
|
+
} else {
|
|
267
|
+
return $ToString(a) < $ToString(b);
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
var $Lte = (a, b) => {
|
|
271
|
+
if (overloadNumberString(a, b)) {
|
|
272
|
+
return $ToNumber(a) <= $ToNumber(b);
|
|
273
|
+
} else {
|
|
274
|
+
return $ToString(a) <= $ToString(b);
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
var $Eq = (a, b) => {
|
|
278
|
+
$AssertInit(a);
|
|
279
|
+
$AssertInit(b);
|
|
280
|
+
if (typeof a == "number" && typeof b == "number") return a === b;
|
|
281
|
+
return isSame(a, b);
|
|
282
|
+
};
|
|
283
|
+
var $Neq = (a, b) => {
|
|
284
|
+
return !$Eq(a, b);
|
|
285
|
+
};
|
|
286
|
+
var $Aeq = (a, b) => {
|
|
287
|
+
if (overloadNumberString(a, b)) {
|
|
288
|
+
const an = $ToNumber(a);
|
|
289
|
+
const bn = $ToNumber(b);
|
|
290
|
+
const EPS = 1e-15;
|
|
291
|
+
if (isNaN(an) || isNaN(bn)) return false;
|
|
292
|
+
if (an === bn) return true;
|
|
293
|
+
const absoluteDifference = abs(an - bn);
|
|
294
|
+
if (absoluteDifference < EPS) return true;
|
|
295
|
+
const base = min(abs(an), abs(bn));
|
|
296
|
+
return absoluteDifference < base * EPS;
|
|
297
|
+
} else {
|
|
298
|
+
const as = $ToString(a);
|
|
299
|
+
const bs = $ToString(b);
|
|
300
|
+
if (as === bs) return true;
|
|
301
|
+
const ai = as.toLowerCase();
|
|
302
|
+
const bi = bs.toLowerCase();
|
|
303
|
+
if (ai === bi) return true;
|
|
304
|
+
const an = ai.normalize("NFC");
|
|
305
|
+
const bn = bi.normalize("NFC");
|
|
306
|
+
return an === bn;
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
var $Naeq = (a, b) => {
|
|
310
|
+
return !$Aeq(a, b);
|
|
311
|
+
};
|
|
312
|
+
var $Same = (a, b) => {
|
|
313
|
+
$AssertInit(a);
|
|
314
|
+
$AssertInit(b);
|
|
315
|
+
return isSame(a, b);
|
|
316
|
+
};
|
|
317
|
+
var $Nsame = (a, b) => {
|
|
318
|
+
return !$Same(a, b);
|
|
319
|
+
};
|
|
320
|
+
var $In = (value, iterable) => {
|
|
321
|
+
$AssertInit(value);
|
|
322
|
+
$AssertInit(iterable);
|
|
323
|
+
if (iterable == null) return false;
|
|
324
|
+
if (typeof iterable != "object") return false;
|
|
325
|
+
if (isVmArray(iterable)) {
|
|
326
|
+
if (value == null) {
|
|
327
|
+
for (const item of iterable) if (item == null) return true;
|
|
328
|
+
return false;
|
|
329
|
+
}
|
|
330
|
+
if (isVmPrimitive(value)) return iterable.includes(value);
|
|
331
|
+
return iterable.some((item = null) => isSame(item, value));
|
|
332
|
+
}
|
|
333
|
+
const key = toString(value, void 0);
|
|
334
|
+
if (isVmWrapper(iterable)) return iterable.has(key);
|
|
335
|
+
return hasOwnEnumerable(iterable, key);
|
|
336
|
+
};
|
|
337
|
+
var $Concat = (...args) => {
|
|
338
|
+
return args.map((a) => toFormat(a, null)).join("");
|
|
339
|
+
};
|
|
340
|
+
var $Pos = (a) => {
|
|
341
|
+
return $ToNumber(a);
|
|
342
|
+
};
|
|
343
|
+
var $Neg = (a) => {
|
|
344
|
+
return -$ToNumber(a);
|
|
345
|
+
};
|
|
346
|
+
var $Not = (a) => {
|
|
347
|
+
return !$ToBoolean(a);
|
|
348
|
+
};
|
|
349
|
+
var $Length = (value) => {
|
|
350
|
+
$AssertInit(value);
|
|
351
|
+
if (isVmArray(value)) return value.length;
|
|
352
|
+
if (isVmRecord(value)) return keys(value).length;
|
|
353
|
+
if (isVmWrapper(value)) return value.keys().length;
|
|
354
|
+
throw new VmError(`Value has no length: ${display(value)}`, 0);
|
|
355
|
+
};
|
|
356
|
+
var $Omit = (value, omitted) => {
|
|
357
|
+
$AssertInit(value);
|
|
358
|
+
if (value == null || !isVmRecord(value)) return {};
|
|
359
|
+
const result = {};
|
|
360
|
+
const valueKeys = keys(value);
|
|
361
|
+
const omittedSet = new Set(omitted.map($ToString));
|
|
362
|
+
for (const key of valueKeys) {
|
|
363
|
+
if (!omittedSet.has(key)) {
|
|
364
|
+
result[key] = value[key] ?? null;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
return result;
|
|
368
|
+
};
|
|
369
|
+
var $Pick = (value, picked) => {
|
|
370
|
+
$AssertInit(value);
|
|
371
|
+
if (value == null || !isVmRecord(value)) return {};
|
|
372
|
+
const result = {};
|
|
373
|
+
for (const key of picked) {
|
|
374
|
+
const k = $ToString(key);
|
|
375
|
+
if (hasOwnEnumerable(value, k)) {
|
|
376
|
+
result[k] = value[k] ?? null;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
return result;
|
|
380
|
+
};
|
|
381
|
+
var sliceCore = (value, start, end, exclusive) => {
|
|
382
|
+
const { length } = value;
|
|
383
|
+
if (isNaN(start)) start = 0;
|
|
384
|
+
else if (start < 0) start = length + start;
|
|
385
|
+
if (isNaN(end)) end = exclusive ? length : length - 1;
|
|
386
|
+
else if (end < 0) end = length + end;
|
|
387
|
+
start = ceil(start);
|
|
388
|
+
if (exclusive || !isSafeInteger(end)) {
|
|
389
|
+
end = ceil(end);
|
|
390
|
+
} else {
|
|
391
|
+
end = end + 1;
|
|
392
|
+
}
|
|
393
|
+
return slice.call(value, start, end);
|
|
394
|
+
};
|
|
395
|
+
var $Slice = (value, start, end) => {
|
|
396
|
+
$AssertInit(value);
|
|
397
|
+
if (!isVmArray(value)) throw new VmError(`Expected array, got ${display(value)}`, []);
|
|
398
|
+
const s = start != null ? $ToNumber(start) : 0;
|
|
399
|
+
const e = end != null ? $ToNumber(end) : value.length - 1;
|
|
400
|
+
return sliceCore(value, s, e, false);
|
|
401
|
+
};
|
|
402
|
+
var $SliceExclusive = (value, start, end) => {
|
|
403
|
+
$AssertInit(value);
|
|
404
|
+
if (!isVmArray(value)) throw new VmError(`Expected array, got ${display(value)}`, []);
|
|
405
|
+
const s = start != null ? $ToNumber(start) : 0;
|
|
406
|
+
const e = end != null ? $ToNumber(end) : value.length;
|
|
407
|
+
return sliceCore(value, s, e, true);
|
|
408
|
+
};
|
|
409
|
+
var $AssertInit = (value) => {
|
|
410
|
+
if (value === void 0) throw new VmError(`Uninitialized value`, null);
|
|
411
|
+
};
|
|
412
|
+
var $Call = (func, args) => {
|
|
413
|
+
for (const a of args) {
|
|
414
|
+
$AssertInit(a);
|
|
415
|
+
}
|
|
416
|
+
if (isVmExtern(func)) {
|
|
417
|
+
return func.call(args) ?? null;
|
|
418
|
+
}
|
|
419
|
+
if (isVmFunction(func)) {
|
|
420
|
+
return func(...args) ?? null;
|
|
421
|
+
}
|
|
422
|
+
throw new VmError(`Value is not callable: ${display(func)}`, null);
|
|
423
|
+
};
|
|
424
|
+
var $Type = (value) => {
|
|
425
|
+
if (value == null) return "nil";
|
|
426
|
+
if (isVmWrapper(value)) return value.type;
|
|
427
|
+
if (isVmArray(value)) return "array";
|
|
428
|
+
if (typeof value == "object") return "record";
|
|
429
|
+
return typeof value;
|
|
430
|
+
};
|
|
431
|
+
var $ToBoolean = (value) => {
|
|
432
|
+
if (typeof value == "boolean") return value;
|
|
433
|
+
$AssertInit(value);
|
|
434
|
+
return toBoolean(value, void 0);
|
|
435
|
+
};
|
|
436
|
+
var $ToString = (value) => {
|
|
437
|
+
if (typeof value == "string") return value;
|
|
438
|
+
$AssertInit(value);
|
|
439
|
+
return toString(value, void 0);
|
|
440
|
+
};
|
|
441
|
+
var $ToNumber = (value) => {
|
|
442
|
+
if (typeof value == "number") return value;
|
|
443
|
+
$AssertInit(value);
|
|
444
|
+
return toNumber(value, void 0);
|
|
445
|
+
};
|
|
446
|
+
var $IsBoolean = (value) => {
|
|
447
|
+
$AssertInit(value);
|
|
448
|
+
return typeof value == "boolean";
|
|
449
|
+
};
|
|
450
|
+
var $IsNumber = (value) => {
|
|
451
|
+
$AssertInit(value);
|
|
452
|
+
return typeof value == "number";
|
|
453
|
+
};
|
|
454
|
+
var $IsString = (value) => {
|
|
455
|
+
$AssertInit(value);
|
|
456
|
+
return typeof value == "string";
|
|
457
|
+
};
|
|
458
|
+
var $IsRecord = (value) => {
|
|
459
|
+
$AssertInit(value);
|
|
460
|
+
return isVmRecord(value);
|
|
461
|
+
};
|
|
462
|
+
var $IsArray = (value) => {
|
|
463
|
+
$AssertInit(value);
|
|
464
|
+
return isVmArray(value);
|
|
465
|
+
};
|
|
466
|
+
var $AssertNonNil = (value) => {
|
|
467
|
+
$AssertInit(value);
|
|
468
|
+
if (value !== null) return;
|
|
469
|
+
throw new VmError(`Expected non-nil value`, null);
|
|
470
|
+
};
|
|
471
|
+
var $Has = (obj, key) => {
|
|
472
|
+
$AssertInit(obj);
|
|
473
|
+
const pk = $ToString(key);
|
|
474
|
+
if (obj == null || typeof obj != "object") return false;
|
|
475
|
+
if (isVmWrapper(obj)) return obj.has(pk);
|
|
476
|
+
return hasOwnEnumerable(obj, pk);
|
|
477
|
+
};
|
|
478
|
+
var $Get = (obj, key) => {
|
|
479
|
+
$AssertInit(obj);
|
|
480
|
+
if (isVmArray(obj)) {
|
|
481
|
+
const index = $ToNumber(key);
|
|
482
|
+
if (isNaN(index)) return null;
|
|
483
|
+
return at.call(obj, trunc(index)) ?? null;
|
|
484
|
+
}
|
|
485
|
+
const pk = $ToString(key);
|
|
486
|
+
if (obj == null || typeof obj != "object") return null;
|
|
487
|
+
if (isVmWrapper(obj)) return obj.get(pk) ?? null;
|
|
488
|
+
if (!hasOwnEnumerable(obj, pk)) return null;
|
|
489
|
+
return obj[pk] ?? null;
|
|
490
|
+
};
|
|
491
|
+
var $Set = (obj, key, value) => {
|
|
492
|
+
$AssertInit(obj);
|
|
493
|
+
$AssertInit(value);
|
|
494
|
+
const pk = $ToString(key);
|
|
495
|
+
if (obj == null) return;
|
|
496
|
+
if (!isVmExtern(obj)) throw new VmError(`Expected extern, got ${display(obj)}`, void 0);
|
|
497
|
+
obj.set(pk, value);
|
|
498
|
+
};
|
|
499
|
+
var $Iterable = (value) => {
|
|
500
|
+
$AssertInit(value);
|
|
501
|
+
if (isVmWrapper(value)) return value.keys();
|
|
502
|
+
if (isVmArray(value)) return value;
|
|
503
|
+
if (value != null && typeof value == "object") return keys(value);
|
|
504
|
+
throw new VmError(`Value is not iterable: ${display(value)}`, isVmFunction(value) ? [] : [value]);
|
|
505
|
+
};
|
|
506
|
+
var $RecordSpread = (record) => {
|
|
507
|
+
$AssertInit(record);
|
|
508
|
+
if (record == null || isVmRecord(record)) return record;
|
|
509
|
+
if (isVmArray(record)) {
|
|
510
|
+
const result = {};
|
|
511
|
+
const len2 = record.length;
|
|
512
|
+
for (let i = 0; i < len2; i++) {
|
|
513
|
+
const item = record[i];
|
|
514
|
+
result[i] = item ?? null;
|
|
515
|
+
}
|
|
516
|
+
return result;
|
|
517
|
+
}
|
|
518
|
+
if (isVmExtern(record)) {
|
|
519
|
+
const result = create(null);
|
|
520
|
+
for (const key of record.keys()) {
|
|
521
|
+
const value = record.get(key) ?? null;
|
|
522
|
+
if (isVmPrimitive(value)) {
|
|
523
|
+
result[key] = value;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
return result;
|
|
527
|
+
}
|
|
528
|
+
throw new VmError(`Expected record, array, extern or nil, got ${display(record)}`, null);
|
|
529
|
+
};
|
|
530
|
+
var $ArraySpread = (array) => {
|
|
531
|
+
$AssertInit(array);
|
|
532
|
+
if (array == null) return [];
|
|
533
|
+
if (isVmArray(array)) return array;
|
|
534
|
+
if (isVmExtern(array) && typeof array.value[Symbol.iterator] == "function") {
|
|
535
|
+
const result = [];
|
|
536
|
+
for (const item of array.value) {
|
|
537
|
+
if (isVmPrimitive(item)) {
|
|
538
|
+
result.push(item);
|
|
539
|
+
} else {
|
|
540
|
+
result.push(null);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
return result;
|
|
544
|
+
}
|
|
545
|
+
throw new VmError(`Expected array, iterable extern or nil, got ${display(array)}`, []);
|
|
546
|
+
};
|
|
547
|
+
var $Format = (value, format2) => {
|
|
548
|
+
$AssertInit(value);
|
|
549
|
+
const f = format2 == null ? "" : $ToString(format2);
|
|
550
|
+
return toFormat(value, f);
|
|
551
|
+
};
|
|
552
|
+
|
|
553
|
+
// src/vm/types/wrapper.ts
|
|
554
|
+
var VmWrapper = class {
|
|
555
|
+
constructor(value) {
|
|
556
|
+
this.value = value;
|
|
557
|
+
}
|
|
558
|
+
/** Convert the object to JSON */
|
|
559
|
+
toJSON() {
|
|
560
|
+
return void 0;
|
|
561
|
+
}
|
|
562
|
+
/** 转为字符串 */
|
|
563
|
+
toString(useBraces) {
|
|
564
|
+
const { type, describe } = this;
|
|
565
|
+
if (!describe) return `<${type}>`;
|
|
566
|
+
return `<${type} ${describe}>`;
|
|
567
|
+
}
|
|
568
|
+
};
|
|
569
|
+
Object.defineProperty(VmWrapper.prototype, kVmWrapper, { value: true });
|
|
570
|
+
|
|
571
|
+
// src/vm/types/boundary.ts
|
|
572
|
+
function toVmFunctionProxy(fn) {
|
|
573
|
+
const cached = fn[kVmFunctionProxy];
|
|
574
|
+
if (cached != null) return cached;
|
|
575
|
+
const proxy = (...args) => {
|
|
576
|
+
const ret = $Call(
|
|
577
|
+
fn,
|
|
578
|
+
// 作为函数参数传入的值一定丢失了它的 this
|
|
579
|
+
args.map((v) => wrapToVmValue(v, null))
|
|
580
|
+
);
|
|
581
|
+
return unwrapFromVmValue(ret);
|
|
582
|
+
};
|
|
583
|
+
defineProperty(fn, kVmFunctionProxy, { value: proxy });
|
|
584
|
+
defineProperty(proxy, kVmFunctionProxy, { value: fn });
|
|
585
|
+
defineProperty(proxy, "name", {
|
|
586
|
+
value: fn.name,
|
|
587
|
+
configurable: true
|
|
588
|
+
});
|
|
589
|
+
return proxy;
|
|
590
|
+
}
|
|
591
|
+
function fromVmFunctionProxy(fn) {
|
|
592
|
+
if (isVmFunction(fn)) return fn;
|
|
593
|
+
const original = fn[kVmFunctionProxy];
|
|
594
|
+
if (original && isVmFunction(original)) return original;
|
|
595
|
+
return void 0;
|
|
596
|
+
}
|
|
597
|
+
function wrapToVmValue(value, thisArg = null, assumeVmValue) {
|
|
598
|
+
if (value == null) return null;
|
|
599
|
+
switch (typeof value) {
|
|
600
|
+
case "function": {
|
|
601
|
+
const unwrapped = fromVmFunctionProxy(value);
|
|
602
|
+
if (unwrapped) return unwrapped;
|
|
603
|
+
return new VmExtern(value, thisArg);
|
|
604
|
+
}
|
|
605
|
+
case "object": {
|
|
606
|
+
if (isVmWrapper(value)) return value;
|
|
607
|
+
if (value instanceof Date) return value.valueOf();
|
|
608
|
+
if (assumeVmValue?.(value)) return value;
|
|
609
|
+
return new VmExtern(value);
|
|
610
|
+
}
|
|
611
|
+
case "string":
|
|
612
|
+
case "number":
|
|
613
|
+
case "boolean":
|
|
614
|
+
return value;
|
|
615
|
+
case "bigint":
|
|
616
|
+
return Number(value);
|
|
617
|
+
case "symbol":
|
|
618
|
+
case "undefined":
|
|
619
|
+
default:
|
|
620
|
+
return null;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
function unwrapFromVmValue(value) {
|
|
624
|
+
if (isVmFunction(value)) {
|
|
625
|
+
return toVmFunctionProxy(value);
|
|
626
|
+
}
|
|
627
|
+
if (value == null || typeof value != "object") return value;
|
|
628
|
+
if (!isVmExtern(value)) return value;
|
|
629
|
+
if (value.thisArg == null || typeof value.value != "function") {
|
|
630
|
+
return value.value;
|
|
631
|
+
}
|
|
632
|
+
const f = value;
|
|
633
|
+
const caller = f.thisArg.value;
|
|
634
|
+
return new Proxy(f.value, {
|
|
635
|
+
apply(target, thisArg, args) {
|
|
636
|
+
return apply(target, caller, args);
|
|
637
|
+
}
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
// src/vm/types/extern.ts
|
|
642
|
+
var ObjectPrototype = Object.prototype;
|
|
643
|
+
var ObjectToString = ObjectPrototype.toString;
|
|
644
|
+
var FunctionToString = Function.prototype.toString;
|
|
645
|
+
var ArrayToString = Array.prototype.toString;
|
|
646
|
+
var ArrayMap = Array.prototype.map;
|
|
647
|
+
var VmExtern = class extends VmWrapper {
|
|
648
|
+
constructor(value, thisArg = null) {
|
|
649
|
+
super(value);
|
|
650
|
+
this.thisArg = thisArg;
|
|
651
|
+
}
|
|
652
|
+
/** Check if the object has a property */
|
|
653
|
+
access(key, read) {
|
|
654
|
+
if (key.startsWith("_")) return false;
|
|
655
|
+
if (typeof this.value == "function" && (key === "prototype" || key === "arguments" || key === "caller"))
|
|
656
|
+
return false;
|
|
657
|
+
if (hasOwn(this.value, key)) return true;
|
|
658
|
+
if (!read) return true;
|
|
659
|
+
if (!(key in this.value)) return false;
|
|
660
|
+
if (key === "constructor") return false;
|
|
661
|
+
const prop = this.value[key];
|
|
662
|
+
if (key in Function.prototype && prop === Function.prototype[key]) return false;
|
|
663
|
+
if (key in Array.prototype && prop === Array.prototype[key]) return false;
|
|
664
|
+
if (key in Object.prototype && prop === Object.prototype[key]) return false;
|
|
665
|
+
return true;
|
|
666
|
+
}
|
|
667
|
+
/** 决定是否对属性进行包装 */
|
|
668
|
+
assumeVmValue(value, key) {
|
|
669
|
+
return false;
|
|
670
|
+
}
|
|
671
|
+
/** @inheritdoc */
|
|
672
|
+
has(key) {
|
|
673
|
+
return this.access(key, true);
|
|
674
|
+
}
|
|
675
|
+
/** @inheritdoc */
|
|
676
|
+
get(key) {
|
|
677
|
+
if (!this.has(key)) return void 0;
|
|
678
|
+
const prop = this.value[key];
|
|
679
|
+
return wrapToVmValue(prop, this, (v) => this.assumeVmValue(v, key));
|
|
680
|
+
}
|
|
681
|
+
/** Set a property on the object */
|
|
682
|
+
set(key, value) {
|
|
683
|
+
if (!this.access(key, false)) return false;
|
|
684
|
+
const prop = unwrapFromVmValue(value);
|
|
685
|
+
this.value[key] = prop;
|
|
686
|
+
return true;
|
|
687
|
+
}
|
|
688
|
+
/** Call extern value */
|
|
689
|
+
call(args) {
|
|
690
|
+
const { value } = this;
|
|
691
|
+
if (typeof value != "function") {
|
|
692
|
+
throw VmError.from(`Not a callable extern`, null, null);
|
|
693
|
+
}
|
|
694
|
+
const caller = this.thisArg?.value ?? null;
|
|
695
|
+
const unwrappedArgs = args.map(unwrapFromVmValue);
|
|
696
|
+
let ret;
|
|
697
|
+
try {
|
|
698
|
+
ret = apply(value, caller, unwrappedArgs);
|
|
699
|
+
} catch (ex) {
|
|
700
|
+
throw VmError.from(`Callable extern`, ex, null);
|
|
701
|
+
}
|
|
702
|
+
return wrapToVmValue(ret, null, (obj) => this.assumeVmValue(obj, void 0));
|
|
703
|
+
}
|
|
704
|
+
/** @inheritdoc */
|
|
705
|
+
keys() {
|
|
706
|
+
const keys4 = [];
|
|
707
|
+
for (const key in this.value) {
|
|
708
|
+
if (this.has(key)) keys4.push(key);
|
|
709
|
+
}
|
|
710
|
+
return keys4;
|
|
711
|
+
}
|
|
712
|
+
/** @inheritdoc */
|
|
713
|
+
same(other) {
|
|
714
|
+
if (!isVmExtern(other)) return false;
|
|
715
|
+
return this.value === other.value && this.thisArg === other.thisArg;
|
|
716
|
+
}
|
|
717
|
+
/** @inheritdoc */
|
|
718
|
+
toString(useBraces) {
|
|
719
|
+
const { toString: toString2 } = this.value;
|
|
720
|
+
if (typeof toString2 != "function" || toString2 === ObjectToString || toString2 === FunctionToString) {
|
|
721
|
+
return super.toString(useBraces);
|
|
722
|
+
}
|
|
723
|
+
if (toString2 === ArrayToString && isArray(this.value)) {
|
|
724
|
+
const mapped = ArrayMap.call(this.value, (item) => {
|
|
725
|
+
if (item === void 0) return "";
|
|
726
|
+
return innerToString(wrapToVmValue(item ?? null, null), true);
|
|
727
|
+
});
|
|
728
|
+
const str = mapped.join(", ");
|
|
729
|
+
if (useBraces) return `[${str}]`;
|
|
730
|
+
return str;
|
|
731
|
+
}
|
|
732
|
+
return String(this.value);
|
|
733
|
+
}
|
|
734
|
+
/** @inheritdoc */
|
|
735
|
+
get type() {
|
|
736
|
+
return "extern";
|
|
737
|
+
}
|
|
738
|
+
/** @inheritdoc */
|
|
739
|
+
get describe() {
|
|
740
|
+
const tag = ObjectToString.call(this.value).slice(8, -1);
|
|
741
|
+
if (isArray(this.value)) {
|
|
742
|
+
return `${tag}(${this.value.length})`;
|
|
743
|
+
} else if (tag === "Object") {
|
|
744
|
+
const proto = getPrototypeOf(this.value);
|
|
745
|
+
if (proto === ObjectPrototype) {
|
|
746
|
+
return "Object";
|
|
747
|
+
}
|
|
748
|
+
if (proto == null) {
|
|
749
|
+
return "Object: null prototype";
|
|
750
|
+
}
|
|
751
|
+
if (typeof proto.constructor === "function" && proto.constructor.name) {
|
|
752
|
+
return proto.constructor.name;
|
|
753
|
+
}
|
|
754
|
+
} else if (tag === "Function" && "prototype" in this.value && typeof this.value.prototype == "object") {
|
|
755
|
+
const { name } = this.value;
|
|
756
|
+
return `class ${name || "<anonymous>"}`;
|
|
757
|
+
} else if (tag === "Function") {
|
|
758
|
+
const { name } = this.value;
|
|
759
|
+
return `function ${name || "<anonymous>"}()`;
|
|
760
|
+
} else if (tag === "AsyncFunction") {
|
|
761
|
+
const { name } = this.value;
|
|
762
|
+
return `async function ${name || "<anonymous>"}()`;
|
|
763
|
+
} else if (tag === "GeneratorFunction") {
|
|
764
|
+
const { name } = this.value;
|
|
765
|
+
return `function* ${name || "<anonymous>"}()`;
|
|
766
|
+
} else if (tag === "AsyncGeneratorFunction") {
|
|
767
|
+
const { name } = this.value;
|
|
768
|
+
return `async function* ${name || "<anonymous>"}()`;
|
|
769
|
+
}
|
|
770
|
+
return tag;
|
|
771
|
+
}
|
|
772
|
+
};
|
|
773
|
+
Object.defineProperty(VmExtern.prototype, kVmExtern, { value: true });
|
|
774
|
+
|
|
775
|
+
// src/vm/checkpoint.ts
|
|
776
|
+
var MAX_DEPTH = 128;
|
|
777
|
+
var cpDepth = 0;
|
|
778
|
+
var cp = Number.NaN;
|
|
779
|
+
var cpTimeout = 100;
|
|
780
|
+
function Cp() {
|
|
781
|
+
if (!cp) {
|
|
782
|
+
cp = Date.now();
|
|
783
|
+
} else if (Date.now() - cp > cpTimeout) {
|
|
784
|
+
throw new RangeError("Execution timeout");
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
function CpEnter() {
|
|
788
|
+
cpDepth++;
|
|
789
|
+
if (cpDepth <= 1) {
|
|
790
|
+
cp = Date.now();
|
|
791
|
+
cpDepth = 1;
|
|
792
|
+
} else if (cpDepth > MAX_DEPTH) {
|
|
793
|
+
throw new RangeError("Maximum call depth exceeded");
|
|
794
|
+
} else {
|
|
795
|
+
Cp();
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
function CpExit() {
|
|
799
|
+
cpDepth--;
|
|
800
|
+
if (cpDepth < 1) {
|
|
801
|
+
cp = Number.NaN;
|
|
802
|
+
cpDepth = 0;
|
|
803
|
+
} else {
|
|
804
|
+
Cp();
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
function configCheckpoint(timeout = 100) {
|
|
808
|
+
if (typeof timeout !== "number" || timeout <= 0 || Number.isNaN(timeout)) {
|
|
809
|
+
throw new RangeError("Invalid timeout value");
|
|
810
|
+
}
|
|
811
|
+
cpTimeout = timeout;
|
|
812
|
+
}
|
|
52
813
|
|
|
53
|
-
// src/
|
|
54
|
-
|
|
814
|
+
// src/vm/types/function.ts
|
|
815
|
+
function VmFunction(fn, option = {}) {
|
|
816
|
+
if (typeof fn != "function") {
|
|
817
|
+
throw new TypeError("Invalid function");
|
|
818
|
+
}
|
|
819
|
+
const exists = fromVmFunctionProxy(fn);
|
|
820
|
+
if (exists) return exists;
|
|
821
|
+
const info = {
|
|
822
|
+
fullName: option.fullName ?? (fn.name === VM_FUNCTION_ANONYMOUS_NAME ? "" : fn.name),
|
|
823
|
+
isLib: option.isLib ?? false,
|
|
824
|
+
summary: option.summary || void 0,
|
|
825
|
+
params: option.params,
|
|
826
|
+
paramsType: option.paramsType,
|
|
827
|
+
returns: option.returns || void 0,
|
|
828
|
+
returnsType: option.returnsType || void 0,
|
|
829
|
+
examples: option.examples?.length ? option.examples : void 0
|
|
830
|
+
};
|
|
831
|
+
if (option.injectCp) {
|
|
832
|
+
const original = fn;
|
|
833
|
+
info.original = original;
|
|
834
|
+
fn = ((...args) => {
|
|
835
|
+
try {
|
|
836
|
+
CpEnter();
|
|
837
|
+
const ret = original(...args);
|
|
838
|
+
return ret;
|
|
839
|
+
} finally {
|
|
840
|
+
CpExit();
|
|
841
|
+
}
|
|
842
|
+
});
|
|
843
|
+
defineProperty(fn, "name", { value: original.name });
|
|
844
|
+
}
|
|
845
|
+
defineProperty(fn, kVmFunction, {
|
|
846
|
+
value: Object.freeze(info)
|
|
847
|
+
});
|
|
848
|
+
return fn;
|
|
849
|
+
}
|
|
55
850
|
|
|
56
|
-
// src/
|
|
57
|
-
var
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
851
|
+
// src/vm/types/context.ts
|
|
852
|
+
var { freeze } = Object;
|
|
853
|
+
var VM_SHARED_CONTEXT = create(null);
|
|
854
|
+
var VM_SHARED_CONTEXT_KEYS = null;
|
|
855
|
+
function globalVarNotFound(name) {
|
|
856
|
+
throw new VmError(`Global variable '${name}' is not defined.`, null);
|
|
857
|
+
}
|
|
858
|
+
function defineVmContextValue(name, value, override = false) {
|
|
859
|
+
if (!override && name in VM_SHARED_CONTEXT) throw new Error(`Global variable '${name}' is already defined.`);
|
|
860
|
+
let v;
|
|
861
|
+
if (typeof value == "function") {
|
|
862
|
+
v = VmFunction(value, {
|
|
863
|
+
isLib: true,
|
|
864
|
+
fullName: `global.${name}`
|
|
865
|
+
});
|
|
866
|
+
} else {
|
|
867
|
+
v = value;
|
|
868
|
+
}
|
|
869
|
+
VM_SHARED_CONTEXT[name] = v ?? null;
|
|
870
|
+
VM_SHARED_CONTEXT_KEYS = null;
|
|
871
|
+
}
|
|
872
|
+
var DefaultVmContext = freeze({
|
|
873
|
+
[kVmContext]: true,
|
|
874
|
+
/** @inheritdoc */
|
|
875
|
+
keys() {
|
|
876
|
+
VM_SHARED_CONTEXT_KEYS ??= freeze(keys(VM_SHARED_CONTEXT));
|
|
877
|
+
return VM_SHARED_CONTEXT_KEYS;
|
|
878
|
+
},
|
|
879
|
+
/** @inheritdoc */
|
|
880
|
+
get(key) {
|
|
881
|
+
const val = VM_SHARED_CONTEXT[key];
|
|
882
|
+
if (val === void 0) globalVarNotFound(key);
|
|
883
|
+
return val;
|
|
884
|
+
},
|
|
885
|
+
/** @inheritdoc */
|
|
886
|
+
has(key) {
|
|
887
|
+
return key in VM_SHARED_CONTEXT;
|
|
888
|
+
}
|
|
66
889
|
});
|
|
67
|
-
var
|
|
68
|
-
|
|
69
|
-
var
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
890
|
+
var _a;
|
|
891
|
+
_a = kVmContext;
|
|
892
|
+
var ValueVmContext = class {
|
|
893
|
+
constructor(env, describe) {
|
|
894
|
+
this.env = env;
|
|
895
|
+
this.describe = describe;
|
|
896
|
+
this[_a] = true;
|
|
897
|
+
this.cachedKeys = null;
|
|
898
|
+
}
|
|
899
|
+
/** @inheritdoc */
|
|
900
|
+
keys() {
|
|
901
|
+
const defaultKeys = DefaultVmContext.keys();
|
|
902
|
+
if (this.cachedKeys?.[0] !== defaultKeys) {
|
|
903
|
+
const allKeys = freeze([...keys(this.env), ...defaultKeys]);
|
|
904
|
+
this.cachedKeys = freeze([defaultKeys, allKeys]);
|
|
905
|
+
}
|
|
906
|
+
return this.cachedKeys[1];
|
|
907
|
+
}
|
|
908
|
+
/** @inheritdoc */
|
|
909
|
+
get(key) {
|
|
910
|
+
const val = this.env[key];
|
|
911
|
+
if (val === void 0) globalVarNotFound(key);
|
|
912
|
+
return val;
|
|
913
|
+
}
|
|
914
|
+
/** @inheritdoc */
|
|
915
|
+
has(key) {
|
|
916
|
+
return key in this.env;
|
|
917
|
+
}
|
|
918
|
+
};
|
|
919
|
+
var _a2;
|
|
920
|
+
_a2 = kVmContext;
|
|
921
|
+
var FactoryVmContext = class {
|
|
922
|
+
constructor(getter, enumerator, describe) {
|
|
923
|
+
this.getter = getter;
|
|
924
|
+
this.enumerator = enumerator;
|
|
925
|
+
this.describe = describe;
|
|
926
|
+
this[_a2] = true;
|
|
927
|
+
}
|
|
928
|
+
/** @inheritdoc */
|
|
929
|
+
keys() {
|
|
930
|
+
if (!this.enumerator) return DefaultVmContext.keys();
|
|
931
|
+
return freeze([...this.enumerator(), ...DefaultVmContext.keys()]);
|
|
932
|
+
}
|
|
933
|
+
/** @inheritdoc */
|
|
934
|
+
get(key) {
|
|
935
|
+
const value = this.getter(key);
|
|
936
|
+
if (value !== void 0) return value;
|
|
937
|
+
return DefaultVmContext.get(key);
|
|
938
|
+
}
|
|
939
|
+
/** @inheritdoc */
|
|
940
|
+
has(key) {
|
|
941
|
+
return this.getter(key) !== void 0 || DefaultVmContext.has(key);
|
|
942
|
+
}
|
|
943
|
+
};
|
|
944
|
+
function createVmContext(...args) {
|
|
945
|
+
if (args[0] == null && args[1] == null) {
|
|
946
|
+
return { ...DefaultVmContext };
|
|
947
|
+
}
|
|
948
|
+
if (typeof args[0] == "function") {
|
|
949
|
+
const [getter, enumerator, describer2] = args;
|
|
950
|
+
return new FactoryVmContext(getter, enumerator ?? void 0, describer2 ?? void 0);
|
|
951
|
+
}
|
|
952
|
+
const [vmValues, externValues, describer] = args;
|
|
953
|
+
const env = create(VM_SHARED_CONTEXT);
|
|
954
|
+
if (vmValues) {
|
|
955
|
+
for (const [key, value] of entries(vmValues)) {
|
|
956
|
+
if (!isVmAny(value, false)) continue;
|
|
957
|
+
env[key] = value ?? null;
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
if (externValues) {
|
|
961
|
+
for (const [key, value] of entries(externValues)) {
|
|
962
|
+
env[key] = value == null ? null : wrapToVmValue(value, null);
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
return new ValueVmContext(env, describer ?? void 0);
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
// src/compiler/index.ts
|
|
969
|
+
import { loadModule } from "@mirascript/bindings";
|
|
970
|
+
|
|
971
|
+
// src/vm/helpers.ts
|
|
972
|
+
var helpers_exports = {};
|
|
973
|
+
__export(helpers_exports, {
|
|
974
|
+
ArrayRange: () => ArrayRange,
|
|
975
|
+
ArrayRangeExclusive: () => ArrayRangeExclusive,
|
|
976
|
+
Cp: () => Cp,
|
|
977
|
+
CpEnter: () => CpEnter,
|
|
978
|
+
CpExit: () => CpExit,
|
|
979
|
+
Element: () => Element,
|
|
980
|
+
ElementOpt: () => ElementOpt,
|
|
981
|
+
Function: () => Function2,
|
|
982
|
+
GlobalFallback: () => GlobalFallback,
|
|
983
|
+
Upvalue: () => Upvalue,
|
|
984
|
+
Vargs: () => Vargs
|
|
985
|
+
});
|
|
986
|
+
var Vargs = (varags) => {
|
|
987
|
+
for (let i = 0, l = varags.length; i < l; i++) {
|
|
988
|
+
const el = varags[i];
|
|
989
|
+
if (!isVmConst(el)) {
|
|
990
|
+
varags[i] = null;
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
return varags;
|
|
994
|
+
};
|
|
995
|
+
var Element = (value) => {
|
|
996
|
+
$AssertInit(value);
|
|
997
|
+
if (!isVmConst(value)) return null;
|
|
998
|
+
return value;
|
|
999
|
+
};
|
|
1000
|
+
var ElementOpt = (key, value) => {
|
|
1001
|
+
$AssertInit(value);
|
|
1002
|
+
if (value == null || !isVmConst(value)) return {};
|
|
1003
|
+
return { [key]: value };
|
|
1004
|
+
};
|
|
1005
|
+
var Function2 = (fn, name = VM_FUNCTION_ANONYMOUS_NAME) => {
|
|
1006
|
+
defineProperty(fn, "name", { value: name });
|
|
1007
|
+
return VmFunction(fn, { isLib: false, injectCp: false });
|
|
1008
|
+
};
|
|
1009
|
+
var Upvalue = (value) => {
|
|
1010
|
+
$AssertInit(value);
|
|
1011
|
+
return value;
|
|
1012
|
+
};
|
|
1013
|
+
var assertArrayLength = (start, end) => {
|
|
1014
|
+
if (end - start > VM_ARRAY_MAX_LENGTH) {
|
|
1015
|
+
throw new RangeError(`Array length exceeds maximum limit of ${VM_ARRAY_MAX_LENGTH}`);
|
|
1016
|
+
}
|
|
1017
|
+
};
|
|
1018
|
+
var isEmptyRange = (start, end) => {
|
|
1019
|
+
return !isFinite(start) || !isFinite(end) || start > end;
|
|
1020
|
+
};
|
|
1021
|
+
var ArrayRange = (start, end) => {
|
|
1022
|
+
const s = $ToNumber(start);
|
|
1023
|
+
const e = $ToNumber(end);
|
|
1024
|
+
if (isEmptyRange(s, e)) return [];
|
|
1025
|
+
assertArrayLength(s, e);
|
|
1026
|
+
const arr = [];
|
|
1027
|
+
for (let i = s; i <= e; i++) {
|
|
1028
|
+
arr.push(i);
|
|
1029
|
+
}
|
|
1030
|
+
return arr;
|
|
1031
|
+
};
|
|
1032
|
+
var ArrayRangeExclusive = (start, end) => {
|
|
1033
|
+
const s = $ToNumber(start);
|
|
1034
|
+
const e = $ToNumber(end);
|
|
1035
|
+
if (isEmptyRange(s, e)) return [];
|
|
1036
|
+
assertArrayLength(s, e);
|
|
1037
|
+
const arr = [];
|
|
1038
|
+
for (let i = s; i < e; i++) {
|
|
1039
|
+
arr.push(i);
|
|
1040
|
+
}
|
|
1041
|
+
return arr;
|
|
1042
|
+
};
|
|
1043
|
+
function GlobalFallback() {
|
|
1044
|
+
return DefaultVmContext;
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
// src/vm/env.ts
|
|
1048
|
+
var keys2 = [];
|
|
1049
|
+
var values2 = [];
|
|
1050
|
+
for (const [key, value] of entries(operations_exports)) {
|
|
1051
|
+
keys2.push(key);
|
|
1052
|
+
values2.push(value);
|
|
1053
|
+
}
|
|
1054
|
+
for (const [key, value] of entries(helpers_exports)) {
|
|
1055
|
+
keys2.push(key);
|
|
1056
|
+
values2.push(value);
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
// src/compiler/create-script.ts
|
|
1060
|
+
function wrapScript(source, script) {
|
|
1061
|
+
if (kVmScript in script) {
|
|
1062
|
+
return script;
|
|
1063
|
+
}
|
|
1064
|
+
defineProperty(script, "name", { value: VM_SCRIPT_NAME });
|
|
1065
|
+
defineProperty(script, kVmScript, { value: true });
|
|
1066
|
+
if (typeof source === "string") {
|
|
1067
|
+
defineProperty(script, "source", { value: source, configurable: true });
|
|
1068
|
+
} else if (source instanceof Uint8Array) {
|
|
1069
|
+
defineProperty(script, "source", { value: "<buffer>", configurable: true });
|
|
1070
|
+
}
|
|
1071
|
+
return script;
|
|
1072
|
+
}
|
|
1073
|
+
function createScript(source, code) {
|
|
1074
|
+
let script;
|
|
1075
|
+
try {
|
|
1076
|
+
script = new Function(...keys2, code)(...values2);
|
|
1077
|
+
} catch (error) {
|
|
1078
|
+
throw new Error(`Failed to create script`, { cause: error });
|
|
1079
|
+
}
|
|
1080
|
+
return wrapScript(source, script);
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
// src/compiler/compile-fast.ts
|
|
1084
|
+
var REG_NUMBER_FULL = /^\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
|
|
1085
|
+
var REG_IDENTIFIER_FAST = /^(?:\$+|@+)[a-zA-Z0-9_]*$/;
|
|
1086
|
+
var FAST_SCRIPT_MAX_LEN = 32;
|
|
1087
|
+
function compileScriptFast(code, options) {
|
|
1088
|
+
if (code.length > FAST_SCRIPT_MAX_LEN) return void 0;
|
|
1089
|
+
const trimmedCode = code.trim();
|
|
1090
|
+
if (!trimmedCode) {
|
|
1091
|
+
return wrapScript(code, () => null);
|
|
1092
|
+
}
|
|
1093
|
+
switch (trimmedCode) {
|
|
1094
|
+
case "nil":
|
|
1095
|
+
return wrapScript(code, () => null);
|
|
1096
|
+
case "true":
|
|
1097
|
+
return wrapScript(code, () => true);
|
|
1098
|
+
case "false":
|
|
1099
|
+
return wrapScript(code, () => false);
|
|
1100
|
+
case "nan":
|
|
1101
|
+
return wrapScript(code, () => 0 / 0);
|
|
1102
|
+
case "inf":
|
|
1103
|
+
case "+inf":
|
|
1104
|
+
return wrapScript(code, () => 1 / 0);
|
|
1105
|
+
case "-inf":
|
|
1106
|
+
return wrapScript(code, () => -1 / 0);
|
|
1107
|
+
}
|
|
1108
|
+
if (REG_IDENTIFIER_FAST.test(trimmedCode)) {
|
|
1109
|
+
const id = trimmedCode;
|
|
1110
|
+
return wrapScript(code, (global = GlobalFallback()) => global.get(id));
|
|
1111
|
+
}
|
|
1112
|
+
if (REG_NUMBER_FULL.test(trimmedCode)) {
|
|
1113
|
+
const num2 = Number(trimmedCode);
|
|
1114
|
+
if (!isFinite(num2)) return void 0;
|
|
1115
|
+
return wrapScript(code, () => num2);
|
|
1116
|
+
}
|
|
1117
|
+
return void 0;
|
|
1118
|
+
}
|
|
1119
|
+
var FAST_TEMPLATE_MAX_LEN = 1024;
|
|
1120
|
+
function compileTemplateFast(code, options) {
|
|
1121
|
+
if (code.length > FAST_TEMPLATE_MAX_LEN) return void 0;
|
|
1122
|
+
if (!code.includes("$")) {
|
|
1123
|
+
return wrapScript(code, () => code);
|
|
1124
|
+
}
|
|
1125
|
+
return void 0;
|
|
1126
|
+
}
|
|
1127
|
+
function compileFast(code, options) {
|
|
1128
|
+
if (options.sourceMap) return void 0;
|
|
1129
|
+
return (options.input_mode === "Template" ? compileTemplateFast : compileScriptFast)(code, options);
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
// src/compiler/worker-manager.ts
|
|
1133
|
+
var worker;
|
|
1134
|
+
async function getWorker() {
|
|
1135
|
+
if (worker) return worker;
|
|
1136
|
+
worker = new Promise((resolve, reject) => {
|
|
1137
|
+
const w = new Worker(new URL("#compiler/worker", import.meta.url), {
|
|
1138
|
+
type: "module",
|
|
1139
|
+
name: "@mirascript/compiler"
|
|
1140
|
+
});
|
|
1141
|
+
const onError = (e) => {
|
|
1142
|
+
cleanUp();
|
|
1143
|
+
reject(new Error(`Worker failed to start: ${e.message}`));
|
|
1144
|
+
};
|
|
1145
|
+
const onMessage = (e) => {
|
|
1146
|
+
if (e.data === "ready") {
|
|
1147
|
+
cleanUp();
|
|
1148
|
+
resolve(w);
|
|
1149
|
+
} else if (e.data instanceof Error) {
|
|
1150
|
+
cleanUp();
|
|
1151
|
+
reject(e.data);
|
|
1152
|
+
}
|
|
1153
|
+
};
|
|
1154
|
+
w.addEventListener("error", onError);
|
|
1155
|
+
w.addEventListener("message", onMessage);
|
|
1156
|
+
const cleanUp = () => {
|
|
1157
|
+
w.removeEventListener("error", onError);
|
|
1158
|
+
w.removeEventListener("message", onMessage);
|
|
1159
|
+
};
|
|
1160
|
+
setTimeout(() => {
|
|
1161
|
+
onError(new ErrorEvent("error", { message: "Worker did not respond in time" }));
|
|
1162
|
+
}, 3e4);
|
|
1163
|
+
});
|
|
1164
|
+
return worker;
|
|
1165
|
+
}
|
|
1166
|
+
async function compileWorker(...args) {
|
|
1167
|
+
const worker2 = await getWorker();
|
|
1168
|
+
const seq = Math.random();
|
|
1169
|
+
worker2.postMessage([seq, ...args]);
|
|
1170
|
+
return await new Promise((resolve, reject) => {
|
|
1171
|
+
const callback = (ev) => {
|
|
1172
|
+
const data = ev.data;
|
|
1173
|
+
if (!Array.isArray(data)) return;
|
|
1174
|
+
const [retSeq, ...rest] = data;
|
|
1175
|
+
if (seq !== retSeq) return;
|
|
1176
|
+
worker2.removeEventListener("message", callback);
|
|
1177
|
+
if (rest.length === 2) {
|
|
1178
|
+
resolve(rest);
|
|
1179
|
+
} else {
|
|
1180
|
+
reject(rest[0]);
|
|
1181
|
+
}
|
|
1182
|
+
};
|
|
1183
|
+
worker2.addEventListener("message", callback);
|
|
1184
|
+
});
|
|
1185
|
+
}
|
|
1186
|
+
|
|
1187
|
+
// src/compiler/index.ts
|
|
1188
|
+
await loadModule();
|
|
1189
|
+
var WORKER_MIN_LEN = typeof Worker != "function" ? Number.MAX_VALUE : 1024;
|
|
1190
|
+
function reportDiagnostic(source, diagnostics, fileName) {
|
|
1191
|
+
const parsed = parseDiagnostics(source, diagnostics);
|
|
1192
|
+
const messages = formatDiagnostics(parsed.errors, source, fileName);
|
|
1193
|
+
throw new Error(`Failed to compile:
|
|
1194
|
+
${messages.join("\n")}`);
|
|
1195
|
+
}
|
|
1196
|
+
function emitScript(source, [code, diagnostics], options) {
|
|
1197
|
+
if (!code) {
|
|
1198
|
+
reportDiagnostic(source, diagnostics, options.fileName);
|
|
1199
|
+
}
|
|
1200
|
+
const sourcemaps = options.sourceMap ? parseDiagnostics(source, diagnostics, (c) => c === DiagnosticCode.SourceMap).sourcemaps : [];
|
|
1201
|
+
const target = emit(source, code, sourcemaps, options);
|
|
1202
|
+
return createScript(source, target);
|
|
1203
|
+
}
|
|
1204
|
+
async function compile(source, options = {}) {
|
|
1205
|
+
if (options.sourceMap) {
|
|
1206
|
+
options.diagnostic_sourcemap = true;
|
|
1207
|
+
options.diagnostic_position_encoding ??= "Utf16";
|
|
1208
|
+
}
|
|
1209
|
+
if (typeof source == "string") {
|
|
1210
|
+
const result = compileFast(source, options);
|
|
1211
|
+
if (result) return result;
|
|
1212
|
+
}
|
|
1213
|
+
if (source.length < WORKER_MIN_LEN) {
|
|
1214
|
+
const bc = await generateBytecode(source, options);
|
|
1215
|
+
return emitScript(source, bc, options);
|
|
1216
|
+
}
|
|
1217
|
+
const [target, diagnostics] = await compileWorker(source, options);
|
|
1218
|
+
if (target == null) {
|
|
1219
|
+
reportDiagnostic(source, diagnostics, options.fileName);
|
|
1220
|
+
}
|
|
1221
|
+
return createScript(source, target);
|
|
1222
|
+
}
|
|
1223
|
+
function compileSync(source, options = {}) {
|
|
1224
|
+
if (typeof source == "string") {
|
|
1225
|
+
const result = compileFast(source, options);
|
|
1226
|
+
if (result) return result;
|
|
1227
|
+
}
|
|
1228
|
+
const bc = generateBytecodeSync(source, options);
|
|
1229
|
+
return emitScript(source, bc, options);
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
// src/vm/types/module.ts
|
|
1233
|
+
var VmModule = class extends VmWrapper {
|
|
1234
|
+
constructor(name, value) {
|
|
1235
|
+
super(value);
|
|
1236
|
+
this.name = name;
|
|
1237
|
+
}
|
|
1238
|
+
/** @inheritdoc */
|
|
1239
|
+
has(key) {
|
|
1240
|
+
return hasOwnEnumerable(this.value, key);
|
|
1241
|
+
}
|
|
1242
|
+
/** @inheritdoc */
|
|
1243
|
+
get(key) {
|
|
1244
|
+
if (!this.has(key)) return void 0;
|
|
1245
|
+
return this.value[key] ?? null;
|
|
1246
|
+
}
|
|
1247
|
+
/** @inheritdoc */
|
|
1248
|
+
keys() {
|
|
1249
|
+
return keys(this.value);
|
|
1250
|
+
}
|
|
1251
|
+
/** @inheritdoc */
|
|
1252
|
+
same(other) {
|
|
1253
|
+
return this === other;
|
|
1254
|
+
}
|
|
1255
|
+
/** @inheritdoc */
|
|
1256
|
+
get type() {
|
|
1257
|
+
return "module";
|
|
1258
|
+
}
|
|
1259
|
+
/** @inheritdoc */
|
|
1260
|
+
get describe() {
|
|
1261
|
+
return this.name;
|
|
1262
|
+
}
|
|
1263
|
+
};
|
|
1264
|
+
Object.defineProperty(VmModule.prototype, kVmModule, { value: true });
|
|
74
1265
|
|
|
75
1266
|
// src/vm/lib/global/index.ts
|
|
76
1267
|
var global_exports = {};
|
|
77
1268
|
__export(global_exports, {
|
|
78
1269
|
"@e": () => E,
|
|
79
1270
|
"@pi": () => PI,
|
|
80
|
-
abs: () =>
|
|
1271
|
+
abs: () => abs2,
|
|
81
1272
|
acos: () => acos,
|
|
82
1273
|
acosh: () => acosh,
|
|
83
1274
|
all: () => all,
|
|
@@ -92,7 +1283,7 @@ __export(global_exports, {
|
|
|
92
1283
|
b_or: () => b_or,
|
|
93
1284
|
b_xor: () => b_xor,
|
|
94
1285
|
cbrt: () => cbrt,
|
|
95
|
-
ceil: () =>
|
|
1286
|
+
ceil: () => ceil2,
|
|
96
1287
|
chars: () => chars,
|
|
97
1288
|
contains: () => contains,
|
|
98
1289
|
cos: () => cos,
|
|
@@ -112,16 +1303,15 @@ __export(global_exports, {
|
|
|
112
1303
|
from_json: () => from_json,
|
|
113
1304
|
hypot: () => hypot,
|
|
114
1305
|
join: () => join,
|
|
115
|
-
keys: () =>
|
|
1306
|
+
keys: () => keys3,
|
|
116
1307
|
len: () => len,
|
|
117
1308
|
log: () => log,
|
|
118
1309
|
log10: () => log10,
|
|
119
1310
|
log1p: () => log1p,
|
|
120
1311
|
log2: () => log2,
|
|
121
1312
|
map: () => map2,
|
|
122
|
-
matrix: () => matrix,
|
|
123
1313
|
max: () => max,
|
|
124
|
-
min: () =>
|
|
1314
|
+
min: () => min2,
|
|
125
1315
|
panic: () => panic,
|
|
126
1316
|
pow: () => pow2,
|
|
127
1317
|
product: () => product,
|
|
@@ -154,22 +1344,31 @@ __export(global_exports, {
|
|
|
154
1344
|
trim: () => trim,
|
|
155
1345
|
trim_end: () => trim_end,
|
|
156
1346
|
trim_start: () => trim_start,
|
|
157
|
-
trunc: () =>
|
|
158
|
-
values: () =>
|
|
1347
|
+
trunc: () => trunc2,
|
|
1348
|
+
values: () => values3,
|
|
159
1349
|
with: () => _with,
|
|
160
1350
|
zip: () => zip
|
|
161
1351
|
});
|
|
162
1352
|
|
|
163
|
-
// src/vm/lib/
|
|
1353
|
+
// src/vm/lib/helpers.ts
|
|
164
1354
|
function throwError(message, recovered) {
|
|
165
1355
|
const recoveredValue = typeof recovered === "function" && !isVmFunction(recovered) ? recovered() : recovered;
|
|
166
1356
|
throw new VmError(message, recoveredValue);
|
|
167
1357
|
}
|
|
1358
|
+
function describeParam(name) {
|
|
1359
|
+
if (name == null) return "Value";
|
|
1360
|
+
if (typeof name == "string") {
|
|
1361
|
+
if (!name) return "Argument";
|
|
1362
|
+
return `Argument '${name}'`;
|
|
1363
|
+
}
|
|
1364
|
+
const pos = name <= 0 ? "first" : name <= 1 ? "second" : `${name + 1}th`;
|
|
1365
|
+
return `Argument at the ${pos} position`;
|
|
1366
|
+
}
|
|
168
1367
|
function throwUnexpectedTypeError(name, expected, value, recovered) {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
throwError(
|
|
1368
|
+
throwError(`${describeParam(name)} is not ${expected}: ${display(value)}`, recovered);
|
|
1369
|
+
}
|
|
1370
|
+
function throwUnconvertedTypeError(name, expected, value, recovered) {
|
|
1371
|
+
throwError(`${describeParam(name)} cannot be converted to ${expected}: ${display(value)}`, recovered);
|
|
173
1372
|
}
|
|
174
1373
|
function rethrowError(prefix, error, recovered) {
|
|
175
1374
|
const recoveredValue = typeof recovered === "function" && !isVmFunction(recovered) ? recovered() : recovered;
|
|
@@ -177,10 +1376,49 @@ function rethrowError(prefix, error, recovered) {
|
|
|
177
1376
|
}
|
|
178
1377
|
function required(name, value, recovered) {
|
|
179
1378
|
if (value === void 0) {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
1379
|
+
throwError(`${describeParam(name)} is required`, recovered);
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
function expectNumber(name, value) {
|
|
1383
|
+
required(name, value, Number.NaN);
|
|
1384
|
+
const v = toNumber(value, null);
|
|
1385
|
+
if (v == null) {
|
|
1386
|
+
throwUnconvertedTypeError(name, "number", value, Number.NaN);
|
|
183
1387
|
}
|
|
1388
|
+
return v;
|
|
1389
|
+
}
|
|
1390
|
+
function expectNumberRange(name, value, min3, max2) {
|
|
1391
|
+
const v = expectNumber(name, value);
|
|
1392
|
+
if (!isFinite(v)) {
|
|
1393
|
+
throwError(`${describeParam(name)} is not a finite number: ${display(value)}`, Number.NaN);
|
|
1394
|
+
}
|
|
1395
|
+
if (v < min3) {
|
|
1396
|
+
throwError(`${describeParam(name)} is less than minimum value ${min3}: ${display(value)}`, min3);
|
|
1397
|
+
}
|
|
1398
|
+
if (v > max2) {
|
|
1399
|
+
throwError(`${describeParam(name)} is greater than maximum value ${max2}: ${display(value)}`, max2);
|
|
1400
|
+
}
|
|
1401
|
+
return v;
|
|
1402
|
+
}
|
|
1403
|
+
function expectInteger(name, value) {
|
|
1404
|
+
required(name, value, 0);
|
|
1405
|
+
const v = toNumber(value, null);
|
|
1406
|
+
if (v == null) {
|
|
1407
|
+
throwUnconvertedTypeError(name, "integer", value, 0);
|
|
1408
|
+
}
|
|
1409
|
+
const i = Math.trunc(v);
|
|
1410
|
+
if (!isSafeInteger(i)) {
|
|
1411
|
+
throwUnconvertedTypeError(name, "integer", value, 0);
|
|
1412
|
+
}
|
|
1413
|
+
return i;
|
|
1414
|
+
}
|
|
1415
|
+
function expectString(name, value) {
|
|
1416
|
+
required(name, value, "");
|
|
1417
|
+
const v = toString(value, null);
|
|
1418
|
+
if (v == null) {
|
|
1419
|
+
throwUnconvertedTypeError(name, "string", value, "");
|
|
1420
|
+
}
|
|
1421
|
+
return v;
|
|
184
1422
|
}
|
|
185
1423
|
function expectArray(name, value, recovered) {
|
|
186
1424
|
required(name, value, recovered);
|
|
@@ -214,18 +1452,25 @@ function expectCallable(name, value, recovered) {
|
|
|
214
1452
|
}
|
|
215
1453
|
function getNumbers(args) {
|
|
216
1454
|
if (args.length === 0) return [];
|
|
217
|
-
|
|
1455
|
+
let useFirst = false;
|
|
1456
|
+
if (args.length === 1 && isVmArray(args[0])) {
|
|
1457
|
+
args = args[0];
|
|
1458
|
+
useFirst = true;
|
|
1459
|
+
}
|
|
218
1460
|
const numbers = [];
|
|
219
|
-
for (
|
|
220
|
-
|
|
221
|
-
numbers.push($ToNumber(arg));
|
|
1461
|
+
for (let len2 = args.length, i = 0; i < len2; i++) {
|
|
1462
|
+
numbers.push(expectNumber(useFirst ? null : i, args[i]));
|
|
222
1463
|
}
|
|
223
1464
|
return numbers;
|
|
224
1465
|
}
|
|
225
1466
|
function arrayLen(len2) {
|
|
226
|
-
if (len2 == null || isNaN(len2) || len2 <=
|
|
1467
|
+
if (len2 == null || isNaN(len2) || len2 <= -1) {
|
|
1468
|
+
throwError("Array length must be a non-negative integer", null);
|
|
1469
|
+
}
|
|
227
1470
|
len2 = Math.trunc(len2);
|
|
228
|
-
if (len2 > VM_ARRAY_MAX_LENGTH)
|
|
1471
|
+
if (len2 > VM_ARRAY_MAX_LENGTH) {
|
|
1472
|
+
throwError(`Array length exceeds maximum limit of ${VM_ARRAY_MAX_LENGTH}`, null);
|
|
1473
|
+
}
|
|
229
1474
|
return len2;
|
|
230
1475
|
}
|
|
231
1476
|
function map(data, mapper) {
|
|
@@ -281,7 +1526,7 @@ var max = VmLib(build(Math.max), {
|
|
|
281
1526
|
returnsType: "number",
|
|
282
1527
|
examples: ["max(3, 7, 2) // 7"]
|
|
283
1528
|
});
|
|
284
|
-
var
|
|
1529
|
+
var min2 = VmLib(build(Math.min), {
|
|
285
1530
|
summary: "返回一组数中的最小值",
|
|
286
1531
|
params: { "..values": "要比较的数值" },
|
|
287
1532
|
paramsType: { "..values": "number[]" },
|
|
@@ -328,11 +1573,10 @@ var { PI, E } = Math;
|
|
|
328
1573
|
// src/vm/lib/global/math-unary.ts
|
|
329
1574
|
function build2(f) {
|
|
330
1575
|
return (x) => {
|
|
331
|
-
|
|
332
|
-
return f($ToNumber(x));
|
|
1576
|
+
return f(expectNumber("x", x));
|
|
333
1577
|
};
|
|
334
1578
|
}
|
|
335
|
-
var
|
|
1579
|
+
var trunc2 = VmLib(build2(Math.trunc), {
|
|
336
1580
|
summary: "返回数值的整数部分(去除小数)",
|
|
337
1581
|
params: { x: "要取整数部分的数" },
|
|
338
1582
|
paramsType: { x: "number" },
|
|
@@ -344,7 +1588,7 @@ var floor = VmLib(build2(Math.floor), {
|
|
|
344
1588
|
paramsType: { x: "number" },
|
|
345
1589
|
returnsType: "number"
|
|
346
1590
|
});
|
|
347
|
-
var
|
|
1591
|
+
var ceil2 = VmLib(build2(Math.ceil), {
|
|
348
1592
|
summary: "返回大于等于给定数的最小整数",
|
|
349
1593
|
params: { x: "要向上取整的数" },
|
|
350
1594
|
paramsType: { x: "number" },
|
|
@@ -373,7 +1617,7 @@ var sign = VmLib(build2(Math.sign), {
|
|
|
373
1617
|
paramsType: { x: "number" },
|
|
374
1618
|
returnsType: "number"
|
|
375
1619
|
});
|
|
376
|
-
var
|
|
1620
|
+
var abs2 = VmLib(build2(Math.abs), {
|
|
377
1621
|
summary: "返回数值的绝对值",
|
|
378
1622
|
params: { x: "要取绝对值的数" },
|
|
379
1623
|
paramsType: { x: "number" },
|
|
@@ -523,8 +1767,7 @@ var GAMMA_P = [
|
|
|
523
1767
|
var SQRT_2_PI = sqrt2(2 * Math.PI);
|
|
524
1768
|
var factorial = VmLib(
|
|
525
1769
|
(x) => {
|
|
526
|
-
|
|
527
|
-
let n = $ToNumber(x);
|
|
1770
|
+
let n = expectNumber("x", x);
|
|
528
1771
|
if (isNaN(n) || n < 0) return Number.NaN;
|
|
529
1772
|
if (n >= 171) return Number.POSITIVE_INFINITY;
|
|
530
1773
|
if (isInteger(n)) {
|
|
@@ -561,13 +1804,13 @@ var factorial = VmLib(
|
|
|
561
1804
|
|
|
562
1805
|
// src/vm/lib/global/math.ts
|
|
563
1806
|
var { atan2: _atan2, pow: _pow } = Math;
|
|
564
|
-
var atan2 = VmLib((x, y) => _atan2(
|
|
1807
|
+
var atan2 = VmLib((x, y) => _atan2(expectNumber(0, x), expectNumber(1, y)), {
|
|
565
1808
|
summary: "返回从原点到点 (x, y) 的角度(弧度)",
|
|
566
1809
|
params: { x: "x 坐标", y: "y 坐标" },
|
|
567
1810
|
paramsType: { x: "number", y: "number" },
|
|
568
1811
|
returnsType: "number"
|
|
569
1812
|
});
|
|
570
|
-
var pow2 = VmLib((x, y) => _pow(
|
|
1813
|
+
var pow2 = VmLib((x, y) => _pow(expectNumber(0, x), expectNumber(1, y)), {
|
|
571
1814
|
summary: "返回 x 的 y 次幂",
|
|
572
1815
|
params: { x: "底数", y: "指数" },
|
|
573
1816
|
paramsType: { x: "number", y: "number" },
|
|
@@ -583,7 +1826,7 @@ var random = VmLib(Math.random, {
|
|
|
583
1826
|
// src/vm/lib/global/bit.ts
|
|
584
1827
|
var b_and = VmLib(
|
|
585
1828
|
(x, y) => {
|
|
586
|
-
return
|
|
1829
|
+
return expectNumber(0, x) & expectNumber(1, y);
|
|
587
1830
|
},
|
|
588
1831
|
{
|
|
589
1832
|
summary: "返回两个数的按位与",
|
|
@@ -595,7 +1838,7 @@ var b_and = VmLib(
|
|
|
595
1838
|
);
|
|
596
1839
|
var b_or = VmLib(
|
|
597
1840
|
(x, y) => {
|
|
598
|
-
return
|
|
1841
|
+
return expectNumber(0, x) | expectNumber(1, y);
|
|
599
1842
|
},
|
|
600
1843
|
{
|
|
601
1844
|
summary: "返回两个数的按位或",
|
|
@@ -607,7 +1850,7 @@ var b_or = VmLib(
|
|
|
607
1850
|
);
|
|
608
1851
|
var b_not = VmLib(
|
|
609
1852
|
(x) => {
|
|
610
|
-
return
|
|
1853
|
+
return ~expectNumber("x", x);
|
|
611
1854
|
},
|
|
612
1855
|
{
|
|
613
1856
|
summary: "返回一个数的按位取反",
|
|
@@ -619,7 +1862,7 @@ var b_not = VmLib(
|
|
|
619
1862
|
);
|
|
620
1863
|
var b_xor = VmLib(
|
|
621
1864
|
(x, y) => {
|
|
622
|
-
return
|
|
1865
|
+
return expectNumber(0, x) ^ expectNumber(1, y);
|
|
623
1866
|
},
|
|
624
1867
|
{
|
|
625
1868
|
summary: "返回两个数的按位异或",
|
|
@@ -631,7 +1874,7 @@ var b_xor = VmLib(
|
|
|
631
1874
|
);
|
|
632
1875
|
var shl = VmLib(
|
|
633
1876
|
(x, y) => {
|
|
634
|
-
return
|
|
1877
|
+
return expectNumber(0, x) << expectNumber(1, y);
|
|
635
1878
|
},
|
|
636
1879
|
{
|
|
637
1880
|
summary: "返回第一个操作数左移指定的位数",
|
|
@@ -643,7 +1886,7 @@ var shl = VmLib(
|
|
|
643
1886
|
);
|
|
644
1887
|
var sar = VmLib(
|
|
645
1888
|
(x, y) => {
|
|
646
|
-
return
|
|
1889
|
+
return expectNumber(0, x) >> expectNumber(1, y);
|
|
647
1890
|
},
|
|
648
1891
|
{
|
|
649
1892
|
summary: "返回第一个操作数右移指定的位数",
|
|
@@ -655,7 +1898,7 @@ var sar = VmLib(
|
|
|
655
1898
|
);
|
|
656
1899
|
var shr = VmLib(
|
|
657
1900
|
(x, y) => {
|
|
658
|
-
return
|
|
1901
|
+
return expectNumber(0, x) >>> expectNumber(1, y);
|
|
659
1902
|
},
|
|
660
1903
|
{
|
|
661
1904
|
summary: "返回第一个操作数无符号右移指定的位数",
|
|
@@ -668,12 +1911,19 @@ var shr = VmLib(
|
|
|
668
1911
|
|
|
669
1912
|
// src/vm/lib/global/sequence/with.ts
|
|
670
1913
|
var arrIndex = (index) => {
|
|
671
|
-
const idx = Math.trunc(
|
|
672
|
-
if (
|
|
673
|
-
|
|
1914
|
+
const idx = Math.trunc(toNumber(index, Number.NaN));
|
|
1915
|
+
if (isNaN(idx) || idx < 0) {
|
|
1916
|
+
throwError("Array index must be a non-negative integer", index);
|
|
1917
|
+
}
|
|
1918
|
+
if (idx >= VM_ARRAY_MAX_LENGTH) {
|
|
1919
|
+
throwError(`Array index exceeds maximum limit of ${VM_ARRAY_MAX_LENGTH}`, index);
|
|
674
1920
|
}
|
|
675
1921
|
return idx;
|
|
676
1922
|
};
|
|
1923
|
+
var isArrIndex = (key) => {
|
|
1924
|
+
if (typeof key != "number") return false;
|
|
1925
|
+
return isInteger(key) && key >= 0 && key < VM_ARRAY_MAX_LENGTH;
|
|
1926
|
+
};
|
|
677
1927
|
var withInner = (obj, key, keyIndex, value) => {
|
|
678
1928
|
if (keyIndex >= key.length) {
|
|
679
1929
|
return value;
|
|
@@ -684,7 +1934,7 @@ var withInner = (obj, key, keyIndex, value) => {
|
|
|
684
1934
|
result = [...obj];
|
|
685
1935
|
} else if (isVmRecord(obj)) {
|
|
686
1936
|
result = { ...obj };
|
|
687
|
-
} else if (
|
|
1937
|
+
} else if (isArrIndex(k)) {
|
|
688
1938
|
result = [];
|
|
689
1939
|
} else {
|
|
690
1940
|
result = {};
|
|
@@ -696,7 +1946,7 @@ var withInner = (obj, key, keyIndex, value) => {
|
|
|
696
1946
|
}
|
|
697
1947
|
result[index] = withInner(result[index], key, keyIndex + 1, value);
|
|
698
1948
|
} else {
|
|
699
|
-
const prop =
|
|
1949
|
+
const prop = toString(k, void 0);
|
|
700
1950
|
result[prop] = withInner(result[prop], key, keyIndex + 1, value);
|
|
701
1951
|
}
|
|
702
1952
|
return result;
|
|
@@ -738,11 +1988,9 @@ var _with = VmLib(
|
|
|
738
1988
|
let val;
|
|
739
1989
|
if (isVmArray(key)) {
|
|
740
1990
|
index = arrIndex(key[0]);
|
|
741
|
-
if (index < 0) continue;
|
|
742
1991
|
val = withInner(result[index], key, 1, value);
|
|
743
1992
|
} else {
|
|
744
1993
|
index = arrIndex(key);
|
|
745
|
-
if (index < 0) continue;
|
|
746
1994
|
val = value;
|
|
747
1995
|
}
|
|
748
1996
|
while (index > result.length) {
|
|
@@ -758,10 +2006,10 @@ var _with = VmLib(
|
|
|
758
2006
|
let val;
|
|
759
2007
|
if (isVmArray(key)) {
|
|
760
2008
|
const firstKey = key[0];
|
|
761
|
-
prop =
|
|
2009
|
+
prop = toString(firstKey, void 0);
|
|
762
2010
|
val = withInner(result[prop], key, 1, value);
|
|
763
2011
|
} else {
|
|
764
|
-
prop =
|
|
2012
|
+
prop = toString(key, void 0);
|
|
765
2013
|
val = value;
|
|
766
2014
|
}
|
|
767
2015
|
result[prop] = val;
|
|
@@ -788,7 +2036,7 @@ var _with = VmLib(
|
|
|
788
2036
|
);
|
|
789
2037
|
|
|
790
2038
|
// src/vm/lib/global/sequence/entries.ts
|
|
791
|
-
var
|
|
2039
|
+
var keys3 = VmLib(
|
|
792
2040
|
(data) => {
|
|
793
2041
|
expectCompound("data", data, []);
|
|
794
2042
|
if (isVmArray(data)) {
|
|
@@ -812,7 +2060,7 @@ var keys2 = VmLib(
|
|
|
812
2060
|
examples: ["keys([10, 20]) // [0, 1]", 'keys((10, 20)) // ["0", "1"]']
|
|
813
2061
|
}
|
|
814
2062
|
);
|
|
815
|
-
var
|
|
2063
|
+
var values3 = VmLib(
|
|
816
2064
|
(data) => {
|
|
817
2065
|
expectArrayOrRecord("data", data, []);
|
|
818
2066
|
if (isVmArray(data)) {
|
|
@@ -894,7 +2142,7 @@ var map2 = VmLib(
|
|
|
894
2142
|
var filter = VmLib(
|
|
895
2143
|
(data, predicate) => mapImplWrapped(data, "predicate", predicate, (fn, value, key, data2) => {
|
|
896
2144
|
const ret = $Call(fn, [value, key, data2]);
|
|
897
|
-
return
|
|
2145
|
+
return toBoolean(ret, void 0) ? value : void 0;
|
|
898
2146
|
}),
|
|
899
2147
|
{
|
|
900
2148
|
summary: "过滤数组或记录中的元素,返回满足条件的元素",
|
|
@@ -937,7 +2185,7 @@ var find = VmLib(
|
|
|
937
2185
|
required("predicate", predicate, null);
|
|
938
2186
|
const p = isVmCallable(predicate) ? (value, key, data2) => {
|
|
939
2187
|
const ret = $Call(predicate, [value, key, data2]);
|
|
940
|
-
return
|
|
2188
|
+
return toBoolean(ret, void 0);
|
|
941
2189
|
} : (value) => $Same(predicate, value);
|
|
942
2190
|
if (isVmArray(data)) {
|
|
943
2191
|
const { length } = data;
|
|
@@ -979,7 +2227,7 @@ var find = VmLib(
|
|
|
979
2227
|
var flatten = VmLib(
|
|
980
2228
|
(data, depth = 1) => {
|
|
981
2229
|
expectArray("data", data, data);
|
|
982
|
-
return data.flat(
|
|
2230
|
+
return data.flat(expectNumber("depth", depth));
|
|
983
2231
|
},
|
|
984
2232
|
{
|
|
985
2233
|
summary: "将数组扁平化",
|
|
@@ -1014,7 +2262,7 @@ var zip = VmLib(
|
|
|
1014
2262
|
let len2 = 0;
|
|
1015
2263
|
for (const { 0: key, 1: arr } of ets) {
|
|
1016
2264
|
if (!isVmArray(arr)) {
|
|
1017
|
-
throwError(`data[${
|
|
2265
|
+
throwError(`data[${display(key)}] is not an array: ${display(arr)}`, null);
|
|
1018
2266
|
}
|
|
1019
2267
|
len2 = Math.max(len2, arr.length);
|
|
1020
2268
|
}
|
|
@@ -1053,7 +2301,7 @@ var all = VmLib(
|
|
|
1053
2301
|
Cp();
|
|
1054
2302
|
const value = data[i] ?? null;
|
|
1055
2303
|
const ret = $Call(predicate, [value, i, data]);
|
|
1056
|
-
if (
|
|
2304
|
+
if (!toBoolean(ret, void 0)) return false;
|
|
1057
2305
|
}
|
|
1058
2306
|
return true;
|
|
1059
2307
|
} else {
|
|
@@ -1061,7 +2309,7 @@ var all = VmLib(
|
|
|
1061
2309
|
Cp();
|
|
1062
2310
|
const value = v ?? null;
|
|
1063
2311
|
const ret = $Call(predicate, [value, key, data]);
|
|
1064
|
-
if (
|
|
2312
|
+
if (!toBoolean(ret, void 0)) return false;
|
|
1065
2313
|
}
|
|
1066
2314
|
return true;
|
|
1067
2315
|
}
|
|
@@ -1086,7 +2334,7 @@ var any = VmLib(
|
|
|
1086
2334
|
Cp();
|
|
1087
2335
|
const value = data[i] ?? null;
|
|
1088
2336
|
const ret = $Call(predicate, [value, i, data]);
|
|
1089
|
-
if (
|
|
2337
|
+
if (toBoolean(ret, void 0)) return true;
|
|
1090
2338
|
}
|
|
1091
2339
|
return false;
|
|
1092
2340
|
} else {
|
|
@@ -1094,7 +2342,7 @@ var any = VmLib(
|
|
|
1094
2342
|
Cp();
|
|
1095
2343
|
const value = v ?? null;
|
|
1096
2344
|
const ret = $Call(predicate, [value, key, data]);
|
|
1097
|
-
if (
|
|
2345
|
+
if (toBoolean(ret, void 0)) return true;
|
|
1098
2346
|
}
|
|
1099
2347
|
return false;
|
|
1100
2348
|
}
|
|
@@ -1121,8 +2369,8 @@ function defaultCompare(a = null, b = null) {
|
|
|
1121
2369
|
if (a > b) return 1;
|
|
1122
2370
|
return 0;
|
|
1123
2371
|
}
|
|
1124
|
-
const an =
|
|
1125
|
-
const bn =
|
|
2372
|
+
const an = toNumber(a, 0) || 0;
|
|
2373
|
+
const bn = toNumber(b, 0) || 0;
|
|
1126
2374
|
if (an < bn) return -1;
|
|
1127
2375
|
if (an > bn) return 1;
|
|
1128
2376
|
return 0;
|
|
@@ -1132,7 +2380,7 @@ function cmp(comparator, recovered) {
|
|
|
1132
2380
|
expectCallable("comparator", comparator, recovered);
|
|
1133
2381
|
return (a = null, b = null) => {
|
|
1134
2382
|
const ret = $Call(comparator, [a, b]);
|
|
1135
|
-
return
|
|
2383
|
+
return toNumber(ret, 0);
|
|
1136
2384
|
};
|
|
1137
2385
|
}
|
|
1138
2386
|
var sort = VmLib(
|
|
@@ -1198,8 +2446,7 @@ var sort_by = VmLib(
|
|
|
1198
2446
|
var repeat = VmLib(
|
|
1199
2447
|
(data, times) => {
|
|
1200
2448
|
expectConst("data", data, []);
|
|
1201
|
-
|
|
1202
|
-
const n = arrayLen($ToNumber(times));
|
|
2449
|
+
const n = arrayLen(expectNumber("times", times));
|
|
1203
2450
|
const result = [];
|
|
1204
2451
|
result.length = n;
|
|
1205
2452
|
result.fill(data);
|
|
@@ -1241,7 +2488,8 @@ var panic = VmLib(
|
|
|
1241
2488
|
(message) => {
|
|
1242
2489
|
if (message === void 0) console.error(...panic.prefix);
|
|
1243
2490
|
else console.error(...panic.prefix, message);
|
|
1244
|
-
const
|
|
2491
|
+
const mgsStr = toString(message, null);
|
|
2492
|
+
const error = !mgsStr ? "panic" : "panic: " + mgsStr;
|
|
1245
2493
|
throw new VmError(error, void 0);
|
|
1246
2494
|
},
|
|
1247
2495
|
{
|
|
@@ -1299,7 +2547,7 @@ var from_json = VmLib(
|
|
|
1299
2547
|
try {
|
|
1300
2548
|
return parse(json);
|
|
1301
2549
|
} catch (ex) {
|
|
1302
|
-
if (fallback
|
|
2550
|
+
if (fallback !== void 0) return fallback;
|
|
1303
2551
|
rethrowError("Invalid JSON", ex, null);
|
|
1304
2552
|
}
|
|
1305
2553
|
},
|
|
@@ -1314,48 +2562,57 @@ var from_json = VmLib(
|
|
|
1314
2562
|
|
|
1315
2563
|
// src/vm/lib/global/to-primitive.ts
|
|
1316
2564
|
var to_string = VmLib(
|
|
1317
|
-
(data) => {
|
|
2565
|
+
(data, fallback) => {
|
|
1318
2566
|
required("data", data, "");
|
|
1319
|
-
return
|
|
2567
|
+
return toString(data, fallback);
|
|
1320
2568
|
},
|
|
1321
2569
|
{
|
|
1322
2570
|
summary: "将数据转换为字符串",
|
|
1323
|
-
params: {
|
|
1324
|
-
|
|
1325
|
-
|
|
2571
|
+
params: {
|
|
2572
|
+
data: "要转换的数据",
|
|
2573
|
+
fallback: "转换失败时的返回值"
|
|
2574
|
+
},
|
|
2575
|
+
paramsType: { data: "any", fallback: "any" },
|
|
2576
|
+
returnsType: "string | type(fallback)",
|
|
1326
2577
|
examples: ['to_string([1, 2]) // "1, 2"']
|
|
1327
2578
|
}
|
|
1328
2579
|
);
|
|
1329
2580
|
var to_number = VmLib(
|
|
1330
|
-
(data) => {
|
|
2581
|
+
(data, fallback) => {
|
|
1331
2582
|
required("data", data, Number.NaN);
|
|
1332
|
-
return
|
|
2583
|
+
return toNumber(data, fallback);
|
|
1333
2584
|
},
|
|
1334
2585
|
{
|
|
1335
2586
|
summary: "将数据转换为数字",
|
|
1336
|
-
params: {
|
|
1337
|
-
|
|
1338
|
-
|
|
2587
|
+
params: {
|
|
2588
|
+
data: "要转换的数据",
|
|
2589
|
+
fallback: "转换失败时的返回值"
|
|
2590
|
+
},
|
|
2591
|
+
paramsType: { data: "any", fallback: "any" },
|
|
2592
|
+
returnsType: "number | type(fallback)",
|
|
1339
2593
|
examples: ['to_number("1.5") // 1.5']
|
|
1340
2594
|
}
|
|
1341
2595
|
);
|
|
1342
2596
|
var to_boolean = VmLib(
|
|
1343
|
-
(data) => {
|
|
2597
|
+
(data, fallback) => {
|
|
1344
2598
|
required("data", data, false);
|
|
1345
|
-
return
|
|
2599
|
+
return toBoolean(data, fallback);
|
|
1346
2600
|
},
|
|
1347
2601
|
{
|
|
1348
2602
|
summary: "将数据转换为布尔值",
|
|
1349
|
-
params: {
|
|
1350
|
-
|
|
1351
|
-
|
|
2603
|
+
params: {
|
|
2604
|
+
data: "要转换的数据",
|
|
2605
|
+
fallback: "转换失败时的返回值"
|
|
2606
|
+
},
|
|
2607
|
+
paramsType: { data: "any", fallback: "any" },
|
|
2608
|
+
returnsType: "boolean | type(fallback)",
|
|
1352
2609
|
examples: ["to_boolean(nil) // false"]
|
|
1353
2610
|
}
|
|
1354
2611
|
);
|
|
1355
2612
|
var format = VmLib(
|
|
1356
2613
|
(data, format2) => {
|
|
1357
2614
|
required("data", data, "");
|
|
1358
|
-
return
|
|
2615
|
+
return toFormat(data, expectString("format", format2));
|
|
1359
2616
|
},
|
|
1360
2617
|
{
|
|
1361
2618
|
summary: "将数据格式化为指定格式的字符串",
|
|
@@ -1369,8 +2626,7 @@ var format = VmLib(
|
|
|
1369
2626
|
// src/vm/lib/global/string.ts
|
|
1370
2627
|
var chars = VmLib(
|
|
1371
2628
|
(str) => {
|
|
1372
|
-
|
|
1373
|
-
return [...$ToString(str)];
|
|
2629
|
+
return [...expectString("str", str)];
|
|
1374
2630
|
},
|
|
1375
2631
|
{
|
|
1376
2632
|
summary: "将字符串转换为字符数组",
|
|
@@ -1382,9 +2638,7 @@ var chars = VmLib(
|
|
|
1382
2638
|
);
|
|
1383
2639
|
var starts_with = VmLib(
|
|
1384
2640
|
(str, search) => {
|
|
1385
|
-
|
|
1386
|
-
required("search", search, null);
|
|
1387
|
-
return $ToString(str).startsWith($ToString(search));
|
|
2641
|
+
return expectString("str", str).startsWith(expectString("search", search));
|
|
1388
2642
|
},
|
|
1389
2643
|
{
|
|
1390
2644
|
summary: "检查字符串是否以指定子串开头",
|
|
@@ -1396,9 +2650,7 @@ var starts_with = VmLib(
|
|
|
1396
2650
|
);
|
|
1397
2651
|
var ends_with = VmLib(
|
|
1398
2652
|
(str, search) => {
|
|
1399
|
-
|
|
1400
|
-
required("search", search, null);
|
|
1401
|
-
return $ToString(str).endsWith($ToString(search));
|
|
2653
|
+
return expectString("str", str).endsWith(expectString("search", search));
|
|
1402
2654
|
},
|
|
1403
2655
|
{
|
|
1404
2656
|
summary: "检查字符串是否以指定子串结尾",
|
|
@@ -1410,9 +2662,7 @@ var ends_with = VmLib(
|
|
|
1410
2662
|
);
|
|
1411
2663
|
var contains = VmLib(
|
|
1412
2664
|
(str, search) => {
|
|
1413
|
-
|
|
1414
|
-
required("search", search, null);
|
|
1415
|
-
return $ToString(str).includes($ToString(search));
|
|
2665
|
+
return expectString("str", str).includes(expectString("search", search));
|
|
1416
2666
|
},
|
|
1417
2667
|
{
|
|
1418
2668
|
summary: "检查字符串是否包含指定子串",
|
|
@@ -1424,8 +2674,7 @@ var contains = VmLib(
|
|
|
1424
2674
|
);
|
|
1425
2675
|
var trim_start = VmLib(
|
|
1426
2676
|
(str) => {
|
|
1427
|
-
|
|
1428
|
-
return $ToString(str).trimStart();
|
|
2677
|
+
return expectString("str", str).trimStart();
|
|
1429
2678
|
},
|
|
1430
2679
|
{
|
|
1431
2680
|
summary: "去除字符串开头的空白字符",
|
|
@@ -1437,8 +2686,7 @@ var trim_start = VmLib(
|
|
|
1437
2686
|
);
|
|
1438
2687
|
var trim_end = VmLib(
|
|
1439
2688
|
(str) => {
|
|
1440
|
-
|
|
1441
|
-
return $ToString(str).trimEnd();
|
|
2689
|
+
return expectString("str", str).trimEnd();
|
|
1442
2690
|
},
|
|
1443
2691
|
{
|
|
1444
2692
|
summary: "去除字符串结尾的空白字符",
|
|
@@ -1450,8 +2698,7 @@ var trim_end = VmLib(
|
|
|
1450
2698
|
);
|
|
1451
2699
|
var trim = VmLib(
|
|
1452
2700
|
(str) => {
|
|
1453
|
-
|
|
1454
|
-
return $ToString(str).trim();
|
|
2701
|
+
return expectString("str", str).trim();
|
|
1455
2702
|
},
|
|
1456
2703
|
{
|
|
1457
2704
|
summary: "去除字符串两端的空白字符",
|
|
@@ -1463,9 +2710,10 @@ var trim = VmLib(
|
|
|
1463
2710
|
);
|
|
1464
2711
|
var replace = VmLib(
|
|
1465
2712
|
(str, search, replacement = "") => {
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
2713
|
+
return expectString("str", str).replaceAll(
|
|
2714
|
+
expectString("search", search),
|
|
2715
|
+
expectString("replacement", replacement)
|
|
2716
|
+
);
|
|
1469
2717
|
},
|
|
1470
2718
|
{
|
|
1471
2719
|
summary: "替换字符串中的指定子串",
|
|
@@ -1477,9 +2725,8 @@ var replace = VmLib(
|
|
|
1477
2725
|
);
|
|
1478
2726
|
var split = VmLib(
|
|
1479
2727
|
(str, separator = "") => {
|
|
1480
|
-
|
|
1481
|
-
const
|
|
1482
|
-
const p = $ToString(separator);
|
|
2728
|
+
const s = expectString("str", str);
|
|
2729
|
+
const p = expectString("separator", separator);
|
|
1483
2730
|
if (!p) return [...s];
|
|
1484
2731
|
return s.split(p);
|
|
1485
2732
|
},
|
|
@@ -1494,8 +2741,8 @@ var split = VmLib(
|
|
|
1494
2741
|
var join = VmLib(
|
|
1495
2742
|
(arr, separator = "") => {
|
|
1496
2743
|
expectArray("arr", arr, null);
|
|
1497
|
-
const s =
|
|
1498
|
-
return arr.map((v) =>
|
|
2744
|
+
const s = expectString("separator", separator);
|
|
2745
|
+
return arr.map((v) => expectString(null, v)).join(s);
|
|
1499
2746
|
},
|
|
1500
2747
|
{
|
|
1501
2748
|
summary: "将字符串数组连接为单个字符串",
|
|
@@ -1507,33 +2754,54 @@ var join = VmLib(
|
|
|
1507
2754
|
);
|
|
1508
2755
|
|
|
1509
2756
|
// src/vm/lib/global/time.ts
|
|
2757
|
+
var fromNumber = (datetime, fallback) => {
|
|
2758
|
+
const n = new Date(datetime).getTime();
|
|
2759
|
+
if (isFinite(n)) return n;
|
|
2760
|
+
if (fallback) return null;
|
|
2761
|
+
throwError(`${describeParam("datetime")} is an invalid timestamp: ${display(datetime)}`, Number.NaN);
|
|
2762
|
+
};
|
|
2763
|
+
var getTimestamp = (datetime, fallback) => {
|
|
2764
|
+
if (datetime == null) {
|
|
2765
|
+
return Date.now();
|
|
2766
|
+
}
|
|
2767
|
+
if (typeof datetime == "number") {
|
|
2768
|
+
return fromNumber(datetime, fallback);
|
|
2769
|
+
}
|
|
2770
|
+
if (typeof datetime != "string") {
|
|
2771
|
+
if (fallback) return null;
|
|
2772
|
+
throwUnexpectedTypeError("datetime", "number | string", datetime, Number.NaN);
|
|
2773
|
+
}
|
|
2774
|
+
const num2 = toNumber(datetime, Number.NaN);
|
|
2775
|
+
if (!isNaN(num2)) {
|
|
2776
|
+
return fromNumber(num2, fallback);
|
|
2777
|
+
}
|
|
2778
|
+
const parsed = Date.parse(datetime);
|
|
2779
|
+
if (isFinite(parsed)) return parsed;
|
|
2780
|
+
if (fallback) return null;
|
|
2781
|
+
throwError(`${describeParam("datetime")} cannot be parsed as datetime: ${display(datetime)}`, Number.NaN);
|
|
2782
|
+
};
|
|
1510
2783
|
var to_timestamp = VmLib(
|
|
1511
|
-
(datetime) => {
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
if (typeof datetime == "number") {
|
|
1516
|
-
return new Date(datetime).getTime();
|
|
1517
|
-
}
|
|
1518
|
-
const str = $ToString(datetime);
|
|
1519
|
-
if (!str) return Number.NaN;
|
|
1520
|
-
const num2 = $ToNumber(str);
|
|
1521
|
-
if (isFinite(num2)) return num2;
|
|
1522
|
-
return Date.parse(str);
|
|
2784
|
+
(datetime, fallback) => {
|
|
2785
|
+
const timestamp = getTimestamp(datetime, fallback !== void 0);
|
|
2786
|
+
if (timestamp == null) return fallback;
|
|
2787
|
+
return timestamp;
|
|
1523
2788
|
},
|
|
1524
2789
|
{
|
|
1525
2790
|
summary: "将数据转换为 Unix 毫秒时间戳",
|
|
1526
|
-
params: {
|
|
1527
|
-
|
|
1528
|
-
|
|
2791
|
+
params: {
|
|
2792
|
+
datetime: "要转换的数据,默认为当前时间",
|
|
2793
|
+
fallback: "转换失败时的返回值"
|
|
2794
|
+
},
|
|
2795
|
+
paramsType: { datetime: "number | string", fallback: "any" },
|
|
2796
|
+
returnsType: "number | type(fallback)",
|
|
1529
2797
|
examples: ['to_timestamp("1970-01-01T00:00:00Z") // 0']
|
|
1530
2798
|
}
|
|
1531
2799
|
);
|
|
1532
2800
|
var to_datetime = VmLib(
|
|
1533
|
-
(datetime, offset) => {
|
|
1534
|
-
const timestamp =
|
|
1535
|
-
if (
|
|
1536
|
-
const o =
|
|
2801
|
+
(datetime, offset, fallback) => {
|
|
2802
|
+
const timestamp = getTimestamp(datetime, fallback !== void 0);
|
|
2803
|
+
if (timestamp == null) return fallback;
|
|
2804
|
+
const o = expectNumberRange("offset", offset ?? 0, -24, 24);
|
|
1537
2805
|
const dateOffset = new Date(timestamp + o * 1e3 * 60 * 60);
|
|
1538
2806
|
return {
|
|
1539
2807
|
year: dateOffset.getUTCFullYear(),
|
|
@@ -1551,10 +2819,11 @@ var to_datetime = VmLib(
|
|
|
1551
2819
|
summary: "将数据转换为 Date 记录",
|
|
1552
2820
|
params: {
|
|
1553
2821
|
datetime: "要转换的数据,默认为当前时间",
|
|
1554
|
-
offset: "时区偏移量(单位:小时),默认为 0"
|
|
2822
|
+
offset: "时区偏移量(单位:小时),默认为 0",
|
|
2823
|
+
fallback: "转换失败时的返回值"
|
|
1555
2824
|
},
|
|
1556
|
-
paramsType: { datetime: "number | string", offset: "number" },
|
|
1557
|
-
returnsType: "Date",
|
|
2825
|
+
paramsType: { datetime: "number | string", offset: "number", fallback: "any" },
|
|
2826
|
+
returnsType: "Date | type(fallback)",
|
|
1558
2827
|
examples: [
|
|
1559
2828
|
`
|
|
1560
2829
|
to_datetime(0)
|
|
@@ -1568,21 +2837,30 @@ to_datetime(0)
|
|
|
1568
2837
|
}
|
|
1569
2838
|
);
|
|
1570
2839
|
var to_iso8601 = VmLib(
|
|
1571
|
-
(datetime) => {
|
|
1572
|
-
const timestamp =
|
|
1573
|
-
if (
|
|
2840
|
+
(datetime, fallback) => {
|
|
2841
|
+
const timestamp = getTimestamp(datetime, fallback !== void 0);
|
|
2842
|
+
if (timestamp == null) return fallback;
|
|
1574
2843
|
return new Date(timestamp).toISOString();
|
|
1575
2844
|
},
|
|
1576
2845
|
{
|
|
1577
2846
|
summary: "将数据转换为 ISO 8601 格式的字符串",
|
|
1578
|
-
params: {
|
|
1579
|
-
|
|
1580
|
-
|
|
2847
|
+
params: {
|
|
2848
|
+
datetime: "要转换的数据,默认为当前时间",
|
|
2849
|
+
fallback: "转换失败时的返回值"
|
|
2850
|
+
},
|
|
2851
|
+
paramsType: { datetime: "number | string", fallback: "any" },
|
|
2852
|
+
returnsType: "string | type(fallback)",
|
|
1581
2853
|
examples: ['to_iso8601(0) // "1970-01-01T00:00:00.000Z"']
|
|
1582
2854
|
}
|
|
1583
2855
|
);
|
|
1584
2856
|
|
|
1585
|
-
// src/vm/lib/
|
|
2857
|
+
// src/vm/lib/mod/index.ts
|
|
2858
|
+
var mod_exports = {};
|
|
2859
|
+
__export(mod_exports, {
|
|
2860
|
+
matrix: () => matrix_exports
|
|
2861
|
+
});
|
|
2862
|
+
|
|
2863
|
+
// src/vm/lib/mod/matrix.ts
|
|
1586
2864
|
var matrix_exports = {};
|
|
1587
2865
|
__export(matrix_exports, {
|
|
1588
2866
|
add: () => add,
|
|
@@ -1599,12 +2877,12 @@ __export(matrix_exports, {
|
|
|
1599
2877
|
transpose: () => transpose,
|
|
1600
2878
|
zeros: () => zeros
|
|
1601
2879
|
});
|
|
1602
|
-
function sizeImpl(
|
|
1603
|
-
if (!isVmArray(
|
|
1604
|
-
if (
|
|
1605
|
-
const numRows =
|
|
2880
|
+
function sizeImpl(matrix) {
|
|
2881
|
+
if (!isVmArray(matrix)) return [];
|
|
2882
|
+
if (matrix.length === 0) return [0];
|
|
2883
|
+
const numRows = matrix.length;
|
|
1606
2884
|
let numCols = 0;
|
|
1607
|
-
for (const row of
|
|
2885
|
+
for (const row of matrix) {
|
|
1608
2886
|
if (isVmArray(row)) {
|
|
1609
2887
|
numCols = Math.max(numCols, row.length);
|
|
1610
2888
|
} else {
|
|
@@ -1614,12 +2892,12 @@ function sizeImpl(matrix2) {
|
|
|
1614
2892
|
return [numRows, numCols];
|
|
1615
2893
|
}
|
|
1616
2894
|
function num(v) {
|
|
1617
|
-
return
|
|
2895
|
+
return toNumber(v, void 0);
|
|
1618
2896
|
}
|
|
1619
2897
|
var size = VmLib(
|
|
1620
|
-
(
|
|
1621
|
-
required("matrix",
|
|
1622
|
-
return sizeImpl(
|
|
2898
|
+
(matrix) => {
|
|
2899
|
+
required("matrix", matrix, []);
|
|
2900
|
+
return sizeImpl(matrix);
|
|
1623
2901
|
},
|
|
1624
2902
|
{
|
|
1625
2903
|
summary: "获取矩阵尺寸",
|
|
@@ -1630,16 +2908,16 @@ var size = VmLib(
|
|
|
1630
2908
|
}
|
|
1631
2909
|
);
|
|
1632
2910
|
var transpose = VmLib(
|
|
1633
|
-
(
|
|
1634
|
-
required("matrix",
|
|
1635
|
-
const [numRows, numCols] = sizeImpl(
|
|
1636
|
-
if (numRows == null || numCols == null) return
|
|
2911
|
+
(matrix) => {
|
|
2912
|
+
required("matrix", matrix, []);
|
|
2913
|
+
const [numRows, numCols] = sizeImpl(matrix);
|
|
2914
|
+
if (numRows == null || numCols == null) return matrix;
|
|
1637
2915
|
const transposed = [];
|
|
1638
2916
|
for (let j = 0; j < numCols; j++) {
|
|
1639
2917
|
Cp();
|
|
1640
2918
|
const tj = [];
|
|
1641
2919
|
for (let i = 0; i < numRows; i++) {
|
|
1642
|
-
const row =
|
|
2920
|
+
const row = matrix[i] ?? null;
|
|
1643
2921
|
const item = row?.[j] ?? null;
|
|
1644
2922
|
tj[i] = item;
|
|
1645
2923
|
}
|
|
@@ -2039,7 +3317,7 @@ var identity = VmLib(
|
|
|
2039
3317
|
var diagonal = VmLib(
|
|
2040
3318
|
(x, k = 0) => {
|
|
2041
3319
|
expectArray("x", x, []);
|
|
2042
|
-
const fk =
|
|
3320
|
+
const fk = expectInteger("k", k);
|
|
2043
3321
|
if (x.every((e) => isArray(e))) {
|
|
2044
3322
|
const diag = [];
|
|
2045
3323
|
for (let i = 0; i < x.length; i++) {
|
|
@@ -2080,13 +3358,7 @@ var diagonal = VmLib(
|
|
|
2080
3358
|
}
|
|
2081
3359
|
);
|
|
2082
3360
|
|
|
2083
|
-
// src/vm/lib/
|
|
2084
|
-
var matrix = createModule("matrix", matrix_exports);
|
|
2085
|
-
|
|
2086
|
-
// src/vm/lib/_loader.ts
|
|
2087
|
-
for (const [name, value] of entries(global_exports)) {
|
|
2088
|
-
VmSharedContext[name] = wrapEntry(name, value, "global");
|
|
2089
|
-
}
|
|
3361
|
+
// src/vm/lib/loader.ts
|
|
2090
3362
|
function wrapEntry(name, value, module) {
|
|
2091
3363
|
if (typeof value == "function") {
|
|
2092
3364
|
if (value.name !== name) {
|
|
@@ -2112,423 +3384,33 @@ function createModule(name, lib2) {
|
|
|
2112
3384
|
}
|
|
2113
3385
|
return new VmModule(name, mod);
|
|
2114
3386
|
}
|
|
2115
|
-
var lib = global_exports;
|
|
2116
|
-
|
|
2117
|
-
// src/helpers/serialize.ts
|
|
2118
|
-
var REG_IDENTIFIER_FULL = new RegExp(`^${REG_IDENTIFIER.source}$`, REG_IDENTIFIER.flags);
|
|
2119
|
-
var REG_ORDINAL_FULL = new RegExp(`^${REG_ORDINAL.source}$`, REG_ORDINAL.flags);
|
|
2120
|
-
var DEFAULT_OPTIONS = Object.freeze({
|
|
2121
|
-
maxDepth: 128,
|
|
2122
|
-
serializeNil,
|
|
2123
|
-
serializeBoolean,
|
|
2124
|
-
serializeNumber,
|
|
2125
|
-
serializeString: serializeStringImpl,
|
|
2126
|
-
serializeStringQuote: (value) => value,
|
|
2127
|
-
serializeStringEscape: (value) => value,
|
|
2128
|
-
serializeStringContent: (value) => value,
|
|
2129
|
-
serializeArray,
|
|
2130
|
-
serializeRecord,
|
|
2131
|
-
serializePropName: String,
|
|
2132
|
-
serializeFunction: serializeNil,
|
|
2133
|
-
serializeModule: serializeNil,
|
|
2134
|
-
serializeExtern: serializeNil
|
|
2135
|
-
});
|
|
2136
|
-
function isDefaultOptions(options) {
|
|
2137
|
-
return options == null || options === DEFAULT_OPTIONS;
|
|
2138
|
-
}
|
|
2139
|
-
function getSerializeOptions(options) {
|
|
2140
|
-
if (isDefaultOptions(options)) return DEFAULT_OPTIONS;
|
|
2141
|
-
let opt = null;
|
|
2142
|
-
for (const key in options) {
|
|
2143
|
-
if (!hasOwn(options, key) || !hasOwn(DEFAULT_OPTIONS, key)) continue;
|
|
2144
|
-
const el = options[key];
|
|
2145
|
-
if (el == null) continue;
|
|
2146
|
-
opt ??= { ...DEFAULT_OPTIONS };
|
|
2147
|
-
opt[key] = el;
|
|
2148
|
-
}
|
|
2149
|
-
return opt ? Object.freeze(opt) : DEFAULT_OPTIONS;
|
|
2150
|
-
}
|
|
2151
|
-
function serializeStringImpl(value, options) {
|
|
2152
|
-
if (!/[\p{C}'"`$\\]/u.test(value)) {
|
|
2153
|
-
const oq = options.serializeStringQuote(`'`, true, options);
|
|
2154
|
-
const cq = options.serializeStringQuote(`'`, false, options);
|
|
2155
|
-
const c = options.serializeStringContent(value, options);
|
|
2156
|
-
return oq + c + cq;
|
|
2157
|
-
}
|
|
2158
|
-
let ret = options.serializeStringQuote(`'`, true, options);
|
|
2159
|
-
for (const char of value) {
|
|
2160
|
-
if (char === "'") {
|
|
2161
|
-
ret += options.serializeStringEscape(String.raw`\'`, options);
|
|
2162
|
-
} else if (char === "\0") {
|
|
2163
|
-
ret += options.serializeStringEscape(String.raw`\0`, options);
|
|
2164
|
-
} else if (char === "\n") {
|
|
2165
|
-
ret += options.serializeStringEscape(String.raw`\n`, options);
|
|
2166
|
-
} else if (char === "\r") {
|
|
2167
|
-
ret += options.serializeStringEscape(String.raw`\r`, options);
|
|
2168
|
-
} else if (char === " ") {
|
|
2169
|
-
ret += options.serializeStringEscape(String.raw`\t`, options);
|
|
2170
|
-
} else if (char === "\b") {
|
|
2171
|
-
ret += options.serializeStringEscape(String.raw`\b`, options);
|
|
2172
|
-
} else if (char === "\f") {
|
|
2173
|
-
ret += options.serializeStringEscape(String.raw`\f`, options);
|
|
2174
|
-
} else if (char === "\v") {
|
|
2175
|
-
ret += options.serializeStringEscape(String.raw`\v`, options);
|
|
2176
|
-
} else if (char === "\\") {
|
|
2177
|
-
ret += options.serializeStringEscape(String.raw`\\`, options);
|
|
2178
|
-
} else if (char === "$") {
|
|
2179
|
-
ret += options.serializeStringEscape(String.raw`\$`, options);
|
|
2180
|
-
} else if (/\p{C}/u.test(char)) {
|
|
2181
|
-
const code = char.codePointAt(0);
|
|
2182
|
-
if (code <= 127) {
|
|
2183
|
-
ret += options.serializeStringEscape(String.raw`\x${code.toString(16).padStart(2, "0")}`, options);
|
|
2184
|
-
} else if (code >= 55296 && code <= 57343) {
|
|
2185
|
-
ret += options.serializeStringContent("�", options);
|
|
2186
|
-
} else {
|
|
2187
|
-
ret += options.serializeStringEscape(String.raw`\u{${code.toString(16)}}`, options);
|
|
2188
|
-
}
|
|
2189
|
-
} else {
|
|
2190
|
-
ret += options.serializeStringContent(char, options);
|
|
2191
|
-
}
|
|
2192
|
-
}
|
|
2193
|
-
ret += options.serializeStringQuote(`'`, false, options);
|
|
2194
|
-
return ret;
|
|
2195
|
-
}
|
|
2196
|
-
function serializeString(value, options) {
|
|
2197
|
-
return serializeStringImpl(value, getSerializeOptions(options));
|
|
2198
|
-
}
|
|
2199
|
-
function serializeRecordKeyDefault(key) {
|
|
2200
|
-
if (REG_ORDINAL_FULL.test(key) || REG_IDENTIFIER_FULL.test(key)) {
|
|
2201
|
-
return key;
|
|
2202
|
-
}
|
|
2203
|
-
return serializeStringImpl(key, DEFAULT_OPTIONS);
|
|
2204
|
-
}
|
|
2205
|
-
function serializeRecordKeyOpt(value, options) {
|
|
2206
|
-
if (isDefaultOptions(options)) {
|
|
2207
|
-
return serializeRecordKeyDefault(value);
|
|
2208
|
-
}
|
|
2209
|
-
if (REG_ORDINAL_FULL.test(value)) {
|
|
2210
|
-
return options.serializePropName(Number(value), options);
|
|
2211
|
-
}
|
|
2212
|
-
if (REG_IDENTIFIER_FULL.test(value)) {
|
|
2213
|
-
return options.serializePropName(value, options);
|
|
2214
|
-
}
|
|
2215
|
-
return options.serializeString(value, options);
|
|
2216
|
-
}
|
|
2217
|
-
function serializeRecordKey(key, options) {
|
|
2218
|
-
if (isDefaultOptions(options)) {
|
|
2219
|
-
return serializeRecordKeyDefault(key);
|
|
2220
|
-
}
|
|
2221
|
-
return serializeRecordKeyOpt(key, getSerializeOptions(options));
|
|
2222
|
-
}
|
|
2223
|
-
function serializeNil() {
|
|
2224
|
-
return "nil";
|
|
2225
|
-
}
|
|
2226
|
-
function serializeBoolean(value) {
|
|
2227
|
-
return value ? "true" : "false";
|
|
2228
|
-
}
|
|
2229
|
-
function serializeNumber(value) {
|
|
2230
|
-
if (isNaN(value)) return "nan";
|
|
2231
|
-
if (!isFinite(value)) return value < 0 ? "-inf" : "inf";
|
|
2232
|
-
if (value === 0) {
|
|
2233
|
-
if (1 / value < 0) return "-0";
|
|
2234
|
-
return "0";
|
|
2235
|
-
}
|
|
2236
|
-
return String(value);
|
|
2237
|
-
}
|
|
2238
|
-
function serializeArray(value, depth, options) {
|
|
2239
|
-
if (depth > options.maxDepth) return `[]`;
|
|
2240
|
-
if (value.length === 0) return "[]";
|
|
2241
|
-
let str = "[";
|
|
2242
|
-
for (let i = 0; i < value.length; i++) {
|
|
2243
|
-
if (i > 0) str += ", ";
|
|
2244
|
-
str += serializeImpl(value[i], depth, options);
|
|
2245
|
-
}
|
|
2246
|
-
str += "]";
|
|
2247
|
-
return str;
|
|
2248
|
-
}
|
|
2249
|
-
var { valueOf } = Object.prototype;
|
|
2250
|
-
function customValueOf(value) {
|
|
2251
|
-
const thisValueOf = value.valueOf;
|
|
2252
|
-
if (typeof thisValueOf != "function" || thisValueOf === valueOf) {
|
|
2253
|
-
return void 0;
|
|
2254
|
-
}
|
|
2255
|
-
const customValue = thisValueOf.call(value);
|
|
2256
|
-
if (customValue === value) return void 0;
|
|
2257
|
-
return customValue;
|
|
2258
|
-
}
|
|
2259
|
-
function serializeRecord(value, depth, options) {
|
|
2260
|
-
const customValue = customValueOf(value);
|
|
2261
|
-
if (customValue !== void 0) {
|
|
2262
|
-
return serializeImpl(customValue, depth - 1, options);
|
|
2263
|
-
}
|
|
2264
|
-
if (depth > options.maxDepth) return `()`;
|
|
2265
|
-
const e = entries(value);
|
|
2266
|
-
if (e.length === 0) return "()";
|
|
2267
|
-
if (e.length === 1) {
|
|
2268
|
-
const [k, v] = e[0];
|
|
2269
|
-
if (k === "0") {
|
|
2270
|
-
return `(${serializeImpl(v, depth, options)},)`;
|
|
2271
|
-
}
|
|
2272
|
-
return `(${serializeRecordKeyOpt(k, options)}: ${serializeImpl(v, depth, options)})`;
|
|
2273
|
-
}
|
|
2274
|
-
const omitKey = isVmArrayLikeRecordByEntires(e);
|
|
2275
|
-
let str = "(";
|
|
2276
|
-
for (const [key, val] of e) {
|
|
2277
|
-
if (str.length > 1) str += ", ";
|
|
2278
|
-
if (omitKey) {
|
|
2279
|
-
str += serializeImpl(val, depth, options);
|
|
2280
|
-
} else {
|
|
2281
|
-
str += `${serializeRecordKeyOpt(key, options)}: ${serializeImpl(val, depth, options)}`;
|
|
2282
|
-
}
|
|
2283
|
-
}
|
|
2284
|
-
str += ")";
|
|
2285
|
-
return str;
|
|
2286
|
-
}
|
|
2287
|
-
function serializeImpl(value, depth, options) {
|
|
2288
|
-
if (value == null) {
|
|
2289
|
-
return options.serializeNil(options);
|
|
2290
|
-
}
|
|
2291
|
-
if (typeof value == "boolean") {
|
|
2292
|
-
return options.serializeBoolean(value, options);
|
|
2293
|
-
}
|
|
2294
|
-
if (typeof value == "number") {
|
|
2295
|
-
return options.serializeNumber(value, options);
|
|
2296
|
-
}
|
|
2297
|
-
if (typeof value == "string") {
|
|
2298
|
-
return options.serializeString(value, options);
|
|
2299
|
-
}
|
|
2300
|
-
if (isVmFunction(value)) {
|
|
2301
|
-
return options.serializeFunction(value, options);
|
|
2302
|
-
}
|
|
2303
|
-
if (isVmModule(value)) {
|
|
2304
|
-
return options.serializeModule(value, depth + 1, options);
|
|
2305
|
-
}
|
|
2306
|
-
if (isVmExtern(value)) {
|
|
2307
|
-
return options.serializeExtern(value, depth + 1, options);
|
|
2308
|
-
}
|
|
2309
|
-
if (isVmArray(value)) {
|
|
2310
|
-
return options.serializeArray(value, depth + 1, options);
|
|
2311
|
-
}
|
|
2312
|
-
if (isVmRecord(value)) {
|
|
2313
|
-
return options.serializeRecord(value, depth + 1, options);
|
|
2314
|
-
}
|
|
2315
|
-
value;
|
|
2316
|
-
return options.serializeNil(options);
|
|
2317
|
-
}
|
|
2318
|
-
function serialize(value, options) {
|
|
2319
|
-
return serializeImpl(value, 0, getSerializeOptions(options));
|
|
2320
|
-
}
|
|
2321
|
-
|
|
2322
|
-
// src/compiler/index.ts
|
|
2323
|
-
import { loadModule } from "@mirascript/bindings";
|
|
2324
|
-
|
|
2325
|
-
// src/vm/env.ts
|
|
2326
|
-
var keys3 = [];
|
|
2327
|
-
var values3 = [];
|
|
2328
|
-
for (const [key, value] of entries(operations_exports)) {
|
|
2329
|
-
keys3.push(key);
|
|
2330
|
-
values3.push(value);
|
|
2331
|
-
}
|
|
2332
|
-
for (const [key, value] of entries(helpers_exports)) {
|
|
2333
|
-
keys3.push(key);
|
|
2334
|
-
values3.push(value);
|
|
2335
|
-
}
|
|
2336
|
-
|
|
2337
|
-
// src/compiler/create-script.ts
|
|
2338
|
-
var kVmScript = Symbol.for("mirascript.vm.script");
|
|
2339
|
-
function wrapScript(source, script) {
|
|
2340
|
-
if (kVmScript in script) {
|
|
2341
|
-
return script;
|
|
2342
|
-
}
|
|
2343
|
-
defineProperty(script, kVmScript, { value: true });
|
|
2344
|
-
if (typeof source === "string") {
|
|
2345
|
-
defineProperty(script, "source", { value: source, configurable: true });
|
|
2346
|
-
} else if (source instanceof Uint8Array) {
|
|
2347
|
-
defineProperty(script, "source", { value: "<buffer>", configurable: true });
|
|
2348
|
-
}
|
|
2349
|
-
return script;
|
|
2350
|
-
}
|
|
2351
|
-
function createScript(source, code) {
|
|
2352
|
-
let script;
|
|
2353
|
-
try {
|
|
2354
|
-
script = new Function(...keys3, code)(...values3);
|
|
2355
|
-
} catch (error) {
|
|
2356
|
-
throw new Error(`Failed to create script`, { cause: error });
|
|
2357
|
-
}
|
|
2358
|
-
return wrapScript(source, script);
|
|
2359
|
-
}
|
|
2360
|
-
|
|
2361
|
-
// src/compiler/compile-fast.ts
|
|
2362
|
-
var REG_NUMBER_FULL = /^\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
|
|
2363
|
-
var REG_IDENTIFIER_FAST = /^(?:\$+|@+)[a-zA-Z0-9_]*$/;
|
|
2364
|
-
var FAST_SCRIPT_MAX_LEN = 32;
|
|
2365
|
-
function compileScriptFast(code, options) {
|
|
2366
|
-
if (code.length > FAST_SCRIPT_MAX_LEN) return void 0;
|
|
2367
|
-
const trimmedCode = code.trim();
|
|
2368
|
-
if (!trimmedCode) {
|
|
2369
|
-
return wrapScript(code, () => null);
|
|
2370
|
-
}
|
|
2371
|
-
switch (trimmedCode) {
|
|
2372
|
-
case "nil":
|
|
2373
|
-
return wrapScript(code, () => null);
|
|
2374
|
-
case "true":
|
|
2375
|
-
return wrapScript(code, () => true);
|
|
2376
|
-
case "false":
|
|
2377
|
-
return wrapScript(code, () => false);
|
|
2378
|
-
case "nan":
|
|
2379
|
-
return wrapScript(code, () => 0 / 0);
|
|
2380
|
-
case "inf":
|
|
2381
|
-
case "+inf":
|
|
2382
|
-
return wrapScript(code, () => 1 / 0);
|
|
2383
|
-
case "-inf":
|
|
2384
|
-
return wrapScript(code, () => -1 / 0);
|
|
2385
|
-
}
|
|
2386
|
-
if (REG_IDENTIFIER_FAST.test(trimmedCode)) {
|
|
2387
|
-
const id = trimmedCode;
|
|
2388
|
-
return wrapScript(code, (global = GlobalFallback()) => global.get(id));
|
|
2389
|
-
}
|
|
2390
|
-
if (REG_NUMBER_FULL.test(trimmedCode)) {
|
|
2391
|
-
const num2 = Number(trimmedCode);
|
|
2392
|
-
if (!isFinite(num2)) return void 0;
|
|
2393
|
-
return wrapScript(code, () => num2);
|
|
2394
|
-
}
|
|
2395
|
-
return void 0;
|
|
2396
|
-
}
|
|
2397
|
-
var FAST_TEMPLATE_MAX_LEN = 1024;
|
|
2398
|
-
function compileTemplateFast(code, options) {
|
|
2399
|
-
if (code.length > FAST_TEMPLATE_MAX_LEN) return void 0;
|
|
2400
|
-
if (!code.includes("$")) {
|
|
2401
|
-
return wrapScript(code, () => code);
|
|
2402
|
-
}
|
|
2403
|
-
return void 0;
|
|
2404
|
-
}
|
|
2405
|
-
function compileFast(code, options) {
|
|
2406
|
-
if (options.sourceMap) return void 0;
|
|
2407
|
-
return (options.input_mode === "Template" ? compileTemplateFast : compileScriptFast)(code, options);
|
|
2408
|
-
}
|
|
2409
|
-
|
|
2410
|
-
// src/compiler/worker-manager.ts
|
|
2411
|
-
var worker;
|
|
2412
|
-
async function getWorker() {
|
|
2413
|
-
if (worker) return worker;
|
|
2414
|
-
worker = new Promise((resolve, reject) => {
|
|
2415
|
-
const w = new Worker(new URL("#compiler/worker", import.meta.url), {
|
|
2416
|
-
type: "module",
|
|
2417
|
-
name: "@mirascript/compiler"
|
|
2418
|
-
});
|
|
2419
|
-
const onError = (e) => {
|
|
2420
|
-
cleanUp();
|
|
2421
|
-
reject(new Error(`Worker failed to start: ${e.message}`));
|
|
2422
|
-
};
|
|
2423
|
-
const onMessage = (e) => {
|
|
2424
|
-
if (e.data === "ready") {
|
|
2425
|
-
cleanUp();
|
|
2426
|
-
resolve(w);
|
|
2427
|
-
} else if (e.data instanceof Error) {
|
|
2428
|
-
cleanUp();
|
|
2429
|
-
reject(e.data);
|
|
2430
|
-
}
|
|
2431
|
-
};
|
|
2432
|
-
w.addEventListener("error", onError);
|
|
2433
|
-
w.addEventListener("message", onMessage);
|
|
2434
|
-
const cleanUp = () => {
|
|
2435
|
-
w.removeEventListener("error", onError);
|
|
2436
|
-
w.removeEventListener("message", onMessage);
|
|
2437
|
-
};
|
|
2438
|
-
setTimeout(() => {
|
|
2439
|
-
onError(new ErrorEvent("error", { message: "Worker did not respond in time" }));
|
|
2440
|
-
}, 3e4);
|
|
2441
|
-
});
|
|
2442
|
-
return worker;
|
|
2443
|
-
}
|
|
2444
|
-
async function compileWorker(...args) {
|
|
2445
|
-
const worker2 = await getWorker();
|
|
2446
|
-
const seq = Math.random();
|
|
2447
|
-
worker2.postMessage([seq, ...args]);
|
|
2448
|
-
return await new Promise((resolve, reject) => {
|
|
2449
|
-
const callback = (ev) => {
|
|
2450
|
-
const data = ev.data;
|
|
2451
|
-
if (!Array.isArray(data)) return;
|
|
2452
|
-
const [retSeq, ...rest] = data;
|
|
2453
|
-
if (seq !== retSeq) return;
|
|
2454
|
-
worker2.removeEventListener("message", callback);
|
|
2455
|
-
if (rest.length === 2) {
|
|
2456
|
-
resolve(rest);
|
|
2457
|
-
} else {
|
|
2458
|
-
reject(rest[0]);
|
|
2459
|
-
}
|
|
2460
|
-
};
|
|
2461
|
-
worker2.addEventListener("message", callback);
|
|
2462
|
-
});
|
|
2463
|
-
}
|
|
2464
3387
|
|
|
2465
|
-
// src/
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
function reportDiagnostic(source, diagnostics) {
|
|
2469
|
-
const parsed = parseDiagnostics(source, diagnostics);
|
|
2470
|
-
const messages = parsed.errors.map(formatDiagnostic);
|
|
2471
|
-
throw new Error(`Failed to compile:
|
|
2472
|
-
${messages.join("\n")}`);
|
|
2473
|
-
}
|
|
2474
|
-
function emitScript(source, [code, diagnostics], options) {
|
|
2475
|
-
if (!code) {
|
|
2476
|
-
reportDiagnostic(source, diagnostics);
|
|
2477
|
-
}
|
|
2478
|
-
const sourcemaps = options.sourceMap ? parseDiagnostics(source, diagnostics, (c) => c === DiagnosticCode.SourceMap).sourcemaps : [];
|
|
2479
|
-
const target = emit(source, code, sourcemaps, options);
|
|
2480
|
-
return createScript(source, target);
|
|
2481
|
-
}
|
|
2482
|
-
async function compile(source, options = {}) {
|
|
2483
|
-
if (options.sourceMap) {
|
|
2484
|
-
options.diagnostic_sourcemap = true;
|
|
2485
|
-
options.diagnostic_position_encoding ??= "Utf16";
|
|
2486
|
-
}
|
|
2487
|
-
if (typeof source == "string") {
|
|
2488
|
-
const result = compileFast(source, options);
|
|
2489
|
-
if (result) return result;
|
|
2490
|
-
}
|
|
2491
|
-
if (source.length < WORKER_MIN_LEN) {
|
|
2492
|
-
const bc = await generateBytecode(source, options);
|
|
2493
|
-
return emitScript(source, bc, options);
|
|
2494
|
-
}
|
|
2495
|
-
const [target, diagnostics] = await compileWorker(source, options);
|
|
2496
|
-
if (target == null) {
|
|
2497
|
-
reportDiagnostic(source, diagnostics);
|
|
2498
|
-
}
|
|
2499
|
-
return createScript(source, target);
|
|
3388
|
+
// src/vm/lib/index.ts
|
|
3389
|
+
for (const [name, value] of entries(global_exports)) {
|
|
3390
|
+
VM_SHARED_CONTEXT[name] = wrapEntry(name, value, "global");
|
|
2500
3391
|
}
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
if (result) return result;
|
|
2505
|
-
}
|
|
2506
|
-
const bc = generateBytecodeSync(source, options);
|
|
2507
|
-
return emitScript(source, bc, options);
|
|
3392
|
+
for (const [name, value] of entries(mod_exports)) {
|
|
3393
|
+
const mod = createModule(name, value);
|
|
3394
|
+
VM_SHARED_CONTEXT[name] = wrapEntry(name, mod, "global");
|
|
2508
3395
|
}
|
|
2509
|
-
|
|
2510
|
-
// src/subtle.ts
|
|
2511
|
-
var keywords = () => {
|
|
2512
|
-
const kw = Object.freeze(getModule().keywords());
|
|
2513
|
-
keywords = () => kw;
|
|
2514
|
-
return kw;
|
|
2515
|
-
};
|
|
3396
|
+
var lib = Object.freeze(Object.assign(create(null), global_exports, mod_exports));
|
|
2516
3397
|
|
|
2517
3398
|
export {
|
|
2518
|
-
|
|
3399
|
+
convert_exports,
|
|
3400
|
+
operations_exports,
|
|
3401
|
+
VmExtern,
|
|
3402
|
+
wrapToVmValue,
|
|
3403
|
+
unwrapFromVmValue,
|
|
3404
|
+
configCheckpoint,
|
|
3405
|
+
VmFunction,
|
|
3406
|
+
defineVmContextValue,
|
|
3407
|
+
DefaultVmContext,
|
|
3408
|
+
createVmContext,
|
|
2519
3409
|
emitScript,
|
|
2520
3410
|
compile,
|
|
2521
3411
|
compileSync,
|
|
2522
|
-
|
|
3412
|
+
VmModule,
|
|
2523
3413
|
debug_print,
|
|
2524
|
-
lib
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
serializeNil,
|
|
2528
|
-
serializeBoolean,
|
|
2529
|
-
serializeNumber,
|
|
2530
|
-
serializeArray,
|
|
2531
|
-
serializeRecord,
|
|
2532
|
-
serialize
|
|
2533
|
-
};
|
|
2534
|
-
//# sourceMappingURL=chunk-NT235HY3.js.map
|
|
3414
|
+
lib
|
|
3415
|
+
};
|
|
3416
|
+
//# sourceMappingURL=chunk-W2I5XPIE.js.map
|