@mirascript/mirascript 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-5FQWUJIY.js +766 -0
- package/dist/chunk-5FQWUJIY.js.map +6 -0
- package/dist/chunk-BTDGMWFK.js +202 -0
- package/dist/chunk-BTDGMWFK.js.map +6 -0
- package/dist/chunk-DCXIWIW5.js +3419 -0
- package/dist/chunk-DCXIWIW5.js.map +6 -0
- package/dist/chunk-RAPJ3XLV.js +10 -0
- package/dist/chunk-RAPJ3XLV.js.map +6 -0
- package/dist/cli/execute.d.ts +4 -0
- package/dist/cli/execute.d.ts.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +191 -0
- package/dist/cli/index.js.map +6 -0
- package/dist/cli/print.d.ts +4 -0
- package/dist/cli/print.d.ts.map +1 -0
- package/dist/compiler/compile-bytecode.d.ts +12 -0
- package/dist/compiler/compile-bytecode.d.ts.map +1 -0
- package/dist/compiler/compile-fast.d.ts +7 -0
- package/dist/compiler/compile-fast.d.ts.map +1 -0
- package/dist/compiler/create-script.d.ts +7 -0
- package/dist/compiler/create-script.d.ts.map +1 -0
- package/dist/compiler/diagnostic.d.ts +56 -0
- package/dist/compiler/diagnostic.d.ts.map +1 -0
- package/dist/compiler/emit.d.ts +4 -0
- package/dist/compiler/emit.d.ts.map +1 -0
- package/dist/compiler/index.d.ts +13 -0
- package/dist/compiler/index.d.ts.map +1 -0
- package/dist/compiler/types.d.ts +16 -0
- package/dist/compiler/types.d.ts.map +1 -0
- package/dist/compiler/worker-manager.d.ts +6 -0
- package/dist/compiler/worker-manager.d.ts.map +1 -0
- package/dist/compiler/worker.d.ts +6 -0
- package/dist/compiler/worker.d.ts.map +1 -0
- package/dist/compiler/worker.js +34 -0
- package/dist/compiler/worker.js.map +6 -0
- package/dist/helpers/constants.d.ts +3 -0
- package/dist/helpers/constants.d.ts.map +1 -0
- package/dist/helpers/serialize.d.ts +45 -0
- package/dist/helpers/serialize.d.ts.map +1 -0
- package/dist/helpers/utils.d.ts +36 -0
- package/dist/helpers/utils.d.ts.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +61 -0
- package/dist/index.js.map +6 -0
- package/dist/subtle.d.ts +7 -0
- package/dist/subtle.d.ts.map +1 -0
- package/dist/subtle.js +30 -0
- package/dist/subtle.js.map +6 -0
- package/dist/vm/env.d.ts +3 -0
- package/dist/vm/env.d.ts.map +1 -0
- package/dist/vm/error.d.ts +11 -0
- package/dist/vm/error.d.ts.map +1 -0
- package/dist/vm/helpers.d.ts +21 -0
- package/dist/vm/helpers.d.ts.map +1 -0
- package/dist/vm/index.d.ts +5 -0
- package/dist/vm/index.d.ts.map +1 -0
- package/dist/vm/lib/_helpers.d.ts +35 -0
- package/dist/vm/lib/_helpers.d.ts.map +1 -0
- package/dist/vm/lib/_loader.d.ts +16 -0
- package/dist/vm/lib/_loader.d.ts.map +1 -0
- package/dist/vm/lib/global/bit.d.ts +9 -0
- package/dist/vm/lib/global/bit.d.ts.map +1 -0
- package/dist/vm/lib/global/debug.d.ts +5 -0
- package/dist/vm/lib/global/debug.d.ts.map +1 -0
- package/dist/vm/lib/global/index.d.ts +10 -0
- package/dist/vm/lib/global/index.d.ts.map +1 -0
- package/dist/vm/lib/global/json.d.ts +4 -0
- package/dist/vm/lib/global/json.d.ts.map +1 -0
- package/dist/vm/lib/global/math-additional.d.ts +3 -0
- package/dist/vm/lib/global/math-additional.d.ts.map +1 -0
- package/dist/vm/lib/global/math-arr.d.ts +8 -0
- package/dist/vm/lib/global/math-arr.d.ts.map +1 -0
- package/dist/vm/lib/global/math-const.d.ts +3 -0
- package/dist/vm/lib/global/math-const.d.ts.map +1 -0
- package/dist/vm/lib/global/math-unary.d.ts +29 -0
- package/dist/vm/lib/global/math-unary.d.ts.map +1 -0
- package/dist/vm/lib/global/math.d.ts +9 -0
- package/dist/vm/lib/global/math.d.ts.map +1 -0
- package/dist/vm/lib/global/mod/index.d.ts +3 -0
- package/dist/vm/lib/global/mod/index.d.ts.map +1 -0
- package/dist/vm/lib/global/mod/matrix.d.ts +16 -0
- package/dist/vm/lib/global/mod/matrix.d.ts.map +1 -0
- package/dist/vm/lib/global/sequence/all-any.d.ts +4 -0
- package/dist/vm/lib/global/sequence/all-any.d.ts.map +1 -0
- package/dist/vm/lib/global/sequence/entries.d.ts +12 -0
- package/dist/vm/lib/global/sequence/entries.d.ts.map +1 -0
- package/dist/vm/lib/global/sequence/find.d.ts +10 -0
- package/dist/vm/lib/global/sequence/find.d.ts.map +1 -0
- package/dist/vm/lib/global/sequence/flatten.d.ts +3 -0
- package/dist/vm/lib/global/sequence/flatten.d.ts.map +1 -0
- package/dist/vm/lib/global/sequence/index.d.ts +12 -0
- package/dist/vm/lib/global/sequence/index.d.ts.map +1 -0
- package/dist/vm/lib/global/sequence/len.d.ts +3 -0
- package/dist/vm/lib/global/sequence/len.d.ts.map +1 -0
- package/dist/vm/lib/global/sequence/map-filter.d.ts +9 -0
- package/dist/vm/lib/global/sequence/map-filter.d.ts.map +1 -0
- package/dist/vm/lib/global/sequence/repeat.d.ts +4 -0
- package/dist/vm/lib/global/sequence/repeat.d.ts.map +1 -0
- package/dist/vm/lib/global/sequence/reverse.d.ts +3 -0
- package/dist/vm/lib/global/sequence/reverse.d.ts.map +1 -0
- package/dist/vm/lib/global/sequence/sort.d.ts +5 -0
- package/dist/vm/lib/global/sequence/sort.d.ts.map +1 -0
- package/dist/vm/lib/global/sequence/with.d.ts +5 -0
- package/dist/vm/lib/global/sequence/with.d.ts.map +1 -0
- package/dist/vm/lib/global/sequence/zip.d.ts +4 -0
- package/dist/vm/lib/global/sequence/zip.d.ts.map +1 -0
- package/dist/vm/lib/global/string.d.ts +12 -0
- package/dist/vm/lib/global/string.d.ts.map +1 -0
- package/dist/vm/lib/global/time.d.ts +15 -0
- package/dist/vm/lib/global/time.d.ts.map +1 -0
- package/dist/vm/lib/global/to-primitive.d.ts +6 -0
- package/dist/vm/lib/global/to-primitive.d.ts.map +1 -0
- package/dist/vm/operations.d.ts +49 -0
- package/dist/vm/operations.d.ts.map +1 -0
- package/dist/vm/types/checker.d.ts +30 -0
- package/dist/vm/types/checker.d.ts.map +1 -0
- package/dist/vm/types/context.d.ts +43 -0
- package/dist/vm/types/context.d.ts.map +1 -0
- package/dist/vm/types/extern.d.ts +32 -0
- package/dist/vm/types/extern.d.ts.map +1 -0
- package/dist/vm/types/function.d.ts +49 -0
- package/dist/vm/types/function.d.ts.map +1 -0
- package/dist/vm/types/index.d.ts +75 -0
- package/dist/vm/types/index.d.ts.map +1 -0
- package/dist/vm/types/module.d.ts +25 -0
- package/dist/vm/types/module.d.ts.map +1 -0
- package/dist/vm/types/script.d.ts +14 -0
- package/dist/vm/types/script.d.ts.map +1 -0
- package/dist/vm/types/wrapper.d.ts +25 -0
- package/dist/vm/types/wrapper.d.ts.map +1 -0
- package/package.json +55 -0
- package/src/cli/execute.ts +32 -0
- package/src/cli/index.ts +73 -0
- package/src/cli/print.ts +41 -0
- package/src/compiler/compile-bytecode.ts +65 -0
- package/src/compiler/compile-fast.ts +81 -0
- package/src/compiler/create-script.ts +34 -0
- package/src/compiler/diagnostic.ts +175 -0
- package/src/compiler/emit.ts +764 -0
- package/src/compiler/index.ts +67 -0
- package/src/compiler/types.ts +16 -0
- package/src/compiler/worker-manager.ts +60 -0
- package/src/compiler/worker.ts +37 -0
- package/src/helpers/constants.ts +3 -0
- package/src/helpers/serialize.ts +280 -0
- package/src/helpers/utils.ts +16 -0
- package/src/index.ts +3 -0
- package/src/subtle.ts +6 -0
- package/src/vm/env.ts +16 -0
- package/src/vm/error.ts +22 -0
- package/src/vm/helpers.ts +121 -0
- package/src/vm/index.ts +5 -0
- package/src/vm/lib/_helpers.ts +215 -0
- package/src/vm/lib/_loader.ts +51 -0
- package/src/vm/lib/global/bit.ts +93 -0
- package/src/vm/lib/global/debug.ts +36 -0
- package/src/vm/lib/global/index.ts +9 -0
- package/src/vm/lib/global/json.ts +45 -0
- package/src/vm/lib/global/math-additional.ts +71 -0
- package/src/vm/lib/global/math-arr.ts +62 -0
- package/src/vm/lib/global/math-const.ts +2 -0
- package/src/vm/lib/global/math-unary.ts +171 -0
- package/src/vm/lib/global/math.ts +27 -0
- package/src/vm/lib/global/mod/index.ts +4 -0
- package/src/vm/lib/global/mod/matrix.ts +579 -0
- package/src/vm/lib/global/sequence/all-any.ts +73 -0
- package/src/vm/lib/global/sequence/entries.ts +67 -0
- package/src/vm/lib/global/sequence/find.ts +49 -0
- package/src/vm/lib/global/sequence/flatten.ts +16 -0
- package/src/vm/lib/global/sequence/index.ts +11 -0
- package/src/vm/lib/global/sequence/len.ts +15 -0
- package/src/vm/lib/global/sequence/map-filter.ts +82 -0
- package/src/vm/lib/global/sequence/repeat.ts +28 -0
- package/src/vm/lib/global/sequence/reverse.ts +17 -0
- package/src/vm/lib/global/sequence/sort.ts +88 -0
- package/src/vm/lib/global/sequence/with.ts +43 -0
- package/src/vm/lib/global/sequence/zip.ts +40 -0
- package/src/vm/lib/global/string.ts +149 -0
- package/src/vm/lib/global/time.ts +73 -0
- package/src/vm/lib/global/to-primitive.ts +58 -0
- package/src/vm/operations.ts +497 -0
- package/src/vm/types/checker.ts +164 -0
- package/src/vm/types/context.ts +161 -0
- package/src/vm/types/extern.ts +166 -0
- package/src/vm/types/function.ts +136 -0
- package/src/vm/types/index.ts +124 -0
- package/src/vm/types/module.ts +40 -0
- package/src/vm/types/script.ts +18 -0
- package/src/vm/types/wrapper.ts +28 -0
|
@@ -0,0 +1,764 @@
|
|
|
1
|
+
import { OpCode } from '@mirascript/wasm/types';
|
|
2
|
+
import { encodeURL } from 'js-base64';
|
|
3
|
+
import type { VmConst, VmPrimitive } from '../vm/index.js';
|
|
4
|
+
import type { ScriptInput, TranspileOptions } from './types.js';
|
|
5
|
+
|
|
6
|
+
/** 生成代码 */
|
|
7
|
+
export function emit(source: ScriptInput, chunk: Uint8Array, options: TranspileOptions): string {
|
|
8
|
+
const gen = new Emitter(source, chunk, options);
|
|
9
|
+
gen.read();
|
|
10
|
+
const code = gen.codeLines.join('\n');
|
|
11
|
+
return code;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** 解析常量 */
|
|
15
|
+
function readConst(reader: DataView, offset: number): [value: VmPrimitive, consumed: number] {
|
|
16
|
+
const type = reader.getUint8(offset);
|
|
17
|
+
switch (type) {
|
|
18
|
+
/* c8 ignore next 2 */
|
|
19
|
+
case 0:
|
|
20
|
+
return [null, 1];
|
|
21
|
+
case 1:
|
|
22
|
+
return [true, 1];
|
|
23
|
+
case 2:
|
|
24
|
+
return [false, 1];
|
|
25
|
+
case 3: {
|
|
26
|
+
const ordinal = reader.getInt32(offset + 1, true);
|
|
27
|
+
return [ordinal, 5];
|
|
28
|
+
}
|
|
29
|
+
case 4: {
|
|
30
|
+
const num = reader.getFloat64(offset + 1, true);
|
|
31
|
+
return [num, 9];
|
|
32
|
+
}
|
|
33
|
+
case 5: {
|
|
34
|
+
const len = reader.getUint32(offset + 1, true);
|
|
35
|
+
const str = new TextDecoder().decode(new Uint8Array(reader.buffer, reader.byteOffset + offset + 5, len));
|
|
36
|
+
return [str, 5 + len];
|
|
37
|
+
}
|
|
38
|
+
/* c8 ignore next 2 */
|
|
39
|
+
default:
|
|
40
|
+
throw new Error(`Unknown constant type: ${type}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** 将值转为 JS */
|
|
45
|
+
function toJavascript(value: VmConst | undefined): string {
|
|
46
|
+
/* c8 ignore next 2 */
|
|
47
|
+
if (value === null) return 'null';
|
|
48
|
+
if (value === undefined) return 'undefined';
|
|
49
|
+
if (typeof value == 'object' || typeof value == 'string') {
|
|
50
|
+
return JSON.stringify(value);
|
|
51
|
+
}
|
|
52
|
+
// JSON 无法处理 NaN 等特殊数字
|
|
53
|
+
return String(value);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const ORIGIN = `mira://MiraScript`;
|
|
57
|
+
let sourceId = 1;
|
|
58
|
+
|
|
59
|
+
/** 创建数组 */
|
|
60
|
+
function createArray<T>(length: number, fn: (index: number) => T): T[] {
|
|
61
|
+
// micro bench shows that this is faster than Array.from
|
|
62
|
+
const result: T[] = [];
|
|
63
|
+
for (let i = 0; i < length; i++) {
|
|
64
|
+
result.push(fn(i));
|
|
65
|
+
}
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** 代码生成 */
|
|
70
|
+
class Emitter {
|
|
71
|
+
constructor(
|
|
72
|
+
readonly source: ScriptInput,
|
|
73
|
+
readonly chunk: Uint8Array,
|
|
74
|
+
readonly options: TranspileOptions,
|
|
75
|
+
) {
|
|
76
|
+
this.pretty = options.pretty ?? false;
|
|
77
|
+
|
|
78
|
+
const reader = new DataView(chunk.buffer, chunk.byteOffset, chunk.byteLength);
|
|
79
|
+
this.chunkSize = reader.getUint32(0, true);
|
|
80
|
+
this.codeSize = reader.getUint32(4, true);
|
|
81
|
+
this.constSize = reader.getUint32(8 + this.codeSize, true);
|
|
82
|
+
|
|
83
|
+
this.codeReader = new DataView(chunk.buffer, chunk.byteOffset + 8, this.codeSize);
|
|
84
|
+
this.constReader = new DataView(chunk.buffer, chunk.byteOffset + 12 + this.codeSize, this.constSize);
|
|
85
|
+
}
|
|
86
|
+
readonly pretty;
|
|
87
|
+
readonly chunkSize: number;
|
|
88
|
+
readonly codeSize: number;
|
|
89
|
+
private readonly constReader: DataView;
|
|
90
|
+
/** 读取常量表 */
|
|
91
|
+
private readConsts(): void {
|
|
92
|
+
for (let i = 0, index = 0; i < this.constSize; index++) {
|
|
93
|
+
const [constant, size] = readConst(this.constReader, i);
|
|
94
|
+
this.constants.push(toJavascript(constant));
|
|
95
|
+
i += size;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
readonly constants: string[] = [];
|
|
99
|
+
|
|
100
|
+
readonly constSize: number;
|
|
101
|
+
private readonly codeReader: DataView;
|
|
102
|
+
private codeOffset = 0;
|
|
103
|
+
private closureCounter = 0;
|
|
104
|
+
private identCounter = 0;
|
|
105
|
+
|
|
106
|
+
/** 制造缩进 */
|
|
107
|
+
private ident(len = 0): string {
|
|
108
|
+
if (!this.pretty) return '';
|
|
109
|
+
return ' '.repeat(this.identCounter + len);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
readonly codeLines: string[] = [];
|
|
113
|
+
|
|
114
|
+
/** Read variable */
|
|
115
|
+
private rv(i: number, level = 0): string {
|
|
116
|
+
if (!i) return 'null';
|
|
117
|
+
const c = this.closureCounter - level;
|
|
118
|
+
return `var_${c}_${i}`;
|
|
119
|
+
}
|
|
120
|
+
/** Write variable */
|
|
121
|
+
private wv(i: number, level = 0): string {
|
|
122
|
+
if (!i) return '_';
|
|
123
|
+
return this.rv(i, level);
|
|
124
|
+
}
|
|
125
|
+
/** 读取 code param */
|
|
126
|
+
private readParam(wide: boolean): number {
|
|
127
|
+
const value = wide
|
|
128
|
+
? this.codeReader.getUint32(this.codeOffset, true)
|
|
129
|
+
: this.codeReader.getUint8(this.codeOffset);
|
|
130
|
+
this.codeOffset += wide ? 4 : 1;
|
|
131
|
+
return value;
|
|
132
|
+
}
|
|
133
|
+
/** 读取 code param */
|
|
134
|
+
private readIndex(wide: boolean): number {
|
|
135
|
+
const value = wide ? this.codeReader.getInt32(this.codeOffset, true) : this.codeReader.getInt8(this.codeOffset);
|
|
136
|
+
this.codeOffset += wide ? 4 : 1;
|
|
137
|
+
return value;
|
|
138
|
+
}
|
|
139
|
+
/** 读取闭包 */
|
|
140
|
+
private readClosure(): void {
|
|
141
|
+
this.closureCounter++;
|
|
142
|
+
this.identCounter++;
|
|
143
|
+
while (this.codeOffset < this.codeSize) {
|
|
144
|
+
const opcode_raw = this.codeReader.getUint8(this.codeOffset);
|
|
145
|
+
const opcode = opcode_raw & 0x7f;
|
|
146
|
+
if (opcode !== OpCode.FuncEnd) {
|
|
147
|
+
this.readCode();
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
this.codeOffset++;
|
|
151
|
+
const body = this.ident(-1) + `} finally { CpExit(); } });`;
|
|
152
|
+
this.codeLines.push(body);
|
|
153
|
+
this.closureCounter--;
|
|
154
|
+
this.identCounter--;
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** 读取块结束 */
|
|
160
|
+
private readBlockEnd(end: OpCode): void {
|
|
161
|
+
while (this.codeOffset < this.codeSize) {
|
|
162
|
+
const opcode_raw = this.codeReader.getUint8(this.codeOffset);
|
|
163
|
+
const opcode = opcode_raw & 0x7f;
|
|
164
|
+
if (opcode !== end) {
|
|
165
|
+
this.readCode();
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
this.codeOffset++;
|
|
169
|
+
this.identCounter--;
|
|
170
|
+
if (end === OpCode.LoopEnd) {
|
|
171
|
+
this.closureCounter--;
|
|
172
|
+
}
|
|
173
|
+
const body = this.ident() + `};`;
|
|
174
|
+
this.codeLines.push(body);
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** 读取 if else 或 if 结束 */
|
|
180
|
+
private readIfElse(): void {
|
|
181
|
+
this.identCounter++;
|
|
182
|
+
while (this.codeOffset < this.codeSize) {
|
|
183
|
+
const opcode_raw = this.codeReader.getUint8(this.codeOffset);
|
|
184
|
+
const opcode = opcode_raw & 0x7f;
|
|
185
|
+
if (opcode === OpCode.IfEnd) {
|
|
186
|
+
return this.readBlockEnd(OpCode.IfEnd);
|
|
187
|
+
}
|
|
188
|
+
if (opcode === OpCode.Else) {
|
|
189
|
+
this.codeOffset++;
|
|
190
|
+
const body = this.ident(-1) + `} else {`;
|
|
191
|
+
this.codeLines.push(body);
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
if (opcode === OpCode.ElIf) {
|
|
195
|
+
this.codeOffset++;
|
|
196
|
+
const body = this.ident(-1) + `} else `;
|
|
197
|
+
this.codeLines.push(body);
|
|
198
|
+
return this.readCode();
|
|
199
|
+
}
|
|
200
|
+
this.readCode();
|
|
201
|
+
}
|
|
202
|
+
return this.readBlockEnd(OpCode.IfEnd);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/** 读取 record */
|
|
206
|
+
private readRecord(obj: number): void {
|
|
207
|
+
this.identCounter++;
|
|
208
|
+
while (this.codeOffset < this.codeSize) {
|
|
209
|
+
const opcode_raw = this.codeReader.getUint8(this.codeOffset++);
|
|
210
|
+
const opcode = opcode_raw & 0x7f;
|
|
211
|
+
const wide = opcode_raw >= 0x80;
|
|
212
|
+
const read = () => this.readParam(wide);
|
|
213
|
+
let code = '';
|
|
214
|
+
switch (opcode) {
|
|
215
|
+
case OpCode.FieldOpt:
|
|
216
|
+
case OpCode.Field: {
|
|
217
|
+
const field = read();
|
|
218
|
+
const field_name = this.constants[field];
|
|
219
|
+
/* c8 ignore next 3 */
|
|
220
|
+
if (!field_name) {
|
|
221
|
+
throw new Error(`Unknown field ${field}`);
|
|
222
|
+
}
|
|
223
|
+
const value = read();
|
|
224
|
+
const opt = opcode === OpCode.FieldOpt;
|
|
225
|
+
// Use computed property names to avoid prototype pollution
|
|
226
|
+
code = opt
|
|
227
|
+
? `...ElementOpt(${field_name}, ${this.rv(value)}),`
|
|
228
|
+
: `[${field_name}]: Element(${this.rv(value)}),`;
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
case OpCode.FieldOptDyn:
|
|
232
|
+
case OpCode.FieldDyn: {
|
|
233
|
+
const field = read();
|
|
234
|
+
const value = read();
|
|
235
|
+
const opt = opcode === OpCode.FieldOptDyn;
|
|
236
|
+
code = opt
|
|
237
|
+
? `...ElementOpt(${this.rv(field)}, ${this.rv(value)}),`
|
|
238
|
+
: `[${this.rv(field)}]: Element(${this.rv(value)}),`;
|
|
239
|
+
break;
|
|
240
|
+
}
|
|
241
|
+
case OpCode.FieldOptIndex:
|
|
242
|
+
case OpCode.FieldIndex: {
|
|
243
|
+
const field = this.readIndex(wide);
|
|
244
|
+
const value = read();
|
|
245
|
+
const opt = opcode === OpCode.FieldOptIndex;
|
|
246
|
+
code = opt
|
|
247
|
+
? `...ElementOpt(${field}, ${this.rv(value)}),`
|
|
248
|
+
: `[${field}]: Element(${this.rv(value)}),`;
|
|
249
|
+
break;
|
|
250
|
+
}
|
|
251
|
+
case OpCode.Spread: {
|
|
252
|
+
const value = read();
|
|
253
|
+
code = `...$RecordSpread(${this.rv(value)}),`;
|
|
254
|
+
break;
|
|
255
|
+
}
|
|
256
|
+
case OpCode.Freeze: {
|
|
257
|
+
this.identCounter--;
|
|
258
|
+
code = `});`;
|
|
259
|
+
break;
|
|
260
|
+
}
|
|
261
|
+
default: {
|
|
262
|
+
code = `// ?${OpCode[opcode] ?? opcode}`;
|
|
263
|
+
break;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
const ident = this.ident();
|
|
267
|
+
this.codeLines.push(ident + code);
|
|
268
|
+
if (opcode === OpCode.Freeze) {
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/** 读取 array */
|
|
275
|
+
private readArray(arr: number): void {
|
|
276
|
+
this.identCounter++;
|
|
277
|
+
while (this.codeOffset < this.codeSize) {
|
|
278
|
+
const opcode_raw = this.codeReader.getUint8(this.codeOffset++);
|
|
279
|
+
const opcode = opcode_raw & 0x7f;
|
|
280
|
+
const wide = opcode_raw >= 0x80;
|
|
281
|
+
const read = () => this.readParam(wide);
|
|
282
|
+
let code = '';
|
|
283
|
+
switch (opcode) {
|
|
284
|
+
case OpCode.Item: {
|
|
285
|
+
const value = read();
|
|
286
|
+
code = `Element(${this.rv(value)}),`;
|
|
287
|
+
break;
|
|
288
|
+
}
|
|
289
|
+
case OpCode.ItemRange: {
|
|
290
|
+
const start = this.readIndex(wide);
|
|
291
|
+
const end = this.readIndex(wide);
|
|
292
|
+
code = `...ArrayRange(${start}, ${end}),`;
|
|
293
|
+
break;
|
|
294
|
+
}
|
|
295
|
+
case OpCode.ItemRangeDyn: {
|
|
296
|
+
const start = read();
|
|
297
|
+
const end = read();
|
|
298
|
+
code = `...ArrayRange(${this.rv(start)}, ${this.rv(end)}),`;
|
|
299
|
+
break;
|
|
300
|
+
}
|
|
301
|
+
case OpCode.ItemRangeExclusiveDyn: {
|
|
302
|
+
const start = read();
|
|
303
|
+
const end = read();
|
|
304
|
+
code = `...ArrayRangeExclusive(${this.rv(start)}, ${this.rv(end)}),`;
|
|
305
|
+
break;
|
|
306
|
+
}
|
|
307
|
+
case OpCode.Spread: {
|
|
308
|
+
const value = read();
|
|
309
|
+
code = `...$ArraySpread(${this.rv(value)}),`;
|
|
310
|
+
break;
|
|
311
|
+
}
|
|
312
|
+
case OpCode.Freeze: {
|
|
313
|
+
this.identCounter--;
|
|
314
|
+
code = `]);`;
|
|
315
|
+
break;
|
|
316
|
+
}
|
|
317
|
+
default: {
|
|
318
|
+
code = `// ?${OpCode[opcode] ?? opcode}`;
|
|
319
|
+
break;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
const ident = this.ident();
|
|
323
|
+
this.codeLines.push(ident + code);
|
|
324
|
+
if (opcode === OpCode.Freeze) {
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/** 读取代码 */
|
|
331
|
+
private readCode(): void {
|
|
332
|
+
const opcode_raw = this.codeReader.getUint8(this.codeOffset++);
|
|
333
|
+
const opcode = opcode_raw & 0x7f;
|
|
334
|
+
const wide = opcode_raw >= 0x80;
|
|
335
|
+
const read = () => this.readParam(wide);
|
|
336
|
+
const readIndex = () => this.readIndex(wide);
|
|
337
|
+
const ident = this.ident();
|
|
338
|
+
let code = '';
|
|
339
|
+
let reg = 0;
|
|
340
|
+
switch (opcode) {
|
|
341
|
+
case OpCode.FuncVarg:
|
|
342
|
+
case OpCode.Func: {
|
|
343
|
+
const script = this.codeOffset === 1;
|
|
344
|
+
reg = read();
|
|
345
|
+
const varg = opcode === OpCode.FuncVarg;
|
|
346
|
+
const argn = read();
|
|
347
|
+
const regn = read();
|
|
348
|
+
const args = createArray(argn, (i) => {
|
|
349
|
+
const wv = this.wv(i + 1, -1);
|
|
350
|
+
if (varg && i === argn - 1) {
|
|
351
|
+
// 最后一个参数为可变参数
|
|
352
|
+
return `...vargs`;
|
|
353
|
+
}
|
|
354
|
+
return `${wv} = null`;
|
|
355
|
+
});
|
|
356
|
+
const regs = createArray(regn - argn + 1, (i) => (i ? this.wv(i + argn, -1) : this.wv(0, -1))).join(
|
|
357
|
+
', ',
|
|
358
|
+
);
|
|
359
|
+
if (script) {
|
|
360
|
+
args.unshift(`global = GlobalFallback()`);
|
|
361
|
+
code = `'use strict'; return (function script(${args.join(', ')}) { try { CpEnter(); var ${regs};`;
|
|
362
|
+
} else {
|
|
363
|
+
code = `${this.wv(reg)} = Function(function (${args.join(', ')}) { try { CpEnter(); var ${regs};`;
|
|
364
|
+
}
|
|
365
|
+
if (varg) {
|
|
366
|
+
code += ` var ${this.wv(argn, -1)} = Vargs(vargs);`;
|
|
367
|
+
}
|
|
368
|
+
break;
|
|
369
|
+
}
|
|
370
|
+
case OpCode.Constant: {
|
|
371
|
+
reg = read();
|
|
372
|
+
const i = read();
|
|
373
|
+
const c = this.constants[i];
|
|
374
|
+
code = `${this.wv(reg)} = ${c};`;
|
|
375
|
+
break;
|
|
376
|
+
}
|
|
377
|
+
case OpCode.Uninit: {
|
|
378
|
+
reg = read();
|
|
379
|
+
code = `${this.wv(reg)} = undefined;`;
|
|
380
|
+
break;
|
|
381
|
+
}
|
|
382
|
+
case OpCode.Return: {
|
|
383
|
+
reg = read();
|
|
384
|
+
code = `return ${this.rv(reg)};`;
|
|
385
|
+
break;
|
|
386
|
+
}
|
|
387
|
+
case OpCode.Add:
|
|
388
|
+
case OpCode.Sub:
|
|
389
|
+
case OpCode.Mul:
|
|
390
|
+
case OpCode.Div:
|
|
391
|
+
case OpCode.Mod:
|
|
392
|
+
case OpCode.Pow:
|
|
393
|
+
case OpCode.Gt:
|
|
394
|
+
case OpCode.Gte:
|
|
395
|
+
case OpCode.Lt:
|
|
396
|
+
case OpCode.Lte:
|
|
397
|
+
case OpCode.Eq:
|
|
398
|
+
case OpCode.Neq:
|
|
399
|
+
case OpCode.Aeq:
|
|
400
|
+
case OpCode.Naeq:
|
|
401
|
+
case OpCode.Same:
|
|
402
|
+
case OpCode.Nsame:
|
|
403
|
+
case OpCode.In:
|
|
404
|
+
case OpCode.And:
|
|
405
|
+
case OpCode.Or:
|
|
406
|
+
case OpCode.Format: {
|
|
407
|
+
reg = read();
|
|
408
|
+
const left = read();
|
|
409
|
+
const right = read();
|
|
410
|
+
code = `${this.wv(reg)} = $${OpCode[opcode]}(${this.rv(left)}, ${this.rv(right)});`;
|
|
411
|
+
break;
|
|
412
|
+
}
|
|
413
|
+
case OpCode.InGlobal: {
|
|
414
|
+
reg = read();
|
|
415
|
+
const left = read();
|
|
416
|
+
code = `${this.wv(reg)} = global.has(${this.rv(left)});`;
|
|
417
|
+
break;
|
|
418
|
+
}
|
|
419
|
+
case OpCode.Concat: {
|
|
420
|
+
reg = read();
|
|
421
|
+
const n = read();
|
|
422
|
+
const args = createArray(n, () => read());
|
|
423
|
+
code = `${this.wv(reg)} = $${OpCode[opcode]}(${args.map((a) => this.rv(a)).join(', ')});`;
|
|
424
|
+
break;
|
|
425
|
+
}
|
|
426
|
+
case OpCode.Omit:
|
|
427
|
+
case OpCode.Pick: {
|
|
428
|
+
reg = read();
|
|
429
|
+
const value = read();
|
|
430
|
+
const n = read();
|
|
431
|
+
const args = createArray(n, () => this.constants[read()]!);
|
|
432
|
+
|
|
433
|
+
code = `${this.wv(reg)} = $${OpCode[opcode]}(${this.rv(value)}, [${args.join(', ')}]);`;
|
|
434
|
+
break;
|
|
435
|
+
}
|
|
436
|
+
case OpCode.Call:
|
|
437
|
+
case OpCode.CallDyn: {
|
|
438
|
+
reg = read();
|
|
439
|
+
const func = read();
|
|
440
|
+
const n = read();
|
|
441
|
+
const args = createArray(n, () => read());
|
|
442
|
+
const ns = read();
|
|
443
|
+
const spreads = createArray(ns, () => read());
|
|
444
|
+
const callTarget = opcode === OpCode.Call ? `global.get(${this.constants[func]})` : this.rv(func);
|
|
445
|
+
code = `${this.wv(reg)} = $Call(${callTarget}, [${args
|
|
446
|
+
.map((a, i) => {
|
|
447
|
+
if (spreads.includes(i)) return `...$ArraySpread(${this.rv(a)})`;
|
|
448
|
+
else return this.rv(a);
|
|
449
|
+
})
|
|
450
|
+
.join(', ')}]);`;
|
|
451
|
+
break;
|
|
452
|
+
}
|
|
453
|
+
case OpCode.Assign: {
|
|
454
|
+
reg = read();
|
|
455
|
+
const value = read();
|
|
456
|
+
code = `${this.wv(reg)} = ${this.rv(value)};`;
|
|
457
|
+
break;
|
|
458
|
+
}
|
|
459
|
+
case OpCode.Pos:
|
|
460
|
+
case OpCode.Neg:
|
|
461
|
+
case OpCode.Not:
|
|
462
|
+
case OpCode.Type:
|
|
463
|
+
case OpCode.ToBoolean:
|
|
464
|
+
case OpCode.ToNumber:
|
|
465
|
+
case OpCode.ToString:
|
|
466
|
+
case OpCode.IsBoolean:
|
|
467
|
+
case OpCode.IsNumber:
|
|
468
|
+
case OpCode.IsString:
|
|
469
|
+
case OpCode.IsRecord:
|
|
470
|
+
case OpCode.IsArray:
|
|
471
|
+
case OpCode.Length: {
|
|
472
|
+
reg = read();
|
|
473
|
+
const value = read();
|
|
474
|
+
code = `${this.wv(reg)} = $${OpCode[opcode]}(${this.rv(value)});`;
|
|
475
|
+
break;
|
|
476
|
+
}
|
|
477
|
+
case OpCode.AssertInit:
|
|
478
|
+
case OpCode.AssertNonNil: {
|
|
479
|
+
reg = read();
|
|
480
|
+
code = `$${OpCode[opcode]}(${this.rv(reg)})`;
|
|
481
|
+
break;
|
|
482
|
+
}
|
|
483
|
+
case OpCode.Get: {
|
|
484
|
+
reg = read();
|
|
485
|
+
const obj = read();
|
|
486
|
+
const prop = this.constants[read()];
|
|
487
|
+
code = `${this.wv(reg)} = $Get(${this.rv(obj)}, ${prop});`;
|
|
488
|
+
break;
|
|
489
|
+
}
|
|
490
|
+
case OpCode.GetIndex: {
|
|
491
|
+
reg = read();
|
|
492
|
+
const obj = read();
|
|
493
|
+
const index = readIndex();
|
|
494
|
+
code = `${this.wv(reg)} = $Get(${this.rv(obj)}, ${index});`;
|
|
495
|
+
break;
|
|
496
|
+
}
|
|
497
|
+
case OpCode.GetDyn: {
|
|
498
|
+
reg = read();
|
|
499
|
+
const obj = read();
|
|
500
|
+
const index = read();
|
|
501
|
+
code = `${this.wv(reg)} = $Get(${this.rv(obj)}, ${this.rv(index)});`;
|
|
502
|
+
break;
|
|
503
|
+
}
|
|
504
|
+
case OpCode.Has: {
|
|
505
|
+
reg = read();
|
|
506
|
+
const obj = read();
|
|
507
|
+
const prop = this.constants[read()];
|
|
508
|
+
code = `${this.wv(reg)} = $Has(${this.rv(obj)}, ${prop});`;
|
|
509
|
+
break;
|
|
510
|
+
}
|
|
511
|
+
case OpCode.HasIndex: {
|
|
512
|
+
reg = read();
|
|
513
|
+
const obj = read();
|
|
514
|
+
const index = readIndex();
|
|
515
|
+
code = `${this.wv(reg)} = $Has(${this.rv(obj)}, ${index});`;
|
|
516
|
+
break;
|
|
517
|
+
}
|
|
518
|
+
case OpCode.HasDyn: {
|
|
519
|
+
reg = read();
|
|
520
|
+
const obj = read();
|
|
521
|
+
const index = read();
|
|
522
|
+
code = `${this.wv(reg)} = $Has(${this.rv(obj)}, ${this.rv(index)});`;
|
|
523
|
+
break;
|
|
524
|
+
}
|
|
525
|
+
case OpCode.Set: {
|
|
526
|
+
reg = read();
|
|
527
|
+
const obj = read();
|
|
528
|
+
const prop = this.constants[read()];
|
|
529
|
+
code = `$Set(${this.rv(obj)}, ${prop}, ${this.rv(reg)});`;
|
|
530
|
+
break;
|
|
531
|
+
}
|
|
532
|
+
case OpCode.SetIndex: {
|
|
533
|
+
reg = read();
|
|
534
|
+
const obj = read();
|
|
535
|
+
const index = readIndex();
|
|
536
|
+
code = `$Set(${this.rv(obj)}, ${index}, ${this.rv(reg)});`;
|
|
537
|
+
break;
|
|
538
|
+
}
|
|
539
|
+
case OpCode.SetDyn: {
|
|
540
|
+
reg = read();
|
|
541
|
+
const obj = read();
|
|
542
|
+
const index = read();
|
|
543
|
+
code = `$Set(${this.rv(obj)}, ${this.rv(index)}, ${this.rv(reg)});`;
|
|
544
|
+
break;
|
|
545
|
+
}
|
|
546
|
+
case OpCode.GetGlobal: {
|
|
547
|
+
reg = read();
|
|
548
|
+
const i = read();
|
|
549
|
+
const c = this.constants[i];
|
|
550
|
+
code = `${this.wv(reg)} = global.get(${c}) ?? null;`;
|
|
551
|
+
break;
|
|
552
|
+
}
|
|
553
|
+
case OpCode.GetGlobalDyn: {
|
|
554
|
+
reg = read();
|
|
555
|
+
const name = read();
|
|
556
|
+
code = `${this.wv(reg)} = global.get(${this.rv(name)}) ?? null;`;
|
|
557
|
+
break;
|
|
558
|
+
}
|
|
559
|
+
case OpCode.GetUpvalue: {
|
|
560
|
+
reg = read();
|
|
561
|
+
const level = read();
|
|
562
|
+
const up = read();
|
|
563
|
+
code = `${this.wv(reg)} = Upvalue(${this.rv(up, level)});`;
|
|
564
|
+
break;
|
|
565
|
+
}
|
|
566
|
+
case OpCode.SetUpvalue: {
|
|
567
|
+
reg = read();
|
|
568
|
+
const level = read();
|
|
569
|
+
const up = read();
|
|
570
|
+
code = `${this.wv(up, level)} = ${this.rv(reg)};`;
|
|
571
|
+
break;
|
|
572
|
+
}
|
|
573
|
+
case OpCode.Slice: {
|
|
574
|
+
reg = read();
|
|
575
|
+
const obj = read();
|
|
576
|
+
const start = readIndex();
|
|
577
|
+
const end = readIndex();
|
|
578
|
+
code = `${this.wv(reg)} = $Slice(${this.rv(obj)}, ${start}, ${end});`;
|
|
579
|
+
break;
|
|
580
|
+
}
|
|
581
|
+
case OpCode.SliceStart: {
|
|
582
|
+
reg = read();
|
|
583
|
+
const obj = read();
|
|
584
|
+
const end = readIndex();
|
|
585
|
+
code = `${this.wv(reg)} = $Slice(${this.rv(obj)}, null, ${end});`;
|
|
586
|
+
break;
|
|
587
|
+
}
|
|
588
|
+
case OpCode.SliceEnd: {
|
|
589
|
+
reg = read();
|
|
590
|
+
const obj = read();
|
|
591
|
+
const start = readIndex();
|
|
592
|
+
code = `${this.wv(reg)} = $Slice(${this.rv(obj)}, ${start}, null);`;
|
|
593
|
+
break;
|
|
594
|
+
}
|
|
595
|
+
case OpCode.SliceDyn: {
|
|
596
|
+
reg = read();
|
|
597
|
+
const obj = read();
|
|
598
|
+
const start = read();
|
|
599
|
+
const end = read();
|
|
600
|
+
code = `${this.wv(reg)} = $Slice(${this.rv(obj)}, ${this.rv(start)}, ${this.rv(end)});`;
|
|
601
|
+
break;
|
|
602
|
+
}
|
|
603
|
+
case OpCode.SliceExclusiveDyn: {
|
|
604
|
+
reg = read();
|
|
605
|
+
const obj = read();
|
|
606
|
+
const start = read();
|
|
607
|
+
const end = read();
|
|
608
|
+
code = `${this.wv(reg)} = $SliceExclusive(${this.rv(obj)}, ${this.rv(start)}, ${this.rv(end)});`;
|
|
609
|
+
break;
|
|
610
|
+
}
|
|
611
|
+
case OpCode.Record: {
|
|
612
|
+
reg = read();
|
|
613
|
+
code = `${this.wv(reg)} = ({`;
|
|
614
|
+
break;
|
|
615
|
+
}
|
|
616
|
+
case OpCode.Array: {
|
|
617
|
+
reg = read();
|
|
618
|
+
code = `${this.wv(reg)} = ([`;
|
|
619
|
+
break;
|
|
620
|
+
}
|
|
621
|
+
case OpCode.If: {
|
|
622
|
+
const cond = read();
|
|
623
|
+
code = `if (${this.rv(cond)} !== false && $ToBoolean(${this.rv(cond)}) !== false) {`;
|
|
624
|
+
break;
|
|
625
|
+
}
|
|
626
|
+
case OpCode.IfNot: {
|
|
627
|
+
const cond = read();
|
|
628
|
+
code = `if (${this.rv(cond)} !== true && $ToBoolean(${this.rv(cond)}) !== true) {`;
|
|
629
|
+
break;
|
|
630
|
+
}
|
|
631
|
+
case OpCode.IfInit: {
|
|
632
|
+
const cond = read();
|
|
633
|
+
code = `if (${this.rv(cond)} !== undefined) {`;
|
|
634
|
+
break;
|
|
635
|
+
}
|
|
636
|
+
case OpCode.IfNotInit: {
|
|
637
|
+
const cond = read();
|
|
638
|
+
code = `if (${this.rv(cond)} === undefined) {`;
|
|
639
|
+
break;
|
|
640
|
+
}
|
|
641
|
+
case OpCode.IfNil: {
|
|
642
|
+
const cond = read();
|
|
643
|
+
code = `if (${this.rv(cond)} === null) {`;
|
|
644
|
+
break;
|
|
645
|
+
}
|
|
646
|
+
case OpCode.IfNotNil: {
|
|
647
|
+
const cond = read();
|
|
648
|
+
code = `if (${this.rv(cond)} !== null) {`;
|
|
649
|
+
break;
|
|
650
|
+
}
|
|
651
|
+
case OpCode.LoopFor: {
|
|
652
|
+
const nreg = read();
|
|
653
|
+
const iterable = read();
|
|
654
|
+
const regs = createArray(nreg - 1, (i) => this.wv(i + 2, -1));
|
|
655
|
+
regs.unshift('_');
|
|
656
|
+
const ir = this.wv(1, -1);
|
|
657
|
+
code = `for (let ${ir} of $Iterable(${this.rv(iterable)})) { ${ir} ??= null; Cp(); let ${regs.join(', ')};`;
|
|
658
|
+
break;
|
|
659
|
+
}
|
|
660
|
+
case OpCode.LoopRange:
|
|
661
|
+
case OpCode.LoopRangeExclusive: {
|
|
662
|
+
const nreg = read();
|
|
663
|
+
const start = read();
|
|
664
|
+
const end = read();
|
|
665
|
+
const exclusive = opcode === OpCode.LoopRangeExclusive;
|
|
666
|
+
const regs = createArray(nreg - 1, (i) => this.wv(i + 2, -1));
|
|
667
|
+
regs.unshift('_');
|
|
668
|
+
const i = this.wv(1, -1);
|
|
669
|
+
code = `for (let start = $ToNumber(${this.rv(start)}), end = $ToNumber(${this.rv(end)}), ${i} = start; ${i} ${exclusive ? '<' : '<='} end; ${i} += 1) { Cp(); let ${regs.join(', ')};`;
|
|
670
|
+
break;
|
|
671
|
+
}
|
|
672
|
+
case OpCode.Loop: {
|
|
673
|
+
const nreg = read();
|
|
674
|
+
const regs = createArray(nreg, (i) => this.wv(i + 1, -1));
|
|
675
|
+
regs.unshift('_');
|
|
676
|
+
code = `while (true) { Cp(); let ${regs.join(', ')};`;
|
|
677
|
+
break;
|
|
678
|
+
}
|
|
679
|
+
case OpCode.Break: {
|
|
680
|
+
code = `break;`;
|
|
681
|
+
break;
|
|
682
|
+
}
|
|
683
|
+
case OpCode.Continue: {
|
|
684
|
+
code = `continue;`;
|
|
685
|
+
break;
|
|
686
|
+
}
|
|
687
|
+
default: {
|
|
688
|
+
code = `; // ${OpCode[opcode] ?? opcode}`;
|
|
689
|
+
break;
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
this.codeLines.push(ident + code);
|
|
693
|
+
switch (opcode) {
|
|
694
|
+
case OpCode.FuncVarg:
|
|
695
|
+
case OpCode.Func: {
|
|
696
|
+
this.readClosure();
|
|
697
|
+
break;
|
|
698
|
+
}
|
|
699
|
+
case OpCode.If:
|
|
700
|
+
case OpCode.IfNot:
|
|
701
|
+
case OpCode.IfNil:
|
|
702
|
+
case OpCode.IfNotNil:
|
|
703
|
+
case OpCode.IfInit:
|
|
704
|
+
case OpCode.IfNotInit: {
|
|
705
|
+
this.readIfElse();
|
|
706
|
+
break;
|
|
707
|
+
}
|
|
708
|
+
case OpCode.Loop:
|
|
709
|
+
case OpCode.LoopFor:
|
|
710
|
+
case OpCode.LoopRange:
|
|
711
|
+
case OpCode.LoopRangeExclusive: {
|
|
712
|
+
this.identCounter++;
|
|
713
|
+
this.closureCounter++;
|
|
714
|
+
this.readBlockEnd(OpCode.LoopEnd);
|
|
715
|
+
break;
|
|
716
|
+
}
|
|
717
|
+
case OpCode.Record: {
|
|
718
|
+
this.readRecord(reg);
|
|
719
|
+
break;
|
|
720
|
+
}
|
|
721
|
+
case OpCode.Array: {
|
|
722
|
+
this.readArray(reg);
|
|
723
|
+
break;
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
/** 读取 chunk */
|
|
729
|
+
read(): void {
|
|
730
|
+
this.readConsts();
|
|
731
|
+
this.readCode();
|
|
732
|
+
this.addSourceMap();
|
|
733
|
+
}
|
|
734
|
+
/** 添加源映射 */
|
|
735
|
+
addSourceMap(): void {
|
|
736
|
+
if (!this.options.sourceMap) return;
|
|
737
|
+
let fileName = (this.options.fileName ?? '').trim();
|
|
738
|
+
const hasSchema = /^\w+:/.test(fileName);
|
|
739
|
+
if (!hasSchema) {
|
|
740
|
+
if (fileName.startsWith('/')) {
|
|
741
|
+
fileName = fileName.replace(/^\\+\s*/, '');
|
|
742
|
+
}
|
|
743
|
+
if (!fileName) {
|
|
744
|
+
fileName = `${sourceId++}.${this.options.input_mode === 'Template' ? 'miratpl' : 'mira'}`;
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
const data = {
|
|
748
|
+
version: 3,
|
|
749
|
+
file: fileName,
|
|
750
|
+
sourceRoot: hasSchema ? '' : ORIGIN,
|
|
751
|
+
sources: [fileName],
|
|
752
|
+
sourcesContent: [ArrayBuffer.isView(this.source) ? null : this.source],
|
|
753
|
+
names: [],
|
|
754
|
+
mappings: '',
|
|
755
|
+
};
|
|
756
|
+
const prefix = '//# ';
|
|
757
|
+
const sourceURL = hasSchema ? fileName : `${ORIGIN}/${fileName}.js`;
|
|
758
|
+
this.codeLines.push(
|
|
759
|
+
// Prevent source map from being recognized as of this file
|
|
760
|
+
`${prefix}sourceURL=${sourceURL}`,
|
|
761
|
+
`${prefix}sourceMappingURL=data:application/json;base64,${encodeURL(JSON.stringify(data))}`,
|
|
762
|
+
);
|
|
763
|
+
}
|
|
764
|
+
}
|