@mirascript/mirascript 0.1.38 → 0.1.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/{chunk-SEZII6RI.js → chunk-GBWG7BQZ.js} +6 -5
  2. package/dist/chunk-GBWG7BQZ.js.map +6 -0
  3. package/dist/{chunk-C6YXWSTI.js → chunk-SXCYD4OW.js} +34 -28
  4. package/dist/chunk-SXCYD4OW.js.map +6 -0
  5. package/dist/compiler/worker.js +1 -1
  6. package/dist/helpers/constants.d.ts +1 -1
  7. package/dist/helpers/constants.d.ts.map +1 -1
  8. package/dist/helpers/utils.d.ts +3 -3
  9. package/dist/helpers/utils.d.ts.map +1 -1
  10. package/dist/index.js +180 -6
  11. package/dist/index.js.map +2 -2
  12. package/dist/subtle.js +64 -7
  13. package/dist/subtle.js.map +2 -2
  14. package/dist/vm/types/extern.d.ts +9 -2
  15. package/dist/vm/types/extern.d.ts.map +1 -1
  16. package/package.json +5 -15
  17. package/src/helpers/constants.ts +1 -1
  18. package/src/helpers/utils.ts +2 -2
  19. package/src/vm/operations/helpers.ts +4 -4
  20. package/src/vm/operations/utils.ts +11 -11
  21. package/src/vm/types/extern.ts +23 -11
  22. package/cli.js +0 -3
  23. package/dist/chunk-C6YXWSTI.js.map +0 -6
  24. package/dist/chunk-HGARNCSR.js +0 -74
  25. package/dist/chunk-HGARNCSR.js.map +0 -6
  26. package/dist/chunk-RQRTM6AH.js +0 -188
  27. package/dist/chunk-RQRTM6AH.js.map +0 -6
  28. package/dist/chunk-SEZII6RI.js.map +0 -6
  29. package/dist/cli/execute.d.ts +0 -4
  30. package/dist/cli/execute.d.ts.map +0 -1
  31. package/dist/cli/index.d.ts +0 -9
  32. package/dist/cli/index.d.ts.map +0 -1
  33. package/dist/cli/index.js +0 -165
  34. package/dist/cli/index.js.map +0 -6
  35. package/dist/cli/print.d.ts +0 -4
  36. package/dist/cli/print.d.ts.map +0 -1
  37. package/src/cli/execute.ts +0 -40
  38. package/src/cli/index.ts +0 -89
  39. package/src/cli/print.ts +0 -57
package/dist/index.js CHANGED
@@ -1,20 +1,25 @@
1
1
  import {
2
- compile,
3
- compileSync
4
- } from "./chunk-RQRTM6AH.js";
5
- import {
2
+ $GlobalFallback,
6
3
  VmExtern,
7
4
  VmFunction,
8
5
  VmModule,
9
6
  configCheckpoint,
7
+ createScript,
10
8
  createVmContext,
11
9
  defineVmContextValue,
10
+ emitScript,
11
+ reportDiagnostic,
12
12
  unwrapFromVmValue,
13
+ wrapScript,
13
14
  wrapToVmValue
14
- } from "./chunk-C6YXWSTI.js";
15
+ } from "./chunk-SXCYD4OW.js";
15
16
  import {
16
17
  VmError,
18
+ defineProperty,
19
+ generateBytecode,
20
+ generateBytecodeSync,
17
21
  getVmFunctionInfo,
22
+ isFinite,
18
23
  isVmAny,
19
24
  isVmArray,
20
25
  isVmArrayLikeRecord,
@@ -33,7 +38,176 @@ import {
33
38
  isVmValue,
34
39
  isVmWrapper,
35
40
  serialize
36
- } from "./chunk-SEZII6RI.js";
41
+ } from "./chunk-GBWG7BQZ.js";
42
+
43
+ // src/compiler/compile-fast.ts
44
+ import { isKeyword } from "@mirascript/constants";
45
+ var REG_NUMBER_FULL = /^(?:[+-])?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
46
+ var REG_IDENTIFIER_FAST = /^(?:\$+|@+|[A-Za-z])[a-zA-Z0-9_]*$/;
47
+ var FAST_SCRIPT_MAX_LEN = 32;
48
+ function constantFiniteNumber(value) {
49
+ if (value === 0) {
50
+ if (Object.is(value, -0)) {
51
+ return () => -0;
52
+ } else {
53
+ return () => 0;
54
+ }
55
+ }
56
+ const f = () => value;
57
+ defineProperty(f, "toString", {
58
+ value: () => {
59
+ return `() => ${value};`;
60
+ },
61
+ writable: false,
62
+ enumerable: false,
63
+ configurable: false
64
+ });
65
+ return f;
66
+ }
67
+ function constantString(value) {
68
+ const f = () => value;
69
+ defineProperty(f, "toString", {
70
+ value: () => {
71
+ return `() => ${JSON.stringify(value)};`;
72
+ },
73
+ writable: false,
74
+ enumerable: false,
75
+ configurable: false
76
+ });
77
+ return f;
78
+ }
79
+ function nan() {
80
+ return () => 0 / 0;
81
+ }
82
+ function posInf() {
83
+ return () => 1 / 0;
84
+ }
85
+ function negInf() {
86
+ return () => -1 / 0;
87
+ }
88
+ function constantBoolean(value) {
89
+ if (value) {
90
+ return () => true;
91
+ } else {
92
+ return () => false;
93
+ }
94
+ }
95
+ function nil() {
96
+ return () => null;
97
+ }
98
+ function globalVariable(id) {
99
+ const f = (global) => (global ?? $GlobalFallback()).get(id);
100
+ defineProperty(f, "toString", {
101
+ value: () => {
102
+ return `(global) => (global ?? $GlobalFallback()).get(${JSON.stringify(id)});`;
103
+ },
104
+ writable: false,
105
+ enumerable: false,
106
+ configurable: false
107
+ });
108
+ return f;
109
+ }
110
+ function compileScriptFast(code) {
111
+ if (code.length > FAST_SCRIPT_MAX_LEN) return void 0;
112
+ const trimmedCode = code.trim();
113
+ if (!trimmedCode) {
114
+ return wrapScript(code, "Script", nil());
115
+ }
116
+ switch (trimmedCode) {
117
+ case "nil":
118
+ return wrapScript(code, "Script", nil());
119
+ case "true":
120
+ return wrapScript(code, "Script", constantBoolean(true));
121
+ case "false":
122
+ return wrapScript(code, "Script", constantBoolean(false));
123
+ case "nan":
124
+ return wrapScript(code, "Script", nan());
125
+ case "inf":
126
+ case "+inf":
127
+ return wrapScript(code, "Script", posInf());
128
+ case "-inf":
129
+ return wrapScript(code, "Script", negInf());
130
+ }
131
+ if (REG_IDENTIFIER_FAST.test(trimmedCode)) {
132
+ const id = trimmedCode;
133
+ if (isKeyword(id)) {
134
+ return void 0;
135
+ }
136
+ return wrapScript(code, "Script", globalVariable(id));
137
+ }
138
+ if (REG_NUMBER_FULL.test(trimmedCode)) {
139
+ const num = Number(trimmedCode);
140
+ if (!isFinite(num)) return void 0;
141
+ return wrapScript(code, "Script", constantFiniteNumber(num));
142
+ }
143
+ return void 0;
144
+ }
145
+ var FAST_TEMPLATE_MAX_LEN = 1024;
146
+ function compileTemplateFast(code) {
147
+ if (code.length > FAST_TEMPLATE_MAX_LEN) return void 0;
148
+ if (!code.includes("$")) {
149
+ return wrapScript(code, "Template", constantString(code));
150
+ }
151
+ return void 0;
152
+ }
153
+ function compileFast(code, options) {
154
+ if (options.sourceMap) return void 0;
155
+ return (options.input_mode === "Template" ? compileTemplateFast : compileScriptFast)(code);
156
+ }
157
+
158
+ // src/compiler/worker-manager.ts
159
+ import { WorkerPool } from "@cloudpss/worker/pool";
160
+ var pool = /* @__PURE__ */ new WorkerPool(
161
+ () => {
162
+ return new Worker(new URL("#compiler/worker", import.meta.url), {
163
+ type: "module",
164
+ name: "@mirascript/compiler"
165
+ });
166
+ },
167
+ {
168
+ name: "@mirascript/compiler"
169
+ }
170
+ );
171
+ async function compileWorker(...args) {
172
+ return await pool.call("compile", args);
173
+ }
174
+
175
+ // src/compiler/index.ts
176
+ var WORKER_MIN_LEN = typeof Worker != "function" ? Number.MAX_VALUE : 1024;
177
+ function getOptions(options) {
178
+ options ??= {};
179
+ if (options.sourceMap) {
180
+ options.diagnostic_sourcemap = true;
181
+ options.diagnostic_position_encoding ??= "Utf16";
182
+ }
183
+ options.input_mode ??= "Script";
184
+ return options;
185
+ }
186
+ async function compile(source, options) {
187
+ options = getOptions(options);
188
+ if (typeof source == "string") {
189
+ const result = compileFast(source, options);
190
+ if (result) return result;
191
+ }
192
+ if (source.length < WORKER_MIN_LEN) {
193
+ const bc = await generateBytecode(source, options);
194
+ return emitScript(source, bc, options);
195
+ }
196
+ const [target, diagnostics] = await compileWorker(source, options);
197
+ if (target == null) {
198
+ reportDiagnostic(source, diagnostics, options.fileName);
199
+ }
200
+ return createScript(source, options.input_mode ?? "Script", target);
201
+ }
202
+ function compileSync(source, options) {
203
+ options = getOptions(options);
204
+ if (typeof source == "string") {
205
+ const result = compileFast(source, options);
206
+ if (result) return result;
207
+ }
208
+ const bc = generateBytecodeSync(source, options);
209
+ return emitScript(source, bc, options);
210
+ }
37
211
  export {
38
212
  VmError,
39
213
  VmExtern,
package/dist/index.js.map CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": [],
4
- "mappings": "",
3
+ "sources": ["../src/compiler/compile-fast.ts", "../src/compiler/worker-manager.ts", "../src/compiler/index.ts"],
4
+ "mappings": "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",
5
5
  "names": []
6
6
  }
package/dist/subtle.js CHANGED
@@ -1,8 +1,3 @@
1
- import {
2
- OpCode,
3
- analyzeGlobalReferences,
4
- isKeyword
5
- } from "./chunk-HGARNCSR.js";
6
1
  import {
7
2
  DefaultVmContext,
8
3
  convert_exports,
@@ -11,9 +6,10 @@ import {
11
6
  lib,
12
7
  operations_exports,
13
8
  wrapScript
14
- } from "./chunk-C6YXWSTI.js";
9
+ } from "./chunk-SXCYD4OW.js";
15
10
  import {
16
11
  DiagnosticCode,
12
+ REG_IDENTIFIER,
17
13
  constants_exports,
18
14
  display,
19
15
  formatDiagnostics,
@@ -29,7 +25,68 @@ import {
29
25
  serializeRecord,
30
26
  serializeRecordKey,
31
27
  serializeString
32
- } from "./chunk-SEZII6RI.js";
28
+ } from "./chunk-GBWG7BQZ.js";
29
+
30
+ // src/subtle.ts
31
+ import { OpCode, isKeyword } from "@mirascript/constants";
32
+
33
+ // src/helpers/analyze.ts
34
+ var REG_SPILT = /\s*!?\s*\.\s*/u;
35
+ var REG_CHAIN = new RegExp(
36
+ String.raw`^(${REG_IDENTIFIER.source})(?:${REG_SPILT.source}(?:\d+|${REG_IDENTIFIER.source}))*`,
37
+ "u"
38
+ );
39
+ var { parseInt } = Number;
40
+ function analyzeGlobalReferences(expression, mode) {
41
+ if (expression.trim() === "") {
42
+ return [];
43
+ }
44
+ const [code, diagnostics] = generateBytecodeSync(expression, {
45
+ input_mode: mode || "Script",
46
+ diagnostic_position_encoding: "Utf16",
47
+ // 需要设为 true 以便在编译失败时返回空的 bytecode
48
+ diagnostic_error: true,
49
+ diagnostic_warning: false,
50
+ diagnostic_info: false,
51
+ diagnostic_hint: false,
52
+ diagnostic_reference: false,
53
+ diagnostic_tag: true,
54
+ diagnostic_sourcemap: false,
55
+ trivia: false
56
+ });
57
+ if (code == null || diagnostics.length === 0) {
58
+ return [];
59
+ }
60
+ const parsedDiagnostics = parseDiagnostics(expression, diagnostics);
61
+ const globals = parsedDiagnostics.tags.filter((t) => t.code === DiagnosticCode.GlobalVariable);
62
+ if (globals.length === 0) {
63
+ return [];
64
+ }
65
+ const lines = expression.split(/\r?\n/);
66
+ const result = /* @__PURE__ */ new Set();
67
+ for (const global of globals) {
68
+ const line = lines[global.range.startLineNumber - 1];
69
+ if (!line) continue;
70
+ const access = line.slice(global.range.startColumn - 1);
71
+ const chain = REG_CHAIN.exec(access);
72
+ if (chain == null) continue;
73
+ const globalName = chain[1];
74
+ if (globalName?.length !== global.range.endColumn - global.range.startColumn) continue;
75
+ const chainStr = chain[0].split(REG_SPILT).join(".");
76
+ result.add(chainStr);
77
+ }
78
+ const accessChains = [];
79
+ for (const chainStr of result) {
80
+ const parts = chainStr.split(".").map((part) => {
81
+ if (/^\d/.test(part)) {
82
+ return parseInt(part, 10);
83
+ }
84
+ return part;
85
+ });
86
+ accessChains.push(parts);
87
+ }
88
+ return accessChains;
89
+ }
33
90
  export {
34
91
  DefaultVmContext,
35
92
  DiagnosticCode,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": [],
4
- "mappings": "",
3
+ "sources": ["../src/subtle.ts", "../src/helpers/analyze.ts"],
4
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,SAAS,QAAQ,iBAAiB;;;ACMlC,IAAM,YAAY;AAClB,IAAM,YAAY,IAAI;AAAA,EAClB,OAAO,QAAQ,eAAe,MAAM,OAAO,UAAU,MAAM,UAAU,eAAe,MAAM;AAAA,EAC1F;AACJ;AAEA,IAAM,EAAE,SAAS,IAAI;AAId,SAAS,wBAAwB,YAAoB,MAA0C;AAClG,MAAI,WAAW,KAAK,MAAM,IAAI;AAC1B,WAAO,CAAC;AAAA,EACZ;AACA,QAAM,CAAC,MAAM,WAAW,IAAI,qBAAqB,YAAY;AAAA,IACzD,YAAY,QAAQ;AAAA,IACpB,8BAA8B;AAAA;AAAA,IAE9B,kBAAkB;AAAA,IAClB,oBAAoB;AAAA,IACpB,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,sBAAsB;AAAA,IACtB,gBAAgB;AAAA,IAChB,sBAAsB;AAAA,IACtB,QAAQ;AAAA,EACZ,CAAC;AACD,MAAI,QAAQ,QAAQ,YAAY,WAAW,GAAG;AAC1C,WAAO,CAAC;AAAA,EACZ;AACA,QAAM,oBAAoB,iBAAiB,YAAY,WAAW;AAClE,QAAM,UAAU,kBAAkB,KAAK,OAAO,CAAC,MAAM,EAAE,SAAS,eAAe,cAAc;AAC7F,MAAI,QAAQ,WAAW,GAAG;AACtB,WAAO,CAAC;AAAA,EACZ;AACA,QAAM,QAAQ,WAAW,MAAM,OAAO;AACtC,QAAM,SAAS,oBAAI,IAAY;AAC/B,aAAW,UAAU,SAAS;AAE1B,UAAM,OAAO,MAAM,OAAO,MAAM,kBAAkB,CAAC;AACnD,QAAI,CAAC,KAAM;AACX,UAAM,SAAS,KAAK,MAAM,OAAO,MAAM,cAAc,CAAC;AACtD,UAAM,QAAQ,UAAU,KAAK,MAAM;AACnC,QAAI,SAAS,KAAM;AACnB,UAAM,aAAa,MAAM,CAAC;AAC1B,QAAI,YAAY,WAAW,OAAO,MAAM,YAAY,OAAO,MAAM,YAAa;AAC9E,UAAM,WAAW,MAAM,CAAC,EAAE,MAAM,SAAS,EAAE,KAAK,GAAG;AACnD,WAAO,IAAI,QAAQ;AAAA,EACvB;AACA,QAAM,eAAuC,CAAC;AAC9C,aAAW,YAAY,QAAQ;AAC3B,UAAM,QAAQ,SAAS,MAAM,GAAG,EAAE,IAAI,CAAC,SAAS;AAC5C,UAAI,MAAM,KAAK,IAAI,GAAG;AAElB,eAAO,SAAS,MAAM,EAAE;AAAA,MAC5B;AACA,aAAO;AAAA,IACX,CAAC;AACD,iBAAa,KAAK,KAAwC;AAAA,EAC9D;AACA,SAAO;AACX;",
5
5
  "names": []
6
6
  }
@@ -9,7 +9,10 @@ export declare class VmExtern<const T extends object = object> extends VmWrapper
9
9
  value: T,
10
10
  /** 当 {@link value} 是函数时,绑定的 this 参数 */
11
11
  thisArg?: ThisParameterType<T> | null);
12
- /** Check if the object has a property */
12
+ /**
13
+ * Check if the object has a property
14
+ * This method will be used in {@link get}, {@link set}, {@link has}, and {@link keys} methods
15
+ */
13
16
  protected access(key: string, read: boolean): boolean;
14
17
  /** 决定是否对属性进行包装 */
15
18
  assumeVmValue(value: object, key: keyof T | undefined): value is Exclude<VmConst, VmPrimitive>;
@@ -25,7 +28,11 @@ export declare class VmExtern<const T extends object = object> extends VmWrapper
25
28
  keys(includeNonEnumerable?: boolean): string[];
26
29
  /** @inheritdoc */
27
30
  same(other: VmAny): boolean;
28
- /** @inheritdoc */
31
+ /**
32
+ * Should this extern be treated as array-like?
33
+ *
34
+ * By default, this method returns true if the wrapped value is an Array or a TypedArray.
35
+ */
29
36
  isArrayLike(): this is VmExtern<ArrayLike<unknown>>;
30
37
  /** @inheritdoc */
31
38
  toString(useBraces: boolean): string;
@@ -1 +1 @@
1
- {"version":3,"file":"extern.d.ts","sourceRoot":"","sources":["../../../src/vm/types/extern.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAwBzC,mCAAmC;AACnC,qBAAa,QAAQ,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,SAAS,CAAC,CAAC,CAAC;IAInE,uCAAuC;IACvC,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,IAAI;;IAH7C,UAAU;IACV,KAAK,EAAE,CAAC;IACR,uCAAuC;IAC9B,OAAO,GAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,IAAW;IAKxD,yCAAyC;IACzC,SAAS,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO;IAiBrD,kBAAkB;IAClB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,SAAS,GAAG,KAAK,IAAI,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC;IAI9F,kBAAkB;IACT,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAGlC,kBAAkB;IACT,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK;IAMhC,mCAAmC;IACnC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO;IAMzC,wBAAwB;IACxB,IAAI,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,GAAG,KAAK;IAerC,kBAAkB;IACT,IAAI,CAAC,oBAAoB,UAAQ,GAAG,MAAM,EAAE;IAqBrD,kBAAkB;IACT,IAAI,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO;IAIpC,kBAAkB;IAClB,WAAW,IAAI,IAAI,IAAI,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAGnD,kBAAkB;IACT,QAAQ,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM;IAiB7C,kBAAkB;IAClB,IAAa,IAAI,IAAI,QAAQ,CAE5B;IACD,kBAAkB;IAClB,IAAa,GAAG,IAAI,MAAM,CA6BzB;CACJ"}
1
+ {"version":3,"file":"extern.d.ts","sourceRoot":"","sources":["../../../src/vm/types/extern.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AA4BzC,mCAAmC;AACnC,qBAAa,QAAQ,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,SAAS,CAAC,CAAC,CAAC;IAInE,uCAAuC;IACvC,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,IAAI;;IAH7C,UAAU;IACV,KAAK,EAAE,CAAC;IACR,uCAAuC;IAC9B,OAAO,GAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,IAAW;IAKxD;;;OAGG;IACH,SAAS,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO;IAiBrD,kBAAkB;IAClB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,SAAS,GAAG,KAAK,IAAI,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC;IAI9F,kBAAkB;IACT,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAGlC,kBAAkB;IACT,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK;IAMhC,mCAAmC;IACnC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO;IAMzC,wBAAwB;IACxB,IAAI,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,GAAG,KAAK;IAerC,kBAAkB;IACT,IAAI,CAAC,oBAAoB,UAAQ,GAAG,MAAM,EAAE;IAmBrD,kBAAkB;IACT,IAAI,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO;IAIpC;;;;OAIG;IACH,WAAW,IAAI,IAAI,IAAI,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAGnD,kBAAkB;IACT,QAAQ,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM;IAoB7C,kBAAkB;IAClB,IAAa,IAAI,IAAI,QAAQ,CAE5B;IACD,kBAAkB;IAClB,IAAa,GAAG,IAAI,MAAM,CA6BzB;CACJ"}
package/package.json CHANGED
@@ -1,12 +1,11 @@
1
1
  {
2
2
  "name": "@mirascript/mirascript",
3
- "version": "0.1.38",
3
+ "version": "0.1.40",
4
4
  "author": "CloudPSS",
5
5
  "license": "MIT",
6
6
  "description": "An expression based scripting language.",
7
7
  "type": "module",
8
8
  "main": "./dist/index.js",
9
- "bin": "./cli.js",
10
9
  "types": "./dist/index.d.ts",
11
10
  "exports": {
12
11
  ".": {
@@ -17,10 +16,6 @@
17
16
  "@mirascript/dev": "./src/subtle.ts",
18
17
  "default": "./dist/subtle.js"
19
18
  },
20
- "./cli": {
21
- "@mirascript/dev": "./src/cli/index.ts",
22
- "default": "./dist/cli/index.js"
23
- },
24
19
  "./package.json": "./package.json"
25
20
  },
26
21
  "imports": {
@@ -32,19 +27,15 @@
32
27
  },
33
28
  "dependencies": {
34
29
  "@cloudpss/worker": "^0.1.10",
35
- "@commander-js/extra-typings": "^14.0.0",
36
- "ansi-styles": "^6.2.3",
37
- "commander": "^14.0.2",
38
30
  "source-map-js": "^1.2.1",
39
31
  "supports-color": "^10.2.2",
40
- "@mirascript/bindings": "~0.1.38",
41
- "@mirascript/constants": "~0.1.38"
32
+ "@mirascript/bindings": "~0.1.40",
33
+ "@mirascript/constants": "~0.1.40"
42
34
  },
43
35
  "devDependencies": {
44
- "@types/node": "^25.0.8",
36
+ "@types/node": "^25.0.10",
45
37
  "ava": "^6.4.1",
46
38
  "c8": "^10.1.3",
47
- "madge": "^8.0.0",
48
39
  "tinybench": "^6.0.0",
49
40
  "type-fest": "^5.4.1"
50
41
  },
@@ -52,8 +43,7 @@
52
43
  "watch": "pnpm build:ts --watch",
53
44
  "build:ts": "pnpm clean && tsc",
54
45
  "build": "pnpm build:ts --emitDeclarationOnly && node ./esbuild.config.js",
55
- "mirascript": "node --enable-source-maps ./cli.js",
56
- "deps": "madge --circular --warning ./src",
46
+ "deps": "pnpm dlx madge --circular --warning ./src",
57
47
  "clean": "rimraf dist",
58
48
  "test": "c8 ava",
59
49
  "bench": "node ./bench/index.ts"
@@ -8,7 +8,7 @@ export const REG_HEX = /0[xX][a-fA-F0-9_]*[a-fA-F0-9]/;
8
8
  export const REG_OCT = /0[oO][0-7_]*[0-7]/;
9
9
  export const REG_BIN = /0[bB][01_]*[01]/;
10
10
  export const REG_NUMBER = /\d[\d_]*(?:\.[\d_]+)?(?:[eE][+-]?[\d_]*\d)?/u;
11
- export const VM_ARRAY_MAX_LENGTH = 2 ** 31 - 1;
11
+ export const VM_ARRAY_MAX_LENGTH = 0x800_0000; // 128 MB, v8's max array length
12
12
 
13
13
  export const kVmScript = Symbol.for('mirascript.vm.script');
14
14
  export const kVmFunction = Symbol.for('mirascript.vm.function');
@@ -8,8 +8,8 @@ export const {
8
8
  POSITIVE_INFINITY: PositiveInfinity,
9
9
  NEGATIVE_INFINITY: NegativeInfinity,
10
10
  } = Number;
11
- export const { hasOwn, keys, values, entries, create, getPrototypeOf, fromEntries, defineProperty } = Object;
12
- export const { apply } = Reflect;
11
+ export const { hasOwn, keys, values, entries, create, fromEntries, defineProperty, getOwnPropertyNames } = Object;
12
+ export const { apply, getPrototypeOf } = Reflect;
13
13
 
14
14
  /**
15
15
  * Determines whether an object has an enumerable property with the specified name.
@@ -35,8 +35,8 @@ export function $Upvalue(value: VmAny): VmValue {
35
35
  return value;
36
36
  }
37
37
 
38
- const assertArrayLength = (start: number, end: number) => {
39
- if (end - start > VM_ARRAY_MAX_LENGTH) {
38
+ const assertArrayLength = (len: number) => {
39
+ if (len > VM_ARRAY_MAX_LENGTH) {
40
40
  throw new RangeError(`Array length exceeds maximum limit of ${VM_ARRAY_MAX_LENGTH}`);
41
41
  }
42
42
  };
@@ -48,7 +48,7 @@ export function $ArrayRange(start: VmAny, end: VmAny): VmArray {
48
48
  const s = $ToNumber(start);
49
49
  const e = $ToNumber(end);
50
50
  if (isEmptyRange(s, e)) return [];
51
- assertArrayLength(s, e);
51
+ assertArrayLength(e - s + 1);
52
52
  const arr = [];
53
53
  for (let i = s; i <= e; i++) {
54
54
  arr.push(i);
@@ -60,7 +60,7 @@ export function $ArrayRangeExclusive(start: VmAny, end: VmAny): VmArray {
60
60
  const s = $ToNumber(start);
61
61
  const e = $ToNumber(end);
62
62
  if (isEmptyRange(s, e)) return [];
63
- assertArrayLength(s, e);
63
+ assertArrayLength(e - s);
64
64
  const arr = [];
65
65
  for (let i = s; i < e; i++) {
66
66
  arr.push(i);
@@ -46,19 +46,19 @@ export function isSame(a: VmValue, b: VmValue): boolean {
46
46
  // Compare record fields
47
47
  const aKeys = keys(a);
48
48
  const bKeys = keys(b);
49
- if (aKeys.length !== bKeys.length) {
50
- return false;
51
- }
52
- for (const key of aKeys) {
53
- if (!hasOwnEnumerable(b, key)) {
54
- return false;
55
- }
56
- /* c8 ignore next 2 */
49
+
50
+ const len = aKeys.length;
51
+ if (len !== bKeys.length) return false;
52
+
53
+ if (len === 0) return true;
54
+
55
+ let i = len;
56
+ while (i--) {
57
+ const key = aKeys[i]!;
58
+ if (!hasOwnEnumerable(b, key)) return false;
57
59
  const av = a[key] ?? null;
58
60
  const bv = b[key] ?? null;
59
- if (!isSame(av, bv)) {
60
- return false;
61
- }
61
+ if (!isSame(av, bv)) return false;
62
62
  }
63
63
  return true;
64
64
  }
@@ -1,5 +1,5 @@
1
1
  import { VmError } from '../../helpers/error.js';
2
- import { getPrototypeOf, hasOwn, apply, isArray } from '../../helpers/utils.js';
2
+ import { getPrototypeOf, getOwnPropertyNames, hasOwn, apply, isArray } from '../../helpers/utils.js';
3
3
  import { innerToString } from '../../helpers/convert/to-string.js';
4
4
  import { isVmExtern } from '../../helpers/types.js';
5
5
  import { kVmExtern } from '../../helpers/constants.js';
@@ -20,6 +20,10 @@ const TypedArrayToString = Uint8Array.prototype.toString;
20
20
  /** 获取类的名称,如果无法确定则返回 null */
21
21
  // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
22
22
  function classNameOf(kls: Function): string | null {
23
+ const { displayName } = kls as typeof kls & { displayName?: string };
24
+ if (typeof displayName === 'string' && displayName.trim()) {
25
+ return displayName.trim();
26
+ }
23
27
  const { name } = kls;
24
28
  if (typeof name == 'string' && name.length > 2) {
25
29
  // Looks like a non-minified name
@@ -39,7 +43,10 @@ export class VmExtern<const T extends object = object> extends VmWrapper<T> {
39
43
  super(value);
40
44
  }
41
45
 
42
- /** Check if the object has a property */
46
+ /**
47
+ * Check if the object has a property
48
+ * This method will be used in {@link get}, {@link set}, {@link has}, and {@link keys} methods
49
+ */
43
50
  protected access(key: string, read: boolean): boolean {
44
51
  // __proto__ and other “private” properties are not accessible
45
52
  if (key.startsWith('_')) return false;
@@ -107,15 +114,13 @@ export class VmExtern<const T extends object = object> extends VmWrapper<T> {
107
114
  } else {
108
115
  const keys = new Set<string>();
109
116
  let e: unknown = this.value;
110
- while (e && (typeof e == 'object' || typeof e == 'function')) {
111
- for (const key of Object.getOwnPropertyNames(e)) {
112
- if (this.access(key, true)) {
113
- keys.add(key);
114
- }
117
+ while (e != null && (typeof e == 'object' || typeof e == 'function')) {
118
+ for (const key of getOwnPropertyNames(e)) {
119
+ keys.add(key);
115
120
  }
116
- e = Object.getPrototypeOf(e);
121
+ e = getPrototypeOf(e);
117
122
  }
118
- return Array.from(keys);
123
+ return Array.from(keys).filter((key) => this.access(key, true));
119
124
  }
120
125
  }
121
126
  /** @inheritdoc */
@@ -123,7 +128,11 @@ export class VmExtern<const T extends object = object> extends VmWrapper<T> {
123
128
  if (!isVmExtern(other)) return false;
124
129
  return this.value === other.value && this.thisArg === other.thisArg;
125
130
  }
126
- /** @inheritdoc */
131
+ /**
132
+ * Should this extern be treated as array-like?
133
+ *
134
+ * By default, this method returns true if the wrapped value is an Array or a TypedArray.
135
+ */
127
136
  isArrayLike(): this is VmExtern<ArrayLike<unknown>> {
128
137
  return isArray(this.value) || (ArrayBuffer.isView(this.value) && 'length' in this.value);
129
138
  }
@@ -132,9 +141,11 @@ export class VmExtern<const T extends object = object> extends VmWrapper<T> {
132
141
  // eslint-disable-next-line @typescript-eslint/unbound-method
133
142
  const { toString } = this.value;
134
143
  if (typeof toString != 'function' || toString === ObjectToString || toString === FunctionToString) {
144
+ // When the toString method is not overridden or invalid, provide a better default representation
135
145
  return super.toString(useBraces);
136
146
  }
137
147
  if ((toString === ArrayToString || toString === TypedArrayToString) && this.isArrayLike()) {
148
+ // Handle array-like externs specially when using default toString
138
149
  const mapped = ArrayMap.call(this.value, (item: unknown) => {
139
150
  if (item === undefined) return '';
140
151
  return innerToString(wrapToVmValue(item ?? null, null, null), true);
@@ -143,6 +154,7 @@ export class VmExtern<const T extends object = object> extends VmWrapper<T> {
143
154
  if (useBraces) return `[${str}]`;
144
155
  return str;
145
156
  }
157
+ // Use the wrapped object's toString method
146
158
  return String(this.value);
147
159
  }
148
160
  /** @inheritdoc */
@@ -162,7 +174,7 @@ export class VmExtern<const T extends object = object> extends VmWrapper<T> {
162
174
  if (proto == null) {
163
175
  return 'Object: null prototype';
164
176
  }
165
- if (typeof proto.constructor === 'function' && proto.constructor.name) {
177
+ if (typeof proto.constructor === 'function') {
166
178
  return classNameOf(proto.constructor) ?? 'Object';
167
179
  }
168
180
  } else if (tag === 'Function' && 'prototype' in this.value && typeof this.value.prototype == 'object') {
package/cli.js DELETED
@@ -1,3 +0,0 @@
1
- import program from './dist/cli/index.js';
2
-
3
- await program.parseAsync();