watr 3.2.1 → 4.0.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/LICENSE +26 -0
- package/bin/watr.js +83 -0
- package/dist/watr.js +1815 -0
- package/dist/watr.min.js +5 -0
- package/package.json +61 -14
- package/readme.md +42 -92
- package/src/compile.js +560 -532
- package/src/const.js +142 -52
- package/src/encode.js +89 -35
- package/src/parse.js +41 -28
- package/src/print.js +73 -12
- package/src/util.js +80 -2
- package/types/src/compile.d.ts +8 -0
- package/types/src/compile.d.ts.map +1 -0
- package/types/src/const.d.ts +87 -0
- package/types/src/const.d.ts.map +1 -0
- package/types/src/encode.d.ts +58 -0
- package/types/src/encode.d.ts.map +1 -0
- package/types/src/parse.d.ts +3 -0
- package/types/src/parse.d.ts.map +1 -0
- package/types/src/print.d.ts +16 -0
- package/types/src/print.d.ts.map +1 -0
- package/types/src/util.d.ts +18 -0
- package/types/src/util.d.ts.map +1 -0
- package/types/watr.d.ts +34 -0
- package/types/watr.d.ts.map +1 -0
- package/watr.js +233 -3
package/dist/watr.js
ADDED
|
@@ -0,0 +1,1815 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __export = (target, all) => {
|
|
3
|
+
for (var name2 in all)
|
|
4
|
+
__defProp(target, name2, { get: all[name2], enumerable: true });
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
// src/encode.js
|
|
8
|
+
var encode_exports = {};
|
|
9
|
+
__export(encode_exports, {
|
|
10
|
+
f32: () => f32,
|
|
11
|
+
f64: () => f64,
|
|
12
|
+
i16: () => i16,
|
|
13
|
+
i32: () => i32,
|
|
14
|
+
i64: () => i64,
|
|
15
|
+
i8: () => i8,
|
|
16
|
+
uleb: () => uleb,
|
|
17
|
+
uleb5: () => uleb5
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// src/util.js
|
|
21
|
+
var err = (text, pos = err.i) => {
|
|
22
|
+
if (pos != null && err.src) {
|
|
23
|
+
let line = 1, col = 1;
|
|
24
|
+
for (let i = 0; i < pos && i < err.src.length; i++) {
|
|
25
|
+
if (err.src[i] === "\n") line++, col = 1;
|
|
26
|
+
else col++;
|
|
27
|
+
}
|
|
28
|
+
text += ` at ${line}:${col}`;
|
|
29
|
+
}
|
|
30
|
+
throw Error(text);
|
|
31
|
+
};
|
|
32
|
+
var sepRE = /^_|_$|[^\da-f]_|_[^\da-f]/i;
|
|
33
|
+
var intRE = /^[+-]?(?:0x[\da-f]+|\d+)$/i;
|
|
34
|
+
var tenc = new TextEncoder();
|
|
35
|
+
var tdec = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true });
|
|
36
|
+
var escape = { n: 10, r: 13, t: 9, '"': 34, "'": 39, "\\": 92 };
|
|
37
|
+
var str = (s) => {
|
|
38
|
+
let bytes = [], i = 1, code, c, buf = "";
|
|
39
|
+
const commit = () => (buf && bytes.push(...tenc.encode(buf)), buf = "");
|
|
40
|
+
while (i < s.length - 1) {
|
|
41
|
+
c = s[i++], code = null;
|
|
42
|
+
if (c === "\\") {
|
|
43
|
+
if (s[i] === "u") {
|
|
44
|
+
i++, i++;
|
|
45
|
+
c = String.fromCodePoint(parseInt(s.slice(i, i = s.indexOf("}", i)), 16));
|
|
46
|
+
i++;
|
|
47
|
+
} else if (escape[s[i]]) code = escape[s[i++]];
|
|
48
|
+
else if (!isNaN(code = parseInt(s[i] + s[i + 1], 16))) i++, i++;
|
|
49
|
+
else c += s[i];
|
|
50
|
+
}
|
|
51
|
+
code != null ? (commit(), bytes.push(code)) : buf += c;
|
|
52
|
+
}
|
|
53
|
+
commit();
|
|
54
|
+
bytes.valueOf = () => s;
|
|
55
|
+
return bytes;
|
|
56
|
+
};
|
|
57
|
+
var unescape = (s) => tdec.decode(new Uint8Array(str(s)));
|
|
58
|
+
|
|
59
|
+
// src/encode.js
|
|
60
|
+
var uleb = (n, buffer = []) => {
|
|
61
|
+
if (n == null) return buffer;
|
|
62
|
+
if (typeof n === "string") n = /[_x]/i.test(n) ? BigInt(n.replaceAll("_", "")) : i32.parse(n);
|
|
63
|
+
if (typeof n === "bigint") {
|
|
64
|
+
while (true) {
|
|
65
|
+
const byte2 = Number(n & 0x7Fn);
|
|
66
|
+
n >>= 7n;
|
|
67
|
+
if (n === 0n) {
|
|
68
|
+
buffer.push(byte2);
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
buffer.push(byte2 | 128);
|
|
72
|
+
}
|
|
73
|
+
return buffer;
|
|
74
|
+
}
|
|
75
|
+
let byte = n & 127;
|
|
76
|
+
n >>>= 7;
|
|
77
|
+
if (n === 0) {
|
|
78
|
+
buffer.push(byte);
|
|
79
|
+
return buffer;
|
|
80
|
+
}
|
|
81
|
+
buffer.push(byte | 128);
|
|
82
|
+
return uleb(n, buffer);
|
|
83
|
+
};
|
|
84
|
+
function uleb5(value) {
|
|
85
|
+
const result = [];
|
|
86
|
+
for (let i = 0; i < 5; i++) {
|
|
87
|
+
let byte = value & 127;
|
|
88
|
+
value >>>= 7;
|
|
89
|
+
if (i < 4) {
|
|
90
|
+
byte |= 128;
|
|
91
|
+
}
|
|
92
|
+
result.push(byte);
|
|
93
|
+
}
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
function i32(n, buffer = []) {
|
|
97
|
+
if (typeof n === "string") n = i32.parse(n);
|
|
98
|
+
while (true) {
|
|
99
|
+
const byte = Number(n & 127);
|
|
100
|
+
n >>= 7;
|
|
101
|
+
if (n === 0 && (byte & 64) === 0 || n === -1 && (byte & 64) !== 0) {
|
|
102
|
+
buffer.push(byte);
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
buffer.push(byte | 128);
|
|
106
|
+
}
|
|
107
|
+
return buffer;
|
|
108
|
+
}
|
|
109
|
+
var cleanInt = (v) => !sepRE.test(v) && intRE.test(v = v.replaceAll("_", "")) ? v : err(`Bad int ${v}`);
|
|
110
|
+
var i8 = i32;
|
|
111
|
+
var i16 = i32;
|
|
112
|
+
i32.parse = (n) => {
|
|
113
|
+
n = parseInt(cleanInt(n));
|
|
114
|
+
if (n < -2147483648 || n > 4294967295) err(`i32 constant out of range`);
|
|
115
|
+
return n;
|
|
116
|
+
};
|
|
117
|
+
function i64(n, buffer = []) {
|
|
118
|
+
if (typeof n === "string") n = i64.parse(n);
|
|
119
|
+
while (true) {
|
|
120
|
+
const byte = Number(n & 0x7Fn);
|
|
121
|
+
n >>= 7n;
|
|
122
|
+
if (n === 0n && (byte & 64) === 0 || n === -1n && (byte & 64) !== 0) {
|
|
123
|
+
buffer.push(byte);
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
buffer.push(byte | 128);
|
|
127
|
+
}
|
|
128
|
+
return buffer;
|
|
129
|
+
}
|
|
130
|
+
i64.parse = (n) => {
|
|
131
|
+
n = cleanInt(n);
|
|
132
|
+
n = n[0] === "-" ? -BigInt(n.slice(1)) : BigInt(n);
|
|
133
|
+
if (n < -0x8000000000000000n || n > 0xffffffffffffffffn) err(`i64 constant out of range`);
|
|
134
|
+
byteView.setBigInt64(0, n);
|
|
135
|
+
return byteView.getBigInt64(0);
|
|
136
|
+
};
|
|
137
|
+
var byteView = new DataView(new Float64Array(1).buffer);
|
|
138
|
+
var F32_SIGN = 2147483648;
|
|
139
|
+
var F32_NAN = 2139095040;
|
|
140
|
+
function f32(input, value, idx) {
|
|
141
|
+
if (typeof input === "string" && ~(idx = input.indexOf("nan:"))) {
|
|
142
|
+
value = i32.parse(input.slice(idx + 4));
|
|
143
|
+
value |= F32_NAN;
|
|
144
|
+
if (input[0] === "-") value |= F32_SIGN;
|
|
145
|
+
byteView.setInt32(0, value);
|
|
146
|
+
} else {
|
|
147
|
+
value = typeof input === "string" ? f32.parse(input) : input;
|
|
148
|
+
byteView.setFloat32(0, value);
|
|
149
|
+
}
|
|
150
|
+
return [
|
|
151
|
+
byteView.getUint8(3),
|
|
152
|
+
byteView.getUint8(2),
|
|
153
|
+
byteView.getUint8(1),
|
|
154
|
+
byteView.getUint8(0)
|
|
155
|
+
];
|
|
156
|
+
}
|
|
157
|
+
var F64_SIGN = 0x8000000000000000n;
|
|
158
|
+
var F64_NAN = 0x7ff0000000000000n;
|
|
159
|
+
function f64(input, value, idx) {
|
|
160
|
+
if (typeof input === "string" && ~(idx = input.indexOf("nan:"))) {
|
|
161
|
+
value = i64.parse(input.slice(idx + 4));
|
|
162
|
+
value |= F64_NAN;
|
|
163
|
+
if (input[0] === "-") value |= F64_SIGN;
|
|
164
|
+
byteView.setBigInt64(0, value);
|
|
165
|
+
} else {
|
|
166
|
+
value = typeof input === "string" ? f64.parse(input) : input;
|
|
167
|
+
byteView.setFloat64(0, value);
|
|
168
|
+
}
|
|
169
|
+
return [
|
|
170
|
+
byteView.getUint8(7),
|
|
171
|
+
byteView.getUint8(6),
|
|
172
|
+
byteView.getUint8(5),
|
|
173
|
+
byteView.getUint8(4),
|
|
174
|
+
byteView.getUint8(3),
|
|
175
|
+
byteView.getUint8(2),
|
|
176
|
+
byteView.getUint8(1),
|
|
177
|
+
byteView.getUint8(0)
|
|
178
|
+
];
|
|
179
|
+
}
|
|
180
|
+
f64.parse = (input, max = Number.MAX_VALUE) => {
|
|
181
|
+
input = input.replaceAll("_", "");
|
|
182
|
+
let sign = 1;
|
|
183
|
+
if (input[0] === "-") sign = -1, input = input.slice(1);
|
|
184
|
+
else if (input[0] === "+") input = input.slice(1);
|
|
185
|
+
if (input[1] === "x") {
|
|
186
|
+
let [sig, exp = "0"] = input.split(/p/i);
|
|
187
|
+
let [int, fract = ""] = sig.split(".");
|
|
188
|
+
let flen = fract.length ?? 0;
|
|
189
|
+
let intVal = parseInt(int);
|
|
190
|
+
isNaN(intVal) && err();
|
|
191
|
+
let fractVal = fract ? parseInt("0x" + fract) / 16 ** flen : 0;
|
|
192
|
+
exp = parseInt(exp, 10);
|
|
193
|
+
let value = sign * (intVal + fractVal) * 2 ** exp;
|
|
194
|
+
value = Math.max(-max, Math.min(max, value));
|
|
195
|
+
return value;
|
|
196
|
+
}
|
|
197
|
+
if (input.includes("nan")) return sign < 0 ? NaN : NaN;
|
|
198
|
+
if (input.includes("inf")) return sign * Infinity;
|
|
199
|
+
return sign * parseFloat(input);
|
|
200
|
+
};
|
|
201
|
+
f32.parse = (input) => f64.parse(input, 34028234663852886e22);
|
|
202
|
+
|
|
203
|
+
// src/const.js
|
|
204
|
+
var INSTR = [
|
|
205
|
+
// 0x00-0x0a: control
|
|
206
|
+
"unreachable",
|
|
207
|
+
"nop",
|
|
208
|
+
"block block",
|
|
209
|
+
"loop block",
|
|
210
|
+
"if block",
|
|
211
|
+
"else null",
|
|
212
|
+
"then null",
|
|
213
|
+
,
|
|
214
|
+
"throw tagidx",
|
|
215
|
+
,
|
|
216
|
+
"throw_ref",
|
|
217
|
+
// 0x0b-0x19: control
|
|
218
|
+
"end end",
|
|
219
|
+
"br labelidx",
|
|
220
|
+
"br_if labelidx",
|
|
221
|
+
"br_table br_table",
|
|
222
|
+
"return",
|
|
223
|
+
"call funcidx",
|
|
224
|
+
"call_indirect call_indirect",
|
|
225
|
+
"return_call funcidx",
|
|
226
|
+
"return_call_indirect call_indirect",
|
|
227
|
+
"call_ref typeidx",
|
|
228
|
+
"return_call_ref typeidx",
|
|
229
|
+
,
|
|
230
|
+
,
|
|
231
|
+
,
|
|
232
|
+
,
|
|
233
|
+
// 0x1a-0x1f: parametric
|
|
234
|
+
"drop",
|
|
235
|
+
"select select",
|
|
236
|
+
"",
|
|
237
|
+
,
|
|
238
|
+
,
|
|
239
|
+
"try_table try_table",
|
|
240
|
+
// 0x20-0x27: variable
|
|
241
|
+
"local.get localidx",
|
|
242
|
+
"local.set localidx",
|
|
243
|
+
"local.tee localidx",
|
|
244
|
+
"global.get globalidx",
|
|
245
|
+
"global.set globalidx",
|
|
246
|
+
"table.get tableidx",
|
|
247
|
+
"table.set tableidx",
|
|
248
|
+
,
|
|
249
|
+
// 0x28-0x3e: memory
|
|
250
|
+
"i32.load memarg",
|
|
251
|
+
"i64.load memarg",
|
|
252
|
+
"f32.load memarg",
|
|
253
|
+
"f64.load memarg",
|
|
254
|
+
"i32.load8_s memarg",
|
|
255
|
+
"i32.load8_u memarg",
|
|
256
|
+
"i32.load16_s memarg",
|
|
257
|
+
"i32.load16_u memarg",
|
|
258
|
+
"i64.load8_s memarg",
|
|
259
|
+
"i64.load8_u memarg",
|
|
260
|
+
"i64.load16_s memarg",
|
|
261
|
+
"i64.load16_u memarg",
|
|
262
|
+
"i64.load32_s memarg",
|
|
263
|
+
"i64.load32_u memarg",
|
|
264
|
+
"i32.store memarg",
|
|
265
|
+
"i64.store memarg",
|
|
266
|
+
"f32.store memarg",
|
|
267
|
+
"f64.store memarg",
|
|
268
|
+
"i32.store8 memarg",
|
|
269
|
+
"i32.store16 memarg",
|
|
270
|
+
"i64.store8 memarg",
|
|
271
|
+
"i64.store16 memarg",
|
|
272
|
+
"i64.store32 memarg",
|
|
273
|
+
// 0x3f-0x40: memory size/grow
|
|
274
|
+
"memory.size opt_memory",
|
|
275
|
+
"memory.grow opt_memory",
|
|
276
|
+
// 0x41-0x44: const
|
|
277
|
+
"i32.const i32",
|
|
278
|
+
"i64.const i64",
|
|
279
|
+
"f32.const f32",
|
|
280
|
+
"f64.const f64",
|
|
281
|
+
// 0x45-0x4f: i32 comparison
|
|
282
|
+
"i32.eqz",
|
|
283
|
+
"i32.eq",
|
|
284
|
+
"i32.ne",
|
|
285
|
+
"i32.lt_s",
|
|
286
|
+
"i32.lt_u",
|
|
287
|
+
"i32.gt_s",
|
|
288
|
+
"i32.gt_u",
|
|
289
|
+
"i32.le_s",
|
|
290
|
+
"i32.le_u",
|
|
291
|
+
"i32.ge_s",
|
|
292
|
+
"i32.ge_u",
|
|
293
|
+
// 0x50-0x5a: i64 comparison
|
|
294
|
+
"i64.eqz",
|
|
295
|
+
"i64.eq",
|
|
296
|
+
"i64.ne",
|
|
297
|
+
"i64.lt_s",
|
|
298
|
+
"i64.lt_u",
|
|
299
|
+
"i64.gt_s",
|
|
300
|
+
"i64.gt_u",
|
|
301
|
+
"i64.le_s",
|
|
302
|
+
"i64.le_u",
|
|
303
|
+
"i64.ge_s",
|
|
304
|
+
"i64.ge_u",
|
|
305
|
+
// 0x5b-0x60: f32 comparison
|
|
306
|
+
"f32.eq",
|
|
307
|
+
"f32.ne",
|
|
308
|
+
"f32.lt",
|
|
309
|
+
"f32.gt",
|
|
310
|
+
"f32.le",
|
|
311
|
+
"f32.ge",
|
|
312
|
+
// 0x61-0x66: f64 comparison
|
|
313
|
+
"f64.eq",
|
|
314
|
+
"f64.ne",
|
|
315
|
+
"f64.lt",
|
|
316
|
+
"f64.gt",
|
|
317
|
+
"f64.le",
|
|
318
|
+
"f64.ge",
|
|
319
|
+
// 0x67-0x78: i32 arithmetic
|
|
320
|
+
"i32.clz",
|
|
321
|
+
"i32.ctz",
|
|
322
|
+
"i32.popcnt",
|
|
323
|
+
"i32.add",
|
|
324
|
+
"i32.sub",
|
|
325
|
+
"i32.mul",
|
|
326
|
+
"i32.div_s",
|
|
327
|
+
"i32.div_u",
|
|
328
|
+
"i32.rem_s",
|
|
329
|
+
"i32.rem_u",
|
|
330
|
+
"i32.and",
|
|
331
|
+
"i32.or",
|
|
332
|
+
"i32.xor",
|
|
333
|
+
"i32.shl",
|
|
334
|
+
"i32.shr_s",
|
|
335
|
+
"i32.shr_u",
|
|
336
|
+
"i32.rotl",
|
|
337
|
+
"i32.rotr",
|
|
338
|
+
// 0x79-0x8a: i64 arithmetic
|
|
339
|
+
"i64.clz",
|
|
340
|
+
"i64.ctz",
|
|
341
|
+
"i64.popcnt",
|
|
342
|
+
"i64.add",
|
|
343
|
+
"i64.sub",
|
|
344
|
+
"i64.mul",
|
|
345
|
+
"i64.div_s",
|
|
346
|
+
"i64.div_u",
|
|
347
|
+
"i64.rem_s",
|
|
348
|
+
"i64.rem_u",
|
|
349
|
+
"i64.and",
|
|
350
|
+
"i64.or",
|
|
351
|
+
"i64.xor",
|
|
352
|
+
"i64.shl",
|
|
353
|
+
"i64.shr_s",
|
|
354
|
+
"i64.shr_u",
|
|
355
|
+
"i64.rotl",
|
|
356
|
+
"i64.rotr",
|
|
357
|
+
// 0x8b-0x98: f32 arithmetic
|
|
358
|
+
"f32.abs",
|
|
359
|
+
"f32.neg",
|
|
360
|
+
"f32.ceil",
|
|
361
|
+
"f32.floor",
|
|
362
|
+
"f32.trunc",
|
|
363
|
+
"f32.nearest",
|
|
364
|
+
"f32.sqrt",
|
|
365
|
+
"f32.add",
|
|
366
|
+
"f32.sub",
|
|
367
|
+
"f32.mul",
|
|
368
|
+
"f32.div",
|
|
369
|
+
"f32.min",
|
|
370
|
+
"f32.max",
|
|
371
|
+
"f32.copysign",
|
|
372
|
+
// 0x99-0xa6: f64 arithmetic
|
|
373
|
+
"f64.abs",
|
|
374
|
+
"f64.neg",
|
|
375
|
+
"f64.ceil",
|
|
376
|
+
"f64.floor",
|
|
377
|
+
"f64.trunc",
|
|
378
|
+
"f64.nearest",
|
|
379
|
+
"f64.sqrt",
|
|
380
|
+
"f64.add",
|
|
381
|
+
"f64.sub",
|
|
382
|
+
"f64.mul",
|
|
383
|
+
"f64.div",
|
|
384
|
+
"f64.min",
|
|
385
|
+
"f64.max",
|
|
386
|
+
"f64.copysign",
|
|
387
|
+
// 0xa7-0xc4: conversions (no immediates)
|
|
388
|
+
"i32.wrap_i64",
|
|
389
|
+
"i32.trunc_f32_s",
|
|
390
|
+
"i32.trunc_f32_u",
|
|
391
|
+
"i32.trunc_f64_s",
|
|
392
|
+
"i32.trunc_f64_u",
|
|
393
|
+
"i64.extend_i32_s",
|
|
394
|
+
"i64.extend_i32_u",
|
|
395
|
+
"i64.trunc_f32_s",
|
|
396
|
+
"i64.trunc_f32_u",
|
|
397
|
+
"i64.trunc_f64_s",
|
|
398
|
+
"i64.trunc_f64_u",
|
|
399
|
+
"f32.convert_i32_s",
|
|
400
|
+
"f32.convert_i32_u",
|
|
401
|
+
"f32.convert_i64_s",
|
|
402
|
+
"f32.convert_i64_u",
|
|
403
|
+
"f32.demote_f64",
|
|
404
|
+
"f64.convert_i32_s",
|
|
405
|
+
"f64.convert_i32_u",
|
|
406
|
+
"f64.convert_i64_s",
|
|
407
|
+
"f64.convert_i64_u",
|
|
408
|
+
"f64.promote_f32",
|
|
409
|
+
"i32.reinterpret_f32",
|
|
410
|
+
"i64.reinterpret_f64",
|
|
411
|
+
"f32.reinterpret_i32",
|
|
412
|
+
"f64.reinterpret_i64",
|
|
413
|
+
// 0xc0-0xc4: sign extension
|
|
414
|
+
"i32.extend8_s",
|
|
415
|
+
"i32.extend16_s",
|
|
416
|
+
"i64.extend8_s",
|
|
417
|
+
"i64.extend16_s",
|
|
418
|
+
"i64.extend32_s",
|
|
419
|
+
,
|
|
420
|
+
,
|
|
421
|
+
,
|
|
422
|
+
,
|
|
423
|
+
,
|
|
424
|
+
,
|
|
425
|
+
,
|
|
426
|
+
,
|
|
427
|
+
,
|
|
428
|
+
,
|
|
429
|
+
,
|
|
430
|
+
// 0xd0-0xd6: reference
|
|
431
|
+
"ref.null ref_null",
|
|
432
|
+
"ref.is_null",
|
|
433
|
+
"ref.func funcidx",
|
|
434
|
+
"ref.eq",
|
|
435
|
+
"ref.as_non_null",
|
|
436
|
+
"br_on_null labelidx",
|
|
437
|
+
"br_on_non_null labelidx",
|
|
438
|
+
,
|
|
439
|
+
,
|
|
440
|
+
,
|
|
441
|
+
,
|
|
442
|
+
,
|
|
443
|
+
,
|
|
444
|
+
,
|
|
445
|
+
,
|
|
446
|
+
,
|
|
447
|
+
,
|
|
448
|
+
,
|
|
449
|
+
,
|
|
450
|
+
,
|
|
451
|
+
,
|
|
452
|
+
,
|
|
453
|
+
,
|
|
454
|
+
,
|
|
455
|
+
,
|
|
456
|
+
,
|
|
457
|
+
,
|
|
458
|
+
,
|
|
459
|
+
,
|
|
460
|
+
,
|
|
461
|
+
,
|
|
462
|
+
,
|
|
463
|
+
,
|
|
464
|
+
,
|
|
465
|
+
,
|
|
466
|
+
,
|
|
467
|
+
,
|
|
468
|
+
,
|
|
469
|
+
,
|
|
470
|
+
,
|
|
471
|
+
,
|
|
472
|
+
,
|
|
473
|
+
,
|
|
474
|
+
// 0xfb: GC instructions (nested array for multi-byte opcodes)
|
|
475
|
+
[
|
|
476
|
+
"struct.new typeidx",
|
|
477
|
+
"struct.new_default typeidx",
|
|
478
|
+
"struct.get typeidx_field",
|
|
479
|
+
"struct.get_s typeidx_field",
|
|
480
|
+
"struct.get_u typeidx_field",
|
|
481
|
+
"struct.set typeidx_field",
|
|
482
|
+
"array.new typeidx",
|
|
483
|
+
"array.new_default typeidx",
|
|
484
|
+
"array.new_fixed typeidx_multi",
|
|
485
|
+
"array.new_data typeidx_dataidx",
|
|
486
|
+
"array.new_elem typeidx_elemidx",
|
|
487
|
+
"array.get typeidx",
|
|
488
|
+
"array.get_s typeidx",
|
|
489
|
+
"array.get_u typeidx",
|
|
490
|
+
"array.set typeidx",
|
|
491
|
+
"array.len",
|
|
492
|
+
"array.fill typeidx",
|
|
493
|
+
"array.copy typeidx_typeidx",
|
|
494
|
+
"array.init_data typeidx_dataidx",
|
|
495
|
+
"array.init_elem typeidx_elemidx",
|
|
496
|
+
"ref.test reftype",
|
|
497
|
+
"",
|
|
498
|
+
"ref.cast reftype",
|
|
499
|
+
"",
|
|
500
|
+
"br_on_cast reftype2",
|
|
501
|
+
"br_on_cast_fail reftype2",
|
|
502
|
+
"any.convert_extern",
|
|
503
|
+
"extern.convert_any",
|
|
504
|
+
"ref.i31",
|
|
505
|
+
"i31.get_s",
|
|
506
|
+
"i31.get_u"
|
|
507
|
+
],
|
|
508
|
+
// 0xfc: Bulk memory/table operations (nested array)
|
|
509
|
+
[
|
|
510
|
+
"i32.trunc_sat_f32_s",
|
|
511
|
+
"i32.trunc_sat_f32_u",
|
|
512
|
+
"i32.trunc_sat_f64_s",
|
|
513
|
+
"i32.trunc_sat_f64_u",
|
|
514
|
+
"i64.trunc_sat_f32_s",
|
|
515
|
+
"i64.trunc_sat_f32_u",
|
|
516
|
+
"i64.trunc_sat_f64_s",
|
|
517
|
+
"i64.trunc_sat_f64_u",
|
|
518
|
+
"memory.init dataidx_memoryidx",
|
|
519
|
+
"data.drop dataidx",
|
|
520
|
+
"memory.copy memoryidx_memoryidx",
|
|
521
|
+
"memory.fill memoryidx?",
|
|
522
|
+
"table.init reversed",
|
|
523
|
+
"elem.drop elemidx",
|
|
524
|
+
"table.copy tableidx_tableidx",
|
|
525
|
+
"table.grow tableidx",
|
|
526
|
+
"table.size tableidx",
|
|
527
|
+
"table.fill tableidx",
|
|
528
|
+
,
|
|
529
|
+
"i64.add128",
|
|
530
|
+
"i64.sub128",
|
|
531
|
+
"i64.mul_wide_s",
|
|
532
|
+
"i64.mul_wide_u"
|
|
533
|
+
],
|
|
534
|
+
// 0xfd: SIMD instructions (nested array)
|
|
535
|
+
[
|
|
536
|
+
"v128.load memarg",
|
|
537
|
+
"v128.load8x8_s memarg",
|
|
538
|
+
"v128.load8x8_u memarg",
|
|
539
|
+
"v128.load16x4_s memarg",
|
|
540
|
+
"v128.load16x4_u memarg",
|
|
541
|
+
"v128.load32x2_s memarg",
|
|
542
|
+
"v128.load32x2_u memarg",
|
|
543
|
+
"v128.load8_splat memarg",
|
|
544
|
+
"v128.load16_splat memarg",
|
|
545
|
+
"v128.load32_splat memarg",
|
|
546
|
+
"v128.load64_splat memarg",
|
|
547
|
+
"v128.store memarg",
|
|
548
|
+
"v128.const v128const",
|
|
549
|
+
"i8x16.shuffle shuffle",
|
|
550
|
+
"i8x16.swizzle",
|
|
551
|
+
"i8x16.splat",
|
|
552
|
+
"i16x8.splat",
|
|
553
|
+
"i32x4.splat",
|
|
554
|
+
"i64x2.splat",
|
|
555
|
+
"f32x4.splat",
|
|
556
|
+
"f64x2.splat",
|
|
557
|
+
"i8x16.extract_lane_s laneidx",
|
|
558
|
+
"i8x16.extract_lane_u laneidx",
|
|
559
|
+
"i8x16.replace_lane laneidx",
|
|
560
|
+
"i16x8.extract_lane_s laneidx",
|
|
561
|
+
"i16x8.extract_lane_u laneidx",
|
|
562
|
+
"i16x8.replace_lane laneidx",
|
|
563
|
+
"i32x4.extract_lane laneidx",
|
|
564
|
+
"i32x4.replace_lane laneidx",
|
|
565
|
+
"i64x2.extract_lane laneidx",
|
|
566
|
+
"i64x2.replace_lane laneidx",
|
|
567
|
+
"f32x4.extract_lane laneidx",
|
|
568
|
+
"f32x4.replace_lane laneidx",
|
|
569
|
+
"f64x2.extract_lane laneidx",
|
|
570
|
+
"f64x2.replace_lane laneidx",
|
|
571
|
+
"i8x16.eq",
|
|
572
|
+
"i8x16.ne",
|
|
573
|
+
"i8x16.lt_s",
|
|
574
|
+
"i8x16.lt_u",
|
|
575
|
+
"i8x16.gt_s",
|
|
576
|
+
"i8x16.gt_u",
|
|
577
|
+
"i8x16.le_s",
|
|
578
|
+
"i8x16.le_u",
|
|
579
|
+
"i8x16.ge_s",
|
|
580
|
+
"i8x16.ge_u",
|
|
581
|
+
"i16x8.eq",
|
|
582
|
+
"i16x8.ne",
|
|
583
|
+
"i16x8.lt_s",
|
|
584
|
+
"i16x8.lt_u",
|
|
585
|
+
"i16x8.gt_s",
|
|
586
|
+
"i16x8.gt_u",
|
|
587
|
+
"i16x8.le_s",
|
|
588
|
+
"i16x8.le_u",
|
|
589
|
+
"i16x8.ge_s",
|
|
590
|
+
"i16x8.ge_u",
|
|
591
|
+
"i32x4.eq",
|
|
592
|
+
"i32x4.ne",
|
|
593
|
+
"i32x4.lt_s",
|
|
594
|
+
"i32x4.lt_u",
|
|
595
|
+
"i32x4.gt_s",
|
|
596
|
+
"i32x4.gt_u",
|
|
597
|
+
"i32x4.le_s",
|
|
598
|
+
"i32x4.le_u",
|
|
599
|
+
"i32x4.ge_s",
|
|
600
|
+
"i32x4.ge_u",
|
|
601
|
+
"f32x4.eq",
|
|
602
|
+
"f32x4.ne",
|
|
603
|
+
"f32x4.lt",
|
|
604
|
+
"f32x4.gt",
|
|
605
|
+
"f32x4.le",
|
|
606
|
+
"f32x4.ge",
|
|
607
|
+
"f64x2.eq",
|
|
608
|
+
"f64x2.ne",
|
|
609
|
+
"f64x2.lt",
|
|
610
|
+
"f64x2.gt",
|
|
611
|
+
"f64x2.le",
|
|
612
|
+
"f64x2.ge",
|
|
613
|
+
"v128.not",
|
|
614
|
+
"v128.and",
|
|
615
|
+
"v128.andnot",
|
|
616
|
+
"v128.or",
|
|
617
|
+
"v128.xor",
|
|
618
|
+
"v128.bitselect",
|
|
619
|
+
"v128.any_true",
|
|
620
|
+
"v128.load8_lane memlane",
|
|
621
|
+
"v128.load16_lane memlane",
|
|
622
|
+
"v128.load32_lane memlane",
|
|
623
|
+
"v128.load64_lane memlane",
|
|
624
|
+
"v128.store8_lane memlane",
|
|
625
|
+
"v128.store16_lane memlane",
|
|
626
|
+
"v128.store32_lane memlane",
|
|
627
|
+
"v128.store64_lane memlane",
|
|
628
|
+
"v128.load32_zero memarg",
|
|
629
|
+
"v128.load64_zero memarg",
|
|
630
|
+
"f32x4.demote_f64x2_zero",
|
|
631
|
+
"f64x2.promote_low_f32x4",
|
|
632
|
+
"i8x16.abs",
|
|
633
|
+
"i8x16.neg",
|
|
634
|
+
"i8x16.popcnt",
|
|
635
|
+
"i8x16.all_true",
|
|
636
|
+
"i8x16.bitmask",
|
|
637
|
+
"i8x16.narrow_i16x8_s",
|
|
638
|
+
"i8x16.narrow_i16x8_u",
|
|
639
|
+
"f32x4.ceil",
|
|
640
|
+
"f32x4.floor",
|
|
641
|
+
"f32x4.trunc",
|
|
642
|
+
"f32x4.nearest",
|
|
643
|
+
"i8x16.shl",
|
|
644
|
+
"i8x16.shr_s",
|
|
645
|
+
"i8x16.shr_u",
|
|
646
|
+
"i8x16.add",
|
|
647
|
+
"i8x16.add_sat_s",
|
|
648
|
+
"i8x16.add_sat_u",
|
|
649
|
+
"i8x16.sub",
|
|
650
|
+
"i8x16.sub_sat_s",
|
|
651
|
+
"i8x16.sub_sat_u",
|
|
652
|
+
"f64x2.ceil",
|
|
653
|
+
"f64x2.floor",
|
|
654
|
+
"i8x16.min_s",
|
|
655
|
+
"i8x16.min_u",
|
|
656
|
+
"i8x16.max_s",
|
|
657
|
+
"i8x16.max_u",
|
|
658
|
+
"f64x2.trunc",
|
|
659
|
+
"i8x16.avgr_u",
|
|
660
|
+
"i16x8.extadd_pairwise_i8x16_s",
|
|
661
|
+
"i16x8.extadd_pairwise_i8x16_u",
|
|
662
|
+
"i32x4.extadd_pairwise_i16x8_s",
|
|
663
|
+
"i32x4.extadd_pairwise_i16x8_u",
|
|
664
|
+
"i16x8.abs",
|
|
665
|
+
"i16x8.neg",
|
|
666
|
+
"i16x8.q15mulr_sat_s",
|
|
667
|
+
"i16x8.all_true",
|
|
668
|
+
"i16x8.bitmask",
|
|
669
|
+
"i16x8.narrow_i32x4_s",
|
|
670
|
+
"i16x8.narrow_i32x4_u",
|
|
671
|
+
"i16x8.extend_low_i8x16_s",
|
|
672
|
+
"i16x8.extend_high_i8x16_s",
|
|
673
|
+
"i16x8.extend_low_i8x16_u",
|
|
674
|
+
"i16x8.extend_high_i8x16_u",
|
|
675
|
+
"i16x8.shl",
|
|
676
|
+
"i16x8.shr_s",
|
|
677
|
+
"i16x8.shr_u",
|
|
678
|
+
"i16x8.add",
|
|
679
|
+
"i16x8.add_sat_s",
|
|
680
|
+
"i16x8.add_sat_u",
|
|
681
|
+
"i16x8.sub",
|
|
682
|
+
"i16x8.sub_sat_s",
|
|
683
|
+
"i16x8.sub_sat_u",
|
|
684
|
+
"f64x2.nearest",
|
|
685
|
+
"i16x8.mul",
|
|
686
|
+
"i16x8.min_s",
|
|
687
|
+
"i16x8.min_u",
|
|
688
|
+
"i16x8.max_s",
|
|
689
|
+
"i16x8.max_u",
|
|
690
|
+
,
|
|
691
|
+
"i16x8.avgr_u",
|
|
692
|
+
"i16x8.extmul_low_i8x16_s",
|
|
693
|
+
"i16x8.extmul_high_i8x16_s",
|
|
694
|
+
"i16x8.extmul_low_i8x16_u",
|
|
695
|
+
"i16x8.extmul_high_i8x16_u",
|
|
696
|
+
"i32x4.abs",
|
|
697
|
+
"i32x4.neg",
|
|
698
|
+
,
|
|
699
|
+
"i32x4.all_true",
|
|
700
|
+
"i32x4.bitmask",
|
|
701
|
+
,
|
|
702
|
+
,
|
|
703
|
+
"i32x4.extend_low_i16x8_s",
|
|
704
|
+
"i32x4.extend_high_i16x8_s",
|
|
705
|
+
"i32x4.extend_low_i16x8_u",
|
|
706
|
+
"i32x4.extend_high_i16x8_u",
|
|
707
|
+
"i32x4.shl",
|
|
708
|
+
"i32x4.shr_s",
|
|
709
|
+
"i32x4.shr_u",
|
|
710
|
+
"i32x4.add",
|
|
711
|
+
,
|
|
712
|
+
,
|
|
713
|
+
"i32x4.sub",
|
|
714
|
+
,
|
|
715
|
+
,
|
|
716
|
+
,
|
|
717
|
+
"i32x4.mul",
|
|
718
|
+
"i32x4.min_s",
|
|
719
|
+
"i32x4.min_u",
|
|
720
|
+
"i32x4.max_s",
|
|
721
|
+
"i32x4.max_u",
|
|
722
|
+
"i32x4.dot_i16x8_s",
|
|
723
|
+
,
|
|
724
|
+
"i32x4.extmul_low_i16x8_s",
|
|
725
|
+
"i32x4.extmul_high_i16x8_s",
|
|
726
|
+
"i32x4.extmul_low_i16x8_u",
|
|
727
|
+
"i32x4.extmul_high_i16x8_u",
|
|
728
|
+
"i64x2.abs",
|
|
729
|
+
"i64x2.neg",
|
|
730
|
+
,
|
|
731
|
+
"i64x2.all_true",
|
|
732
|
+
"i64x2.bitmask",
|
|
733
|
+
,
|
|
734
|
+
,
|
|
735
|
+
"i64x2.extend_low_i32x4_s",
|
|
736
|
+
"i64x2.extend_high_i32x4_s",
|
|
737
|
+
"i64x2.extend_low_i32x4_u",
|
|
738
|
+
"i64x2.extend_high_i32x4_u",
|
|
739
|
+
"i64x2.shl",
|
|
740
|
+
"i64x2.shr_s",
|
|
741
|
+
"i64x2.shr_u",
|
|
742
|
+
"i64x2.add",
|
|
743
|
+
,
|
|
744
|
+
,
|
|
745
|
+
"i64x2.sub",
|
|
746
|
+
,
|
|
747
|
+
,
|
|
748
|
+
,
|
|
749
|
+
"i64x2.mul",
|
|
750
|
+
"i64x2.eq",
|
|
751
|
+
"i64x2.ne",
|
|
752
|
+
"i64x2.lt_s",
|
|
753
|
+
"i64x2.gt_s",
|
|
754
|
+
"i64x2.le_s",
|
|
755
|
+
"i64x2.ge_s",
|
|
756
|
+
"i64x2.extmul_low_i32x4_s",
|
|
757
|
+
"i64x2.extmul_high_i32x4_s",
|
|
758
|
+
"i64x2.extmul_low_i32x4_u",
|
|
759
|
+
"i64x2.extmul_high_i32x4_u",
|
|
760
|
+
"f32x4.abs",
|
|
761
|
+
"f32x4.neg",
|
|
762
|
+
,
|
|
763
|
+
"f32x4.sqrt",
|
|
764
|
+
"f32x4.add",
|
|
765
|
+
"f32x4.sub",
|
|
766
|
+
"f32x4.mul",
|
|
767
|
+
"f32x4.div",
|
|
768
|
+
"f32x4.min",
|
|
769
|
+
"f32x4.max",
|
|
770
|
+
"f32x4.pmin",
|
|
771
|
+
"f32x4.pmax",
|
|
772
|
+
"f64x2.abs",
|
|
773
|
+
"f64x2.neg",
|
|
774
|
+
,
|
|
775
|
+
"f64x2.sqrt",
|
|
776
|
+
"f64x2.add",
|
|
777
|
+
"f64x2.sub",
|
|
778
|
+
"f64x2.mul",
|
|
779
|
+
"f64x2.div",
|
|
780
|
+
"f64x2.min",
|
|
781
|
+
"f64x2.max",
|
|
782
|
+
"f64x2.pmin",
|
|
783
|
+
"f64x2.pmax",
|
|
784
|
+
"i32x4.trunc_sat_f32x4_s",
|
|
785
|
+
"i32x4.trunc_sat_f32x4_u",
|
|
786
|
+
"f32x4.convert_i32x4_s",
|
|
787
|
+
"f32x4.convert_i32x4_u",
|
|
788
|
+
"i32x4.trunc_sat_f64x2_s_zero",
|
|
789
|
+
"i32x4.trunc_sat_f64x2_u_zero",
|
|
790
|
+
"f64x2.convert_low_i32x4_s",
|
|
791
|
+
"f64x2.convert_low_i32x4_u",
|
|
792
|
+
"i8x16.relaxed_swizzle",
|
|
793
|
+
"i32x4.relaxed_trunc_f32x4_s",
|
|
794
|
+
"i32x4.relaxed_trunc_f32x4_u",
|
|
795
|
+
"i32x4.relaxed_trunc_f64x2_s_zero",
|
|
796
|
+
"i32x4.relaxed_trunc_f64x2_u_zero",
|
|
797
|
+
"f32x4.relaxed_madd",
|
|
798
|
+
"f32x4.relaxed_nmadd",
|
|
799
|
+
"f64x2.relaxed_madd",
|
|
800
|
+
"f64x2.relaxed_nmadd",
|
|
801
|
+
"i8x16.relaxed_laneselect",
|
|
802
|
+
"i16x8.relaxed_laneselect",
|
|
803
|
+
"i32x4.relaxed_laneselect",
|
|
804
|
+
"i64x2.relaxed_laneselect",
|
|
805
|
+
"f32x4.relaxed_min",
|
|
806
|
+
"f32x4.relaxed_max",
|
|
807
|
+
"f64x2.relaxed_min",
|
|
808
|
+
"f64x2.relaxed_max",
|
|
809
|
+
"i16x8.relaxed_q15mulr_s",
|
|
810
|
+
"i16x8.relaxed_dot_i8x16_i7x16_s",
|
|
811
|
+
"i32x4.relaxed_dot_i8x16_i7x16_add_s"
|
|
812
|
+
],
|
|
813
|
+
// 0xfe: atomic/thread instructions
|
|
814
|
+
[
|
|
815
|
+
"memory.atomic.notify memarg",
|
|
816
|
+
"memory.atomic.wait32 memarg",
|
|
817
|
+
"memory.atomic.wait64 memarg",
|
|
818
|
+
"atomic.fence opt_memory",
|
|
819
|
+
,
|
|
820
|
+
,
|
|
821
|
+
,
|
|
822
|
+
,
|
|
823
|
+
,
|
|
824
|
+
,
|
|
825
|
+
,
|
|
826
|
+
,
|
|
827
|
+
,
|
|
828
|
+
,
|
|
829
|
+
,
|
|
830
|
+
,
|
|
831
|
+
"i32.atomic.load memarg",
|
|
832
|
+
"i64.atomic.load memarg",
|
|
833
|
+
"i32.atomic.load8_u memarg",
|
|
834
|
+
"i32.atomic.load16_u memarg",
|
|
835
|
+
"i64.atomic.load8_u memarg",
|
|
836
|
+
"i64.atomic.load16_u memarg",
|
|
837
|
+
"i64.atomic.load32_u memarg",
|
|
838
|
+
"i32.atomic.store memarg",
|
|
839
|
+
"i64.atomic.store memarg",
|
|
840
|
+
"i32.atomic.store8 memarg",
|
|
841
|
+
"i32.atomic.store16 memarg",
|
|
842
|
+
"i64.atomic.store8 memarg",
|
|
843
|
+
"i64.atomic.store16 memarg",
|
|
844
|
+
"i64.atomic.store32 memarg",
|
|
845
|
+
"i32.atomic.rmw.add memarg",
|
|
846
|
+
"i64.atomic.rmw.add memarg",
|
|
847
|
+
"i32.atomic.rmw8.add_u memarg",
|
|
848
|
+
"i32.atomic.rmw16.add_u memarg",
|
|
849
|
+
"i64.atomic.rmw8.add_u memarg",
|
|
850
|
+
"i64.atomic.rmw16.add_u memarg",
|
|
851
|
+
"i64.atomic.rmw32.add_u memarg",
|
|
852
|
+
"i32.atomic.rmw.sub memarg",
|
|
853
|
+
"i64.atomic.rmw.sub memarg",
|
|
854
|
+
"i32.atomic.rmw8.sub_u memarg",
|
|
855
|
+
"i32.atomic.rmw16.sub_u memarg",
|
|
856
|
+
"i64.atomic.rmw8.sub_u memarg",
|
|
857
|
+
"i64.atomic.rmw16.sub_u memarg",
|
|
858
|
+
"i64.atomic.rmw32.sub_u memarg",
|
|
859
|
+
"i32.atomic.rmw.and memarg",
|
|
860
|
+
"i64.atomic.rmw.and memarg",
|
|
861
|
+
"i32.atomic.rmw8.and_u memarg",
|
|
862
|
+
"i32.atomic.rmw16.and_u memarg",
|
|
863
|
+
"i64.atomic.rmw8.and_u memarg",
|
|
864
|
+
"i64.atomic.rmw16.and_u memarg",
|
|
865
|
+
"i64.atomic.rmw32.and_u memarg",
|
|
866
|
+
"i32.atomic.rmw.or memarg",
|
|
867
|
+
"i64.atomic.rmw.or memarg",
|
|
868
|
+
"i32.atomic.rmw8.or_u memarg",
|
|
869
|
+
"i32.atomic.rmw16.or_u memarg",
|
|
870
|
+
"i64.atomic.rmw8.or_u memarg",
|
|
871
|
+
"i64.atomic.rmw16.or_u memarg",
|
|
872
|
+
"i64.atomic.rmw32.or_u memarg",
|
|
873
|
+
"i32.atomic.rmw.xor memarg",
|
|
874
|
+
"i64.atomic.rmw.xor memarg",
|
|
875
|
+
"i32.atomic.rmw8.xor_u memarg",
|
|
876
|
+
"i32.atomic.rmw16.xor_u memarg",
|
|
877
|
+
"i64.atomic.rmw8.xor_u memarg",
|
|
878
|
+
"i64.atomic.rmw16.xor_u memarg",
|
|
879
|
+
"i64.atomic.rmw32.xor_u memarg",
|
|
880
|
+
"i32.atomic.rmw.xchg memarg",
|
|
881
|
+
"i64.atomic.rmw.xchg memarg",
|
|
882
|
+
"i32.atomic.rmw8.xchg_u memarg",
|
|
883
|
+
"i32.atomic.rmw16.xchg_u memarg",
|
|
884
|
+
"i64.atomic.rmw8.xchg_u memarg",
|
|
885
|
+
"i64.atomic.rmw16.xchg_u memarg",
|
|
886
|
+
"i64.atomic.rmw32.xchg_u memarg",
|
|
887
|
+
"i32.atomic.rmw.cmpxchg memarg",
|
|
888
|
+
"i64.atomic.rmw.cmpxchg memarg",
|
|
889
|
+
"i32.atomic.rmw8.cmpxchg_u memarg",
|
|
890
|
+
"i32.atomic.rmw16.cmpxchg_u memarg",
|
|
891
|
+
"i64.atomic.rmw8.cmpxchg_u memarg",
|
|
892
|
+
"i64.atomic.rmw16.cmpxchg_u memarg",
|
|
893
|
+
"i64.atomic.rmw32.cmpxchg_u memarg"
|
|
894
|
+
]
|
|
895
|
+
];
|
|
896
|
+
var SECTION = { custom: 0, type: 1, import: 2, func: 3, table: 4, memory: 5, tag: 13, global: 6, export: 7, start: 8, elem: 9, datacount: 12, code: 10, data: 11 };
|
|
897
|
+
var TYPE = {
|
|
898
|
+
// Value types
|
|
899
|
+
i8: 120,
|
|
900
|
+
i16: 119,
|
|
901
|
+
i32: 127,
|
|
902
|
+
i64: 126,
|
|
903
|
+
f32: 125,
|
|
904
|
+
f64: 124,
|
|
905
|
+
void: 64,
|
|
906
|
+
v128: 123,
|
|
907
|
+
// Heap types
|
|
908
|
+
exn: 105,
|
|
909
|
+
noexn: 116,
|
|
910
|
+
nofunc: 115,
|
|
911
|
+
noextern: 114,
|
|
912
|
+
none: 113,
|
|
913
|
+
func: 112,
|
|
914
|
+
extern: 111,
|
|
915
|
+
any: 110,
|
|
916
|
+
eq: 109,
|
|
917
|
+
i31: 108,
|
|
918
|
+
struct: 107,
|
|
919
|
+
array: 106,
|
|
920
|
+
// Reference type abbreviations (absheaptype abbrs)
|
|
921
|
+
nullfuncref: 115,
|
|
922
|
+
nullexternref: 114,
|
|
923
|
+
nullexnref: 116,
|
|
924
|
+
nullref: 113,
|
|
925
|
+
funcref: 112,
|
|
926
|
+
externref: 111,
|
|
927
|
+
exnref: 105,
|
|
928
|
+
anyref: 110,
|
|
929
|
+
eqref: 109,
|
|
930
|
+
i31ref: 108,
|
|
931
|
+
structref: 107,
|
|
932
|
+
arrayref: 106,
|
|
933
|
+
// ref, refnull
|
|
934
|
+
ref: 100,
|
|
935
|
+
// -0x1c
|
|
936
|
+
refnull: 99,
|
|
937
|
+
// -0x1d
|
|
938
|
+
// Recursion group / type definition opcodes
|
|
939
|
+
sub: 80,
|
|
940
|
+
subfinal: 79,
|
|
941
|
+
rec: 78
|
|
942
|
+
};
|
|
943
|
+
var DEFTYPE = { func: 96, struct: 95, array: 94, sub: 80, subfinal: 79, rec: 78 };
|
|
944
|
+
var KIND = { func: 0, table: 1, memory: 2, global: 3, tag: 4 };
|
|
945
|
+
|
|
946
|
+
// src/parse.js
|
|
947
|
+
var parse_default = (str2) => {
|
|
948
|
+
let i = 0, level = [], buf = "", q = 0, depth = 0;
|
|
949
|
+
const commit = () => buf && (level.push(buf), buf = "");
|
|
950
|
+
const parseLevel = (pos) => {
|
|
951
|
+
level.i = pos;
|
|
952
|
+
for (let c, root, p; i < str2.length; ) {
|
|
953
|
+
c = str2.charCodeAt(i);
|
|
954
|
+
if (q === 34) buf += str2[i++], c === 92 ? buf += str2[i++] : c === 34 && (commit(), q = 0);
|
|
955
|
+
else if (q > 59) c === 40 && str2.charCodeAt(i + 1) === 59 ? (q++, buf += str2[i++] + str2[i++]) : (
|
|
956
|
+
// nested (;
|
|
957
|
+
c === 59 && str2.charCodeAt(i + 1) === 41 ? (buf += str2[i++] + str2[i++], --q === 59 && (commit(), q = 0)) : (
|
|
958
|
+
// ;)
|
|
959
|
+
buf += str2[i++]
|
|
960
|
+
)
|
|
961
|
+
);
|
|
962
|
+
else if (q < 0) c === 10 || c === 13 ? (buf += str2[i++], commit(), q = 0) : buf += str2[i++];
|
|
963
|
+
else if (c === 34) buf !== "$" && commit(), q = 34, buf += str2[i++];
|
|
964
|
+
else if (c === 40 && str2.charCodeAt(i + 1) === 59) commit(), q = 60, buf = str2[i++] + str2[i++];
|
|
965
|
+
else if (c === 59 && str2.charCodeAt(i + 1) === 59) commit(), q = -1, buf = str2[i++] + str2[i++];
|
|
966
|
+
else if (c === 40 && str2.charCodeAt(i + 1) === 64) commit(), p = i, i += 2, buf = "@", depth++, (root = level).push(level = []), parseLevel(p), level = root;
|
|
967
|
+
else if (c === 40) commit(), p = i++, depth++, (root = level).push(level = []), parseLevel(p), level = root;
|
|
968
|
+
else if (c === 41) return commit(), i++, depth--;
|
|
969
|
+
else if (c <= 32) commit(), i++;
|
|
970
|
+
else buf += str2[i++];
|
|
971
|
+
}
|
|
972
|
+
q < 0 && commit();
|
|
973
|
+
commit();
|
|
974
|
+
};
|
|
975
|
+
parseLevel(0);
|
|
976
|
+
if (q === 34) err(`Unclosed quote`, i);
|
|
977
|
+
if (q > 59) err(`Unclosed block comment`, i);
|
|
978
|
+
if (depth > 0) err(`Unclosed parenthesis`, i);
|
|
979
|
+
if (i < str2.length) err(`Unexpected closing parenthesis`, i);
|
|
980
|
+
return level.length > 1 ? level : level[0] || [];
|
|
981
|
+
};
|
|
982
|
+
|
|
983
|
+
// src/compile.js
|
|
984
|
+
var cleanup = (node, result) => !Array.isArray(node) ? typeof node !== "string" ? node : (
|
|
985
|
+
// skip comments: ;; ... or (; ... ;)
|
|
986
|
+
node[0] === ";" || node[1] === ";" ? null : (
|
|
987
|
+
// normalize quoted ids: $"name" -> $name (if no escapes), else $unescaped
|
|
988
|
+
node[0] === "$" && node[1] === '"' ? node.includes("\\") ? "$" + unescape(node.slice(1)) : "$" + node.slice(2, -1) : (
|
|
989
|
+
// convert string literals to byte arrays with valueOf
|
|
990
|
+
node[0] === '"' ? str(node) : node
|
|
991
|
+
)
|
|
992
|
+
)
|
|
993
|
+
) : (
|
|
994
|
+
// remove annotations like (@name ...) except @custom and @metadata.code.*
|
|
995
|
+
node[0]?.[0] === "@" && node[0] !== "@custom" && !node[0]?.startsWith?.("@metadata.code.") ? null : (
|
|
996
|
+
// unwrap single-element array containing module (after removing comments), preserve .i
|
|
997
|
+
(result = node.map(cleanup).filter((n) => n != null), result.i = node.i, result.length === 1 && result[0]?.[0] === "module" ? result[0] : result)
|
|
998
|
+
)
|
|
999
|
+
);
|
|
1000
|
+
function compile(nodes) {
|
|
1001
|
+
if (typeof nodes === "string") err.src = nodes, nodes = parse_default(nodes) || [];
|
|
1002
|
+
else err.src = "";
|
|
1003
|
+
err.i = 0;
|
|
1004
|
+
nodes = cleanup(nodes) || [];
|
|
1005
|
+
let idx = 0;
|
|
1006
|
+
if (nodes[0] === "module") idx++, isId(nodes[idx]) && idx++;
|
|
1007
|
+
else if (typeof nodes[0] === "string") nodes = [nodes];
|
|
1008
|
+
if (nodes[idx] === "binary") return Uint8Array.from(nodes.slice(++idx).flat());
|
|
1009
|
+
if (nodes[idx] === "quote") return compile(nodes.slice(++idx).map((v) => v.valueOf().slice(1, -1)).flat().join(""));
|
|
1010
|
+
const ctx = [];
|
|
1011
|
+
for (let kind in SECTION) (ctx[SECTION[kind]] = ctx[kind] = []).name = kind;
|
|
1012
|
+
ctx.metadata = {};
|
|
1013
|
+
nodes.slice(idx).filter((n) => {
|
|
1014
|
+
if (!Array.isArray(n)) {
|
|
1015
|
+
let pos = err.src?.indexOf(n, err.i);
|
|
1016
|
+
if (pos >= 0) err.i = pos;
|
|
1017
|
+
err(`Unexpected token ${n}`);
|
|
1018
|
+
}
|
|
1019
|
+
let [kind, ...node] = n;
|
|
1020
|
+
err.i = n.i;
|
|
1021
|
+
if (kind === "@custom") {
|
|
1022
|
+
ctx.custom.push(node);
|
|
1023
|
+
} else if (kind === "rec") {
|
|
1024
|
+
for (let i = 0; i < node.length; i++) {
|
|
1025
|
+
let [, ...subnode] = node[i];
|
|
1026
|
+
name(subnode, ctx.type);
|
|
1027
|
+
(subnode = typedef(subnode, ctx)).push(i ? true : [ctx.type.length, node.length]);
|
|
1028
|
+
ctx.type.push(subnode);
|
|
1029
|
+
}
|
|
1030
|
+
} else if (kind === "type") {
|
|
1031
|
+
name(node, ctx.type);
|
|
1032
|
+
ctx.type.push(typedef(node, ctx));
|
|
1033
|
+
} else if (kind === "start" || kind === "export") ctx[kind].push(node);
|
|
1034
|
+
else return true;
|
|
1035
|
+
}).forEach((n) => {
|
|
1036
|
+
let [kind, ...node] = n;
|
|
1037
|
+
err.i = n.i;
|
|
1038
|
+
let imported;
|
|
1039
|
+
if (kind === "import") [kind, ...node] = (imported = node).pop();
|
|
1040
|
+
let items = ctx[kind];
|
|
1041
|
+
if (!items) err(`Unknown section ${kind}`);
|
|
1042
|
+
name(node, items);
|
|
1043
|
+
while (node[0]?.[0] === "export") ctx.export.push([node.shift()[1], [kind, items?.length]]);
|
|
1044
|
+
if (node[0]?.[0] === "import") [, ...imported] = node.shift();
|
|
1045
|
+
if (kind === "table") {
|
|
1046
|
+
const is64 = node[0] === "i64", idx2 = is64 ? 1 : 0;
|
|
1047
|
+
if (node[idx2 + 1]?.[0] === "elem") {
|
|
1048
|
+
let [reftype2, [, ...els]] = [node[idx2], node[idx2 + 1]];
|
|
1049
|
+
node = is64 ? ["i64", els.length, els.length, reftype2] : [els.length, els.length, reftype2];
|
|
1050
|
+
ctx.elem.push([["table", items.length], ["offset", [is64 ? "i64.const" : "i32.const", is64 ? 0n : 0]], reftype2, ...els]);
|
|
1051
|
+
}
|
|
1052
|
+
} else if (kind === "memory") {
|
|
1053
|
+
const is64 = node[0] === "i64", idx2 = is64 ? 1 : 0;
|
|
1054
|
+
if (node[idx2]?.[0] === "data") {
|
|
1055
|
+
let [, ...data] = node.splice(idx2, 1)[0], m = "" + Math.ceil(data.reduce((s, d) => s + d.length, 0) / 65536);
|
|
1056
|
+
ctx.data.push([["memory", items.length], [is64 ? "i64.const" : "i32.const", is64 ? 0n : 0], ...data]);
|
|
1057
|
+
node = is64 ? ["i64", m, m] : [m, m];
|
|
1058
|
+
}
|
|
1059
|
+
} else if (kind === "func") {
|
|
1060
|
+
let [idx2, param, result] = typeuse(node, ctx);
|
|
1061
|
+
idx2 ??= regtype(param, result, ctx);
|
|
1062
|
+
!imported && ctx.code.push([[idx2, param, result], ...normalize(node, ctx)]);
|
|
1063
|
+
node = [["type", idx2]];
|
|
1064
|
+
} else if (kind === "tag") {
|
|
1065
|
+
let [idx2, param] = typeuse(node, ctx);
|
|
1066
|
+
idx2 ??= regtype(param, [], ctx);
|
|
1067
|
+
node = [["type", idx2]];
|
|
1068
|
+
}
|
|
1069
|
+
if (imported) ctx.import.push([...imported, [kind, ...node]]), node = null;
|
|
1070
|
+
items.push(node);
|
|
1071
|
+
});
|
|
1072
|
+
const bin = (kind, count = true) => {
|
|
1073
|
+
const items = ctx[kind].filter(Boolean).map((item) => build[kind](item, ctx)).filter(Boolean);
|
|
1074
|
+
if (kind === SECTION.custom) return items.flatMap((content) => [kind, ...vec(content)]);
|
|
1075
|
+
return !items.length ? [] : [kind, ...vec(count ? vec(items) : items)];
|
|
1076
|
+
};
|
|
1077
|
+
const binMeta = () => {
|
|
1078
|
+
const sections = [];
|
|
1079
|
+
for (const type in ctx.metadata) {
|
|
1080
|
+
const name2 = vec(str(`"metadata.code.${type}"`));
|
|
1081
|
+
const content = vec(ctx.metadata[type].map(
|
|
1082
|
+
([funcIdx, instances]) => [...uleb(funcIdx), ...vec(instances.map(([pos, data]) => [...uleb(pos), ...vec(data)]))]
|
|
1083
|
+
));
|
|
1084
|
+
sections.push(0, ...vec([...name2, ...content]));
|
|
1085
|
+
}
|
|
1086
|
+
return sections;
|
|
1087
|
+
};
|
|
1088
|
+
return Uint8Array.from([
|
|
1089
|
+
0,
|
|
1090
|
+
97,
|
|
1091
|
+
115,
|
|
1092
|
+
109,
|
|
1093
|
+
// magic
|
|
1094
|
+
1,
|
|
1095
|
+
0,
|
|
1096
|
+
0,
|
|
1097
|
+
0,
|
|
1098
|
+
// version
|
|
1099
|
+
...bin(SECTION.custom),
|
|
1100
|
+
...bin(SECTION.type),
|
|
1101
|
+
...bin(SECTION.import),
|
|
1102
|
+
...bin(SECTION.func),
|
|
1103
|
+
...bin(SECTION.table),
|
|
1104
|
+
...bin(SECTION.memory),
|
|
1105
|
+
...bin(SECTION.tag),
|
|
1106
|
+
...bin(SECTION.global),
|
|
1107
|
+
...bin(SECTION.export),
|
|
1108
|
+
...bin(SECTION.start, false),
|
|
1109
|
+
...bin(SECTION.elem),
|
|
1110
|
+
...bin(SECTION.datacount, false),
|
|
1111
|
+
...bin(SECTION.code),
|
|
1112
|
+
...binMeta(),
|
|
1113
|
+
...bin(SECTION.data)
|
|
1114
|
+
]);
|
|
1115
|
+
}
|
|
1116
|
+
var isIdx = (n) => n?.[0] === "$" || !isNaN(n);
|
|
1117
|
+
var isId = (n) => n?.[0] === "$";
|
|
1118
|
+
var isMemParam = (n) => n?.[0] === "a" || n?.[0] === "o";
|
|
1119
|
+
function normalize(nodes, ctx) {
|
|
1120
|
+
const out = [];
|
|
1121
|
+
nodes = [...nodes];
|
|
1122
|
+
while (nodes.length) {
|
|
1123
|
+
let node = nodes.shift();
|
|
1124
|
+
if (typeof node === "string") {
|
|
1125
|
+
out.push(node);
|
|
1126
|
+
if (node === "block" || node === "if" || node === "loop") {
|
|
1127
|
+
if (isId(nodes[0])) out.push(nodes.shift());
|
|
1128
|
+
out.push(blocktype(nodes, ctx));
|
|
1129
|
+
} else if (node === "else" || node === "end") {
|
|
1130
|
+
if (isId(nodes[0])) nodes.shift();
|
|
1131
|
+
} else if (node === "select") out.push(paramres(nodes)[1]);
|
|
1132
|
+
else if (node.endsWith("call_indirect")) {
|
|
1133
|
+
let tableidx = isIdx(nodes[0]) ? nodes.shift() : 0, [idx, param, result] = typeuse(nodes, ctx);
|
|
1134
|
+
out.push(tableidx, ["type", idx ?? regtype(param, result, ctx)]);
|
|
1135
|
+
} else if (node === "table.init") out.push(isIdx(nodes[1]) ? nodes.shift() : 0, nodes.shift());
|
|
1136
|
+
else if (node === "table.copy" || node === "memory.copy") out.push(isIdx(nodes[0]) ? nodes.shift() : 0, isIdx(nodes[0]) ? nodes.shift() : 0);
|
|
1137
|
+
else if (node.startsWith("table.")) out.push(isIdx(nodes[0]) ? nodes.shift() : 0);
|
|
1138
|
+
else if (node === "memory.init") {
|
|
1139
|
+
out.push(...isIdx(nodes[1]) ? [nodes.shift(), nodes.shift()].reverse() : [nodes.shift(), 0]);
|
|
1140
|
+
ctx.datacount && (ctx.datacount[0] = true);
|
|
1141
|
+
} else if (node === "data.drop" || node === "array.new_data" || node === "array.init_data") {
|
|
1142
|
+
node === "data.drop" && out.push(nodes.shift());
|
|
1143
|
+
ctx.datacount && (ctx.datacount[0] = true);
|
|
1144
|
+
} else if ((node.startsWith("memory.") || node.endsWith("load") || node.endsWith("store")) && isIdx(nodes[0])) out.push(nodes.shift());
|
|
1145
|
+
} else if (Array.isArray(node)) {
|
|
1146
|
+
const op = node[0];
|
|
1147
|
+
node.i != null && (err.i = node.i);
|
|
1148
|
+
if (op?.startsWith?.("@metadata.code.")) {
|
|
1149
|
+
let type = op.slice(15);
|
|
1150
|
+
out.push(["@metadata", type, node[1]]);
|
|
1151
|
+
continue;
|
|
1152
|
+
}
|
|
1153
|
+
if (typeof op !== "string" || !Array.isArray(INSTR[op])) {
|
|
1154
|
+
out.push(node);
|
|
1155
|
+
continue;
|
|
1156
|
+
}
|
|
1157
|
+
const parts = node.slice(1);
|
|
1158
|
+
if (op === "block" || op === "loop") {
|
|
1159
|
+
out.push(op);
|
|
1160
|
+
if (isId(parts[0])) out.push(parts.shift());
|
|
1161
|
+
out.push(blocktype(parts, ctx), ...normalize(parts, ctx), "end");
|
|
1162
|
+
} else if (op === "if") {
|
|
1163
|
+
let then = [], els = [];
|
|
1164
|
+
if (parts.at(-1)?.[0] === "else") els = normalize(parts.pop().slice(1), ctx);
|
|
1165
|
+
if (parts.at(-1)?.[0] === "then") then = normalize(parts.pop().slice(1), ctx);
|
|
1166
|
+
let immed = [op];
|
|
1167
|
+
if (isId(parts[0])) immed.push(parts.shift());
|
|
1168
|
+
immed.push(blocktype(parts, ctx));
|
|
1169
|
+
out.push(...normalize(parts, ctx), ...immed, ...then);
|
|
1170
|
+
els.length && out.push("else", ...els);
|
|
1171
|
+
out.push("end");
|
|
1172
|
+
} else if (op === "try_table") {
|
|
1173
|
+
out.push(op);
|
|
1174
|
+
if (isId(parts[0])) out.push(parts.shift());
|
|
1175
|
+
out.push(blocktype(parts, ctx));
|
|
1176
|
+
while (parts[0]?.[0] === "catch" || parts[0]?.[0] === "catch_ref" || parts[0]?.[0] === "catch_all" || parts[0]?.[0] === "catch_all_ref") {
|
|
1177
|
+
out.push(parts.shift());
|
|
1178
|
+
}
|
|
1179
|
+
out.push(...normalize(parts, ctx), "end");
|
|
1180
|
+
} else {
|
|
1181
|
+
const imm = [];
|
|
1182
|
+
while (parts.length && (!Array.isArray(parts[0]) || "type,param,result,ref".includes(parts[0][0]))) imm.push(parts.shift());
|
|
1183
|
+
out.push(...normalize(parts, ctx), op, ...imm);
|
|
1184
|
+
nodes.unshift(...out.splice(out.length - 1 - imm.length));
|
|
1185
|
+
}
|
|
1186
|
+
} else out.push(node);
|
|
1187
|
+
}
|
|
1188
|
+
return out;
|
|
1189
|
+
}
|
|
1190
|
+
var regtype = (param, result, ctx, idx = "$" + param + ">" + result) => (ctx.type[idx] ??= ctx.type.push(["func", [param, result]]) - 1, idx);
|
|
1191
|
+
var fieldseq = (nodes, field) => {
|
|
1192
|
+
let seq = [];
|
|
1193
|
+
while (nodes[0]?.[0] === field) {
|
|
1194
|
+
let [, ...args] = nodes.shift(), nm = isId(args[0]) && args.shift();
|
|
1195
|
+
if (nm) nm in seq ? (() => {
|
|
1196
|
+
throw Error(`Duplicate ${field} ${nm}`);
|
|
1197
|
+
})() : seq[nm] = seq.length;
|
|
1198
|
+
seq.push(...args);
|
|
1199
|
+
}
|
|
1200
|
+
return seq;
|
|
1201
|
+
};
|
|
1202
|
+
var paramres = (nodes) => {
|
|
1203
|
+
let param = fieldseq(nodes, "param"), result = fieldseq(nodes, "result");
|
|
1204
|
+
if (nodes[0]?.[0] === "param") throw Error("Unexpected param");
|
|
1205
|
+
return [param, result];
|
|
1206
|
+
};
|
|
1207
|
+
var typeuse = (nodes, ctx) => {
|
|
1208
|
+
if (nodes[0]?.[0] !== "type") return [, ...paramres(nodes)];
|
|
1209
|
+
let [, idx] = nodes.shift(), [param, result] = paramres(nodes);
|
|
1210
|
+
const entry = ctx.type[typeof idx === "string" && isNaN(idx) ? ctx.type[idx] : +idx];
|
|
1211
|
+
if (!entry) throw Error(`Unknown type ${idx}`);
|
|
1212
|
+
if ((param.length || result.length) && entry[1].join(">") !== param + ">" + result) throw Error(`Type ${idx} mismatch`);
|
|
1213
|
+
return [idx, ...entry[1]];
|
|
1214
|
+
};
|
|
1215
|
+
var blocktype = (nodes, ctx) => {
|
|
1216
|
+
let [idx, param, result] = typeuse(nodes, ctx);
|
|
1217
|
+
if (!param.length && !result.length) return;
|
|
1218
|
+
if (!param.length && result.length === 1) return ["result", ...result];
|
|
1219
|
+
return ["type", idx ?? regtype(param, result, ctx)];
|
|
1220
|
+
};
|
|
1221
|
+
var name = (node, list) => {
|
|
1222
|
+
let nm = isId(node[0]) && node.shift();
|
|
1223
|
+
if (nm) nm in list ? err(`Duplicate ${list.name} ${nm}`) : list[nm] = list.length;
|
|
1224
|
+
return nm;
|
|
1225
|
+
};
|
|
1226
|
+
var typedef = ([dfn], ctx) => {
|
|
1227
|
+
let subkind = "subfinal", supertypes = [], compkind;
|
|
1228
|
+
if (dfn[0] === "sub") {
|
|
1229
|
+
subkind = dfn.shift(), dfn[0] === "final" && (subkind += dfn.shift());
|
|
1230
|
+
dfn = (supertypes = dfn).pop();
|
|
1231
|
+
}
|
|
1232
|
+
[compkind, ...dfn] = dfn;
|
|
1233
|
+
if (compkind === "func") dfn = paramres(dfn), ctx.type["$" + dfn.join(">")] ??= ctx.type.length;
|
|
1234
|
+
else if (compkind === "struct") dfn = fieldseq(dfn, "field");
|
|
1235
|
+
else if (compkind === "array") [dfn] = dfn;
|
|
1236
|
+
return [compkind, dfn, subkind, supertypes];
|
|
1237
|
+
};
|
|
1238
|
+
var build = [
|
|
1239
|
+
// (@custom "name" placement? data) - custom section builder
|
|
1240
|
+
([name2, ...rest], ctx) => {
|
|
1241
|
+
let data = rest;
|
|
1242
|
+
if (rest[0]?.[0] === "before" || rest[0]?.[0] === "after") {
|
|
1243
|
+
data = rest.slice(1);
|
|
1244
|
+
}
|
|
1245
|
+
return [...vec(name2), ...data.flat()];
|
|
1246
|
+
},
|
|
1247
|
+
// type kinds
|
|
1248
|
+
// (func params result)
|
|
1249
|
+
// (array i8)
|
|
1250
|
+
// (struct ...fields)
|
|
1251
|
+
([kind, fields, subkind, supertypes, rec], ctx) => {
|
|
1252
|
+
if (rec === true) return;
|
|
1253
|
+
let details;
|
|
1254
|
+
if (rec) {
|
|
1255
|
+
kind = "rec";
|
|
1256
|
+
let [from, length] = rec, subtypes = Array.from({ length }, (_, i) => build[SECTION.type](ctx.type[from + i].slice(0, 4), ctx));
|
|
1257
|
+
details = vec(subtypes);
|
|
1258
|
+
} else if (subkind === "sub" || supertypes?.length) {
|
|
1259
|
+
details = [...vec(supertypes.map((n) => id(n, ctx.type))), ...build[SECTION.type]([kind, fields], ctx)];
|
|
1260
|
+
kind = subkind;
|
|
1261
|
+
} else if (kind === "func") {
|
|
1262
|
+
details = [...vec(fields[0].map((t) => reftype(t, ctx))), ...vec(fields[1].map((t) => reftype(t, ctx)))];
|
|
1263
|
+
} else if (kind === "array") {
|
|
1264
|
+
details = fieldtype(fields, ctx);
|
|
1265
|
+
} else if (kind === "struct") {
|
|
1266
|
+
details = vec(fields.map((t) => fieldtype(t, ctx)));
|
|
1267
|
+
}
|
|
1268
|
+
return [DEFTYPE[kind], ...details];
|
|
1269
|
+
},
|
|
1270
|
+
// (import "math" "add" (func|table|global|memory|tag dfn?))
|
|
1271
|
+
([mod, field, [kind, ...dfn]], ctx) => {
|
|
1272
|
+
let details;
|
|
1273
|
+
if (kind === "func") {
|
|
1274
|
+
let [[, typeidx]] = dfn;
|
|
1275
|
+
details = uleb(id(typeidx, ctx.type));
|
|
1276
|
+
} else if (kind === "tag") {
|
|
1277
|
+
let [[, typeidx]] = dfn;
|
|
1278
|
+
details = [0, ...uleb(id(typeidx, ctx.type))];
|
|
1279
|
+
} else if (kind === "memory") {
|
|
1280
|
+
details = limits(dfn);
|
|
1281
|
+
} else if (kind === "global") {
|
|
1282
|
+
details = fieldtype(dfn[0], ctx);
|
|
1283
|
+
} else if (kind === "table") {
|
|
1284
|
+
details = [...reftype(dfn.pop(), ctx), ...limits(dfn)];
|
|
1285
|
+
} else err(`Unknown kind ${kind}`);
|
|
1286
|
+
return [...vec(mod), ...vec(field), KIND[kind], ...details];
|
|
1287
|
+
},
|
|
1288
|
+
// (func $name? ...params result ...body)
|
|
1289
|
+
([[, typeidx]], ctx) => uleb(id(typeidx, ctx.type)),
|
|
1290
|
+
// (table 1 2 funcref)
|
|
1291
|
+
(node, ctx) => {
|
|
1292
|
+
let lims = limits(node), t = reftype(node.shift(), ctx), [init] = node;
|
|
1293
|
+
return init ? [64, 0, ...t, ...lims, ...expr(init, ctx)] : [...t, ...lims];
|
|
1294
|
+
},
|
|
1295
|
+
// (memory id? export* min max shared)
|
|
1296
|
+
(node, ctx) => limits(node),
|
|
1297
|
+
// (global $id? (mut i32) (i32.const 42))
|
|
1298
|
+
([t, init], ctx) => [...fieldtype(t, ctx), ...expr(init, ctx)],
|
|
1299
|
+
// (export "name" (func|table|mem $name|idx))
|
|
1300
|
+
([nm, [kind, l]], ctx) => [...vec(nm), KIND[kind], ...uleb(id(l, ctx[kind]))],
|
|
1301
|
+
// (start $main)
|
|
1302
|
+
([l], ctx) => uleb(id(l, ctx.func)),
|
|
1303
|
+
// (elem elem*) - passive
|
|
1304
|
+
// (elem declare elem*) - declarative
|
|
1305
|
+
// (elem (table idx)? (offset expr)|(expr) elem*) - active
|
|
1306
|
+
// ref: https://webassembly.github.io/spec/core/binary/modules.html#element-section
|
|
1307
|
+
(parts, ctx) => {
|
|
1308
|
+
let passive = 0, declare = 0, elexpr = 0, nofunc = 0, tabidx, offset, rt;
|
|
1309
|
+
if (parts[0] === "declare") parts.shift(), declare = 1;
|
|
1310
|
+
if (parts[0]?.[0] === "table") {
|
|
1311
|
+
[, tabidx] = parts.shift();
|
|
1312
|
+
tabidx = id(tabidx, ctx.table);
|
|
1313
|
+
} else if ((typeof parts[0] === "string" || typeof parts[0] === "number") && (parts[1]?.[0] === "offset" || Array.isArray(parts[1]) && parts[1][0] !== "item" && !parts[1][0]?.startsWith("ref"))) {
|
|
1314
|
+
tabidx = id(parts.shift(), ctx.table);
|
|
1315
|
+
}
|
|
1316
|
+
if (parts[0]?.[0] === "offset" || Array.isArray(parts[0]) && parts[0][0] !== "item" && !parts[0][0].startsWith("ref")) {
|
|
1317
|
+
offset = parts.shift();
|
|
1318
|
+
if (offset[0] === "offset") [, offset] = offset;
|
|
1319
|
+
offset = expr(offset, ctx);
|
|
1320
|
+
} else if (!declare) passive = 1;
|
|
1321
|
+
if (TYPE[parts[0]] || parts[0]?.[0] === "ref") rt = reftype(parts.shift(), ctx);
|
|
1322
|
+
else if (parts[0] === "func") rt = [TYPE[parts.shift()]];
|
|
1323
|
+
else rt = [TYPE.func];
|
|
1324
|
+
parts = parts.map((el) => {
|
|
1325
|
+
if (el[0] === "item") el = el.length === 3 && el[1] === "ref.func" ? el[2] : el[1];
|
|
1326
|
+
if (el[0] === "ref.func") [, el] = el;
|
|
1327
|
+
if (typeof el !== "string") elexpr = 1;
|
|
1328
|
+
return el;
|
|
1329
|
+
});
|
|
1330
|
+
if (rt[0] !== TYPE.funcref) nofunc = 1, elexpr = 1;
|
|
1331
|
+
let mode = elexpr << 2 | (passive || declare ? declare : !!tabidx || nofunc) << 1 | (passive || declare);
|
|
1332
|
+
return [
|
|
1333
|
+
mode,
|
|
1334
|
+
...// 0b000 e:expr y*:vec(funcidx) | type=(ref func), init ((ref.func y)end)*, active (table=0,offset=e)
|
|
1335
|
+
mode === 0 ? offset : (
|
|
1336
|
+
// 0b001 et:elkind y*:vec(funcidx) | type=0x00, init ((ref.func y)end)*, passive
|
|
1337
|
+
mode === 1 ? [0] : (
|
|
1338
|
+
// 0b010 x:tabidx e:expr et:elkind y*:vec(funcidx) | type=0x00, init ((ref.func y)end)*, active (table=x,offset=e)
|
|
1339
|
+
mode === 2 ? [...uleb(tabidx || 0), ...offset, 0] : (
|
|
1340
|
+
// 0b011 et:elkind y*:vec(funcidx) | type=0x00, init ((ref.func y)end)*, passive declare
|
|
1341
|
+
mode === 3 ? [0] : (
|
|
1342
|
+
// 0b100 e:expr el*:vec(expr) | type=(ref null func), init el*, active (table=0, offset=e)
|
|
1343
|
+
mode === 4 ? offset : (
|
|
1344
|
+
// 0b101 et:reftype el*:vec(expr) | type=et, init el*, passive
|
|
1345
|
+
mode === 5 ? rt : (
|
|
1346
|
+
// 0b110 x:tabidx e:expr et:reftype el*:vec(expr) | type=et, init el*, active (table=x, offset=e)
|
|
1347
|
+
mode === 6 ? [...uleb(tabidx || 0), ...offset, ...rt] : (
|
|
1348
|
+
// 0b111 et:reftype el*:vec(expr) | type=et, init el*, passive declare
|
|
1349
|
+
rt
|
|
1350
|
+
)
|
|
1351
|
+
)
|
|
1352
|
+
)
|
|
1353
|
+
)
|
|
1354
|
+
)
|
|
1355
|
+
)
|
|
1356
|
+
),
|
|
1357
|
+
...vec(
|
|
1358
|
+
parts.map(
|
|
1359
|
+
elexpr ? (
|
|
1360
|
+
// ((ref.func y)end)*
|
|
1361
|
+
(el) => expr(typeof el === "string" ? ["ref.func", el] : el, ctx)
|
|
1362
|
+
) : (
|
|
1363
|
+
// el*
|
|
1364
|
+
(el) => uleb(id(el, ctx.func))
|
|
1365
|
+
)
|
|
1366
|
+
)
|
|
1367
|
+
)
|
|
1368
|
+
];
|
|
1369
|
+
},
|
|
1370
|
+
// (code)
|
|
1371
|
+
(body, ctx) => {
|
|
1372
|
+
let [typeidx, param] = body.shift();
|
|
1373
|
+
if (!param) [, [param]] = ctx.type[id(typeidx, ctx.type)];
|
|
1374
|
+
ctx.local = Object.create(param);
|
|
1375
|
+
ctx.block = [];
|
|
1376
|
+
ctx.local.name = "local";
|
|
1377
|
+
ctx.block.name = "block";
|
|
1378
|
+
if (ctx._codeIdx === void 0) ctx._codeIdx = 0;
|
|
1379
|
+
let codeIdx = ctx._codeIdx++;
|
|
1380
|
+
while (body[0]?.[0] === "local") {
|
|
1381
|
+
let [, ...types] = body.shift();
|
|
1382
|
+
if (isId(types[0])) {
|
|
1383
|
+
let nm = types.shift();
|
|
1384
|
+
if (nm in ctx.local) err(`Duplicate local ${nm}`);
|
|
1385
|
+
else ctx.local[nm] = ctx.local.length;
|
|
1386
|
+
}
|
|
1387
|
+
ctx.local.push(...types);
|
|
1388
|
+
}
|
|
1389
|
+
ctx.meta = {};
|
|
1390
|
+
const bytes = instr(body, ctx);
|
|
1391
|
+
const funcIdx = ctx.import.filter((imp) => imp[2][0] === "func").length + codeIdx;
|
|
1392
|
+
for (const type in ctx.meta) ((ctx.metadata ??= {})[type] ??= []).push([funcIdx, ctx.meta[type]]);
|
|
1393
|
+
let loctypes = ctx.local.slice(param.length).reduce((a, type) => (type == a[a.length - 1]?.[1] ? a[a.length - 1][0]++ : a.push([1, type]), a), []);
|
|
1394
|
+
ctx.local = ctx.block = ctx.meta = null;
|
|
1395
|
+
return vec([...vec(loctypes.map(([n, t]) => [...uleb(n), ...reftype(t, ctx)])), ...bytes]);
|
|
1396
|
+
},
|
|
1397
|
+
// (data (i32.const 0) "\aa" "\bb"?)
|
|
1398
|
+
// (data (memory ref) (offset (i32.const 0)) "\aa" "\bb"?)
|
|
1399
|
+
// (data (global.get $x) "\aa" "\bb"?)
|
|
1400
|
+
(inits, ctx) => {
|
|
1401
|
+
let offset, memidx = 0;
|
|
1402
|
+
if (inits[0]?.[0] === "memory") {
|
|
1403
|
+
[, memidx] = inits.shift();
|
|
1404
|
+
memidx = id(memidx, ctx.memory);
|
|
1405
|
+
} else if ((typeof inits[0] === "string" || typeof inits[0] === "number") && (inits[1]?.[0] === "offset" || Array.isArray(inits[1]) && typeof inits[1][0] === "string")) {
|
|
1406
|
+
memidx = id(inits.shift(), ctx.memory);
|
|
1407
|
+
}
|
|
1408
|
+
if (Array.isArray(inits[0]) && typeof inits[0]?.[0] === "string") {
|
|
1409
|
+
offset = inits.shift();
|
|
1410
|
+
if (offset[0] === "offset") [, offset] = offset;
|
|
1411
|
+
offset ?? err("Bad offset", offset);
|
|
1412
|
+
}
|
|
1413
|
+
return [
|
|
1414
|
+
...// active: 2, x=memidx, e=expr
|
|
1415
|
+
memidx ? [2, ...uleb(memidx), ...expr(offset, ctx)] : (
|
|
1416
|
+
// active: 0, e=expr
|
|
1417
|
+
offset ? [0, ...expr(offset, ctx)] : (
|
|
1418
|
+
// passive: 1
|
|
1419
|
+
[1]
|
|
1420
|
+
)
|
|
1421
|
+
),
|
|
1422
|
+
...vec(inits.flat())
|
|
1423
|
+
];
|
|
1424
|
+
},
|
|
1425
|
+
// datacount
|
|
1426
|
+
(nodes, ctx) => uleb(ctx.data.length),
|
|
1427
|
+
// (tag $name? (type idx))
|
|
1428
|
+
([[, typeidx]], ctx) => [0, ...uleb(id(typeidx, ctx.type))]
|
|
1429
|
+
];
|
|
1430
|
+
var reftype = (t, ctx) => t[0] === "ref" ? t[1] == "null" ? TYPE[t[2]] ? [TYPE[t[2]]] : [TYPE.refnull, ...uleb(id(t[t.length - 1], ctx.type))] : [TYPE.ref, ...uleb(TYPE[t[t.length - 1]] || id(t[t.length - 1], ctx.type))] : (
|
|
1431
|
+
// abbrs
|
|
1432
|
+
[TYPE[t] ?? err(`Unknown type ${t}`)]
|
|
1433
|
+
);
|
|
1434
|
+
var fieldtype = (t, ctx, mut = t[0] === "mut" ? 1 : 0) => [...reftype(mut ? t[1] : t, ctx), mut];
|
|
1435
|
+
var IMM = {
|
|
1436
|
+
null: () => [],
|
|
1437
|
+
reversed: (n, c) => {
|
|
1438
|
+
let t = n.shift(), e = n.shift();
|
|
1439
|
+
return [...uleb(id(e, c.elem)), ...uleb(id(t, c.table))];
|
|
1440
|
+
},
|
|
1441
|
+
block: (n, c) => {
|
|
1442
|
+
c.block.push(1);
|
|
1443
|
+
isId(n[0]) && (c.block[n.shift()] = c.block.length);
|
|
1444
|
+
let t = n.shift();
|
|
1445
|
+
return !t ? [TYPE.void] : t[0] === "result" ? reftype(t[1], c) : uleb(id(t[1], c.type));
|
|
1446
|
+
},
|
|
1447
|
+
try_table: (n, c) => {
|
|
1448
|
+
isId(n[0]) && (c.block[n.shift()] = c.block.length + 1);
|
|
1449
|
+
let blocktype2 = n.shift();
|
|
1450
|
+
let result = !blocktype2 ? [TYPE.void] : blocktype2[0] === "result" ? reftype(blocktype2[1], c) : uleb(id(blocktype2[1], c.type));
|
|
1451
|
+
let catches = [], count = 0;
|
|
1452
|
+
while (n[0]?.[0] === "catch" || n[0]?.[0] === "catch_ref" || n[0]?.[0] === "catch_all" || n[0]?.[0] === "catch_all_ref") {
|
|
1453
|
+
let clause = n.shift();
|
|
1454
|
+
let kind = clause[0] === "catch" ? 0 : clause[0] === "catch_ref" ? 1 : clause[0] === "catch_all" ? 2 : 3;
|
|
1455
|
+
if (kind <= 1) catches.push(kind, ...uleb(id(clause[1], c.tag)), ...uleb(blockid(clause[2], c.block)));
|
|
1456
|
+
else catches.push(kind, ...uleb(blockid(clause[1], c.block)));
|
|
1457
|
+
count++;
|
|
1458
|
+
}
|
|
1459
|
+
c.block.push(1);
|
|
1460
|
+
return [...result, ...uleb(count), ...catches];
|
|
1461
|
+
},
|
|
1462
|
+
end: (_n, c) => (c.block.pop(), []),
|
|
1463
|
+
call_indirect: (n, c) => {
|
|
1464
|
+
let t = n.shift(), [, idx] = n.shift();
|
|
1465
|
+
return [...uleb(id(idx, c.type)), ...uleb(id(t, c.table))];
|
|
1466
|
+
},
|
|
1467
|
+
br_table: (n, c) => {
|
|
1468
|
+
let labels = [], count = 0;
|
|
1469
|
+
while (n[0] && (!isNaN(n[0]) || isId(n[0]))) labels.push(...uleb(blockid(n.shift(), c.block))), count++;
|
|
1470
|
+
return [...uleb(count - 1), ...labels];
|
|
1471
|
+
},
|
|
1472
|
+
select: (n, c) => {
|
|
1473
|
+
let r = n.shift() || [];
|
|
1474
|
+
return r.length ? vec(r.map((t) => reftype(t, c))) : [];
|
|
1475
|
+
},
|
|
1476
|
+
ref_null: (n, c) => {
|
|
1477
|
+
let t = n.shift();
|
|
1478
|
+
return TYPE[t] ? [TYPE[t]] : uleb(id(t, c.type));
|
|
1479
|
+
},
|
|
1480
|
+
memarg: (n, c, op) => memargEnc(n, op, isIdx(n[0]) && !isMemParam(n[0]) ? id(n.shift(), c.memory) : 0),
|
|
1481
|
+
opt_memory: (n, c) => uleb(id(isIdx(n[0]) ? n.shift() : 0, c.memory)),
|
|
1482
|
+
reftype: (n, c) => {
|
|
1483
|
+
let ht = reftype(n.shift(), c);
|
|
1484
|
+
return ht.length > 1 ? ht.slice(1) : ht;
|
|
1485
|
+
},
|
|
1486
|
+
reftype2: (n, c) => {
|
|
1487
|
+
let b = blockid(n.shift(), c.block), h1 = reftype(n.shift(), c), h2 = reftype(n.shift(), c);
|
|
1488
|
+
return [(h2[0] !== TYPE.ref) << 1 | h1[0] !== TYPE.ref, ...uleb(b), h1.pop(), h2.pop()];
|
|
1489
|
+
},
|
|
1490
|
+
v128const: (n) => {
|
|
1491
|
+
let [t, num] = n.shift().split("x"), bits = +t.slice(1), stride = bits >>> 3;
|
|
1492
|
+
num = +num;
|
|
1493
|
+
if (t[0] === "i") {
|
|
1494
|
+
let arr2 = num === 16 ? new Uint8Array(16) : num === 8 ? new Uint16Array(8) : num === 4 ? new Uint32Array(4) : new BigUint64Array(2);
|
|
1495
|
+
for (let j = 0; j < num; j++) arr2[j] = encode_exports[t].parse(n.shift());
|
|
1496
|
+
return [...new Uint8Array(arr2.buffer)];
|
|
1497
|
+
}
|
|
1498
|
+
let arr = new Uint8Array(16);
|
|
1499
|
+
for (let j = 0; j < num; j++) arr.set(encode_exports[t](n.shift()), j * stride);
|
|
1500
|
+
return [...arr];
|
|
1501
|
+
},
|
|
1502
|
+
shuffle: (n) => {
|
|
1503
|
+
let result = [];
|
|
1504
|
+
for (let j = 0; j < 16; j++) result.push(parseUint(n.shift(), 32));
|
|
1505
|
+
if (typeof n[0] === "string" && !isNaN(n[0])) err(`invalid lane length`);
|
|
1506
|
+
return result;
|
|
1507
|
+
},
|
|
1508
|
+
memlane: (n, c, op) => {
|
|
1509
|
+
const memIdx = isId(n[0]) || isIdx(n[0]) && (isMemParam(n[1]) || isIdx(n[1])) ? id(n.shift(), c.memory) : 0;
|
|
1510
|
+
return [...memargEnc(n, op, memIdx), ...uleb(parseUint(n.shift()))];
|
|
1511
|
+
},
|
|
1512
|
+
"*": (n) => uleb(n.shift()),
|
|
1513
|
+
// *idx types
|
|
1514
|
+
labelidx: (n, c) => uleb(blockid(n.shift(), c.block)),
|
|
1515
|
+
laneidx: (n) => [parseUint(n.shift(), 255)],
|
|
1516
|
+
funcidx: (n, c) => uleb(id(n.shift(), c.func)),
|
|
1517
|
+
typeidx: (n, c) => uleb(id(n.shift(), c.type)),
|
|
1518
|
+
tableidx: (n, c) => uleb(id(n.shift(), c.table)),
|
|
1519
|
+
memoryidx: (n, c) => uleb(id(n.shift(), c.memory)),
|
|
1520
|
+
globalidx: (n, c) => uleb(id(n.shift(), c.global)),
|
|
1521
|
+
localidx: (n, c) => uleb(id(n.shift(), c.local)),
|
|
1522
|
+
dataidx: (n, c) => uleb(id(n.shift(), c.data)),
|
|
1523
|
+
elemidx: (n, c) => uleb(id(n.shift(), c.elem)),
|
|
1524
|
+
tagidx: (n, c) => uleb(id(n.shift(), c.tag)),
|
|
1525
|
+
"memoryidx?": (n, c) => uleb(id(isIdx(n[0]) ? n.shift() : 0, c.memory)),
|
|
1526
|
+
// Value type
|
|
1527
|
+
i32: (n) => i32(n.shift()),
|
|
1528
|
+
i64: (n) => i64(n.shift()),
|
|
1529
|
+
f32: (n) => f32(n.shift()),
|
|
1530
|
+
f64: (n) => f64(n.shift()),
|
|
1531
|
+
v128: (n) => (void 0)(n.shift()),
|
|
1532
|
+
// Combinations
|
|
1533
|
+
typeidx_field: (n, c) => {
|
|
1534
|
+
let typeId = id(n.shift(), c.type);
|
|
1535
|
+
return [...uleb(typeId), ...uleb(id(n.shift(), c.type[typeId][1]))];
|
|
1536
|
+
},
|
|
1537
|
+
typeidx_multi: (n, c) => [...uleb(id(n.shift(), c.type)), ...uleb(n.shift())],
|
|
1538
|
+
typeidx_dataidx: (n, c) => [...uleb(id(n.shift(), c.type)), ...uleb(id(n.shift(), c.data))],
|
|
1539
|
+
typeidx_elemidx: (n, c) => [...uleb(id(n.shift(), c.type)), ...uleb(id(n.shift(), c.elem))],
|
|
1540
|
+
typeidx_typeidx: (n, c) => [...uleb(id(n.shift(), c.type)), ...uleb(id(n.shift(), c.type))],
|
|
1541
|
+
dataidx_memoryidx: (n, c) => [...uleb(id(n.shift(), c.data)), ...uleb(id(n.shift(), c.memory))],
|
|
1542
|
+
memoryidx_memoryidx: (n, c) => [...uleb(id(n.shift(), c.memory)), ...uleb(id(n.shift(), c.memory))],
|
|
1543
|
+
tableidx_tableidx: (n, c) => [...uleb(id(n.shift(), c.table)), ...uleb(id(n.shift(), c.table))]
|
|
1544
|
+
};
|
|
1545
|
+
var HANDLER = {};
|
|
1546
|
+
(function populate(items, pre) {
|
|
1547
|
+
for (let op = 0, item, nm, imm; op < items.length; op++) if (item = items[op]) {
|
|
1548
|
+
if (Array.isArray(item)) populate(item, op);
|
|
1549
|
+
else [nm, imm] = item.split(" "), INSTR[nm] = pre ? [pre, ...uleb(op)] : [op], imm && (HANDLER[nm] = IMM[imm]);
|
|
1550
|
+
}
|
|
1551
|
+
})(INSTR);
|
|
1552
|
+
var instr = (nodes, ctx) => {
|
|
1553
|
+
let out = [], meta = [];
|
|
1554
|
+
while (nodes?.length) {
|
|
1555
|
+
let op = nodes.shift();
|
|
1556
|
+
if (op?.[0] === "@metadata") {
|
|
1557
|
+
meta.push(op.slice(1));
|
|
1558
|
+
continue;
|
|
1559
|
+
}
|
|
1560
|
+
if (Array.isArray(op)) {
|
|
1561
|
+
op.i != null && (err.i = op.i);
|
|
1562
|
+
err(`Unknown instruction ${op[0]}`);
|
|
1563
|
+
}
|
|
1564
|
+
let [...bytes] = INSTR[op] || err(`Unknown instruction ${op}`);
|
|
1565
|
+
if (HANDLER[op]) {
|
|
1566
|
+
if (op === "select" && nodes[0]?.length) bytes[0]++;
|
|
1567
|
+
else if (HANDLER[op] === IMM.reftype && (nodes[0][1] === "null" || nodes[0][0] !== "ref")) {
|
|
1568
|
+
bytes[bytes.length - 1]++;
|
|
1569
|
+
}
|
|
1570
|
+
bytes.push(...HANDLER[op](nodes, ctx, op));
|
|
1571
|
+
}
|
|
1572
|
+
for (const [type, data] of meta) (ctx.meta[type] ??= []).push([out.length, data]);
|
|
1573
|
+
out.push(...bytes);
|
|
1574
|
+
}
|
|
1575
|
+
return out.push(11), out;
|
|
1576
|
+
};
|
|
1577
|
+
var expr = (node, ctx) => instr(normalize([node], ctx), ctx);
|
|
1578
|
+
var id = (nm, list, n) => (n = isId(nm) ? list[nm] : +nm, n in list ? n : err(`Unknown ${list.name} ${nm}`));
|
|
1579
|
+
var blockid = (nm, block, i) => (i = isId(nm) ? block.length - block[nm] : +nm, isNaN(i) || i > block.length ? err(`Bad label ${nm}`) : i);
|
|
1580
|
+
var memarg = (args) => {
|
|
1581
|
+
let align2, offset, k, v;
|
|
1582
|
+
while (isMemParam(args[0])) [k, v] = args.shift().split("="), k === "offset" ? offset = +v : k === "align" ? align2 = +v : err(`Unknown param ${k}=${v}`);
|
|
1583
|
+
if (offset < 0 || offset > 4294967295) err(`Bad offset ${offset}`);
|
|
1584
|
+
if (align2 <= 0 || align2 > 4294967295) err(`Bad align ${align2}`);
|
|
1585
|
+
if (align2) (align2 = Math.log2(align2)) % 1 && err(`Bad align ${align2}`);
|
|
1586
|
+
return [align2, offset];
|
|
1587
|
+
};
|
|
1588
|
+
var memargEnc = (nodes, op, memIdx = 0) => {
|
|
1589
|
+
const [a, o] = memarg(nodes), alignVal = (a ?? align(op)) | (memIdx && 64);
|
|
1590
|
+
return memIdx ? [...uleb(alignVal), ...uleb(memIdx), ...uleb(o ?? 0)] : [...uleb(alignVal), ...uleb(o ?? 0)];
|
|
1591
|
+
};
|
|
1592
|
+
var align = (op) => {
|
|
1593
|
+
let i = op.indexOf(".", 3) + 1, group = op.slice(1, op[0] === "v" ? 4 : 3);
|
|
1594
|
+
if (op[i] === "a") i = op.indexOf(".", i) + 1;
|
|
1595
|
+
if (op[0] === "m") return op.includes("64") ? 3 : 2;
|
|
1596
|
+
if (op[i] === "r") {
|
|
1597
|
+
let m2 = op.slice(i, i + 6).match(/\d+/);
|
|
1598
|
+
return m2 ? Math.log2(m2[0] / 8) : Math.log2(+group / 8);
|
|
1599
|
+
}
|
|
1600
|
+
let k = op[i] === "l" ? i + 4 : i + 5, m = op.slice(k).match(/(\d+)(x|_|$)/);
|
|
1601
|
+
return Math.log2(m ? m[2] === "x" ? 8 : m[1] / 8 : +group / 8);
|
|
1602
|
+
};
|
|
1603
|
+
var limits = (node) => {
|
|
1604
|
+
const is64 = node[0] === "i64" && node.shift();
|
|
1605
|
+
const shared = node[node.length - 1] === "shared" && node.pop();
|
|
1606
|
+
const hasMax = !isNaN(parseInt(node[1]));
|
|
1607
|
+
const flag = (is64 ? 4 : 0) | (shared ? 2 : 0) | (hasMax ? 1 : 0);
|
|
1608
|
+
const parse = is64 ? (v) => {
|
|
1609
|
+
if (typeof v === "bigint") return v;
|
|
1610
|
+
const str2 = typeof v === "string" ? v.replaceAll("_", "") : String(v);
|
|
1611
|
+
return BigInt(str2);
|
|
1612
|
+
} : parseUint;
|
|
1613
|
+
return hasMax ? [flag, ...uleb(parse(node.shift())), ...uleb(parse(node.shift()))] : [flag, ...uleb(parse(node.shift()))];
|
|
1614
|
+
};
|
|
1615
|
+
var parseUint = (v, max = 4294967295) => {
|
|
1616
|
+
const n = typeof v === "string" && v[0] !== "+" ? i32.parse(v) : typeof v === "number" ? v : err(`Bad int ${v}`);
|
|
1617
|
+
return n > max ? err(`Value out of range ${v}`) : n;
|
|
1618
|
+
};
|
|
1619
|
+
var vec = (a) => [...uleb(a.length), ...a.flat()];
|
|
1620
|
+
|
|
1621
|
+
// src/print.js
|
|
1622
|
+
function print(tree, options = {}) {
|
|
1623
|
+
if (typeof tree === "string") tree = parse_default(tree);
|
|
1624
|
+
let { indent = " ", newline = "\n", comments = true } = options;
|
|
1625
|
+
indent ||= "", newline ||= "";
|
|
1626
|
+
if (typeof tree[0] === "string" && tree[0][0] !== ";") return printNode(tree);
|
|
1627
|
+
return tree.filter((node) => comments || !isComment(node)).map((node) => printNode(node)).join(newline);
|
|
1628
|
+
function isComment(node) {
|
|
1629
|
+
return typeof node === "string" && node[1] === ";";
|
|
1630
|
+
}
|
|
1631
|
+
function printNode(node, level = 0) {
|
|
1632
|
+
if (!Array.isArray(node)) return node;
|
|
1633
|
+
let content = node[0];
|
|
1634
|
+
if (!content) return "";
|
|
1635
|
+
let afterLineComment = false;
|
|
1636
|
+
if (content === "try_table") {
|
|
1637
|
+
let i = 1;
|
|
1638
|
+
if (typeof node[i] === "string" && node[i][0] === "$") content += " " + node[i++];
|
|
1639
|
+
if (Array.isArray(node[i]) && (node[i][0] === "result" || node[i][0] === "type")) content += " " + printNode(node[i++], level);
|
|
1640
|
+
while (Array.isArray(node[i]) && /^catch/.test(node[i][0])) content += " " + printNode(node[i++], level).trim();
|
|
1641
|
+
for (; i < node.length; i++) content += Array.isArray(node[i]) ? newline + indent.repeat(level + 1) + printNode(node[i], level + 1) : " " + node[i];
|
|
1642
|
+
return `(${content + newline + indent.repeat(level)})`;
|
|
1643
|
+
}
|
|
1644
|
+
let flat = !!newline && node.length < 4 && !node.some((n) => typeof n === "string" && n[0] === ";" && n[1] === ";");
|
|
1645
|
+
let curIndent = indent.repeat(level + 1);
|
|
1646
|
+
for (let i = 1; i < node.length; i++) {
|
|
1647
|
+
const sub = node[i].valueOf();
|
|
1648
|
+
if (typeof sub === "string" && sub[1] === ";") {
|
|
1649
|
+
if (!comments) continue;
|
|
1650
|
+
if (sub[0] === ";") {
|
|
1651
|
+
if (newline) {
|
|
1652
|
+
content += newline + curIndent + sub.trimEnd();
|
|
1653
|
+
afterLineComment = true;
|
|
1654
|
+
} else {
|
|
1655
|
+
const last = content[content.length - 1];
|
|
1656
|
+
if (last && last !== " " && last !== "(") content += " ";
|
|
1657
|
+
content += sub.trimEnd() + "\n";
|
|
1658
|
+
}
|
|
1659
|
+
} else {
|
|
1660
|
+
const last = content[content.length - 1];
|
|
1661
|
+
if (last && last !== " " && last !== "(") content += " ";
|
|
1662
|
+
content += sub.trimEnd();
|
|
1663
|
+
}
|
|
1664
|
+
} else if (Array.isArray(sub)) {
|
|
1665
|
+
if (flat) flat = sub.every((sub2) => !Array.isArray(sub2));
|
|
1666
|
+
content += newline + curIndent + printNode(sub, level + 1);
|
|
1667
|
+
afterLineComment = false;
|
|
1668
|
+
} else if (node[0] === "data") {
|
|
1669
|
+
flat = false;
|
|
1670
|
+
if (newline || content[content.length - 1] !== ")") content += newline || " ";
|
|
1671
|
+
content += curIndent + sub;
|
|
1672
|
+
afterLineComment = false;
|
|
1673
|
+
} else {
|
|
1674
|
+
const last = content[content.length - 1];
|
|
1675
|
+
if (afterLineComment && newline) content += newline + curIndent;
|
|
1676
|
+
else if (last === "\n") content += "";
|
|
1677
|
+
else if (last && last !== ")" && last !== " ") content += " ";
|
|
1678
|
+
else if (newline || last === ")") content += " ";
|
|
1679
|
+
content += sub;
|
|
1680
|
+
afterLineComment = false;
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
if (flat) return `(${content.replaceAll(newline + curIndent + "(", " (")})`;
|
|
1684
|
+
return `(${content + newline + indent.repeat(level)})`;
|
|
1685
|
+
}
|
|
1686
|
+
}
|
|
1687
|
+
|
|
1688
|
+
// watr.js
|
|
1689
|
+
var PUA = "\uE000";
|
|
1690
|
+
var instrType = (op) => {
|
|
1691
|
+
if (!op || typeof op !== "string") return null;
|
|
1692
|
+
const prefix = op.split(".")[0];
|
|
1693
|
+
if (/^[if](32|64)|v128/.test(prefix)) return prefix;
|
|
1694
|
+
if (/\.(eq|ne|[lg][te]|eqz)/.test(op)) return "i32";
|
|
1695
|
+
if (op === "memory.size" || op === "memory.grow") return "i32";
|
|
1696
|
+
return null;
|
|
1697
|
+
};
|
|
1698
|
+
var exprType = (node, ctx = {}) => {
|
|
1699
|
+
if (!Array.isArray(node)) {
|
|
1700
|
+
if (typeof node === "string" && node[0] === "$" && ctx.locals?.[node]) return ctx.locals[node];
|
|
1701
|
+
return null;
|
|
1702
|
+
}
|
|
1703
|
+
const [op, ...args] = node;
|
|
1704
|
+
if (instrType(op)) return instrType(op);
|
|
1705
|
+
if (op === "local.get" && ctx.locals?.[args[0]]) return ctx.locals[args[0]];
|
|
1706
|
+
if (op === "call" && ctx.funcs?.[args[0]]) return ctx.funcs[args[0]].result?.[0];
|
|
1707
|
+
return null;
|
|
1708
|
+
};
|
|
1709
|
+
function walk(node, fn) {
|
|
1710
|
+
node = fn(node);
|
|
1711
|
+
if (Array.isArray(node)) {
|
|
1712
|
+
for (let i = 0; i < node.length; i++) {
|
|
1713
|
+
let child = walk(node[i], fn);
|
|
1714
|
+
if (child?._splice) node.splice(i, 1, ...child), i += child.length - 1;
|
|
1715
|
+
else node[i] = child;
|
|
1716
|
+
}
|
|
1717
|
+
}
|
|
1718
|
+
return node;
|
|
1719
|
+
}
|
|
1720
|
+
function inferImports(ast, funcs) {
|
|
1721
|
+
const imports = [];
|
|
1722
|
+
const importMap = /* @__PURE__ */ new Map();
|
|
1723
|
+
walk(ast, (node) => {
|
|
1724
|
+
if (!Array.isArray(node)) return node;
|
|
1725
|
+
if (node[0] === "call" && typeof node[1] === "function") {
|
|
1726
|
+
const fn = node[1];
|
|
1727
|
+
if (!importMap.has(fn)) {
|
|
1728
|
+
const params = [];
|
|
1729
|
+
for (let i = 2; i < node.length; i++) {
|
|
1730
|
+
const t = exprType(node[i]);
|
|
1731
|
+
if (t) params.push(t);
|
|
1732
|
+
}
|
|
1733
|
+
const idx = imports.length;
|
|
1734
|
+
const name2 = fn.name || `$fn${idx}`;
|
|
1735
|
+
importMap.set(fn, { idx, name: name2.startsWith("$") ? name2 : "$" + name2, params, fn });
|
|
1736
|
+
imports.push(importMap.get(fn));
|
|
1737
|
+
}
|
|
1738
|
+
const imp = importMap.get(fn);
|
|
1739
|
+
node[1] = imp.name;
|
|
1740
|
+
}
|
|
1741
|
+
return node;
|
|
1742
|
+
});
|
|
1743
|
+
return imports;
|
|
1744
|
+
}
|
|
1745
|
+
function genImports(imports) {
|
|
1746
|
+
return imports.map(
|
|
1747
|
+
({ name: name2, params }) => ["import", '"env"', `"${name2.slice(1)}"`, ["func", name2, ...params.map((t) => ["param", t])]]
|
|
1748
|
+
);
|
|
1749
|
+
}
|
|
1750
|
+
function compile2(source, ...values) {
|
|
1751
|
+
if (Array.isArray(source) && source.raw) {
|
|
1752
|
+
let src = source[0];
|
|
1753
|
+
for (let i = 0; i < values.length; i++) {
|
|
1754
|
+
src += PUA + source[i + 1];
|
|
1755
|
+
}
|
|
1756
|
+
let ast = parse_default(src);
|
|
1757
|
+
const funcsToImport = [];
|
|
1758
|
+
let idx = 0;
|
|
1759
|
+
ast = walk(ast, (node) => {
|
|
1760
|
+
if (node === PUA) {
|
|
1761
|
+
const value = values[idx++];
|
|
1762
|
+
if (typeof value === "function") {
|
|
1763
|
+
funcsToImport.push(value);
|
|
1764
|
+
return value;
|
|
1765
|
+
}
|
|
1766
|
+
if (typeof value === "string" && (value[0] === "(" || /^\s*\(/.test(value))) {
|
|
1767
|
+
const parsed = parse_default(value);
|
|
1768
|
+
if (Array.isArray(parsed) && Array.isArray(parsed[0])) {
|
|
1769
|
+
parsed._splice = true;
|
|
1770
|
+
}
|
|
1771
|
+
return parsed;
|
|
1772
|
+
}
|
|
1773
|
+
if (value instanceof Uint8Array) return [...value];
|
|
1774
|
+
return value;
|
|
1775
|
+
}
|
|
1776
|
+
return node;
|
|
1777
|
+
});
|
|
1778
|
+
let importObjs = null;
|
|
1779
|
+
if (funcsToImport.length) {
|
|
1780
|
+
const imports = inferImports(ast, funcsToImport);
|
|
1781
|
+
if (imports.length) {
|
|
1782
|
+
const importDecls = genImports(imports);
|
|
1783
|
+
if (ast[0] === "module") {
|
|
1784
|
+
ast.splice(1, 0, ...importDecls);
|
|
1785
|
+
} else if (typeof ast[0] === "string") {
|
|
1786
|
+
ast = [...importDecls, ast];
|
|
1787
|
+
} else {
|
|
1788
|
+
ast.unshift(...importDecls);
|
|
1789
|
+
}
|
|
1790
|
+
importObjs = { env: {} };
|
|
1791
|
+
for (const imp of imports) {
|
|
1792
|
+
importObjs.env[imp.name.slice(1)] = imp.fn;
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
}
|
|
1796
|
+
const binary = compile(ast);
|
|
1797
|
+
if (importObjs) binary._imports = importObjs;
|
|
1798
|
+
return binary;
|
|
1799
|
+
}
|
|
1800
|
+
return compile(source);
|
|
1801
|
+
}
|
|
1802
|
+
function watr(strings, ...values) {
|
|
1803
|
+
const binary = compile2(strings, ...values);
|
|
1804
|
+
const module = new WebAssembly.Module(binary);
|
|
1805
|
+
const instance = new WebAssembly.Instance(module, binary._imports);
|
|
1806
|
+
return instance.exports;
|
|
1807
|
+
}
|
|
1808
|
+
var watr_default = watr;
|
|
1809
|
+
export {
|
|
1810
|
+
compile2 as compile,
|
|
1811
|
+
watr_default as default,
|
|
1812
|
+
parse_default as parse,
|
|
1813
|
+
print,
|
|
1814
|
+
watr
|
|
1815
|
+
};
|