watr 4.2.0 → 4.3.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/watr.js +186 -51
- package/dist/watr.min.js +5 -5
- package/package.json +1 -1
- package/readme.md +7 -12
- package/src/compile.js +165 -49
- package/src/const.js +12 -4
- package/src/optimize.js +15 -2
- package/src/parse.js +2 -2
- package/src/util.js +4 -4
- package/types/src/compile.d.ts.map +1 -1
- package/types/src/const.d.ts +6 -0
- package/types/src/const.d.ts.map +1 -1
- package/types/src/optimize.d.ts.map +1 -1
- package/types/src/util.d.ts +3 -3
- package/types/src/util.d.ts.map +1 -1
package/dist/watr.js
CHANGED
|
@@ -18,7 +18,7 @@ __export(encode_exports, {
|
|
|
18
18
|
});
|
|
19
19
|
|
|
20
20
|
// src/util.js
|
|
21
|
-
var err = (text, pos = err.
|
|
21
|
+
var err = (text, pos = err.loc) => {
|
|
22
22
|
if (pos != null && err.src) {
|
|
23
23
|
let line = 1, col = 1;
|
|
24
24
|
for (let i = 0; i < pos && i < err.src.length; i++) {
|
|
@@ -447,13 +447,14 @@ var INSTR = [
|
|
|
447
447
|
,
|
|
448
448
|
,
|
|
449
449
|
,
|
|
450
|
-
|
|
451
|
-
,
|
|
452
|
-
,
|
|
453
|
-
,
|
|
454
|
-
,
|
|
455
|
-
,
|
|
456
|
-
,
|
|
450
|
+
// 0xe0-0xe6: stack switching (Phase 3)
|
|
451
|
+
"cont.new typeidx",
|
|
452
|
+
"cont.bind cont_bind",
|
|
453
|
+
"suspend tagidx",
|
|
454
|
+
"resume resume",
|
|
455
|
+
"resume_throw resume_throw",
|
|
456
|
+
"resume_throw_ref resume_throw_ref",
|
|
457
|
+
"switch switch_cont",
|
|
457
458
|
,
|
|
458
459
|
,
|
|
459
460
|
,
|
|
@@ -506,7 +507,15 @@ var INSTR = [
|
|
|
506
507
|
"extern.convert_any",
|
|
507
508
|
"ref.i31",
|
|
508
509
|
"i31.get_s",
|
|
509
|
-
"i31.get_u"
|
|
510
|
+
"i31.get_u",
|
|
511
|
+
,
|
|
512
|
+
"struct.new_desc typeidx",
|
|
513
|
+
"struct.new_default_desc typeidx",
|
|
514
|
+
"ref.get_desc typeidx",
|
|
515
|
+
"ref.cast_desc_eq reftype",
|
|
516
|
+
,
|
|
517
|
+
"br_on_cast_desc_eq reftype2",
|
|
518
|
+
"br_on_cast_desc_eq_fail reftype2"
|
|
510
519
|
],
|
|
511
520
|
// 0xfc: Bulk memory/table operations (nested array)
|
|
512
521
|
[
|
|
@@ -920,6 +929,9 @@ var TYPE = {
|
|
|
920
929
|
i31: 108,
|
|
921
930
|
struct: 107,
|
|
922
931
|
array: 106,
|
|
932
|
+
cont: 104,
|
|
933
|
+
nocont: 117,
|
|
934
|
+
// stack switching (Phase 3)
|
|
923
935
|
// Reference type abbreviations (absheaptype abbrs)
|
|
924
936
|
nullfuncref: 115,
|
|
925
937
|
nullexternref: 114,
|
|
@@ -933,6 +945,9 @@ var TYPE = {
|
|
|
933
945
|
i31ref: 108,
|
|
934
946
|
structref: 107,
|
|
935
947
|
arrayref: 106,
|
|
948
|
+
contref: 104,
|
|
949
|
+
nocontref: 117,
|
|
950
|
+
// stack switching abbreviations
|
|
936
951
|
// ref, refnull
|
|
937
952
|
ref: 100,
|
|
938
953
|
// -0x1c
|
|
@@ -943,7 +958,7 @@ var TYPE = {
|
|
|
943
958
|
subfinal: 79,
|
|
944
959
|
rec: 78
|
|
945
960
|
};
|
|
946
|
-
var DEFTYPE = { func: 96, struct: 95, array: 94, sub: 80, subfinal: 79, rec: 78 };
|
|
961
|
+
var DEFTYPE = { func: 96, struct: 95, array: 94, cont: 93, sub: 80, subfinal: 79, rec: 78 };
|
|
947
962
|
var KIND = { func: 0, table: 1, memory: 2, global: 3, tag: 4 };
|
|
948
963
|
|
|
949
964
|
// src/parse.js
|
|
@@ -951,7 +966,7 @@ var parse_default = (str2) => {
|
|
|
951
966
|
let i = 0, level = [], buf = "", q = 0, depth = 0;
|
|
952
967
|
const commit = () => buf && (level.push(buf), buf = "");
|
|
953
968
|
const parseLevel = (pos) => {
|
|
954
|
-
level.
|
|
969
|
+
level.loc = pos;
|
|
955
970
|
for (let c, root, p; i < str2.length; ) {
|
|
956
971
|
c = str2.charCodeAt(i);
|
|
957
972
|
if (q === 34) buf += str2[i++], c === 92 ? buf += str2[i++] : c === 34 && (commit(), q = 0);
|
|
@@ -996,48 +1011,79 @@ var cleanup = (node, result) => !Array.isArray(node) ? typeof node !== "string"
|
|
|
996
1011
|
) : (
|
|
997
1012
|
// remove annotations like (@name ...) except @custom and @metadata.code.*
|
|
998
1013
|
node[0]?.[0] === "@" && node[0] !== "@custom" && !node[0]?.startsWith?.("@metadata.code.") ? null : (
|
|
999
|
-
// unwrap single-element array containing module (after removing comments), preserve .
|
|
1000
|
-
(result = node.map(cleanup).filter((n) => n != null), result.
|
|
1014
|
+
// unwrap single-element array containing module (after removing comments), preserve .loc
|
|
1015
|
+
(result = node.map(cleanup).filter((n) => n != null), result.loc = node.loc, result.length === 1 && result[0]?.[0] === "module" ? result[0] : result)
|
|
1001
1016
|
)
|
|
1002
1017
|
);
|
|
1003
1018
|
function compile(nodes) {
|
|
1004
1019
|
if (typeof nodes === "string") err.src = nodes, nodes = parse_default(nodes) || [];
|
|
1005
1020
|
else err.src = "";
|
|
1006
|
-
err.
|
|
1021
|
+
err.loc = 0;
|
|
1007
1022
|
nodes = cleanup(nodes) || [];
|
|
1008
1023
|
let idx = 0;
|
|
1009
1024
|
if (nodes[0] === "module") idx++, isId(nodes[idx]) && idx++;
|
|
1010
1025
|
else if (typeof nodes[0] === "string") nodes = [nodes];
|
|
1011
1026
|
if (nodes[idx] === "binary") return Uint8Array.from(nodes.slice(++idx).flat());
|
|
1012
1027
|
if (nodes[idx] === "quote") return compile(nodes.slice(++idx).map((v) => v.valueOf().slice(1, -1)).flat().join(""));
|
|
1028
|
+
nodes = nodes.flatMap((n, i) => {
|
|
1029
|
+
if (i < idx || !Array.isArray(n) || n[0] !== "import") return [n];
|
|
1030
|
+
const [, mod, ...rest] = n;
|
|
1031
|
+
if (!rest.some((r) => Array.isArray(r) && r[0] === "item")) return [n];
|
|
1032
|
+
const lastIsType = Array.isArray(rest.at(-1)) && rest.at(-1)[0] !== "item";
|
|
1033
|
+
if (lastIsType) {
|
|
1034
|
+
const type = rest.at(-1);
|
|
1035
|
+
return rest.slice(0, -1).filter((r) => r[0] === "item").map(([, nm]) => ["import", mod, nm, type]);
|
|
1036
|
+
}
|
|
1037
|
+
return rest.filter((r) => r[0] === "item").map(([, nm, type]) => ["import", mod, nm, type]);
|
|
1038
|
+
});
|
|
1013
1039
|
const ctx = [];
|
|
1014
1040
|
for (let kind in SECTION) (ctx[SECTION[kind]] = ctx[kind] = []).name = kind;
|
|
1015
1041
|
ctx.metadata = {};
|
|
1016
1042
|
nodes.slice(idx).filter((n) => {
|
|
1017
1043
|
if (!Array.isArray(n)) {
|
|
1018
|
-
let pos = err.
|
|
1019
|
-
|
|
1044
|
+
let pos = err.loc, src = err.src, c;
|
|
1045
|
+
while ((pos = src.indexOf(n, pos)) >= 0) {
|
|
1046
|
+
c = src.charCodeAt(pos - 1);
|
|
1047
|
+
if (pos > 0 && (c > 47 && c < 58 || c > 64 && c < 91 || c > 96 && c < 123 || c === 95 || c === 36)) {
|
|
1048
|
+
pos++;
|
|
1049
|
+
continue;
|
|
1050
|
+
}
|
|
1051
|
+
c = src.charCodeAt(pos + n.length);
|
|
1052
|
+
if (c > 47 && c < 58 || c > 64 && c < 91 || c > 96 && c < 123 || c === 95) {
|
|
1053
|
+
pos++;
|
|
1054
|
+
continue;
|
|
1055
|
+
}
|
|
1056
|
+
break;
|
|
1057
|
+
}
|
|
1058
|
+
if (pos >= 0) err.loc = pos;
|
|
1020
1059
|
err(`Unexpected token ${n}`);
|
|
1021
1060
|
}
|
|
1022
1061
|
let [kind, ...node] = n;
|
|
1023
|
-
err.
|
|
1062
|
+
err.loc = n.loc;
|
|
1024
1063
|
if (kind === "@custom") {
|
|
1025
1064
|
ctx.custom.push(node);
|
|
1026
1065
|
} else if (kind === "rec") {
|
|
1027
1066
|
for (let i = 0; i < node.length; i++) {
|
|
1028
1067
|
let [, ...subnode] = node[i];
|
|
1029
1068
|
name(subnode, ctx.type);
|
|
1069
|
+
const tdesc = [];
|
|
1070
|
+
while (subnode[0]?.[0] === "descriptor" || subnode[0]?.[0] === "describes") tdesc.push(subnode.shift());
|
|
1030
1071
|
(subnode = typedef(subnode, ctx)).push(i ? true : [ctx.type.length, node.length]);
|
|
1072
|
+
if (tdesc.length) subnode.desc = subnode.desc ? [...tdesc, ...subnode.desc] : tdesc;
|
|
1031
1073
|
ctx.type.push(subnode);
|
|
1032
1074
|
}
|
|
1033
1075
|
} else if (kind === "type") {
|
|
1034
1076
|
name(node, ctx.type);
|
|
1035
|
-
|
|
1077
|
+
const tdesc = [];
|
|
1078
|
+
while (node[0]?.[0] === "descriptor" || node[0]?.[0] === "describes") tdesc.push(node.shift());
|
|
1079
|
+
const td = typedef(node, ctx);
|
|
1080
|
+
if (tdesc.length) td.desc = td.desc ? [...tdesc, ...td.desc] : tdesc;
|
|
1081
|
+
ctx.type.push(td);
|
|
1036
1082
|
} else if (kind === "start" || kind === "export") ctx[kind].push(node);
|
|
1037
1083
|
else return true;
|
|
1038
1084
|
}).forEach((n) => {
|
|
1039
1085
|
let [kind, ...node] = n;
|
|
1040
|
-
err.
|
|
1086
|
+
err.loc = n.loc;
|
|
1041
1087
|
let imported;
|
|
1042
1088
|
if (kind === "import") [kind, ...node] = (imported = node).pop();
|
|
1043
1089
|
let items = ctx[kind];
|
|
@@ -1055,7 +1101,8 @@ function compile(nodes) {
|
|
|
1055
1101
|
} else if (kind === "memory") {
|
|
1056
1102
|
const is64 = node[0] === "i64", idx2 = is64 ? 1 : 0;
|
|
1057
1103
|
if (node[idx2]?.[0] === "data") {
|
|
1058
|
-
|
|
1104
|
+
const ps = node.find((n2) => Array.isArray(n2) && n2[0] === "pagesize")?.[1] ?? 65536;
|
|
1105
|
+
let [, ...data] = node.splice(idx2, 1)[0], m = "" + Math.ceil(data.reduce((s, d) => s + d.length, 0) / ps);
|
|
1059
1106
|
ctx.data.push([["memory", items.length], [is64 ? "i64.const" : "i32.const", is64 ? 0n : 0], ...data]);
|
|
1060
1107
|
node = is64 ? ["i64", m, m] : [m, m];
|
|
1061
1108
|
}
|
|
@@ -1147,7 +1194,7 @@ function normalize(nodes, ctx) {
|
|
|
1147
1194
|
} else if ((node.startsWith("memory.") || node.endsWith("load") || node.endsWith("store")) && isIdx(nodes[0])) out.push(nodes.shift());
|
|
1148
1195
|
} else if (Array.isArray(node)) {
|
|
1149
1196
|
const op = node[0];
|
|
1150
|
-
node.
|
|
1197
|
+
node.loc != null && (err.loc = node.loc);
|
|
1151
1198
|
if (op?.startsWith?.("@metadata.code.")) {
|
|
1152
1199
|
let type = op.slice(15);
|
|
1153
1200
|
out.push(["@metadata", type, node[1]]);
|
|
@@ -1182,7 +1229,7 @@ function normalize(nodes, ctx) {
|
|
|
1182
1229
|
out.push(...normalize(parts, ctx), "end");
|
|
1183
1230
|
} else {
|
|
1184
1231
|
const imm = [];
|
|
1185
|
-
while (parts.length && (!Array.isArray(parts[0]) || "type,param,result,ref".includes(parts[0][0]))) imm.push(parts.shift());
|
|
1232
|
+
while (parts.length && (!Array.isArray(parts[0]) || "type,param,result,ref,exact,on".includes(parts[0][0]))) imm.push(parts.shift());
|
|
1186
1233
|
out.push(...normalize(parts, ctx), op, ...imm);
|
|
1187
1234
|
nodes.unshift(...out.splice(out.length - 1 - imm.length));
|
|
1188
1235
|
}
|
|
@@ -1227,16 +1274,19 @@ var name = (node, list) => {
|
|
|
1227
1274
|
return nm;
|
|
1228
1275
|
};
|
|
1229
1276
|
var typedef = ([dfn], ctx) => {
|
|
1230
|
-
let subkind = "subfinal", supertypes = [], compkind;
|
|
1277
|
+
let subkind = "subfinal", supertypes = [], compkind, desc = [];
|
|
1231
1278
|
if (dfn[0] === "sub") {
|
|
1232
1279
|
subkind = dfn.shift(), dfn[0] === "final" && (subkind += dfn.shift());
|
|
1233
1280
|
dfn = (supertypes = dfn).pop();
|
|
1281
|
+
supertypes = supertypes.filter((n) => Array.isArray(n) && (n[0] === "descriptor" || n[0] === "describes") ? (desc.push(n), false) : true);
|
|
1234
1282
|
}
|
|
1235
1283
|
[compkind, ...dfn] = dfn;
|
|
1236
1284
|
if (compkind === "func") dfn = paramres(dfn), ctx.type["$" + dfn.join(">")] ??= ctx.type.length;
|
|
1237
1285
|
else if (compkind === "struct") dfn = fieldseq(dfn, "field");
|
|
1238
1286
|
else if (compkind === "array") [dfn] = dfn;
|
|
1239
|
-
|
|
1287
|
+
const result = [compkind, dfn, subkind, supertypes];
|
|
1288
|
+
if (desc.length) result.desc = desc;
|
|
1289
|
+
return result;
|
|
1240
1290
|
};
|
|
1241
1291
|
var build = [
|
|
1242
1292
|
// (@custom "name" placement? data) - custom section builder
|
|
@@ -1251,29 +1301,37 @@ var build = [
|
|
|
1251
1301
|
// (func params result)
|
|
1252
1302
|
// (array i8)
|
|
1253
1303
|
// (struct ...fields)
|
|
1254
|
-
(
|
|
1304
|
+
// (cont $ft) - stack switching (Phase 3)
|
|
1305
|
+
(node, ctx) => {
|
|
1306
|
+
const [kind, fields, subkind, supertypes, rec] = node;
|
|
1255
1307
|
if (rec === true) return;
|
|
1256
|
-
|
|
1308
|
+
const descPfx = (node.desc ?? []).flatMap(([clause, ref]) => [clause === "descriptor" ? 77 : 76, ...uleb(id(ref, ctx.type))]);
|
|
1309
|
+
const comptype = (k, f) => {
|
|
1310
|
+
if (k === "func") return [DEFTYPE.func, ...vec(f[0].map((t) => reftype(t, ctx))), ...vec(f[1].map((t) => reftype(t, ctx)))];
|
|
1311
|
+
if (k === "array") return [DEFTYPE.array, ...fieldtype(f, ctx)];
|
|
1312
|
+
if (k === "struct") return [DEFTYPE.struct, ...vec(f.map((t) => fieldtype(t, ctx)))];
|
|
1313
|
+
if (k === "cont") return [DEFTYPE.cont, ...uleb(id(f[0] ?? f, ctx.type))];
|
|
1314
|
+
return [DEFTYPE[k]];
|
|
1315
|
+
};
|
|
1257
1316
|
if (rec) {
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1317
|
+
let [from, length] = rec;
|
|
1318
|
+
const subtypes = Array.from({ length }, (_, i) => {
|
|
1319
|
+
const t = ctx.type[from + i], sub = t.slice(0, 4);
|
|
1320
|
+
if (t.desc) sub.desc = t.desc;
|
|
1321
|
+
return build[SECTION.type](sub, ctx);
|
|
1322
|
+
});
|
|
1323
|
+
return [DEFTYPE.rec, ...vec(subtypes)];
|
|
1261
1324
|
} else if (subkind === "sub" || supertypes?.length) {
|
|
1262
|
-
|
|
1263
|
-
kind = subkind;
|
|
1264
|
-
} else if (kind === "func") {
|
|
1265
|
-
details = [...vec(fields[0].map((t) => reftype(t, ctx))), ...vec(fields[1].map((t) => reftype(t, ctx)))];
|
|
1266
|
-
} else if (kind === "array") {
|
|
1267
|
-
details = fieldtype(fields, ctx);
|
|
1268
|
-
} else if (kind === "struct") {
|
|
1269
|
-
details = vec(fields.map((t) => fieldtype(t, ctx)));
|
|
1325
|
+
return [DEFTYPE[subkind], ...vec(supertypes.map((n) => id(n, ctx.type))), ...descPfx, ...comptype(kind, fields)];
|
|
1270
1326
|
}
|
|
1271
|
-
return [
|
|
1327
|
+
return [...descPfx, ...comptype(kind, fields)];
|
|
1272
1328
|
},
|
|
1273
1329
|
// (import "math" "add" (func|table|global|memory|tag dfn?))
|
|
1274
1330
|
([mod, field, [kind, ...dfn]], ctx) => {
|
|
1275
|
-
let details;
|
|
1331
|
+
let details, kindByte = KIND[kind];
|
|
1276
1332
|
if (kind === "func") {
|
|
1333
|
+
const isExact = dfn[0] === "exact" && dfn.shift();
|
|
1334
|
+
if (isExact) kindByte = 32;
|
|
1277
1335
|
let [[, typeidx]] = dfn;
|
|
1278
1336
|
details = uleb(id(typeidx, ctx.type));
|
|
1279
1337
|
} else if (kind === "tag") {
|
|
@@ -1286,7 +1344,7 @@ var build = [
|
|
|
1286
1344
|
} else if (kind === "table") {
|
|
1287
1345
|
details = [...reftype(dfn.pop(), ctx), ...limits(dfn)];
|
|
1288
1346
|
} else err(`Unknown kind ${kind}`);
|
|
1289
|
-
return [...vec(mod), ...vec(field),
|
|
1347
|
+
return [...vec(mod), ...vec(field), kindByte, ...details];
|
|
1290
1348
|
},
|
|
1291
1349
|
// (func $name? ...params result ...body)
|
|
1292
1350
|
([[, typeidx]], ctx) => uleb(id(typeidx, ctx.type)),
|
|
@@ -1400,6 +1458,7 @@ var build = [
|
|
|
1400
1458
|
// (data (i32.const 0) "\aa" "\bb"?)
|
|
1401
1459
|
// (data (memory ref) (offset (i32.const 0)) "\aa" "\bb"?)
|
|
1402
1460
|
// (data (global.get $x) "\aa" "\bb"?)
|
|
1461
|
+
// (data (i8 1 2 3) ...) numeric values (WAT numeric values, Phase 2)
|
|
1403
1462
|
(inits, ctx) => {
|
|
1404
1463
|
let offset, memidx = 0;
|
|
1405
1464
|
if (inits[0]?.[0] === "memory") {
|
|
@@ -1422,7 +1481,7 @@ var build = [
|
|
|
1422
1481
|
[1]
|
|
1423
1482
|
)
|
|
1424
1483
|
),
|
|
1425
|
-
...vec(inits.
|
|
1484
|
+
...vec(inits.flatMap((item) => numdata(item) ?? [...item]))
|
|
1426
1485
|
];
|
|
1427
1486
|
},
|
|
1428
1487
|
// datacount
|
|
@@ -1430,7 +1489,13 @@ var build = [
|
|
|
1430
1489
|
// (tag $name? (type idx))
|
|
1431
1490
|
([[, typeidx]], ctx) => [0, ...uleb(id(typeidx, ctx.type))]
|
|
1432
1491
|
];
|
|
1433
|
-
var reftype = (t, ctx) => t[0] === "ref" ? t[1] == "null" ?
|
|
1492
|
+
var reftype = (t, ctx) => t[0] === "ref" ? t[1] == "null" ? (
|
|
1493
|
+
// (ref null (exact $T)) - exact nullable ref
|
|
1494
|
+
Array.isArray(t[2]) && t[2][0] === "exact" ? [TYPE.refnull, 98, ...uleb(id(t[2][1], ctx.type))] : TYPE[t[2]] ? [TYPE[t[2]]] : [TYPE.refnull, ...uleb(id(t[t.length - 1], ctx.type))]
|
|
1495
|
+
) : (
|
|
1496
|
+
// (ref (exact $T)) - exact non-null ref
|
|
1497
|
+
Array.isArray(t[1]) && t[1][0] === "exact" ? [TYPE.ref, 98, ...uleb(id(t[1][1], ctx.type))] : [TYPE.ref, ...uleb(TYPE[t[t.length - 1]] || id(t[t.length - 1], ctx.type))]
|
|
1498
|
+
) : (
|
|
1434
1499
|
// abbrs
|
|
1435
1500
|
[TYPE[t] ?? err(`Unknown type ${t}`)]
|
|
1436
1501
|
);
|
|
@@ -1478,7 +1543,7 @@ var IMM = {
|
|
|
1478
1543
|
},
|
|
1479
1544
|
ref_null: (n, c) => {
|
|
1480
1545
|
let t = n.shift();
|
|
1481
|
-
return TYPE[t] ? [TYPE[t]] : uleb(id(t, c.type));
|
|
1546
|
+
return Array.isArray(t) && t[0] === "exact" ? [98, ...uleb(id(t[1], c.type))] : TYPE[t] ? [TYPE[t]] : uleb(id(t, c.type));
|
|
1482
1547
|
},
|
|
1483
1548
|
memarg: (n, c, op) => memargEnc(n, op, isIdx(n[0]) && !isMemParam(n[0]) ? id(n.shift(), c.memory) : 0),
|
|
1484
1549
|
opt_memory: (n, c) => uleb(id(isIdx(n[0]) ? n.shift() : 0, c.memory)),
|
|
@@ -1487,8 +1552,8 @@ var IMM = {
|
|
|
1487
1552
|
return ht.length > 1 ? ht.slice(1) : ht;
|
|
1488
1553
|
},
|
|
1489
1554
|
reftype2: (n, c) => {
|
|
1490
|
-
let b = blockid(n.shift(), c.block), h1 = reftype(n.shift(), c), h2 = reftype(n.shift(), c);
|
|
1491
|
-
return [(h2[0] !== TYPE.ref) << 1 | h1[0] !== TYPE.ref, ...uleb(b), h1
|
|
1555
|
+
let b = blockid(n.shift(), c.block), h1 = reftype(n.shift(), c), h2 = reftype(n.shift(), c), ht = (h) => h.length > 1 ? h.slice(1) : h;
|
|
1556
|
+
return [(h2[0] !== TYPE.ref) << 1 | h1[0] !== TYPE.ref, ...uleb(b), ...ht(h1), ...ht(h2)];
|
|
1492
1557
|
},
|
|
1493
1558
|
v128const: (n) => {
|
|
1494
1559
|
let [t, num] = n.shift().split("x"), bits = +t.slice(1), stride = bits >>> 3;
|
|
@@ -1543,7 +1608,47 @@ var IMM = {
|
|
|
1543
1608
|
typeidx_typeidx: (n, c) => [...uleb(id(n.shift(), c.type)), ...uleb(id(n.shift(), c.type))],
|
|
1544
1609
|
dataidx_memoryidx: (n, c) => [...uleb(id(n.shift(), c.data)), ...uleb(id(n.shift(), c.memory))],
|
|
1545
1610
|
memoryidx_memoryidx: (n, c) => [...uleb(id(n.shift(), c.memory)), ...uleb(id(n.shift(), c.memory))],
|
|
1546
|
-
tableidx_tableidx: (n, c) => [...uleb(id(n.shift(), c.table)), ...uleb(id(n.shift(), c.table))]
|
|
1611
|
+
tableidx_tableidx: (n, c) => [...uleb(id(n.shift(), c.table)), ...uleb(id(n.shift(), c.table))],
|
|
1612
|
+
// stack switching handlers (Phase 3)
|
|
1613
|
+
cont_bind: (n, c) => [...uleb(id(n.shift(), c.type)), ...uleb(id(n.shift(), c.type))],
|
|
1614
|
+
switch_cont: (n, c) => [...uleb(id(n.shift(), c.type)), ...uleb(id(n.shift(), c.tag))],
|
|
1615
|
+
resume: (n, c) => {
|
|
1616
|
+
const typeidx = uleb(id(n.shift(), c.type));
|
|
1617
|
+
const handlers = [];
|
|
1618
|
+
let cnt = 0;
|
|
1619
|
+
while (n[0]?.[0] === "on") {
|
|
1620
|
+
const [, tag, label] = n.shift();
|
|
1621
|
+
if (label === "switch") handlers.push(1, ...uleb(id(tag, c.tag)));
|
|
1622
|
+
else handlers.push(0, ...uleb(id(tag, c.tag)), ...uleb(blockid(label, c.block)));
|
|
1623
|
+
cnt++;
|
|
1624
|
+
}
|
|
1625
|
+
return [...typeidx, ...uleb(cnt), ...handlers];
|
|
1626
|
+
},
|
|
1627
|
+
resume_throw: (n, c) => {
|
|
1628
|
+
const typeidx = uleb(id(n.shift(), c.type));
|
|
1629
|
+
const exnidx = uleb(id(n.shift(), c.tag));
|
|
1630
|
+
const handlers = [];
|
|
1631
|
+
let cnt = 0;
|
|
1632
|
+
while (n[0]?.[0] === "on") {
|
|
1633
|
+
const [, tag, label] = n.shift();
|
|
1634
|
+
if (label === "switch") handlers.push(1, ...uleb(id(tag, c.tag)));
|
|
1635
|
+
else handlers.push(0, ...uleb(id(tag, c.tag)), ...uleb(blockid(label, c.block)));
|
|
1636
|
+
cnt++;
|
|
1637
|
+
}
|
|
1638
|
+
return [...typeidx, ...exnidx, ...uleb(cnt), ...handlers];
|
|
1639
|
+
},
|
|
1640
|
+
resume_throw_ref: (n, c) => {
|
|
1641
|
+
const typeidx = uleb(id(n.shift(), c.type));
|
|
1642
|
+
const handlers = [];
|
|
1643
|
+
let cnt = 0;
|
|
1644
|
+
while (n[0]?.[0] === "on") {
|
|
1645
|
+
const [, tag, label] = n.shift();
|
|
1646
|
+
if (label === "switch") handlers.push(1, ...uleb(id(tag, c.tag)));
|
|
1647
|
+
else handlers.push(0, ...uleb(id(tag, c.tag)), ...uleb(blockid(label, c.block)));
|
|
1648
|
+
cnt++;
|
|
1649
|
+
}
|
|
1650
|
+
return [...typeidx, ...uleb(cnt), ...handlers];
|
|
1651
|
+
}
|
|
1547
1652
|
};
|
|
1548
1653
|
var HANDLER = {};
|
|
1549
1654
|
(function populate(items, pre) {
|
|
@@ -1561,7 +1666,7 @@ var instr = (nodes, ctx) => {
|
|
|
1561
1666
|
continue;
|
|
1562
1667
|
}
|
|
1563
1668
|
if (Array.isArray(op)) {
|
|
1564
|
-
op.
|
|
1669
|
+
op.loc != null && (err.loc = op.loc);
|
|
1565
1670
|
err(`Unknown instruction ${op[0]}`);
|
|
1566
1671
|
}
|
|
1567
1672
|
let [...bytes] = INSTR[op] || err(`Unknown instruction ${op}`);
|
|
@@ -1603,17 +1708,36 @@ var align = (op) => {
|
|
|
1603
1708
|
let k = op[i] === "l" ? i + 4 : i + 5, m = op.slice(k).match(/(\d+)(x|_|$)/);
|
|
1604
1709
|
return Math.log2(m ? m[2] === "x" ? 8 : m[1] / 8 : +group / 8);
|
|
1605
1710
|
};
|
|
1711
|
+
var numdata = (item) => {
|
|
1712
|
+
if (!Array.isArray(item)) return null;
|
|
1713
|
+
const [t, ...vs] = item;
|
|
1714
|
+
if (t !== "i8" && t !== "i16" && t !== "i32" && t !== "i64" && t !== "f32" && t !== "f64") return null;
|
|
1715
|
+
const out = [], dv = new DataView(new ArrayBuffer(8));
|
|
1716
|
+
for (const v of vs) {
|
|
1717
|
+
if (t === "i8") out.push(i32.parse(v) & 255 + 256 & 255);
|
|
1718
|
+
else if (t === "i16") dv.setInt16(0, i32.parse(v), true), out.push(...new Uint8Array(dv.buffer, 0, 2));
|
|
1719
|
+
else if (t === "i32") dv.setInt32(0, i32.parse(v), true), out.push(...new Uint8Array(dv.buffer, 0, 4));
|
|
1720
|
+
else if (t === "i64") dv.setBigInt64(0, BigInt(v), true), out.push(...new Uint8Array(dv.buffer, 0, 8));
|
|
1721
|
+
else if (t === "f32") out.push(...f32(v));
|
|
1722
|
+
else if (t === "f64") out.push(...f64(v));
|
|
1723
|
+
}
|
|
1724
|
+
return out;
|
|
1725
|
+
};
|
|
1606
1726
|
var limits = (node) => {
|
|
1607
1727
|
const is64 = node[0] === "i64" && node.shift();
|
|
1608
1728
|
const shared = node[node.length - 1] === "shared" && node.pop();
|
|
1729
|
+
const psIdx = node.findIndex((n) => Array.isArray(n) && n[0] === "pagesize");
|
|
1730
|
+
let psLog2 = -1;
|
|
1731
|
+
if (psIdx >= 0) psLog2 = Math.log2(+node.splice(psIdx, 1)[0][1]);
|
|
1609
1732
|
const hasMax = !isNaN(parseInt(node[1]));
|
|
1610
|
-
const flag = (is64 ? 4 : 0) | (shared ? 2 : 0) | (hasMax ? 1 : 0);
|
|
1733
|
+
const flag = (psLog2 >= 0 ? 8 : 0) | (is64 ? 4 : 0) | (shared ? 2 : 0) | (hasMax ? 1 : 0);
|
|
1611
1734
|
const parse = is64 ? (v) => {
|
|
1612
1735
|
if (typeof v === "bigint") return v;
|
|
1613
1736
|
const str2 = typeof v === "string" ? v.replaceAll("_", "") : String(v);
|
|
1614
1737
|
return BigInt(str2);
|
|
1615
1738
|
} : parseUint;
|
|
1616
|
-
|
|
1739
|
+
const ps = psLog2 >= 0 ? uleb(psLog2) : [];
|
|
1740
|
+
return hasMax ? [flag, ...uleb(parse(node.shift())), ...uleb(parse(node.shift())), ...ps] : [flag, ...uleb(parse(node.shift())), ...ps];
|
|
1617
1741
|
};
|
|
1618
1742
|
var parseUint = (v, max = 4294967295) => {
|
|
1619
1743
|
const n = typeof v === "string" && v[0] !== "+" ? i32.parse(v) : typeof v === "number" ? v : err(`Bad int ${v}`);
|
|
@@ -2687,7 +2811,8 @@ var treeshake = (ast) => {
|
|
|
2687
2811
|
}
|
|
2688
2812
|
}
|
|
2689
2813
|
for (const start of starts) {
|
|
2690
|
-
|
|
2814
|
+
let ref = start[1];
|
|
2815
|
+
if (typeof ref === "string" && ref[0] !== "$") ref = +ref;
|
|
2691
2816
|
if (funcs.has(ref)) funcs.get(ref).used = true;
|
|
2692
2817
|
}
|
|
2693
2818
|
let hasExports = exports.length > 0 || starts.length > 0;
|
|
@@ -3308,7 +3433,17 @@ var inline = (ast) => {
|
|
|
3308
3433
|
}
|
|
3309
3434
|
}
|
|
3310
3435
|
if (params && !hasLocals && !hasExport && params.length <= 2 && body.length === 1) {
|
|
3311
|
-
|
|
3436
|
+
const paramNames = new Set(params.map((p) => p.name));
|
|
3437
|
+
let mutatesParam = false;
|
|
3438
|
+
walk2(body[0], (n) => {
|
|
3439
|
+
if (!Array.isArray(n)) return;
|
|
3440
|
+
if ((n[0] === "local.set" || n[0] === "local.tee") && paramNames.has(n[1])) {
|
|
3441
|
+
mutatesParam = true;
|
|
3442
|
+
}
|
|
3443
|
+
});
|
|
3444
|
+
if (!mutatesParam) {
|
|
3445
|
+
inlinable.set(name2, { body: body[0], params });
|
|
3446
|
+
}
|
|
3312
3447
|
}
|
|
3313
3448
|
}
|
|
3314
3449
|
if (inlinable.size === 0) return result;
|