@mirascript/mirascript 0.1.22 → 0.1.24
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/bench/index.ts +45 -0
- package/dist/{chunk-PECLT2P6.js → chunk-AZICQWZD.js} +35 -9
- package/dist/chunk-AZICQWZD.js.map +6 -0
- package/dist/{chunk-4T5YE7LC.js → chunk-K7JDJG3G.js} +26 -31
- package/dist/chunk-K7JDJG3G.js.map +6 -0
- package/dist/{chunk-7HH5Y4QO.js → chunk-UCIDBTZL.js} +599 -535
- package/dist/chunk-UCIDBTZL.js.map +6 -0
- package/dist/chunk-X6LYEGOK.js +69 -0
- package/dist/chunk-X6LYEGOK.js.map +6 -0
- package/dist/cli/index.js +4 -4
- package/dist/compiler/compile-fast.d.ts.map +1 -1
- package/dist/compiler/create-script.d.ts +6 -2
- package/dist/compiler/create-script.d.ts.map +1 -1
- package/dist/compiler/emit/constants.d.ts +1 -1
- package/dist/compiler/emit/constants.d.ts.map +1 -1
- package/dist/compiler/emit/index.d.ts.map +1 -1
- package/dist/compiler/worker.js +1 -1
- package/dist/helpers/analyze.d.ts +8 -0
- package/dist/helpers/analyze.d.ts.map +1 -0
- package/dist/index.js +3 -3
- package/dist/subtle.d.ts +3 -2
- package/dist/subtle.d.ts.map +1 -1
- package/dist/subtle.js +12 -7
- package/dist/vm/operations/call.d.ts +3 -0
- package/dist/vm/operations/call.d.ts.map +1 -0
- package/dist/vm/operations/common.d.ts +3 -0
- package/dist/vm/operations/common.d.ts.map +1 -0
- package/dist/vm/operations/compound.d.ts +12 -0
- package/dist/vm/operations/compound.d.ts.map +1 -0
- package/dist/vm/operations/convert.d.ts +6 -0
- package/dist/vm/operations/convert.d.ts.map +1 -0
- package/dist/vm/operations/cp.d.ts +2 -0
- package/dist/vm/operations/cp.d.ts.map +1 -0
- package/dist/vm/operations/helpers.d.ts +19 -0
- package/dist/vm/operations/helpers.d.ts.map +1 -0
- package/dist/vm/operations/index.d.ts +10 -0
- package/dist/vm/operations/index.d.ts.map +1 -0
- package/dist/vm/operations/operator.d.ts +24 -0
- package/dist/vm/operations/operator.d.ts.map +1 -0
- package/dist/vm/operations/slice.d.ts +4 -0
- package/dist/vm/operations/slice.d.ts.map +1 -0
- package/dist/vm/operations/type-check.d.ts +9 -0
- package/dist/vm/operations/type-check.d.ts.map +1 -0
- package/dist/vm/operations/utils.d.ts +11 -0
- package/dist/vm/operations/utils.d.ts.map +1 -0
- package/dist/vm/types/boundary.d.ts +2 -3
- package/dist/vm/types/boundary.d.ts.map +1 -1
- package/dist/vm/types/context.d.ts +2 -4
- package/dist/vm/types/context.d.ts.map +1 -1
- package/dist/vm/types/extern.d.ts +3 -3
- package/dist/vm/types/extern.d.ts.map +1 -1
- package/dist/vm/types/index.d.ts +1 -1
- package/dist/vm/types/index.d.ts.map +1 -1
- package/package.json +6 -4
- package/src/compiler/compile-fast.ts +32 -12
- package/src/compiler/create-script.ts +19 -5
- package/src/compiler/emit/constants.ts +1 -1
- package/src/compiler/emit/index.ts +18 -25
- package/src/compiler/emit/sourcemap.ts +8 -8
- package/src/helpers/analyze.ts +70 -0
- package/src/subtle.ts +3 -2
- package/src/vm/lib/global/debug.ts +1 -1
- package/src/vm/lib/global/sequence/all-any.ts +2 -2
- package/src/vm/lib/global/sequence/find.ts +2 -2
- package/src/vm/lib/global/sequence/map-filter.ts +1 -1
- package/src/vm/lib/global/sequence/sort.ts +1 -1
- package/src/vm/lib/global/sequence/with.ts +2 -2
- package/src/vm/lib/global/sequence/zip.ts +1 -1
- package/src/vm/lib/helpers.ts +1 -1
- package/src/vm/lib/mod/matrix.ts +2 -2
- package/src/vm/operations/call.ts +18 -0
- package/src/vm/operations/common.ts +6 -0
- package/src/vm/operations/compound.ts +148 -0
- package/src/vm/operations/convert.ts +24 -0
- package/src/vm/operations/cp.ts +1 -0
- package/src/vm/{helpers.ts → operations/helpers.ts} +17 -18
- package/src/vm/operations/index.ts +9 -0
- package/src/vm/operations/operator.ts +131 -0
- package/src/vm/operations/slice.ts +41 -0
- package/src/vm/operations/type-check.ts +38 -0
- package/src/vm/operations/utils.ts +66 -0
- package/src/vm/types/boundary.ts +18 -13
- package/src/vm/types/context.ts +72 -38
- package/src/vm/types/extern.ts +24 -9
- package/src/vm/types/index.ts +1 -1
- package/dist/chunk-4T5YE7LC.js.map +0 -6
- package/dist/chunk-7HH5Y4QO.js.map +0 -6
- package/dist/chunk-PECLT2P6.js.map +0 -6
- package/dist/chunk-RNLB52WP.js +0 -1
- package/dist/chunk-RNLB52WP.js.map +0 -6
- package/dist/vm/env.d.ts +0 -3
- package/dist/vm/env.d.ts.map +0 -1
- package/dist/vm/helpers.d.ts +0 -20
- package/dist/vm/helpers.d.ts.map +0 -1
- package/dist/vm/operations.d.ts +0 -49
- package/dist/vm/operations.d.ts.map +0 -1
- package/src/vm/env.ts +0 -16
- package/src/vm/operations.ts +0 -412
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { TypeName, VmAny, VmArray, VmRecord, VmValue } from '../types/index.js';
|
|
2
|
+
export declare const $Type: (value: VmAny) => TypeName;
|
|
3
|
+
export declare const $IsBoolean: (value: VmAny) => value is boolean;
|
|
4
|
+
export declare const $IsNumber: (value: VmAny) => value is number;
|
|
5
|
+
export declare const $IsString: (value: VmAny) => value is string;
|
|
6
|
+
export declare const $IsRecord: (value: VmAny) => value is VmRecord;
|
|
7
|
+
export declare const $IsArray: (value: VmAny) => value is VmArray;
|
|
8
|
+
export declare const $AssertNonNil: (value: VmAny) => asserts value is NonNullable<VmValue>;
|
|
9
|
+
//# sourceMappingURL=type-check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type-check.d.ts","sourceRoot":"","sources":["../../../src/vm/operations/type-check.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAGrF,eAAO,MAAM,KAAK,GAAI,OAAO,KAAK,KAAG,QAOpC,CAAC;AACF,eAAO,MAAM,UAAU,GAAI,OAAO,KAAK,KAAG,KAAK,IAAI,OAGlD,CAAC;AACF,eAAO,MAAM,SAAS,GAAI,OAAO,KAAK,KAAG,KAAK,IAAI,MAGjD,CAAC;AACF,eAAO,MAAM,SAAS,GAAI,OAAO,KAAK,KAAG,KAAK,IAAI,MAGjD,CAAC;AACF,eAAO,MAAM,SAAS,GAAI,OAAO,KAAK,KAAG,KAAK,IAAI,QAGjD,CAAC;AACF,eAAO,MAAM,QAAQ,GAAI,OAAO,KAAK,KAAG,KAAK,IAAI,OAGhD,CAAC;AACF,eAAO,MAAM,aAAa,GAAI,OAAO,KAAK,KAAG,QAAQ,KAAK,IAAI,WAAW,CAAC,OAAO,CAIhF,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { VmAny, VmValue } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* 确定操作的重载
|
|
4
|
+
* @returns 如果应按数字处理则返回 true;如果应按字符串处理则返回 false
|
|
5
|
+
*/
|
|
6
|
+
export declare function overloadNumberString(a: VmAny, b: VmAny): boolean;
|
|
7
|
+
/**
|
|
8
|
+
* 检查两个 VmValue 是否相同
|
|
9
|
+
*/
|
|
10
|
+
export declare function isSame(a: VmValue, b: VmValue): boolean;
|
|
11
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/vm/operations/utils.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAExD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,GAAG,OAAO,CAIhE;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,OAAO,CAgDtD"}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import type { VmFunctionLike, VmFunction } from './function.js';
|
|
2
|
-
import { VmExtern } from './extern.js';
|
|
3
2
|
import type { VmAny, VmConst, VmPrimitive, VmValue } from './index.js';
|
|
4
3
|
/** 创建 Mirascript 函数在宿主语言运行的代理 */
|
|
5
4
|
export declare function toVmFunctionProxy<T extends VmFunctionLike>(fn: VmFunction<T>): T;
|
|
6
5
|
/** 解开 Mirascript 函数在宿主语言运行的代理 */
|
|
7
|
-
export declare function fromVmFunctionProxy<T extends VmFunctionLike>(fn: T): VmFunction<T> |
|
|
6
|
+
export declare function fromVmFunctionProxy<T extends VmFunctionLike>(fn: T): VmFunction<T> | null;
|
|
8
7
|
/** 将宿主语言的值包装为 Mirascript 类型 */
|
|
9
|
-
export declare function wrapToVmValue(value: unknown, thisArg?:
|
|
8
|
+
export declare function wrapToVmValue(value: unknown, thisArg?: unknown, assumeVmValue?: ((obj: object) => obj is Exclude<VmConst, VmPrimitive>) | null): VmValue;
|
|
10
9
|
/** 取消宿主语言的值的 Mirascript 包装 */
|
|
11
10
|
export declare function unwrapFromVmValue(value: VmAny): unknown;
|
|
12
11
|
//# sourceMappingURL=boundary.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"boundary.d.ts","sourceRoot":"","sources":["../../../src/vm/types/boundary.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"boundary.d.ts","sourceRoot":"","sources":["../../../src/vm/types/boundary.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhE,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAY,WAAW,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAGjF,iCAAiC;AACjC,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,cAAc,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAmBhF;AAED,iCAAiC;AACjC,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,cAAc,EAAE,EAAE,EAAE,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAOzF;AAED,+BAA+B;AAC/B,wBAAgB,aAAa,CACzB,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,OAAc,EACvB,aAAa,GAAE,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,GAAG,IAAI,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,GAAG,IAAW,GACrF,OAAO,CA0BT;AAYD,+BAA+B;AAC/B,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAYvD"}
|
|
@@ -17,9 +17,7 @@ export interface VmContext {
|
|
|
17
17
|
has(key: string): boolean;
|
|
18
18
|
}
|
|
19
19
|
/** MiraScript 执行上下文 */
|
|
20
|
-
export type VmContextRecord = Record<string,
|
|
21
|
-
/** MiraScript 执行上下文 */
|
|
22
|
-
export type VmContextRecordLoose = Record<string, VmAny>;
|
|
20
|
+
export type VmContextRecord = Record<string, VmAny>;
|
|
23
21
|
export declare const VM_SHARED_CONTEXT: Record<string, VmImmutable>;
|
|
24
22
|
export declare const VM_SHARED_CONTEXT_DESCRIPTIONS: Record<string, string | undefined>;
|
|
25
23
|
/** 定义在所有 MiraScript 执行上下文中共享的全局变量 */
|
|
@@ -29,7 +27,7 @@ export declare const DefaultVmContext: Readonly<VmContext>;
|
|
|
29
27
|
/** 获取用于执行脚本的默认执行上下文 */
|
|
30
28
|
export declare function createVmContext(): Readonly<VmContext>;
|
|
31
29
|
/** 创建用于执行脚本的执行上下文 */
|
|
32
|
-
export declare function createVmContext(vmValues?:
|
|
30
|
+
export declare function createVmContext(vmValues?: VmContextRecord | null, externValues?: Record<string, unknown> | null, describer?: ((key: string) => string | undefined) | null): VmContext;
|
|
33
31
|
/** 创建用于执行脚本的执行上下文 */
|
|
34
32
|
export declare function createVmContext(getter: (key: string) => VmValue | undefined, enumerator?: (() => Iterable<string>) | null, describer?: ((key: string) => string | undefined) | null): VmContext;
|
|
35
33
|
//# sourceMappingURL=context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/vm/types/context.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/vm/types/context.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAK9D,uBAAuB;AACvB,MAAM,WAAW,SAAS;IACtB,YAAY;IACZ,QAAQ,CAAC,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC;IAC5B,0BAA0B;IAC1B,IAAI,IAAI,SAAS,MAAM,EAAE,CAAC;IAC1B,oCAAoC;IACpC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAC1C;;;OAGG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1B,oCAAoC;IACpC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC7B;AACD,uBAAuB;AACvB,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AACpD,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAgB,CAAC;AAC3E,eAAO,MAAM,8BAA8B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAgB,CAAC;AAS/F,qCAAqC;AACrC,wBAAgB,oBAAoB,CAChC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,WAAW,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,KAAK,CAAC,EAClD,QAAQ,UAAQ,EAChB,WAAW,GAAE,MAAM,GAAG,IAAI,GAAG,SAAqB,GACnD,IAAI,CAcN;AAED,aAAa;AACb,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,SAAS,CAsB/C,CAAC;AAqHH,uBAAuB;AACvB,wBAAgB,eAAe,IAAI,QAAQ,CAAC,SAAS,CAAC,CAAC;AACvD,qBAAqB;AACrB,wBAAgB,eAAe,CAC3B,QAAQ,CAAC,EAAE,eAAe,GAAG,IAAI,EACjC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,EAC7C,SAAS,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC,GAAG,IAAI,GACzD,SAAS,CAAC;AACb,qBAAqB;AACrB,wBAAgB,eAAe,CAC3B,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,GAAG,SAAS,EAC5C,UAAU,CAAC,EAAE,CAAC,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,EAC5C,SAAS,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC,GAAG,IAAI,GACzD,SAAS,CAAC"}
|
|
@@ -2,8 +2,8 @@ import type { TypeName, VmAny, VmConst, VmPrimitive, VmValue } from './index.js'
|
|
|
2
2
|
import { VmWrapper } from './wrapper.js';
|
|
3
3
|
/** 包装 Mirascript `extern` 类型的对象 */
|
|
4
4
|
export declare class VmExtern<const T extends object = object> extends VmWrapper<T> {
|
|
5
|
-
readonly thisArg: T
|
|
6
|
-
constructor(value: T, thisArg?: T
|
|
5
|
+
readonly thisArg: ThisParameterType<T> | null;
|
|
6
|
+
constructor(value: T, thisArg?: ThisParameterType<T> | null);
|
|
7
7
|
/** Check if the object has a property */
|
|
8
8
|
protected access(key: string, read: boolean): boolean;
|
|
9
9
|
/** 决定是否对属性进行包装 */
|
|
@@ -17,7 +17,7 @@ export declare class VmExtern<const T extends object = object> extends VmWrapper
|
|
|
17
17
|
/** Call extern value */
|
|
18
18
|
call(args: readonly VmValue[]): VmAny;
|
|
19
19
|
/** @inheritdoc */
|
|
20
|
-
keys(): string[];
|
|
20
|
+
keys(includeNonEnumerable?: boolean): string[];
|
|
21
21
|
/** @inheritdoc */
|
|
22
22
|
same(other: VmAny): boolean;
|
|
23
23
|
/** @inheritdoc */
|
|
@@ -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;
|
|
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;AAWzC,mCAAmC;AACnC,qBAAa,QAAQ,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,SAAS,CAAC,CAAC,CAAC;IAGnE,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,IAAI;gBAD7C,KAAK,EAAE,CAAC,EACC,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,SAAS,CAAC,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,SAAS,GAAG,KAAK,IAAI,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC;IAIxG,kBAAkB;IACT,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAGlC,kBAAkB;IACT,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK;IAKhC,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;IACT,QAAQ,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM;IAiB7C,kBAAkB;IAClB,IAAa,IAAI,IAAI,QAAQ,CAE5B;IACD,kBAAkB;IAClB,IAAa,GAAG,IAAI,MAAM,CAqCzB;CACJ"}
|
package/dist/vm/types/index.d.ts
CHANGED
|
@@ -51,7 +51,7 @@ export interface VmValueMap {
|
|
|
51
51
|
}
|
|
52
52
|
export { isVmAny, isVmArray, isVmArrayLikeRecord, isVmArrayLikeRecordByEntires, isVmArrayLikeRecordByKeys, isVmCallable, isVmConst, isVmContext, isVmExtern, isVmFunction, isVmImmutable, isVmModule, isVmPrimitive, isVmRecord, isVmScript, isVmValue, isVmWrapper, getVmFunctionInfo, } from '../../helpers/types.js';
|
|
53
53
|
export { wrapToVmValue, unwrapFromVmValue } from './boundary.js';
|
|
54
|
-
export { type VmContext, defineVmContextValue, createVmContext } from './context.js';
|
|
54
|
+
export { type VmContext, type VmContextRecord, defineVmContextValue, createVmContext } from './context.js';
|
|
55
55
|
export { VmExtern } from './extern.js';
|
|
56
56
|
export { VmFunction, type VmFunctionInfo, type VmFunctionLike, type VmFunctionOption } from './function.js';
|
|
57
57
|
export { VmModule } from './module.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/vm/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,WAAW;AACX,MAAM,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC;AAExC,6BAA6B;AAC7B,MAAM,MAAM,eAAe,GAAG,SAAS,CAAC;AACxC,qBAAqB;AACrB,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAC3D;;;GAGG;AACH,MAAM,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;AACzD;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAAG;IACnB,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;CAC/C,CAAC;AACF,2BAA2B;AAC3B,MAAM,MAAM,OAAO,GAAG,WAAW,GAAG,QAAQ,GAAG,OAAO,CAAC;AACvD,2BAA2B;AAC3B,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC;AAC1D,0BAA0B;AAC1B,MAAM,MAAM,OAAO,GAAG,WAAW,GAAG,QAAQ,CAAC;AAC7C,kCAAkC;AAClC,MAAM,MAAM,KAAK,GAAG,OAAO,GAAG,eAAe,CAAC;AAE9C,aAAa;AACb,MAAM,WAAW,UAAU;IACvB,SAAS;IACT,GAAG,EAAE,IAAI,CAAC;IACV,UAAU;IACV,MAAM,EAAE,MAAM,CAAC;IACf,SAAS;IACT,MAAM,EAAE,MAAM,CAAC;IACf,UAAU;IACV,OAAO,EAAE,OAAO,CAAC;IACjB,oBAAoB;IACpB,MAAM,EAAE,QAAQ,CAAC;IACjB,oBAAoB;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,oBAAoB;IACpB,QAAQ,EAAE,UAAU,CAAC;IACrB,aAAa;IACb,MAAM,EAAE,QAAQ,CAAC;IACjB,oBAAoB;IACpB,MAAM,EAAE,QAAQ,CAAC;CACpB;AAED,OAAO,EACH,OAAO,EACP,SAAS,EACT,mBAAmB,EACnB,4BAA4B,EAC5B,yBAAyB,EACzB,YAAY,EACZ,SAAS,EACT,WAAW,EACX,UAAU,EACV,YAAY,EACZ,aAAa,EACb,UAAU,EACV,aAAa,EACb,UAAU,EACV,UAAU,EACV,SAAS,EACT,WAAW,EACX,iBAAiB,GACpB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEjE,OAAO,EAAE,KAAK,SAAS,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/vm/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,WAAW;AACX,MAAM,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC;AAExC,6BAA6B;AAC7B,MAAM,MAAM,eAAe,GAAG,SAAS,CAAC;AACxC,qBAAqB;AACrB,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAC3D;;;GAGG;AACH,MAAM,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;AACzD;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAAG;IACnB,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;CAC/C,CAAC;AACF,2BAA2B;AAC3B,MAAM,MAAM,OAAO,GAAG,WAAW,GAAG,QAAQ,GAAG,OAAO,CAAC;AACvD,2BAA2B;AAC3B,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC;AAC1D,0BAA0B;AAC1B,MAAM,MAAM,OAAO,GAAG,WAAW,GAAG,QAAQ,CAAC;AAC7C,kCAAkC;AAClC,MAAM,MAAM,KAAK,GAAG,OAAO,GAAG,eAAe,CAAC;AAE9C,aAAa;AACb,MAAM,WAAW,UAAU;IACvB,SAAS;IACT,GAAG,EAAE,IAAI,CAAC;IACV,UAAU;IACV,MAAM,EAAE,MAAM,CAAC;IACf,SAAS;IACT,MAAM,EAAE,MAAM,CAAC;IACf,UAAU;IACV,OAAO,EAAE,OAAO,CAAC;IACjB,oBAAoB;IACpB,MAAM,EAAE,QAAQ,CAAC;IACjB,oBAAoB;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,oBAAoB;IACpB,QAAQ,EAAE,UAAU,CAAC;IACrB,aAAa;IACb,MAAM,EAAE,QAAQ,CAAC;IACjB,oBAAoB;IACpB,MAAM,EAAE,QAAQ,CAAC;CACpB;AAED,OAAO,EACH,OAAO,EACP,SAAS,EACT,mBAAmB,EACnB,4BAA4B,EAC5B,yBAAyB,EACzB,YAAY,EACZ,SAAS,EACT,WAAW,EACX,UAAU,EACV,YAAY,EACZ,aAAa,EACb,UAAU,EACV,aAAa,EACb,UAAU,EACV,UAAU,EACV,SAAS,EACT,WAAW,EACX,iBAAiB,GACpB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEjE,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,eAAe,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC3G,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC5G,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mirascript/mirascript",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.24",
|
|
4
4
|
"author": "CloudPSS",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "An expression based scripting language.",
|
|
@@ -36,15 +36,16 @@
|
|
|
36
36
|
"commander": "^14.0.2",
|
|
37
37
|
"source-map-js": "^1.2.1",
|
|
38
38
|
"supports-color": "^10.2.2",
|
|
39
|
-
"@mirascript/bindings": "~0.1.
|
|
39
|
+
"@mirascript/bindings": "~0.1.24"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@types/node": "^
|
|
42
|
+
"@types/node": "^25.0.1",
|
|
43
43
|
"@types/sinon": "^21.0.0",
|
|
44
44
|
"ava": "^6.4.1",
|
|
45
45
|
"c8": "^10.1.3",
|
|
46
46
|
"madge": "^8.0.0",
|
|
47
47
|
"sinon": "^21.0.0",
|
|
48
|
+
"tinybench": "^6.0.0",
|
|
48
49
|
"type-fest": "^5.3.1"
|
|
49
50
|
},
|
|
50
51
|
"scripts": {
|
|
@@ -54,6 +55,7 @@
|
|
|
54
55
|
"mirascript": "node --enable-source-maps ./dist/cli/index.js",
|
|
55
56
|
"deps": "madge --circular --warning ./src",
|
|
56
57
|
"clean": "rimraf dist",
|
|
57
|
-
"test": "c8 ava"
|
|
58
|
+
"test": "c8 ava",
|
|
59
|
+
"bench": "node ./bench/index.ts"
|
|
58
60
|
}
|
|
59
61
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { wrapScript, type VmScript } from './create-script.js';
|
|
2
2
|
import type { TranspileOptions } from './types.js';
|
|
3
|
-
import { GlobalFallback } from '../vm/
|
|
3
|
+
import { $GlobalFallback } from '../vm/operations/index.js';
|
|
4
4
|
import type { VmContext, VmValue } from '../vm/index.js';
|
|
5
|
-
import { isFinite } from '../helpers/utils.js';
|
|
5
|
+
import { defineProperty, isFinite } from '../helpers/utils.js';
|
|
6
6
|
import { keywords } from './keywords.js';
|
|
7
7
|
|
|
8
8
|
const REG_NUMBER_FULL = /^(?:[+-])?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
|
|
@@ -28,16 +28,30 @@ function constantFiniteNumber(value: number): () => number {
|
|
|
28
28
|
return () => 0;
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
const f = () => value;
|
|
32
|
+
defineProperty(f, 'toString', {
|
|
33
|
+
value: () => {
|
|
34
|
+
return `() => ${value};`;
|
|
35
|
+
},
|
|
36
|
+
writable: false,
|
|
37
|
+
enumerable: false,
|
|
38
|
+
configurable: false,
|
|
39
|
+
});
|
|
40
|
+
return f;
|
|
33
41
|
}
|
|
34
42
|
/** 构造返回常量的函数 */
|
|
35
43
|
function constantString(value: string): () => string {
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
44
|
+
const f = () => value;
|
|
45
|
+
defineProperty(f, 'toString', {
|
|
46
|
+
value: () => {
|
|
47
|
+
return `() => ${JSON.stringify(value)};`;
|
|
48
|
+
},
|
|
49
|
+
writable: false,
|
|
50
|
+
enumerable: false,
|
|
51
|
+
configurable: false,
|
|
52
|
+
});
|
|
53
|
+
return f;
|
|
39
54
|
}
|
|
40
|
-
|
|
41
55
|
/** 构造返回常量的函数 */
|
|
42
56
|
function nan(): () => number {
|
|
43
57
|
return () => 0 / 0;
|
|
@@ -69,10 +83,16 @@ function nil(): () => null {
|
|
|
69
83
|
|
|
70
84
|
/** 构造返回全局变量的函数 */
|
|
71
85
|
function globalVariable(id: string): (global: VmContext | undefined) => VmValue {
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
86
|
+
const f = (global = $GlobalFallback()): VmValue => global.get(id);
|
|
87
|
+
defineProperty(f, 'toString', {
|
|
88
|
+
value: () => {
|
|
89
|
+
return `(global = $GlobalFallback()) => global.get(${JSON.stringify(id)});`;
|
|
90
|
+
},
|
|
91
|
+
writable: false,
|
|
92
|
+
enumerable: false,
|
|
93
|
+
configurable: false,
|
|
94
|
+
});
|
|
95
|
+
return f;
|
|
76
96
|
}
|
|
77
97
|
|
|
78
98
|
let kw: Set<string> | undefined;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { kVmScript, VM_SCRIPT_NAME } from '../helpers/constants.js';
|
|
2
|
-
import { defineProperty } from '../helpers/utils.js';
|
|
3
|
-
import
|
|
2
|
+
import { defineProperty, entries } from '../helpers/utils.js';
|
|
3
|
+
import * as operations from '../vm/operations/index.js';
|
|
4
4
|
import type { VmValue, VmContext } from '../vm/types/index.js';
|
|
5
5
|
import type { InputMode, ScriptInput } from './types.js';
|
|
6
6
|
|
|
@@ -14,7 +14,9 @@ export type VmScript = VmScriptLike & {
|
|
|
14
14
|
readonly source: string;
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* 将 JS 函数包装为 Mirascript 脚本
|
|
19
|
+
*/
|
|
18
20
|
export function wrapScript(source: ScriptInput, mode: InputMode, script: VmScriptLike): VmScript {
|
|
19
21
|
/* c8 ignore next 3 */
|
|
20
22
|
if (kVmScript in script) {
|
|
@@ -30,12 +32,24 @@ export function wrapScript(source: ScriptInput, mode: InputMode, script: VmScrip
|
|
|
30
32
|
return script as VmScript;
|
|
31
33
|
}
|
|
32
34
|
|
|
33
|
-
|
|
35
|
+
const [keys, values] = (() => {
|
|
36
|
+
const keys: string[] = [];
|
|
37
|
+
const values: unknown[] = [];
|
|
38
|
+
for (const [key, value] of entries(operations)) {
|
|
39
|
+
keys.push(key);
|
|
40
|
+
values.push(value);
|
|
41
|
+
}
|
|
42
|
+
return [keys.join(','), values] as const;
|
|
43
|
+
})();
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* 从 MiraScript 编译结果源代码生成 Mirascript 脚本
|
|
47
|
+
*/
|
|
34
48
|
export function createScript(source: ScriptInput, mode: InputMode, code: string): VmScript {
|
|
35
49
|
let script;
|
|
36
50
|
try {
|
|
37
51
|
// eslint-disable-next-line @typescript-eslint/no-implied-eval, @typescript-eslint/no-unsafe-call
|
|
38
|
-
script = new Function(
|
|
52
|
+
script = new Function(keys, `'use strict';\nreturn ${code}`)(...values) as VmScriptLike;
|
|
39
53
|
/* c8 ignore next 3 */
|
|
40
54
|
} catch (error) {
|
|
41
55
|
throw new Error(`Failed to create script`, { cause: error });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const SCRIPT_PREFIX = `
|
|
1
|
+
export const SCRIPT_PREFIX = `((global = $GlobalFallback()) => { try { $CpEnter();`;
|
|
@@ -128,7 +128,7 @@ export class Emitter {
|
|
|
128
128
|
continue;
|
|
129
129
|
}
|
|
130
130
|
this.codeOffset++;
|
|
131
|
-
const body = this.ident(-1) + `} finally { CpExit(); } });`;
|
|
131
|
+
const body = this.ident(-1) + `} finally { $CpExit(); } });`;
|
|
132
132
|
this.codeLines.push(body);
|
|
133
133
|
this.closureCounter--;
|
|
134
134
|
this.identCounter--;
|
|
@@ -204,8 +204,8 @@ export class Emitter {
|
|
|
204
204
|
const opt = opcode === OpCode.FieldOpt;
|
|
205
205
|
// Use computed property names to avoid prototype pollution
|
|
206
206
|
code = opt
|
|
207
|
-
?
|
|
208
|
-
: `[${field_name}]:
|
|
207
|
+
? `...$ElOpt(${field_name}, ${this.rv(value)}),`
|
|
208
|
+
: `[${field_name}]: $El(${this.rv(value)}),`;
|
|
209
209
|
break;
|
|
210
210
|
}
|
|
211
211
|
case OpCode.FieldOptDyn:
|
|
@@ -214,8 +214,8 @@ export class Emitter {
|
|
|
214
214
|
const value = read();
|
|
215
215
|
const opt = opcode === OpCode.FieldOptDyn;
|
|
216
216
|
code = opt
|
|
217
|
-
?
|
|
218
|
-
: `[${this.rv(field)}]:
|
|
217
|
+
? `...$ElOpt(${this.rv(field)}, ${this.rv(value)}),`
|
|
218
|
+
: `[${this.rv(field)}]: $El(${this.rv(value)}),`;
|
|
219
219
|
break;
|
|
220
220
|
}
|
|
221
221
|
case OpCode.FieldOptIndex:
|
|
@@ -223,9 +223,7 @@ export class Emitter {
|
|
|
223
223
|
const field = this.readIndex(wide);
|
|
224
224
|
const value = read();
|
|
225
225
|
const opt = opcode === OpCode.FieldOptIndex;
|
|
226
|
-
code = opt
|
|
227
|
-
? `...ElementOpt(${field}, ${this.rv(value)}),`
|
|
228
|
-
: `[${field}]: Element(${this.rv(value)}),`;
|
|
226
|
+
code = opt ? `...$ElOpt(${field}, ${this.rv(value)}),` : `[${field}]: $El(${this.rv(value)}),`;
|
|
229
227
|
break;
|
|
230
228
|
}
|
|
231
229
|
case OpCode.Spread: {
|
|
@@ -263,25 +261,25 @@ export class Emitter {
|
|
|
263
261
|
switch (opcode) {
|
|
264
262
|
case OpCode.Item: {
|
|
265
263
|
const value = read();
|
|
266
|
-
code =
|
|
264
|
+
code = `$El(${this.rv(value)}),`;
|
|
267
265
|
break;
|
|
268
266
|
}
|
|
269
267
|
case OpCode.ItemRange: {
|
|
270
268
|
const start = this.readIndex(wide);
|
|
271
269
|
const end = this.readIndex(wide);
|
|
272
|
-
code =
|
|
270
|
+
code = `...$ArrayRange(${start}, ${end}),`;
|
|
273
271
|
break;
|
|
274
272
|
}
|
|
275
273
|
case OpCode.ItemRangeDyn: {
|
|
276
274
|
const start = read();
|
|
277
275
|
const end = read();
|
|
278
|
-
code =
|
|
276
|
+
code = `...$ArrayRange(${this.rv(start)}, ${this.rv(end)}),`;
|
|
279
277
|
break;
|
|
280
278
|
}
|
|
281
279
|
case OpCode.ItemRangeExclusiveDyn: {
|
|
282
280
|
const start = read();
|
|
283
281
|
const end = read();
|
|
284
|
-
code =
|
|
282
|
+
code = `...$ArrayRangeExclusive(${this.rv(start)}, ${this.rv(end)}),`;
|
|
285
283
|
break;
|
|
286
284
|
}
|
|
287
285
|
case OpCode.Spread: {
|
|
@@ -329,7 +327,7 @@ export class Emitter {
|
|
|
329
327
|
const wv = this.wv(i + 1, -1);
|
|
330
328
|
if (varg && i === argn - 1) {
|
|
331
329
|
// 最后一个参数为可变参数
|
|
332
|
-
return `...
|
|
330
|
+
return `...args`;
|
|
333
331
|
}
|
|
334
332
|
return `${wv} = null`;
|
|
335
333
|
});
|
|
@@ -341,16 +339,13 @@ export class Emitter {
|
|
|
341
339
|
if (script) {
|
|
342
340
|
code = `${SCRIPT_PREFIX} var ${regs};`;
|
|
343
341
|
} else {
|
|
344
|
-
if (
|
|
345
|
-
code = `${this.wv(reg)} = Function(null ,(${args.join(', ')}) => { try { CpEnter(); var ${regs};`;
|
|
346
|
-
} else {
|
|
347
|
-
const index = this.functions.length;
|
|
342
|
+
if (this.options.sourceMap) {
|
|
348
343
|
this.functions.push(this.codeLines.length);
|
|
349
|
-
code = `${this.wv(reg)} = Function(fnName_${index} ,(${args.join(', ')}) => { try { CpEnter(); var ${regs};`;
|
|
350
344
|
}
|
|
345
|
+
code = `${this.wv(reg)} = $Fn(null, (${args.join(', ')}) => { try { $CpEnter(); var ${regs};`;
|
|
351
346
|
}
|
|
352
347
|
if (varg) {
|
|
353
|
-
code += ` var ${this.wv(argn, -1)} =
|
|
348
|
+
code += ` var ${this.wv(argn, -1)} = $VArgs(args);`;
|
|
354
349
|
}
|
|
355
350
|
break;
|
|
356
351
|
}
|
|
@@ -546,7 +541,7 @@ export class Emitter {
|
|
|
546
541
|
reg = read();
|
|
547
542
|
const level = read();
|
|
548
543
|
const up = read();
|
|
549
|
-
code = `${this.wv(reg)} = Upvalue(${this.rv(up, level)});`;
|
|
544
|
+
code = `${this.wv(reg)} = $Upvalue(${this.rv(up, level)});`;
|
|
550
545
|
break;
|
|
551
546
|
}
|
|
552
547
|
case OpCode.SetUpvalue: {
|
|
@@ -640,7 +635,7 @@ export class Emitter {
|
|
|
640
635
|
const regs = createArray(nreg - 1, (i) => this.wv(i + 2, -1));
|
|
641
636
|
regs.unshift('_');
|
|
642
637
|
const ir = this.wv(1, -1);
|
|
643
|
-
code = `for (let ${ir} of $Iterable(${this.rv(iterable)})) { ${ir} ??= null; Cp(); let ${regs.join(', ')};`;
|
|
638
|
+
code = `for (let ${ir} of $Iterable(${this.rv(iterable)})) { ${ir} ??= null; $Cp(); let ${regs.join(', ')};`;
|
|
644
639
|
break;
|
|
645
640
|
}
|
|
646
641
|
case OpCode.LoopRange:
|
|
@@ -652,14 +647,14 @@ export class Emitter {
|
|
|
652
647
|
const regs = createArray(nreg - 1, (i) => this.wv(i + 2, -1));
|
|
653
648
|
regs.unshift('_');
|
|
654
649
|
const i = this.wv(1, -1);
|
|
655
|
-
code = `for (let start = $ToNumber(${this.rv(start)}), end = $ToNumber(${this.rv(end)}), ${i} = start; ${i} ${exclusive ? '<' : '<='} end; ${i} += 1) { Cp(); let ${regs.join(', ')};`;
|
|
650
|
+
code = `for (let start = $ToNumber(${this.rv(start)}), end = $ToNumber(${this.rv(end)}), ${i} = start; ${i} ${exclusive ? '<' : '<='} end; ${i} += 1) { $Cp(); let ${regs.join(', ')};`;
|
|
656
651
|
break;
|
|
657
652
|
}
|
|
658
653
|
case OpCode.Loop: {
|
|
659
654
|
const nreg = read();
|
|
660
655
|
const regs = createArray(nreg, (i) => this.wv(i + 1, -1));
|
|
661
656
|
regs.unshift('_');
|
|
662
|
-
code = `while (true) { Cp(); let ${regs.join(', ')};`;
|
|
657
|
+
code = `while (true) { $Cp(); let ${regs.join(', ')};`;
|
|
663
658
|
break;
|
|
664
659
|
}
|
|
665
660
|
case OpCode.Break: {
|
|
@@ -724,8 +719,6 @@ export class Emitter {
|
|
|
724
719
|
addSourceMap(): void {
|
|
725
720
|
if (this.options.sourceMap) {
|
|
726
721
|
createSourceMap(this.source, this.sourcemaps, this.codeLines, this.functions, this.options);
|
|
727
|
-
} else {
|
|
728
|
-
this.codeLines.unshift(`'use strict';`);
|
|
729
722
|
}
|
|
730
723
|
}
|
|
731
724
|
}
|
|
@@ -91,20 +91,20 @@ export function createSourceMap(
|
|
|
91
91
|
source: fileName,
|
|
92
92
|
});
|
|
93
93
|
}
|
|
94
|
-
let fnNames = `'use strict';`;
|
|
95
94
|
if (typeof source === 'string') {
|
|
96
95
|
const lines = source.split(/\r?\n/);
|
|
97
|
-
for (
|
|
98
|
-
const
|
|
99
|
-
const
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
96
|
+
for (const codeLineNo of functions) {
|
|
97
|
+
const mapping = sourcemaps[codeLineNo];
|
|
98
|
+
const sourceLine = mapping ? lines[mapping.startLineNumber - 1] : undefined;
|
|
99
|
+
const fnName =
|
|
100
|
+
mapping && sourceLine ? sourceLine.slice(mapping.startColumn - 1, mapping.endColumn - 1) : '';
|
|
101
|
+
if (!fnName) continue;
|
|
102
|
+
const codeLine = codeLines[codeLineNo]!;
|
|
103
|
+
codeLines[codeLineNo] = codeLine.replace(`= $Fn(null,`, `= $Fn(${toJsLiteral(fnName)},`);
|
|
103
104
|
}
|
|
104
105
|
}
|
|
105
106
|
const sourceURL = hasSchema ? fileName : `${ORIGIN}${fileName}`;
|
|
106
107
|
const dataUrl = toDataUrl(map.toString());
|
|
107
|
-
codeLines.unshift(fnNames);
|
|
108
108
|
codeLines.push(
|
|
109
109
|
// Prevent source map from being recognized as of this file
|
|
110
110
|
`${SOURCE_URL}=${sourceURL}.js`,
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { generateBytecodeSync } from '../compiler/generate-bytecode.js';
|
|
2
|
+
import { DiagnosticCode, parseDiagnostics } from '../compiler/diagnostic.js';
|
|
3
|
+
import { REG_IDENTIFIER } from './constants.js';
|
|
4
|
+
import type { InputMode } from '../compiler/types.js';
|
|
5
|
+
|
|
6
|
+
/** 一个访问链,第一个元素为全局变量名称 */
|
|
7
|
+
export type GlobalReferenceChain = readonly [globalVariableName: string, ...fields: ReadonlyArray<string | number>];
|
|
8
|
+
|
|
9
|
+
const REG_SPILT = /\s*!?\s*\.\s*/u;
|
|
10
|
+
const REG_CHAIN = new RegExp(
|
|
11
|
+
String.raw`^(${REG_IDENTIFIER.source})(?:${REG_SPILT.source}(?:\d+|${REG_IDENTIFIER.source}))*`,
|
|
12
|
+
'u',
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
const { parseInt } = Number;
|
|
16
|
+
/**
|
|
17
|
+
* 分析表达式依赖的全局变量
|
|
18
|
+
*/
|
|
19
|
+
export function analyzeGlobalReferences(expression: string, mode?: InputMode): GlobalReferenceChain[] {
|
|
20
|
+
if (expression.trim() === '') {
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
const [code, diagnostics] = generateBytecodeSync(expression, {
|
|
24
|
+
input_mode: mode || 'Script',
|
|
25
|
+
diagnostic_position_encoding: 'Utf16',
|
|
26
|
+
// 需要设为 true 以便在编译失败时返回空的 bytecode
|
|
27
|
+
diagnostic_error: true,
|
|
28
|
+
diagnostic_warning: false,
|
|
29
|
+
diagnostic_info: false,
|
|
30
|
+
diagnostic_hint: false,
|
|
31
|
+
diagnostic_reference: false,
|
|
32
|
+
diagnostic_tag: true,
|
|
33
|
+
diagnostic_sourcemap: false,
|
|
34
|
+
trivia: false,
|
|
35
|
+
});
|
|
36
|
+
if (code == null || diagnostics.length === 0) {
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
const parsedDiagnostics = parseDiagnostics(expression, diagnostics);
|
|
40
|
+
const globals = parsedDiagnostics.tags.filter((t) => t.code === DiagnosticCode.GlobalVariable);
|
|
41
|
+
if (globals.length === 0) {
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
const lines = expression.split(/\r?\n/);
|
|
45
|
+
const result = new Set<string>();
|
|
46
|
+
for (const global of globals) {
|
|
47
|
+
// 分析每个全局变量访问
|
|
48
|
+
const line = lines[global.range.startLineNumber - 1];
|
|
49
|
+
if (!line) continue;
|
|
50
|
+
const access = line.slice(global.range.startColumn - 1);
|
|
51
|
+
const chain = REG_CHAIN.exec(access);
|
|
52
|
+
if (chain == null) continue;
|
|
53
|
+
const globalName = chain[1];
|
|
54
|
+
if (globalName?.length !== global.range.endColumn - global.range.startColumn) continue;
|
|
55
|
+
const chainStr = chain[0].split(REG_SPILT).join('.');
|
|
56
|
+
result.add(chainStr);
|
|
57
|
+
}
|
|
58
|
+
const accessChains: GlobalReferenceChain[] = [];
|
|
59
|
+
for (const chainStr of result) {
|
|
60
|
+
const parts = chainStr.split('.').map((part) => {
|
|
61
|
+
if (/^\d/.test(part)) {
|
|
62
|
+
// 数字开头的部分一定是数字
|
|
63
|
+
return parseInt(part, 10);
|
|
64
|
+
}
|
|
65
|
+
return part;
|
|
66
|
+
});
|
|
67
|
+
accessChains.push(parts as unknown as GlobalReferenceChain);
|
|
68
|
+
}
|
|
69
|
+
return accessChains;
|
|
70
|
+
}
|
package/src/subtle.ts
CHANGED
|
@@ -4,8 +4,7 @@ export { keywords } from './compiler/keywords.js';
|
|
|
4
4
|
export * as constants from './helpers/constants.js';
|
|
5
5
|
export * as convert from './helpers/convert/index.js';
|
|
6
6
|
export { DefaultVmContext } from './vm/types/context.js';
|
|
7
|
-
export * as operations from './vm/operations.js';
|
|
8
|
-
export * as helpers from './vm/helpers.js';
|
|
7
|
+
export * as operations from './vm/operations/index.js';
|
|
9
8
|
export {
|
|
10
9
|
display as serializeForDisplay,
|
|
11
10
|
serialize,
|
|
@@ -21,4 +20,6 @@ export {
|
|
|
21
20
|
export { lib } from './vm/lib/index.js';
|
|
22
21
|
export * from './compiler/diagnostic.js';
|
|
23
22
|
export { emitScript } from './compiler/emit-script.js';
|
|
23
|
+
export { createScript, wrapScript } from './compiler/create-script.js';
|
|
24
24
|
export { generateBytecode, generateBytecodeSync, type VmBytecodeResult } from './compiler/generate-bytecode.js';
|
|
25
|
+
export { type GlobalReferenceChain, analyzeGlobalReferences } from './helpers/analyze.js';
|
|
@@ -101,7 +101,7 @@ export const panic = VmLib(
|
|
|
101
101
|
// eslint-disable-next-line no-console
|
|
102
102
|
if (message === undefined) console.error(...panic.prefix);
|
|
103
103
|
// eslint-disable-next-line no-console
|
|
104
|
-
else console.error(...panic.prefix, serializeValue(message, '', panic.serializer));
|
|
104
|
+
else console.error(...panic.prefix, serializeValue(message, '', panic.serializer) ?? message);
|
|
105
105
|
const mgsStr = toString(message, null);
|
|
106
106
|
const error = !mgsStr ? 'panic' : 'panic: ' + mgsStr;
|
|
107
107
|
throw new VmError(error, undefined);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { toBoolean } from '../../../../helpers/convert/to-boolean.js';
|
|
2
2
|
import { entries } from '../../../../helpers/utils.js';
|
|
3
|
-
import { Cp } from '../../../
|
|
4
|
-
import { $Call } from '../../../operations.js';
|
|
3
|
+
import { Cp } from '../../../checkpoint.js';
|
|
4
|
+
import { $Call } from '../../../operations/index.js';
|
|
5
5
|
import { isVmArray } from '../../../types/index.js';
|
|
6
6
|
import { expectArrayOrRecord, expectCallable, VmLib } from '../../helpers.js';
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { toBoolean } from '../../../../helpers/convert/to-boolean.js';
|
|
2
2
|
import { entries } from '../../../../helpers/utils.js';
|
|
3
|
-
import { Cp } from '../../../
|
|
4
|
-
import { $Call, $Same } from '../../../operations.js';
|
|
3
|
+
import { Cp } from '../../../checkpoint.js';
|
|
4
|
+
import { $Call, $Same } from '../../../operations/index.js';
|
|
5
5
|
import { type VmValue, isVmArray, isVmCallable } from '../../../types/index.js';
|
|
6
6
|
import { VmLib, expectArrayOrRecord, required } from '../../helpers.js';
|
|
7
7
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { toBoolean } from '../../../../helpers/convert/to-boolean.js';
|
|
2
|
-
import { $Call } from '../../../operations.js';
|
|
2
|
+
import { $Call } from '../../../operations/index.js';
|
|
3
3
|
import { isVmConst, type VmAny, type VmValue } from '../../../types/index.js';
|
|
4
4
|
import { VmLib, expectCallable, expectConst, map as mapImpl } from '../../helpers.js';
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { toNumber } from '../../../../helpers/convert/to-number.js';
|
|
2
|
-
import { $Call } from '../../../operations.js';
|
|
2
|
+
import { $Call } from '../../../operations/index.js';
|
|
3
3
|
import type { VmAny, VmConst, VmValue } from '../../../types/index.js';
|
|
4
4
|
import { VmLib, expectArray, expectCallable } from '../../helpers.js';
|
|
5
5
|
|
|
@@ -2,7 +2,7 @@ import { VM_ARRAY_MAX_LENGTH } from '../../../../helpers/constants.js';
|
|
|
2
2
|
import { toNumber, toString } from '../../../../helpers/convert/index.js';
|
|
3
3
|
import { isVmArray, isVmRecord } from '../../../../helpers/types.js';
|
|
4
4
|
import { isArray, isInteger, isNaN } from '../../../../helpers/utils.js';
|
|
5
|
-
import {
|
|
5
|
+
import { $El } from '../../../operations/helpers.js';
|
|
6
6
|
import type { VmArray, VmConst, VmValue } from '../../../types/index.js';
|
|
7
7
|
import { VmLib, expectArrayOrRecord, expectConst, throwError } from '../../helpers.js';
|
|
8
8
|
|
|
@@ -69,7 +69,7 @@ const normalizeEntries = (data: VmConst, entries: Array<VmValue | undefined>): M
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
const value = entries[i + 1]!;
|
|
72
|
-
entryData.set(key,
|
|
72
|
+
entryData.set(key, $El(value));
|
|
73
73
|
}
|
|
74
74
|
return entryData;
|
|
75
75
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { display } from '../../../../helpers/serialize.js';
|
|
2
|
-
import { Cp } from '../../../
|
|
2
|
+
import { Cp } from '../../../checkpoint.js';
|
|
3
3
|
import { isVmArray, type VmConst, type VmArray } from '../../../types/index.js';
|
|
4
4
|
import { VmLib, throwError } from '../../helpers.js';
|
|
5
5
|
import { entries } from './entries.js';
|