@mirascript/mirascript 0.1.62-alpha.9 → 0.1.63

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 (90) hide show
  1. package/README.md +46 -0
  2. package/dist/{chunk-6CAGNGY6.js → chunk-5BBTXV5A.js} +270 -269
  3. package/dist/chunk-5BBTXV5A.js.map +6 -0
  4. package/dist/{chunk-VRGQ23AK.js → chunk-HZYARHEQ.js} +30 -38
  5. package/dist/chunk-HZYARHEQ.js.map +6 -0
  6. package/dist/compiler/emit/consts.d.ts.map +1 -1
  7. package/dist/compiler/emit-script.d.ts +7 -2
  8. package/dist/compiler/emit-script.d.ts.map +1 -1
  9. package/dist/compiler/index.d.ts +2 -0
  10. package/dist/compiler/index.d.ts.map +1 -1
  11. package/dist/compiler/worker.js +1 -1
  12. package/dist/helpers/constants.d.ts +1 -10
  13. package/dist/helpers/constants.d.ts.map +1 -1
  14. package/dist/helpers/serialize.d.ts.map +1 -1
  15. package/dist/helpers/types.d.ts +5 -1
  16. package/dist/helpers/types.d.ts.map +1 -1
  17. package/dist/helpers/utils.d.ts +7 -1
  18. package/dist/helpers/utils.d.ts.map +1 -1
  19. package/dist/index.js +7 -4
  20. package/dist/index.js.map +1 -1
  21. package/dist/subtle.js +3 -3
  22. package/dist/subtle.js.map +1 -1
  23. package/dist/vm/checkpoint.d.ts +3 -3
  24. package/dist/vm/checkpoint.d.ts.map +1 -1
  25. package/dist/vm/lib/global/debug.d.ts.map +1 -1
  26. package/dist/vm/lib/global/sequence/entries.d.ts.map +1 -1
  27. package/dist/vm/lib/global/sequence/with.d.ts.map +1 -1
  28. package/dist/vm/operations/array-range.d.ts +6 -0
  29. package/dist/vm/operations/array-range.d.ts.map +1 -0
  30. package/dist/vm/operations/call.d.ts.map +1 -1
  31. package/dist/vm/operations/common.d.ts +1 -1
  32. package/dist/vm/operations/common.d.ts.map +1 -1
  33. package/dist/vm/operations/compound.d.ts +10 -10
  34. package/dist/vm/operations/compound.d.ts.map +1 -1
  35. package/dist/vm/operations/convert.d.ts +4 -4
  36. package/dist/vm/operations/convert.d.ts.map +1 -1
  37. package/dist/vm/operations/helpers.d.ts +7 -13
  38. package/dist/vm/operations/helpers.d.ts.map +1 -1
  39. package/dist/vm/operations/index.d.ts +1 -0
  40. package/dist/vm/operations/index.d.ts.map +1 -1
  41. package/dist/vm/operations/operator.d.ts +22 -22
  42. package/dist/vm/operations/operator.d.ts.map +1 -1
  43. package/dist/vm/operations/slice.d.ts +2 -2
  44. package/dist/vm/operations/slice.d.ts.map +1 -1
  45. package/dist/vm/operations/type-check.d.ts +7 -7
  46. package/dist/vm/operations/type-check.d.ts.map +1 -1
  47. package/dist/vm/operations/utils.d.ts +2 -2
  48. package/dist/vm/operations/utils.d.ts.map +1 -1
  49. package/dist/vm/types/boundary.d.ts +1 -1
  50. package/dist/vm/types/boundary.d.ts.map +1 -1
  51. package/dist/vm/types/context.d.ts.map +1 -1
  52. package/dist/vm/types/function.d.ts +0 -4
  53. package/dist/vm/types/function.d.ts.map +1 -1
  54. package/dist/vm/types/index.d.ts +1 -1
  55. package/dist/vm/types/index.d.ts.map +1 -1
  56. package/package.json +21 -8
  57. package/src/compiler/diagnostic.ts +2 -2
  58. package/src/compiler/emit/consts.ts +1 -0
  59. package/src/compiler/emit/index.ts +5 -5
  60. package/src/compiler/emit-script.ts +15 -6
  61. package/src/compiler/index.ts +3 -2
  62. package/src/helpers/analyze.ts +1 -1
  63. package/src/helpers/constants.ts +1 -11
  64. package/src/helpers/serialize.ts +1 -1
  65. package/src/helpers/types.ts +16 -0
  66. package/src/helpers/utils.ts +2 -1
  67. package/src/vm/checkpoint.ts +6 -6
  68. package/src/vm/lib/global/debug.ts +0 -1
  69. package/src/vm/lib/global/sequence/entries.ts +2 -0
  70. package/src/vm/lib/global/sequence/map-filter.ts +4 -4
  71. package/src/vm/lib/global/sequence/with.ts +3 -2
  72. package/src/vm/lib/loader.ts +2 -2
  73. package/src/vm/operations/array-range.ts +37 -0
  74. package/src/vm/operations/call.ts +8 -7
  75. package/src/vm/operations/common.ts +2 -2
  76. package/src/vm/operations/compound.ts +24 -25
  77. package/src/vm/operations/convert.ts +8 -8
  78. package/src/vm/operations/helpers.ts +17 -51
  79. package/src/vm/operations/index.ts +1 -0
  80. package/src/vm/operations/operator.ts +64 -54
  81. package/src/vm/operations/slice.ts +5 -4
  82. package/src/vm/operations/type-check.ts +16 -19
  83. package/src/vm/operations/utils.ts +4 -4
  84. package/src/vm/types/boundary.ts +2 -2
  85. package/src/vm/types/context.ts +1 -2
  86. package/src/vm/types/function.ts +2 -21
  87. package/src/vm/types/index.ts +1 -0
  88. package/bench/index.ts +0 -45
  89. package/dist/chunk-6CAGNGY6.js.map +0 -6
  90. package/dist/chunk-VRGQ23AK.js.map +0 -6
@@ -1,86 +1,52 @@
1
- import { create, defineProperty, entries, isFinite } from '../../helpers/utils.js';
2
- import { VM_ARRAY_MAX_LENGTH, VM_FUNCTION_ANONYMOUS_NAME } from '../../helpers/constants.js';
1
+ import { create, defineProperty, entries } from '../../helpers/utils.js';
2
+ import { VM_FUNCTION_ANONYMOUS_NAME } from '../../helpers/constants.js';
3
3
  import { isVmConst } from '../../helpers/types.js';
4
4
  import type { VmFunctionLike } from '../types/function.js';
5
5
  import { DefaultVmContext, type VmContext } from '../types/context.js';
6
- import type { VmConst, VmAny, VmArray, VmValue, VmImmutable } from '../types/index.js';
6
+ import type { VmConst, VmAny, VmValue, VmImmutable } from '../types/index.js';
7
7
  import { VmModule } from '../types/module.js';
8
8
  import { VmFunction } from '../types/function.js';
9
9
  import { $AssertInit } from './common.js';
10
- import { $ToNumber } from './convert.js';
11
10
 
12
11
  /** 构造 module */
13
- export function $Module<T extends Record<string, () => VmImmutable>>(
12
+ export const $Module = <T extends Record<string, () => VmImmutable>>(
14
13
  name: string,
15
14
  body: T,
16
- ): VmModule<{ [K in keyof T]: ReturnType<T[K]> }> {
15
+ ): VmModule<{ [K in keyof T]: ReturnType<T[K]> }> => {
17
16
  const mod = create(null) as { [K in keyof T]: ReturnType<T[K]> };
18
17
  for (const [key, get] of entries(body)) {
19
- defineProperty(mod, key, { __proto__: null, get, enumerable: true });
18
+ defineProperty(mod, key, { __proto__: null, get, enumerable: true, configurable: true });
20
19
  }
21
20
  return new VmModule(name, mod);
22
- }
21
+ };
23
22
 
24
23
  /** 构造 record | array 元素 */
25
- export function $El(value: VmAny): VmConst {
24
+ export const $El = (value: VmAny): VmConst => {
26
25
  $AssertInit(value);
27
26
  if (!isVmConst(value)) return null;
28
27
  return value;
29
- }
28
+ };
30
29
 
31
30
  const EMPTY = create(null);
32
31
  /** 构造 record 可选元素 */
33
- export function $ElOpt(key: string, value: VmAny): VmConst {
32
+ export const $ElOpt = (key: string, value: VmAny): VmConst => {
34
33
  $AssertInit(value);
35
34
  if (value == null || !isVmConst(value)) return EMPTY;
36
35
  return { __proto__: null, [key]: value };
37
- }
36
+ };
38
37
 
39
38
  /** 构造函数和函数表达式 */
40
- export function $Fn<T extends VmFunctionLike>(name: string | null | undefined, fn: T): VmFunction<T> {
41
- return VmFunction(fn, { isLib: false, injectCp: false, name: name || VM_FUNCTION_ANONYMOUS_NAME });
42
- }
39
+ export const $Fn = <T extends VmFunctionLike>(name: string | null | undefined, fn: T): VmFunction<T> => {
40
+ return VmFunction(fn, { isLib: false, name: name || VM_FUNCTION_ANONYMOUS_NAME });
41
+ };
43
42
 
44
43
  /** 读取闭包上值 */
45
- export function $Upvalue<T extends VmValue>(value: T | undefined): T {
44
+ export const $Upvalue = <T extends VmValue>(value: T | undefined): T => {
46
45
  $AssertInit(value);
47
46
  return value;
48
- }
49
-
50
- const assertArrayLength = (len: number) => {
51
- if (len > VM_ARRAY_MAX_LENGTH) {
52
- throw new RangeError(`Array length exceeds maximum limit of ${VM_ARRAY_MAX_LENGTH}`);
53
- }
54
- };
55
- const isEmptyRange = (start: number, end: number) => {
56
- return !isFinite(start) || !isFinite(end) || start > end;
57
47
  };
58
- /** 构造范围数组 */
59
- export function $ArrayRange(start: VmAny, end: VmAny): VmArray {
60
- const s = $ToNumber(start);
61
- const e = $ToNumber(end);
62
- if (isEmptyRange(s, e)) return [];
63
- assertArrayLength(e - s + 1);
64
- const arr = [];
65
- for (let i = s; i <= e; i++) {
66
- arr.push(i);
67
- }
68
- return arr;
69
- }
70
- /** 构造范围数组(不包含结束值) */
71
- export function $ArrayRangeExclusive(start: VmAny, end: VmAny): VmArray {
72
- const s = $ToNumber(start);
73
- const e = $ToNumber(end);
74
- if (isEmptyRange(s, e)) return [];
75
- assertArrayLength(e - s);
76
- const arr = [];
77
- for (let i = s; i < e; i++) {
78
- arr.push(i);
79
- }
80
- return arr;
81
- }
82
48
 
83
49
  /** 默认执行上下文 */
84
- export function $GlobalFallback(): VmContext {
50
+ export const $GlobalFallback = (): VmContext => {
85
51
  return DefaultVmContext;
86
- }
52
+ };
@@ -7,3 +7,4 @@ export * from './helpers.js';
7
7
  export * from './compound.js';
8
8
  export * from './cp.js';
9
9
  export * from './call.js';
10
+ export * from './array-range.js';
@@ -7,111 +7,121 @@ import { isSame, overloadNumberString } from './utils.js';
7
7
 
8
8
  // String operations
9
9
  /** 字符串连接 */
10
- export function $Concat(...args: readonly string[]): string {
10
+ export function $Concat(...args: readonly VmAny[]): string {
11
11
  return args.map((a) => toFormat(a, null)).join('');
12
12
  }
13
13
 
14
14
  // Unary operations
15
15
  /** 正号 */
16
- export function $Pos(a: VmAny): number {
17
- return $ToNumber(a);
18
- }
16
+ export const $Pos = $ToNumber;
19
17
  /** 负号 */
20
- export function $Neg(a: VmAny): number {
21
- return -$ToNumber(a);
22
- }
18
+ export const $Neg = (a: VmAny): number => -$ToNumber(a);
23
19
  /** 非 */
24
- export function $Not(a: VmAny): boolean {
25
- return !$ToBoolean(a);
26
- }
20
+ export const $Not = (a: VmAny): boolean => !$ToBoolean(a);
27
21
 
28
22
  // Math operations
23
+ const add = (a: VmAny, b: VmAny): number => $ToNumber(a) + $ToNumber(b);
29
24
  /** 加法 */
30
- export function $Add(a: VmAny, b: VmAny): number {
31
- return $ToNumber(a) + $ToNumber(b);
32
- }
25
+ export const $Add = (a: VmAny, b: VmAny): number => {
26
+ if (typeof a == 'number' && typeof b == 'number') return a + b;
27
+ return add(a, b);
28
+ };
29
+ const sub = (a: VmAny, b: VmAny): number => $ToNumber(a) - $ToNumber(b);
33
30
  /** 减法 */
34
- export function $Sub(a: VmAny, b: VmAny): number {
35
- return $ToNumber(a) - $ToNumber(b);
36
- }
31
+ export const $Sub = (a: VmAny, b: VmAny): number => {
32
+ if (typeof a == 'number' && typeof b == 'number') return a - b;
33
+ return sub(a, b);
34
+ };
35
+ const mul = (a: VmAny, b: VmAny): number => $ToNumber(a) * $ToNumber(b);
37
36
  /** 乘法 */
38
- export function $Mul(a: VmAny, b: VmAny): number {
39
- return $ToNumber(a) * $ToNumber(b);
40
- }
37
+ export const $Mul = (a: VmAny, b: VmAny): number => {
38
+ if (typeof a == 'number' && typeof b == 'number') return a * b;
39
+ return mul(a, b);
40
+ };
41
+ const div = (a: VmAny, b: VmAny): number => $ToNumber(a) / $ToNumber(b);
41
42
  /** 除法 */
42
- export function $Div(a: VmAny, b: VmAny): number {
43
- return $ToNumber(a) / $ToNumber(b);
44
- }
43
+ export const $Div = (a: VmAny, b: VmAny): number => {
44
+ if (typeof a == 'number' && typeof b == 'number') return a / b;
45
+ return div(a, b);
46
+ };
47
+ const mod = (a: VmAny, b: VmAny): number => $ToNumber(a) % $ToNumber(b);
45
48
  /** 取模 */
46
- export function $Mod(a: VmAny, b: VmAny): number {
47
- return $ToNumber(a) % $ToNumber(b);
48
- }
49
+ export const $Mod = (a: VmAny, b: VmAny): number => {
50
+ if (typeof a == 'number' && typeof b == 'number') return a % b;
51
+ return mod(a, b);
52
+ };
53
+ const pow = (a: VmAny, b: VmAny): number => $ToNumber(a) ** $ToNumber(b);
49
54
  /** 乘方 */
50
- export function $Pow(a: VmAny, b: VmAny): number {
51
- return $ToNumber(a) ** $ToNumber(b);
52
- }
55
+ export const $Pow = (a: VmAny, b: VmAny): number => {
56
+ if (typeof a == 'number' && typeof b == 'number') return a ** b;
57
+ return pow(a, b);
58
+ };
53
59
 
54
60
  // Logical operations without short-circuiting
61
+ const and = (a: VmAny, b: VmAny): boolean => $ToBoolean(a) && $ToBoolean(b);
55
62
  /** 与 */
56
- export function $And(a: VmAny, b: VmAny): boolean {
57
- return $ToBoolean(a) && $ToBoolean(b);
58
- }
63
+ export const $And = (a: VmAny, b: VmAny): boolean => {
64
+ if (typeof a == 'boolean' && typeof b == 'boolean') return a && b;
65
+ return and(a, b);
66
+ };
67
+ const or = (a: VmAny, b: VmAny): boolean => $ToBoolean(a) || $ToBoolean(b);
59
68
  /** 或 */
60
- export function $Or(a: VmAny, b: VmAny): boolean {
61
- return $ToBoolean(a) || $ToBoolean(b);
62
- }
69
+ export const $Or = (a: VmAny, b: VmAny): boolean => {
70
+ if (typeof a == 'boolean' && typeof b == 'boolean') return a || b;
71
+ return or(a, b);
72
+ };
63
73
 
64
74
  // Comparison operations
65
75
  /** 大于 */
66
- export function $Gt(a: VmAny, b: VmAny): boolean {
76
+ export const $Gt = (a: VmAny, b: VmAny): boolean => {
67
77
  if (overloadNumberString(a, b)) {
68
78
  return $ToNumber(a) > $ToNumber(b);
69
79
  } else {
70
80
  return $ToString(a) > $ToString(b);
71
81
  }
72
- }
82
+ };
73
83
  /** 大于等于 */
74
- export function $Gte(a: VmAny, b: VmAny): boolean {
84
+ export const $Gte = (a: VmAny, b: VmAny): boolean => {
75
85
  if (overloadNumberString(a, b)) {
76
86
  return $ToNumber(a) >= $ToNumber(b);
77
87
  } else {
78
88
  return $ToString(a) >= $ToString(b);
79
89
  }
80
- }
90
+ };
81
91
  /** 小于 */
82
- export function $Lt(a: VmAny, b: VmAny): boolean {
92
+ export const $Lt = (a: VmAny, b: VmAny): boolean => {
83
93
  if (overloadNumberString(a, b)) {
84
94
  return $ToNumber(a) < $ToNumber(b);
85
95
  } else {
86
96
  return $ToString(a) < $ToString(b);
87
97
  }
88
- }
98
+ };
89
99
  /** 小于等于 */
90
- export function $Lte(a: VmAny, b: VmAny): boolean {
100
+ export const $Lte = (a: VmAny, b: VmAny): boolean => {
91
101
  if (overloadNumberString(a, b)) {
92
102
  return $ToNumber(a) <= $ToNumber(b);
93
103
  } else {
94
104
  return $ToString(a) <= $ToString(b);
95
105
  }
96
- }
106
+ };
97
107
 
98
108
  // Equality operations
99
109
  /** 等于 */
100
- export function $Eq(a: VmAny, b: VmAny): boolean {
110
+ export const $Eq = (a: VmAny, b: VmAny): boolean => {
101
111
  $AssertInit(a);
102
112
  $AssertInit(b);
103
113
  // Number comparison is a special case to handle NaN correctly
104
114
  if (typeof a == 'number' && typeof b == 'number') return a === b;
105
115
  return isSame(a, b);
106
- }
116
+ };
107
117
  /** 不等于 */
108
- export function $Neq(a: VmAny, b: VmAny): boolean {
118
+ export const $Neq = (a: VmAny, b: VmAny): boolean => {
109
119
  return !$Eq(a, b);
110
- }
120
+ };
111
121
 
112
122
  const { abs, min } = Math;
113
123
  /** 近似等于 */
114
- export function $Aeq(a: VmAny, b: VmAny): boolean {
124
+ export const $Aeq = (a: VmAny, b: VmAny): boolean => {
115
125
  if (overloadNumberString(a, b)) {
116
126
  const an = $ToNumber(a);
117
127
  const bn = $ToNumber(b);
@@ -135,19 +145,19 @@ export function $Aeq(a: VmAny, b: VmAny): boolean {
135
145
  const bn = bi.normalize('NFC');
136
146
  return an === bn;
137
147
  }
138
- }
148
+ };
139
149
  /** 不近似等于 */
140
- export function $Naeq(a: VmAny, b: VmAny): boolean {
150
+ export const $Naeq = (a: VmAny, b: VmAny): boolean => {
141
151
  return !$Aeq(a, b);
142
- }
152
+ };
143
153
 
144
154
  /** 全等于 */
145
- export function $Same(a: VmAny, b: VmAny): boolean {
155
+ export const $Same = (a: VmAny, b: VmAny): boolean => {
146
156
  $AssertInit(a);
147
157
  $AssertInit(b);
148
158
  return isSame(a, b);
149
- }
159
+ };
150
160
  /** 不全等于 */
151
- export function $Nsame(a: VmAny, b: VmAny): boolean {
161
+ export const $Nsame = (a: VmAny, b: VmAny): boolean => {
152
162
  return !$Same(a, b);
153
- }
163
+ };
@@ -13,6 +13,7 @@ const sliceCore = (value: VmArray, start: number, end: number, exclusive: boolea
13
13
 
14
14
  if (isNaN(start)) start = 0;
15
15
  else if (start < 0) start = length + start;
16
+
16
17
  if (isNaN(end)) end = exclusive ? length : length - 1;
17
18
  else if (end < 0) end = length + end;
18
19
 
@@ -26,18 +27,18 @@ const sliceCore = (value: VmArray, start: number, end: number, exclusive: boolea
26
27
  };
27
28
 
28
29
  /** 获取数组切片 */
29
- export function $Slice(value: VmAny, start: VmAny, end: VmAny): VmArray {
30
+ export const $Slice = (value: VmAny, start: VmAny, end: VmAny): VmArray => {
30
31
  $AssertInit(value);
31
32
  if (!isVmArray(value)) throw new VmError(`Expected array, got ${display(value)}`, []);
32
33
  const s = start != null ? $ToNumber(start) : 0;
33
34
  const e = end != null ? $ToNumber(end) : value.length - 1;
34
35
  return sliceCore(value, s, e, false);
35
- }
36
+ };
36
37
  /** 获取数组切片(不包含结束位置) */
37
- export function $SliceExclusive(value: VmAny, start: VmAny, end: VmAny): VmArray {
38
+ export const $SliceExclusive = (value: VmAny, start: VmAny, end: VmAny): VmArray => {
38
39
  $AssertInit(value);
39
40
  if (!isVmArray(value)) throw new VmError(`Expected array, got ${display(value)}`, []);
40
41
  const s = start != null ? $ToNumber(start) : 0;
41
42
  const e = end != null ? $ToNumber(end) : value.length;
42
43
  return sliceCore(value, s, e, true);
43
- }
44
+ };
@@ -1,45 +1,42 @@
1
1
  import { VmError } from '../../helpers/error.js';
2
- import { isVmArray, isVmRecord, isVmWrapper } from '../../helpers/types.js';
2
+ import { getVmType, isVmArray, isVmRecord } from '../../helpers/types.js';
3
3
  import type { VmTypeName, VmAny, VmArray, VmRecord, VmValue } from '../types/index.js';
4
4
  import { $AssertInit } from './common.js';
5
5
 
6
6
  /** 获取值的类型名称 */
7
- export function $Type(value: VmAny): VmTypeName {
7
+ export const $Type = (value: VmAny): VmTypeName => {
8
8
  // 允许未初始化值通过
9
9
  if (value == null) return 'nil';
10
- if (isVmWrapper(value)) return value.type;
11
- if (isVmArray(value)) return 'array';
12
- if (typeof value == 'object') return 'record';
13
- return typeof value as VmTypeName;
14
- }
10
+ return getVmType(value);
11
+ };
15
12
  /** 判断值是否为布尔值 */
16
- export function $IsBoolean(value: VmAny): value is boolean {
13
+ export const $IsBoolean: (value: VmAny) => value is boolean = (value) => {
17
14
  $AssertInit(value);
18
15
  return typeof value == 'boolean';
19
- }
16
+ };
20
17
  /** 判断值是否为数字 */
21
- export function $IsNumber(value: VmAny): value is number {
18
+ export const $IsNumber: (value: VmAny) => value is number = (value) => {
22
19
  $AssertInit(value);
23
20
  return typeof value == 'number';
24
- }
21
+ };
25
22
  /** 判断值是否为字符串 */
26
- export function $IsString(value: VmAny): value is string {
23
+ export const $IsString: (value: VmAny) => value is string = (value) => {
27
24
  $AssertInit(value);
28
25
  return typeof value == 'string';
29
- }
26
+ };
30
27
  /** 判断值是否为记录 */
31
- export function $IsRecord(value: VmAny): value is VmRecord {
28
+ export const $IsRecord: (value: VmAny) => value is VmRecord = (value) => {
32
29
  $AssertInit(value);
33
30
  return isVmRecord(value);
34
- }
31
+ };
35
32
  /** 判断值是否为数组 */
36
- export function $IsArray(value: VmAny): value is VmArray {
33
+ export const $IsArray: (value: VmAny) => value is VmArray = (value) => {
37
34
  $AssertInit(value);
38
35
  return isVmArray(value);
39
- }
36
+ };
40
37
  /** 断言值非 nil */
41
- export function $AssertNonNil<T extends VmValue>(value: T | undefined): asserts value is NonNullable<T> {
38
+ export const $AssertNonNil: <T extends VmValue>(value: T | undefined) => asserts value is NonNullable<T> = (value) => {
42
39
  $AssertInit(value);
43
40
  if (value !== null) return;
44
41
  throw new VmError(`Expected non-nil value`, null);
45
- }
42
+ };
@@ -6,16 +6,16 @@ import type { VmAny, VmValue } from '../types/index.js';
6
6
  * 确定操作的重载
7
7
  * @returns 如果应按数字处理则返回 true;如果应按字符串处理则返回 false
8
8
  */
9
- export function overloadNumberString(a: VmAny, b: VmAny): boolean {
9
+ export const overloadNumberString = (a: VmAny, b: VmAny): boolean => {
10
10
  if (typeof a == 'number' || typeof b == 'number') return true;
11
11
  if (typeof a == 'string' || typeof b == 'string') return false;
12
12
  return true;
13
- }
13
+ };
14
14
 
15
15
  /**
16
16
  * 检查两个 VmValue 是否相同
17
17
  */
18
- export function isSame(a: VmValue, b: VmValue): boolean {
18
+ export const isSame = (a: VmValue, b: VmValue): boolean => {
19
19
  // Check for NaN
20
20
  if (typeof a == 'number' && typeof b == 'number') {
21
21
  return a === b || (isNaN(a) && isNaN(b));
@@ -63,4 +63,4 @@ export function isSame(a: VmValue, b: VmValue): boolean {
63
63
  return true;
64
64
  }
65
65
  return false;
66
- }
66
+ };
@@ -1,10 +1,10 @@
1
1
  import { defineProperty, apply } from '../../helpers/utils.js';
2
2
  import { isVmExtern, isVmFunction, isVmWrapper } from '../../helpers/types.js';
3
3
  import { kVmFunctionProxy } from '../../helpers/constants.js';
4
+ import { $Call } from '../operations/call.js';
5
+ import type { VmAny, VmConst, VmModule, VmPrimitive, VmValue } from './index.js';
4
6
  import type { VmFunctionLike, VmFunction } from './function.js';
5
7
  import { VmExtern } from './extern.js';
6
- import type { VmAny, VmConst, VmModule, VmPrimitive, VmValue } from './index.js';
7
- import { $Call } from '../operations/call.js';
8
8
 
9
9
  /** 创建 Mirascript 函数在宿主语言运行的代理 */
10
10
  export function toVmFunctionProxy<T extends VmFunctionLike>(fn: VmFunction<T>): T {
@@ -1,10 +1,9 @@
1
- import { create, defineProperty, hasOwn, keys } from '../../helpers/utils.js';
1
+ import { create, defineProperty, hasOwn, keys, freeze } from '../../helpers/utils.js';
2
2
  import { VmError } from '../../helpers/error.js';
3
3
  import { kVmContext } from '../../helpers/constants.js';
4
4
  import type { VmAny, VmImmutable, VmValue } from './index.js';
5
5
  import { wrapToVmValue } from './boundary.js';
6
6
  import { VmFunction } from './function.js';
7
- const { freeze } = Object;
8
7
 
9
8
  /** MiraScript 执行上下文 */
10
9
  export interface VmContext {
@@ -1,11 +1,10 @@
1
1
  import type { Writable } from 'type-fest';
2
2
  import type { DiagnosticCode } from '@mirascript/constants';
3
- import { defineProperty } from '../../helpers/utils.js';
3
+ import { defineProperty, freeze } from '../../helpers/utils.js';
4
4
  import { kVmFunction, VM_FUNCTION_ANONYMOUS_NAME } from '../../helpers/constants.js';
5
5
  import { isVmFunction } from '../../helpers/types.js';
6
6
  import type { VmAny, VmValue } from './index.js';
7
7
  import { fromVmFunctionProxy } from './boundary.js';
8
- import { CpEnter, CpExit } from '../checkpoint.js';
9
8
  import type { VmLib } from '../lib/helpers.js';
10
9
 
11
10
  /**
@@ -37,8 +36,6 @@ export type VmFunctionInfo = {
37
36
  readonly returnsType?: string;
38
37
  /** 文档字符串 */
39
38
  readonly examples?: string[];
40
- /** 如果添加了包装,返回原函数 */
41
- readonly original?: VmFunctionLike;
42
39
  /** 标记为弃用 */
43
40
  readonly deprecated?: { use?: string; message: DiagnosticCode };
44
41
  };
@@ -47,8 +44,6 @@ export type VmFunctionInfo = {
47
44
  export type VmFunctionOption = Partial<Omit<VmFunctionInfo, 'original'>> & {
48
45
  /** 函数名称 */
49
46
  readonly name?: string | null | undefined;
50
- /** 是否注入检查点 */
51
- readonly injectCp?: boolean;
52
47
  };
53
48
 
54
49
  const nameIfNotAnonymous = <T>({ name }: { name: string | undefined }, fallback: T): string | T => {
@@ -76,7 +71,6 @@ export function VmFunction<T extends VmFunctionLike>(
76
71
  opt = {
77
72
  ...option,
78
73
  isLib: true,
79
- injectCp: false,
80
74
  name: nameIfNotAnonymous(option, null),
81
75
  };
82
76
  } else {
@@ -96,20 +90,7 @@ export function VmFunction<T extends VmFunctionLike>(
96
90
  deprecated: opt.deprecated ?? undefined,
97
91
  };
98
92
  const name = opt.name ?? fn.name;
99
- if (opt.injectCp) {
100
- const original = fn;
101
- info.original = original;
102
- fn = ((...args) => {
103
- try {
104
- CpEnter();
105
- const ret = original(...args);
106
- return ret;
107
- } finally {
108
- CpExit();
109
- }
110
- }) as typeof fn;
111
- }
112
93
  defineProperty(fn, 'name', { value: name, configurable: true });
113
- defineProperty(fn, kVmFunction, { value: Object.freeze(info) });
94
+ defineProperty(fn, kVmFunction, { value: freeze(info) });
114
95
  return fn as VmFunction<T>;
115
96
  }
@@ -72,6 +72,7 @@ export {
72
72
  isVmValue,
73
73
  isVmWrapper,
74
74
  getVmFunctionInfo,
75
+ getVmType,
75
76
  } from '../../helpers/types.js';
76
77
 
77
78
  export { wrapToVmValue, unwrapFromVmValue } from './boundary.js';
package/bench/index.ts DELETED
@@ -1,45 +0,0 @@
1
- import { Bench } from 'tinybench';
2
- import { compile, compileSync, createVmContext } from '@mirascript/mirascript';
3
-
4
- const bench = new Bench({ name: 'simple benchmark', time: 100 });
5
- const source = `sin(x) + cos(y + PI / 2) + `.repeat(1) + '0';
6
- const env = { x: 1, y: 2 };
7
-
8
- bench
9
- .add('compile', async () => {
10
- await Promise.all(Array.from({ length: 10 }).map(async () => compile(source)));
11
- })
12
- .add('compileSync', () => {
13
- compileSync(source);
14
- });
15
-
16
- bench.add('createVmContext', () => {
17
- return createVmContext(env);
18
- });
19
-
20
- const vmContext = createVmContext(env);
21
- const script = compileSync(source);
22
- bench.add('run', () => {
23
- return script(vmContext);
24
- });
25
-
26
- bench.add('nativeCompile', () => {
27
- // eslint-disable-next-line @typescript-eslint/no-implied-eval
28
- return new Function('context', `const {sin,cos,PI,x,y} = context; return ${source};`);
29
- });
30
- bench.add('nativeCreateContext', () => {
31
- return { __proto__: Math, ...env };
32
- });
33
- const nativeContext = { __proto__: Math, ...env };
34
- // eslint-disable-next-line @typescript-eslint/no-implied-eval
35
- const nativeScript = new Function('context', `const {sin,cos,PI,x,y} = context; return ${source};`) as (
36
- context: Record<string, unknown>,
37
- ) => unknown;
38
-
39
- bench.add('nativeRun', () => {
40
- return nativeScript(nativeContext);
41
- });
42
-
43
- await bench.run();
44
- // eslint-disable-next-line no-console
45
- console.table(bench.table());