watr 4.2.1 → 4.3.1
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 +326 -46
- package/dist/watr.min.js +6 -5
- package/package.json +1 -1
- package/readme.md +8 -13
- package/src/compile.js +160 -44
- package/src/const.js +31 -5
- package/src/parse.js +7 -3
- package/types/src/compile.d.ts.map +1 -1
- package/types/src/const.d.ts +12 -0
- package/types/src/const.d.ts.map +1 -1
- package/types/src/parse.d.ts.map +1 -1
package/dist/watr.js
CHANGED
|
@@ -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,165 @@ 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",
|
|
519
|
+
,
|
|
520
|
+
,
|
|
521
|
+
,
|
|
522
|
+
,
|
|
523
|
+
,
|
|
524
|
+
,
|
|
525
|
+
,
|
|
526
|
+
,
|
|
527
|
+
,
|
|
528
|
+
,
|
|
529
|
+
,
|
|
530
|
+
,
|
|
531
|
+
,
|
|
532
|
+
,
|
|
533
|
+
,
|
|
534
|
+
,
|
|
535
|
+
,
|
|
536
|
+
,
|
|
537
|
+
,
|
|
538
|
+
,
|
|
539
|
+
,
|
|
540
|
+
,
|
|
541
|
+
,
|
|
542
|
+
,
|
|
543
|
+
,
|
|
544
|
+
,
|
|
545
|
+
,
|
|
546
|
+
,
|
|
547
|
+
,
|
|
548
|
+
,
|
|
549
|
+
,
|
|
550
|
+
,
|
|
551
|
+
,
|
|
552
|
+
,
|
|
553
|
+
,
|
|
554
|
+
,
|
|
555
|
+
,
|
|
556
|
+
,
|
|
557
|
+
,
|
|
558
|
+
,
|
|
559
|
+
,
|
|
560
|
+
,
|
|
561
|
+
,
|
|
562
|
+
,
|
|
563
|
+
,
|
|
564
|
+
,
|
|
565
|
+
,
|
|
566
|
+
,
|
|
567
|
+
,
|
|
568
|
+
,
|
|
569
|
+
,
|
|
570
|
+
,
|
|
571
|
+
,
|
|
572
|
+
,
|
|
573
|
+
,
|
|
574
|
+
,
|
|
575
|
+
,
|
|
576
|
+
,
|
|
577
|
+
,
|
|
578
|
+
,
|
|
579
|
+
,
|
|
580
|
+
,
|
|
581
|
+
,
|
|
582
|
+
,
|
|
583
|
+
,
|
|
584
|
+
,
|
|
585
|
+
,
|
|
586
|
+
,
|
|
587
|
+
,
|
|
588
|
+
,
|
|
589
|
+
,
|
|
590
|
+
,
|
|
591
|
+
,
|
|
592
|
+
,
|
|
593
|
+
,
|
|
594
|
+
,
|
|
595
|
+
,
|
|
596
|
+
,
|
|
597
|
+
,
|
|
598
|
+
,
|
|
599
|
+
,
|
|
600
|
+
,
|
|
601
|
+
,
|
|
602
|
+
,
|
|
603
|
+
,
|
|
604
|
+
,
|
|
605
|
+
,
|
|
606
|
+
,
|
|
607
|
+
,
|
|
608
|
+
// stringref: 0xFB 0x80-0xB7
|
|
609
|
+
"string.new_utf8 memoryidx?",
|
|
610
|
+
"string.new_wtf16 memoryidx?",
|
|
611
|
+
"string.const stringidx",
|
|
612
|
+
"string.measure_utf8",
|
|
613
|
+
"string.measure_wtf8",
|
|
614
|
+
"string.measure_wtf16",
|
|
615
|
+
"string.encode_utf8 memoryidx?",
|
|
616
|
+
"string.encode_wtf16 memoryidx?",
|
|
617
|
+
"string.concat",
|
|
618
|
+
"string.eq",
|
|
619
|
+
"string.is_usv_sequence",
|
|
620
|
+
"string.new_lossy_utf8 memoryidx?",
|
|
621
|
+
"string.new_wtf8 memoryidx?",
|
|
622
|
+
"string.encode_lossy_utf8 memoryidx?",
|
|
623
|
+
"string.encode_wtf8 memoryidx?",
|
|
624
|
+
,
|
|
625
|
+
// 0x8F
|
|
626
|
+
"string.as_wtf8",
|
|
627
|
+
"stringview_wtf8.advance",
|
|
628
|
+
"stringview_wtf8.encode_utf8 memoryidx?",
|
|
629
|
+
"stringview_wtf8.slice",
|
|
630
|
+
"stringview_wtf8.encode_lossy_utf8 memoryidx?",
|
|
631
|
+
"stringview_wtf8.encode_wtf8 memoryidx?",
|
|
632
|
+
,
|
|
633
|
+
,
|
|
634
|
+
// 0x96-0x97
|
|
635
|
+
"string.as_wtf16",
|
|
636
|
+
"stringview_wtf16.length",
|
|
637
|
+
"stringview_wtf16.get_codeunit",
|
|
638
|
+
"stringview_wtf16.encode memoryidx?",
|
|
639
|
+
"stringview_wtf16.slice",
|
|
640
|
+
,
|
|
641
|
+
,
|
|
642
|
+
,
|
|
643
|
+
// 0x9D-0x9F
|
|
644
|
+
"string.as_iter",
|
|
645
|
+
"stringview_iter.next",
|
|
646
|
+
"stringview_iter.advance",
|
|
647
|
+
"stringview_iter.rewind",
|
|
648
|
+
"stringview_iter.slice",
|
|
649
|
+
,
|
|
650
|
+
,
|
|
651
|
+
,
|
|
652
|
+
,
|
|
653
|
+
,
|
|
654
|
+
,
|
|
655
|
+
,
|
|
656
|
+
,
|
|
657
|
+
,
|
|
658
|
+
,
|
|
659
|
+
,
|
|
660
|
+
// 0xA5-0xAF
|
|
661
|
+
"string.new_utf8_array",
|
|
662
|
+
"string.new_wtf16_array",
|
|
663
|
+
"string.encode_utf8_array",
|
|
664
|
+
"string.encode_wtf16_array",
|
|
665
|
+
"string.new_lossy_utf8_array",
|
|
666
|
+
"string.new_wtf8_array",
|
|
667
|
+
"string.encode_lossy_utf8_array",
|
|
668
|
+
"string.encode_wtf8_array"
|
|
510
669
|
],
|
|
511
670
|
// 0xfc: Bulk memory/table operations (nested array)
|
|
512
671
|
[
|
|
@@ -896,7 +1055,7 @@ var INSTR = [
|
|
|
896
1055
|
"i64.atomic.rmw32.cmpxchg_u memarg"
|
|
897
1056
|
]
|
|
898
1057
|
];
|
|
899
|
-
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 };
|
|
1058
|
+
var SECTION = { custom: 0, type: 1, import: 2, func: 3, table: 4, memory: 5, tag: 13, strings: 14, global: 6, export: 7, start: 8, elem: 9, datacount: 12, code: 10, data: 11 };
|
|
900
1059
|
var TYPE = {
|
|
901
1060
|
// Value types
|
|
902
1061
|
i8: 120,
|
|
@@ -920,6 +1079,14 @@ var TYPE = {
|
|
|
920
1079
|
i31: 108,
|
|
921
1080
|
struct: 107,
|
|
922
1081
|
array: 106,
|
|
1082
|
+
cont: 104,
|
|
1083
|
+
nocont: 117,
|
|
1084
|
+
// stack switching (Phase 3)
|
|
1085
|
+
string: 103,
|
|
1086
|
+
stringview_wtf8: 102,
|
|
1087
|
+
stringview_wtf16: 96,
|
|
1088
|
+
stringview_iter: 97,
|
|
1089
|
+
// stringref
|
|
923
1090
|
// Reference type abbreviations (absheaptype abbrs)
|
|
924
1091
|
nullfuncref: 115,
|
|
925
1092
|
nullexternref: 114,
|
|
@@ -933,6 +1100,11 @@ var TYPE = {
|
|
|
933
1100
|
i31ref: 108,
|
|
934
1101
|
structref: 107,
|
|
935
1102
|
arrayref: 106,
|
|
1103
|
+
contref: 104,
|
|
1104
|
+
nocontref: 117,
|
|
1105
|
+
// stack switching abbreviations
|
|
1106
|
+
stringref: 103,
|
|
1107
|
+
// stringref abbreviation
|
|
936
1108
|
// ref, refnull
|
|
937
1109
|
ref: 100,
|
|
938
1110
|
// -0x1c
|
|
@@ -943,7 +1115,7 @@ var TYPE = {
|
|
|
943
1115
|
subfinal: 79,
|
|
944
1116
|
rec: 78
|
|
945
1117
|
};
|
|
946
|
-
var DEFTYPE = { func: 96, struct: 95, array: 94, sub: 80, subfinal: 79, rec: 78 };
|
|
1118
|
+
var DEFTYPE = { func: 96, struct: 95, array: 94, cont: 93, sub: 80, subfinal: 79, rec: 78 };
|
|
947
1119
|
var KIND = { func: 0, table: 1, memory: 2, global: 3, tag: 4 };
|
|
948
1120
|
|
|
949
1121
|
// src/parse.js
|
|
@@ -962,10 +1134,10 @@ var parse_default = (str2) => {
|
|
|
962
1134
|
buf += str2[i++]
|
|
963
1135
|
)
|
|
964
1136
|
);
|
|
965
|
-
else if (q < 0) c === 10 || c === 13 ? (buf += str2[i++], commit(), q = 0) : buf += str2[i++];
|
|
1137
|
+
else if (q < 0) c === 10 || c === 13 ? (buf += str2[i++], commit(), q = 0) : q === -2 && c === 41 ? (commit(), q = 0) : buf += str2[i++];
|
|
966
1138
|
else if (c === 34) buf !== "$" && commit(), q = 34, buf += str2[i++];
|
|
967
1139
|
else if (c === 40 && str2.charCodeAt(i + 1) === 59) commit(), q = 60, buf = str2[i++] + str2[i++];
|
|
968
|
-
else if (c === 59 && str2.charCodeAt(i + 1) === 59) commit(), q = -1, buf = str2[i++] + str2[i++];
|
|
1140
|
+
else if (c === 59 && str2.charCodeAt(i + 1) === 59) commit(), q = str2.indexOf("\n", i) < 0 ? -2 : -1, buf = str2[i++] + str2[i++];
|
|
969
1141
|
else if (c === 40 && str2.charCodeAt(i + 1) === 64) commit(), p = i, i += 2, buf = "@", depth++, (root = level).push(level = []), parseLevel(p), level = root;
|
|
970
1142
|
else if (c === 40) commit(), p = i++, depth++, (root = level).push(level = []), parseLevel(p), level = root;
|
|
971
1143
|
else if (c === 41) return commit(), i++, depth--;
|
|
@@ -1010,6 +1182,17 @@ function compile(nodes) {
|
|
|
1010
1182
|
else if (typeof nodes[0] === "string") nodes = [nodes];
|
|
1011
1183
|
if (nodes[idx] === "binary") return Uint8Array.from(nodes.slice(++idx).flat());
|
|
1012
1184
|
if (nodes[idx] === "quote") return compile(nodes.slice(++idx).map((v) => v.valueOf().slice(1, -1)).flat().join(""));
|
|
1185
|
+
nodes = nodes.flatMap((n, i) => {
|
|
1186
|
+
if (i < idx || !Array.isArray(n) || n[0] !== "import") return [n];
|
|
1187
|
+
const [, mod, ...rest] = n;
|
|
1188
|
+
if (!rest.some((r) => Array.isArray(r) && r[0] === "item")) return [n];
|
|
1189
|
+
const lastIsType = Array.isArray(rest.at(-1)) && rest.at(-1)[0] !== "item";
|
|
1190
|
+
if (lastIsType) {
|
|
1191
|
+
const type = rest.at(-1);
|
|
1192
|
+
return rest.slice(0, -1).filter((r) => r[0] === "item").map(([, nm]) => ["import", mod, nm, type]);
|
|
1193
|
+
}
|
|
1194
|
+
return rest.filter((r) => r[0] === "item").map(([, nm, type]) => ["import", mod, nm, type]);
|
|
1195
|
+
});
|
|
1013
1196
|
const ctx = [];
|
|
1014
1197
|
for (let kind in SECTION) (ctx[SECTION[kind]] = ctx[kind] = []).name = kind;
|
|
1015
1198
|
ctx.metadata = {};
|
|
@@ -1040,12 +1223,19 @@ function compile(nodes) {
|
|
|
1040
1223
|
for (let i = 0; i < node.length; i++) {
|
|
1041
1224
|
let [, ...subnode] = node[i];
|
|
1042
1225
|
name(subnode, ctx.type);
|
|
1226
|
+
const tdesc = [];
|
|
1227
|
+
while (subnode[0]?.[0] === "descriptor" || subnode[0]?.[0] === "describes") tdesc.push(subnode.shift());
|
|
1043
1228
|
(subnode = typedef(subnode, ctx)).push(i ? true : [ctx.type.length, node.length]);
|
|
1229
|
+
if (tdesc.length) subnode.desc = subnode.desc ? [...tdesc, ...subnode.desc] : tdesc;
|
|
1044
1230
|
ctx.type.push(subnode);
|
|
1045
1231
|
}
|
|
1046
1232
|
} else if (kind === "type") {
|
|
1047
1233
|
name(node, ctx.type);
|
|
1048
|
-
|
|
1234
|
+
const tdesc = [];
|
|
1235
|
+
while (node[0]?.[0] === "descriptor" || node[0]?.[0] === "describes") tdesc.push(node.shift());
|
|
1236
|
+
const td = typedef(node, ctx);
|
|
1237
|
+
if (tdesc.length) td.desc = td.desc ? [...tdesc, ...td.desc] : tdesc;
|
|
1238
|
+
ctx.type.push(td);
|
|
1049
1239
|
} else if (kind === "start" || kind === "export") ctx[kind].push(node);
|
|
1050
1240
|
else return true;
|
|
1051
1241
|
}).forEach((n) => {
|
|
@@ -1068,7 +1258,8 @@ function compile(nodes) {
|
|
|
1068
1258
|
} else if (kind === "memory") {
|
|
1069
1259
|
const is64 = node[0] === "i64", idx2 = is64 ? 1 : 0;
|
|
1070
1260
|
if (node[idx2]?.[0] === "data") {
|
|
1071
|
-
|
|
1261
|
+
const ps = node.find((n2) => Array.isArray(n2) && n2[0] === "pagesize")?.[1] ?? 65536;
|
|
1262
|
+
let [, ...data] = node.splice(idx2, 1)[0], m = "" + Math.ceil(data.reduce((s, d) => s + d.length, 0) / ps);
|
|
1072
1263
|
ctx.data.push([["memory", items.length], [is64 ? "i64.const" : "i32.const", is64 ? 0n : 0], ...data]);
|
|
1073
1264
|
node = is64 ? ["i64", m, m] : [m, m];
|
|
1074
1265
|
}
|
|
@@ -1101,6 +1292,12 @@ function compile(nodes) {
|
|
|
1101
1292
|
}
|
|
1102
1293
|
return sections;
|
|
1103
1294
|
};
|
|
1295
|
+
const globalSection = bin(SECTION.global);
|
|
1296
|
+
const elemSection = bin(SECTION.elem);
|
|
1297
|
+
const codeSection = bin(SECTION.code);
|
|
1298
|
+
const metaSection = binMeta();
|
|
1299
|
+
const dataSection = bin(SECTION.data);
|
|
1300
|
+
const stringsSection = ctx.strings.length ? [SECTION.strings, ...vec([0, ...vec(ctx.strings.map((s) => vec(s)))])] : [];
|
|
1104
1301
|
return Uint8Array.from([
|
|
1105
1302
|
0,
|
|
1106
1303
|
97,
|
|
@@ -1119,14 +1316,15 @@ function compile(nodes) {
|
|
|
1119
1316
|
...bin(SECTION.table),
|
|
1120
1317
|
...bin(SECTION.memory),
|
|
1121
1318
|
...bin(SECTION.tag),
|
|
1122
|
-
...
|
|
1319
|
+
...stringsSection,
|
|
1320
|
+
...globalSection,
|
|
1123
1321
|
...bin(SECTION.export),
|
|
1124
1322
|
...bin(SECTION.start, false),
|
|
1125
|
-
...
|
|
1323
|
+
...elemSection,
|
|
1126
1324
|
...bin(SECTION.datacount, false),
|
|
1127
|
-
...
|
|
1128
|
-
...
|
|
1129
|
-
...
|
|
1325
|
+
...codeSection,
|
|
1326
|
+
...metaSection,
|
|
1327
|
+
...dataSection
|
|
1130
1328
|
]);
|
|
1131
1329
|
}
|
|
1132
1330
|
var isIdx = (n) => n?.[0] === "$" || !isNaN(n);
|
|
@@ -1195,7 +1393,7 @@ function normalize(nodes, ctx) {
|
|
|
1195
1393
|
out.push(...normalize(parts, ctx), "end");
|
|
1196
1394
|
} else {
|
|
1197
1395
|
const imm = [];
|
|
1198
|
-
while (parts.length && (!Array.isArray(parts[0]) || "type,param,result,ref".includes(parts[0][0]))) imm.push(parts.shift());
|
|
1396
|
+
while (parts.length && (!Array.isArray(parts[0]) || parts[0].valueOf !== Array.prototype.valueOf || "type,param,result,ref,exact,on".includes(parts[0][0]))) imm.push(parts.shift());
|
|
1199
1397
|
out.push(...normalize(parts, ctx), op, ...imm);
|
|
1200
1398
|
nodes.unshift(...out.splice(out.length - 1 - imm.length));
|
|
1201
1399
|
}
|
|
@@ -1240,16 +1438,19 @@ var name = (node, list) => {
|
|
|
1240
1438
|
return nm;
|
|
1241
1439
|
};
|
|
1242
1440
|
var typedef = ([dfn], ctx) => {
|
|
1243
|
-
let subkind = "subfinal", supertypes = [], compkind;
|
|
1441
|
+
let subkind = "subfinal", supertypes = [], compkind, desc = [];
|
|
1244
1442
|
if (dfn[0] === "sub") {
|
|
1245
1443
|
subkind = dfn.shift(), dfn[0] === "final" && (subkind += dfn.shift());
|
|
1246
1444
|
dfn = (supertypes = dfn).pop();
|
|
1445
|
+
supertypes = supertypes.filter((n) => Array.isArray(n) && (n[0] === "descriptor" || n[0] === "describes") ? (desc.push(n), false) : true);
|
|
1247
1446
|
}
|
|
1248
1447
|
[compkind, ...dfn] = dfn;
|
|
1249
1448
|
if (compkind === "func") dfn = paramres(dfn), ctx.type["$" + dfn.join(">")] ??= ctx.type.length;
|
|
1250
1449
|
else if (compkind === "struct") dfn = fieldseq(dfn, "field");
|
|
1251
1450
|
else if (compkind === "array") [dfn] = dfn;
|
|
1252
|
-
|
|
1451
|
+
const result = [compkind, dfn, subkind, supertypes];
|
|
1452
|
+
if (desc.length) result.desc = desc;
|
|
1453
|
+
return result;
|
|
1253
1454
|
};
|
|
1254
1455
|
var build = [
|
|
1255
1456
|
// (@custom "name" placement? data) - custom section builder
|
|
@@ -1264,29 +1465,37 @@ var build = [
|
|
|
1264
1465
|
// (func params result)
|
|
1265
1466
|
// (array i8)
|
|
1266
1467
|
// (struct ...fields)
|
|
1267
|
-
(
|
|
1468
|
+
// (cont $ft) - stack switching (Phase 3)
|
|
1469
|
+
(node, ctx) => {
|
|
1470
|
+
const [kind, fields, subkind, supertypes, rec] = node;
|
|
1268
1471
|
if (rec === true) return;
|
|
1269
|
-
|
|
1472
|
+
const descPfx = (node.desc ?? []).flatMap(([clause, ref]) => [clause === "descriptor" ? 77 : 76, ...uleb(id(ref, ctx.type))]);
|
|
1473
|
+
const comptype = (k, f) => {
|
|
1474
|
+
if (k === "func") return [DEFTYPE.func, ...vec(f[0].map((t) => reftype(t, ctx))), ...vec(f[1].map((t) => reftype(t, ctx)))];
|
|
1475
|
+
if (k === "array") return [DEFTYPE.array, ...fieldtype(f, ctx)];
|
|
1476
|
+
if (k === "struct") return [DEFTYPE.struct, ...vec(f.map((t) => fieldtype(t, ctx)))];
|
|
1477
|
+
if (k === "cont") return [DEFTYPE.cont, ...uleb(id(f[0] ?? f, ctx.type))];
|
|
1478
|
+
return [DEFTYPE[k]];
|
|
1479
|
+
};
|
|
1270
1480
|
if (rec) {
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1481
|
+
let [from, length] = rec;
|
|
1482
|
+
const subtypes = Array.from({ length }, (_, i) => {
|
|
1483
|
+
const t = ctx.type[from + i], sub = t.slice(0, 4);
|
|
1484
|
+
if (t.desc) sub.desc = t.desc;
|
|
1485
|
+
return build[SECTION.type](sub, ctx);
|
|
1486
|
+
});
|
|
1487
|
+
return [DEFTYPE.rec, ...vec(subtypes)];
|
|
1274
1488
|
} else if (subkind === "sub" || supertypes?.length) {
|
|
1275
|
-
|
|
1276
|
-
kind = subkind;
|
|
1277
|
-
} else if (kind === "func") {
|
|
1278
|
-
details = [...vec(fields[0].map((t) => reftype(t, ctx))), ...vec(fields[1].map((t) => reftype(t, ctx)))];
|
|
1279
|
-
} else if (kind === "array") {
|
|
1280
|
-
details = fieldtype(fields, ctx);
|
|
1281
|
-
} else if (kind === "struct") {
|
|
1282
|
-
details = vec(fields.map((t) => fieldtype(t, ctx)));
|
|
1489
|
+
return [DEFTYPE[subkind], ...vec(supertypes.map((n) => id(n, ctx.type))), ...descPfx, ...comptype(kind, fields)];
|
|
1283
1490
|
}
|
|
1284
|
-
return [
|
|
1491
|
+
return [...descPfx, ...comptype(kind, fields)];
|
|
1285
1492
|
},
|
|
1286
1493
|
// (import "math" "add" (func|table|global|memory|tag dfn?))
|
|
1287
1494
|
([mod, field, [kind, ...dfn]], ctx) => {
|
|
1288
|
-
let details;
|
|
1495
|
+
let details, kindByte = KIND[kind];
|
|
1289
1496
|
if (kind === "func") {
|
|
1497
|
+
const isExact = dfn[0] === "exact" && dfn.shift();
|
|
1498
|
+
if (isExact) kindByte = 32;
|
|
1290
1499
|
let [[, typeidx]] = dfn;
|
|
1291
1500
|
details = uleb(id(typeidx, ctx.type));
|
|
1292
1501
|
} else if (kind === "tag") {
|
|
@@ -1299,7 +1508,7 @@ var build = [
|
|
|
1299
1508
|
} else if (kind === "table") {
|
|
1300
1509
|
details = [...reftype(dfn.pop(), ctx), ...limits(dfn)];
|
|
1301
1510
|
} else err(`Unknown kind ${kind}`);
|
|
1302
|
-
return [...vec(mod), ...vec(field),
|
|
1511
|
+
return [...vec(mod), ...vec(field), kindByte, ...details];
|
|
1303
1512
|
},
|
|
1304
1513
|
// (func $name? ...params result ...body)
|
|
1305
1514
|
([[, typeidx]], ctx) => uleb(id(typeidx, ctx.type)),
|
|
@@ -1413,6 +1622,7 @@ var build = [
|
|
|
1413
1622
|
// (data (i32.const 0) "\aa" "\bb"?)
|
|
1414
1623
|
// (data (memory ref) (offset (i32.const 0)) "\aa" "\bb"?)
|
|
1415
1624
|
// (data (global.get $x) "\aa" "\bb"?)
|
|
1625
|
+
// (data (i8 1 2 3) ...) numeric values (WAT numeric values, Phase 2)
|
|
1416
1626
|
(inits, ctx) => {
|
|
1417
1627
|
let offset, memidx = 0;
|
|
1418
1628
|
if (inits[0]?.[0] === "memory") {
|
|
@@ -1435,7 +1645,7 @@ var build = [
|
|
|
1435
1645
|
[1]
|
|
1436
1646
|
)
|
|
1437
1647
|
),
|
|
1438
|
-
...vec(inits.
|
|
1648
|
+
...vec(inits.flatMap((item) => numdata(item) ?? [...item]))
|
|
1439
1649
|
];
|
|
1440
1650
|
},
|
|
1441
1651
|
// datacount
|
|
@@ -1443,7 +1653,13 @@ var build = [
|
|
|
1443
1653
|
// (tag $name? (type idx))
|
|
1444
1654
|
([[, typeidx]], ctx) => [0, ...uleb(id(typeidx, ctx.type))]
|
|
1445
1655
|
];
|
|
1446
|
-
var reftype = (t, ctx) => t[0] === "ref" ? t[1] == "null" ?
|
|
1656
|
+
var reftype = (t, ctx) => t[0] === "ref" ? t[1] == "null" ? (
|
|
1657
|
+
// (ref null (exact $T)) - exact nullable ref
|
|
1658
|
+
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))]
|
|
1659
|
+
) : (
|
|
1660
|
+
// (ref (exact $T)) - exact non-null ref
|
|
1661
|
+
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))]
|
|
1662
|
+
) : (
|
|
1447
1663
|
// abbrs
|
|
1448
1664
|
[TYPE[t] ?? err(`Unknown type ${t}`)]
|
|
1449
1665
|
);
|
|
@@ -1491,7 +1707,7 @@ var IMM = {
|
|
|
1491
1707
|
},
|
|
1492
1708
|
ref_null: (n, c) => {
|
|
1493
1709
|
let t = n.shift();
|
|
1494
|
-
return TYPE[t] ? [TYPE[t]] : uleb(id(t, c.type));
|
|
1710
|
+
return Array.isArray(t) && t[0] === "exact" ? [98, ...uleb(id(t[1], c.type))] : TYPE[t] ? [TYPE[t]] : uleb(id(t, c.type));
|
|
1495
1711
|
},
|
|
1496
1712
|
memarg: (n, c, op) => memargEnc(n, op, isIdx(n[0]) && !isMemParam(n[0]) ? id(n.shift(), c.memory) : 0),
|
|
1497
1713
|
opt_memory: (n, c) => uleb(id(isIdx(n[0]) ? n.shift() : 0, c.memory)),
|
|
@@ -1500,8 +1716,8 @@ var IMM = {
|
|
|
1500
1716
|
return ht.length > 1 ? ht.slice(1) : ht;
|
|
1501
1717
|
},
|
|
1502
1718
|
reftype2: (n, c) => {
|
|
1503
|
-
let b = blockid(n.shift(), c.block), h1 = reftype(n.shift(), c), h2 = reftype(n.shift(), c);
|
|
1504
|
-
return [(h2[0] !== TYPE.ref) << 1 | h1[0] !== TYPE.ref, ...uleb(b), h1
|
|
1719
|
+
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;
|
|
1720
|
+
return [(h2[0] !== TYPE.ref) << 1 | h1[0] !== TYPE.ref, ...uleb(b), ...ht(h1), ...ht(h2)];
|
|
1505
1721
|
},
|
|
1506
1722
|
v128const: (n) => {
|
|
1507
1723
|
let [t, num] = n.shift().split("x"), bits = +t.slice(1), stride = bits >>> 3;
|
|
@@ -1539,6 +1755,11 @@ var IMM = {
|
|
|
1539
1755
|
elemidx: (n, c) => uleb(id(n.shift(), c.elem)),
|
|
1540
1756
|
tagidx: (n, c) => uleb(id(n.shift(), c.tag)),
|
|
1541
1757
|
"memoryidx?": (n, c) => uleb(id(isIdx(n[0]) ? n.shift() : 0, c.memory)),
|
|
1758
|
+
stringidx: (n, c) => {
|
|
1759
|
+
let s = n.shift(), key = s.valueOf(), idx = c.strings.findIndex((x) => x.valueOf() === key);
|
|
1760
|
+
if (idx < 0) idx = c.strings.push(s) - 1;
|
|
1761
|
+
return uleb(idx);
|
|
1762
|
+
},
|
|
1542
1763
|
// Value type
|
|
1543
1764
|
i32: (n) => i32(n.shift()),
|
|
1544
1765
|
i64: (n) => i64(n.shift()),
|
|
@@ -1556,7 +1777,47 @@ var IMM = {
|
|
|
1556
1777
|
typeidx_typeidx: (n, c) => [...uleb(id(n.shift(), c.type)), ...uleb(id(n.shift(), c.type))],
|
|
1557
1778
|
dataidx_memoryidx: (n, c) => [...uleb(id(n.shift(), c.data)), ...uleb(id(n.shift(), c.memory))],
|
|
1558
1779
|
memoryidx_memoryidx: (n, c) => [...uleb(id(n.shift(), c.memory)), ...uleb(id(n.shift(), c.memory))],
|
|
1559
|
-
tableidx_tableidx: (n, c) => [...uleb(id(n.shift(), c.table)), ...uleb(id(n.shift(), c.table))]
|
|
1780
|
+
tableidx_tableidx: (n, c) => [...uleb(id(n.shift(), c.table)), ...uleb(id(n.shift(), c.table))],
|
|
1781
|
+
// stack switching handlers (Phase 3)
|
|
1782
|
+
cont_bind: (n, c) => [...uleb(id(n.shift(), c.type)), ...uleb(id(n.shift(), c.type))],
|
|
1783
|
+
switch_cont: (n, c) => [...uleb(id(n.shift(), c.type)), ...uleb(id(n.shift(), c.tag))],
|
|
1784
|
+
resume: (n, c) => {
|
|
1785
|
+
const typeidx = uleb(id(n.shift(), c.type));
|
|
1786
|
+
const handlers = [];
|
|
1787
|
+
let cnt = 0;
|
|
1788
|
+
while (n[0]?.[0] === "on") {
|
|
1789
|
+
const [, tag, label] = n.shift();
|
|
1790
|
+
if (label === "switch") handlers.push(1, ...uleb(id(tag, c.tag)));
|
|
1791
|
+
else handlers.push(0, ...uleb(id(tag, c.tag)), ...uleb(blockid(label, c.block)));
|
|
1792
|
+
cnt++;
|
|
1793
|
+
}
|
|
1794
|
+
return [...typeidx, ...uleb(cnt), ...handlers];
|
|
1795
|
+
},
|
|
1796
|
+
resume_throw: (n, c) => {
|
|
1797
|
+
const typeidx = uleb(id(n.shift(), c.type));
|
|
1798
|
+
const exnidx = uleb(id(n.shift(), c.tag));
|
|
1799
|
+
const handlers = [];
|
|
1800
|
+
let cnt = 0;
|
|
1801
|
+
while (n[0]?.[0] === "on") {
|
|
1802
|
+
const [, tag, label] = n.shift();
|
|
1803
|
+
if (label === "switch") handlers.push(1, ...uleb(id(tag, c.tag)));
|
|
1804
|
+
else handlers.push(0, ...uleb(id(tag, c.tag)), ...uleb(blockid(label, c.block)));
|
|
1805
|
+
cnt++;
|
|
1806
|
+
}
|
|
1807
|
+
return [...typeidx, ...exnidx, ...uleb(cnt), ...handlers];
|
|
1808
|
+
},
|
|
1809
|
+
resume_throw_ref: (n, c) => {
|
|
1810
|
+
const typeidx = uleb(id(n.shift(), c.type));
|
|
1811
|
+
const handlers = [];
|
|
1812
|
+
let cnt = 0;
|
|
1813
|
+
while (n[0]?.[0] === "on") {
|
|
1814
|
+
const [, tag, label] = n.shift();
|
|
1815
|
+
if (label === "switch") handlers.push(1, ...uleb(id(tag, c.tag)));
|
|
1816
|
+
else handlers.push(0, ...uleb(id(tag, c.tag)), ...uleb(blockid(label, c.block)));
|
|
1817
|
+
cnt++;
|
|
1818
|
+
}
|
|
1819
|
+
return [...typeidx, ...uleb(cnt), ...handlers];
|
|
1820
|
+
}
|
|
1560
1821
|
};
|
|
1561
1822
|
var HANDLER = {};
|
|
1562
1823
|
(function populate(items, pre) {
|
|
@@ -1616,17 +1877,36 @@ var align = (op) => {
|
|
|
1616
1877
|
let k = op[i] === "l" ? i + 4 : i + 5, m = op.slice(k).match(/(\d+)(x|_|$)/);
|
|
1617
1878
|
return Math.log2(m ? m[2] === "x" ? 8 : m[1] / 8 : +group / 8);
|
|
1618
1879
|
};
|
|
1880
|
+
var numdata = (item) => {
|
|
1881
|
+
if (!Array.isArray(item)) return null;
|
|
1882
|
+
const [t, ...vs] = item;
|
|
1883
|
+
if (t !== "i8" && t !== "i16" && t !== "i32" && t !== "i64" && t !== "f32" && t !== "f64") return null;
|
|
1884
|
+
const out = [], dv = new DataView(new ArrayBuffer(8));
|
|
1885
|
+
for (const v of vs) {
|
|
1886
|
+
if (t === "i8") out.push(i32.parse(v) & 255 + 256 & 255);
|
|
1887
|
+
else if (t === "i16") dv.setInt16(0, i32.parse(v), true), out.push(...new Uint8Array(dv.buffer, 0, 2));
|
|
1888
|
+
else if (t === "i32") dv.setInt32(0, i32.parse(v), true), out.push(...new Uint8Array(dv.buffer, 0, 4));
|
|
1889
|
+
else if (t === "i64") dv.setBigInt64(0, BigInt(v), true), out.push(...new Uint8Array(dv.buffer, 0, 8));
|
|
1890
|
+
else if (t === "f32") out.push(...f32(v));
|
|
1891
|
+
else if (t === "f64") out.push(...f64(v));
|
|
1892
|
+
}
|
|
1893
|
+
return out;
|
|
1894
|
+
};
|
|
1619
1895
|
var limits = (node) => {
|
|
1620
1896
|
const is64 = node[0] === "i64" && node.shift();
|
|
1621
1897
|
const shared = node[node.length - 1] === "shared" && node.pop();
|
|
1898
|
+
const psIdx = node.findIndex((n) => Array.isArray(n) && n[0] === "pagesize");
|
|
1899
|
+
let psLog2 = -1;
|
|
1900
|
+
if (psIdx >= 0) psLog2 = Math.log2(+node.splice(psIdx, 1)[0][1]);
|
|
1622
1901
|
const hasMax = !isNaN(parseInt(node[1]));
|
|
1623
|
-
const flag = (is64 ? 4 : 0) | (shared ? 2 : 0) | (hasMax ? 1 : 0);
|
|
1902
|
+
const flag = (psLog2 >= 0 ? 8 : 0) | (is64 ? 4 : 0) | (shared ? 2 : 0) | (hasMax ? 1 : 0);
|
|
1624
1903
|
const parse = is64 ? (v) => {
|
|
1625
1904
|
if (typeof v === "bigint") return v;
|
|
1626
1905
|
const str2 = typeof v === "string" ? v.replaceAll("_", "") : String(v);
|
|
1627
1906
|
return BigInt(str2);
|
|
1628
1907
|
} : parseUint;
|
|
1629
|
-
|
|
1908
|
+
const ps = psLog2 >= 0 ? uleb(psLog2) : [];
|
|
1909
|
+
return hasMax ? [flag, ...uleb(parse(node.shift())), ...uleb(parse(node.shift())), ...ps] : [flag, ...uleb(parse(node.shift())), ...ps];
|
|
1630
1910
|
};
|
|
1631
1911
|
var parseUint = (v, max = 4294967295) => {
|
|
1632
1912
|
const n = typeof v === "string" && v[0] !== "+" ? i32.parse(v) : typeof v === "number" ? v : err(`Bad int ${v}`);
|