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 CHANGED
@@ -18,7 +18,7 @@ __export(encode_exports, {
18
18
  });
19
19
 
20
20
  // src/util.js
21
- var err = (text, pos = err.i) => {
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.i = pos;
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 .i
1000
- (result = node.map(cleanup).filter((n) => n != null), result.i = node.i, result.length === 1 && result[0]?.[0] === "module" ? result[0] : 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.i = 0;
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.src?.indexOf(n, err.i);
1019
- if (pos >= 0) err.i = pos;
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.i = n.i;
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
- ctx.type.push(typedef(node, ctx));
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.i = n.i;
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
- let [, ...data] = node.splice(idx2, 1)[0], m = "" + Math.ceil(data.reduce((s, d) => s + d.length, 0) / 65536);
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.i != null && (err.i = node.i);
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
- return [compkind, dfn, subkind, supertypes];
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
- ([kind, fields, subkind, supertypes, rec], ctx) => {
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
- let details;
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
- kind = "rec";
1259
- let [from, length] = rec, subtypes = Array.from({ length }, (_, i) => build[SECTION.type](ctx.type[from + i].slice(0, 4), ctx));
1260
- details = vec(subtypes);
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
- details = [...vec(supertypes.map((n) => id(n, ctx.type))), ...build[SECTION.type]([kind, fields], ctx)];
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 [DEFTYPE[kind], ...details];
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), KIND[kind], ...details];
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.flat())
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" ? 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))] : (
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.pop(), h2.pop()];
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.i != null && (err.i = op.i);
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
- return hasMax ? [flag, ...uleb(parse(node.shift())), ...uleb(parse(node.shift()))] : [flag, ...uleb(parse(node.shift()))];
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
- const ref = start[1];
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
- inlinable.set(name2, { body: body[0], params });
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;