wat4wasm 1.0.4 → 1.0.6

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/lib/clean.js CHANGED
@@ -26,7 +26,7 @@ function FUNC_WAT4WASM_START_CALLS(wat) {
26
26
  }
27
27
 
28
28
  export default function (wat) {
29
- let block;
29
+ let block, $name;
30
30
 
31
31
  block = FUNC_WAT4WASM_BLOCK_ONEXTERNREADY(wat);
32
32
  if (!block.hasAnyBlock) { wat = block.removedRaw(); }
@@ -87,5 +87,31 @@ export default function (wat) {
87
87
  .join("\n")
88
88
  );
89
89
 
90
+
91
+ const funcMask = new helpers.MaskSet(wat);
92
+ const unusedCalls = new Set();
93
+
94
+ funcMask.maskAll("import");
95
+ funcMask.maskComments();
96
+
97
+ while (block = funcMask.lastBlockOf("func")) {
98
+ funcMask.mask(block);
99
+ if (($name = block.$name)) {
100
+ if (wat.match(new RegExp(`\\\((call|start|ref\\.func)\\s+\\${$name}(\\s|\\\))`))) {
101
+ continue;
102
+ }
103
+
104
+ if (unusedCalls.has($name) === false) {
105
+ unusedCalls.add($name);
106
+ }
107
+ }
108
+ }
109
+
110
+ unusedCalls.forEach($name => {
111
+ const begin = wat.lastIndexOf(`(func ${$name}`);
112
+ const block = helpers.parseBlockAt(wat, begin);
113
+ if (block) { wat = block.removedRaw() }
114
+ });
115
+
90
116
  return wat;
91
117
  }
package/lib/cli.js CHANGED
@@ -164,7 +164,7 @@ export async function processCLI(compileCallback, PROCESS = process) {
164
164
 
165
165
  let wasmGenerator = ``;
166
166
  if (config.generateWASMFromHEXString && !config.generateWASMFromNumberArray) {
167
- wasmGenerator = `Uint8Array.from(/${wasmhex}/.toString().match(/[a-f0-9]{2}/g).map(h => parseInt(h, 16)))`;
167
+ wasmGenerator = `Uint8Array.from(\`${wasmhex}\`.match(/../g), $ => parseInt($, 16))`;
168
168
  }
169
169
  else if (!config.generateWASMFromHEXString && config.generateWASMFromNumberArray) {
170
170
  wasmGenerator = `Uint8Array.of(${wasmhex.toString().match(/[a-f0-9]{2}/g).map(h => parseInt(h, 16))})`;
@@ -228,7 +228,7 @@ export async function processCLI(compileCallback, PROCESS = process) {
228
228
 
229
229
  let wasmGenerator = ``;
230
230
  if (config.generateWASMFromHEXString && !config.generateWASMFromNumberArray) {
231
- wasmGenerator = `Uint8Array.from(/${wasmhex}/.toString().match(/[a-f0-9]{2}/g).map(h => parseInt(h, 16)))`;
231
+ wasmGenerator = `Uint8Array.from(\`${wasmhex}\`.match(/../g), $ => parseInt($, 16))`;
232
232
  }
233
233
  else if (!config.generateWASMFromHEXString && config.generateWASMFromNumberArray) {
234
234
  wasmGenerator = `Uint8Array.of(${wasmhex.toString().match(/[a-f0-9]{2}/g).map(h => parseInt(h, 16))})`;
package/lib/helpers.js CHANGED
@@ -307,8 +307,18 @@ const helpers = {
307
307
  },
308
308
 
309
309
  hasBlock(raw, keyword, filter) {
310
+ if (!filter && typeof keyword === "object") {
311
+ filter = keyword;
312
+ keyword = "";
313
+ }
314
+
310
315
  if (!keyword) { return raw.indexOf("(", 1) !== -1; };
311
316
  keyword = this.fixBlockKeyword(keyword, filter);
317
+
318
+ if (filter?.includes) {
319
+ return raw.includes(filter.includes);
320
+ }
321
+
312
322
  return raw.includes(keyword);
313
323
  },
314
324
 
@@ -317,7 +327,6 @@ const helpers = {
317
327
  },
318
328
 
319
329
  MaskSet: class MaskSet extends Map {
320
-
321
330
  constructor(raw) {
322
331
  raw = (raw || '').toString().trim();
323
332
  Reflect.defineProperty(super(), "input", { value: raw, writable: true })
@@ -333,6 +342,23 @@ const helpers = {
333
342
  return this.mask(block, "");
334
343
  }
335
344
 
345
+ maskAll(keyword, filter) {
346
+ let block;
347
+
348
+ while (block = this.lastBlockOf(keyword, filter)) {
349
+ this.mask(block);
350
+ }
351
+
352
+ return this
353
+ }
354
+
355
+ maskComments() {
356
+ this.input = this.input
357
+ .split(/\n/)
358
+ .map(l => l.split(";;").at(0))
359
+ .join("\n");
360
+ }
361
+
336
362
  mask(block, maskWith = block.uuid) {
337
363
  if (!block.uuid) {
338
364
  throw new Error(`Raw block needs uuid: ${block}`);
@@ -527,6 +553,10 @@ const helpers = {
527
553
 
528
554
  lastBlockOf(raw, keyword, filter) {
529
555
  if (!raw) throw new Error(`no raw for block: ${keyword}`);
556
+ if (!filter && typeof keyword === "object") {
557
+ filter = keyword;
558
+ keyword = "";
559
+ }
530
560
 
531
561
  keyword = this.fixBlockKeyword(keyword, filter);
532
562
  raw = raw.toString();
package/lib/index.js CHANGED
@@ -20,7 +20,6 @@ import TEXT from "./processors/text.js"
20
20
  import W4W from "./processors/wat4wasm.js"
21
21
 
22
22
  const processors = [
23
- REPLACE_ALL,
24
23
  W4W,
25
24
  TEXT,
26
25
  ASYNC,
@@ -32,6 +31,9 @@ const processors = [
32
31
  REF_FUNC,
33
32
  START,
34
33
  STRING,
34
+ REPLACE_ALL,
35
+ REF_EXTERN,
36
+ DATA,
35
37
  ];
36
38
 
37
39
 
@@ -59,6 +59,8 @@ const TEXT_ONINIT_BLOCK = (offset, length, setter) => String(
59
59
  )
60
60
  `).trim();
61
61
 
62
+ const extern = new Set();
63
+
62
64
  export default function (wat, WAT4WASM) {
63
65
 
64
66
  const maskSet = new helpers.MaskSet(wat);
@@ -74,18 +76,26 @@ export default function (wat, WAT4WASM) {
74
76
 
75
77
  textBlocks.forEach(block => {
76
78
  const text = helpers.findQuotedText(block);
77
- const view = helpers.encodeText(text);
78
-
79
- const dataRequest = WAT4WASM_ALLOC_DATA_BUFFER(wat, view.buffer);
80
-
81
- block.dataOffset = dataRequest.offset;
82
- block.viewLength = view.length;
83
- block.strPreview = helpers.abstract(text);
84
-
85
- wat = dataRequest.modifiedRaw;
79
+ if (extern.has(text) === false) {
80
+ extern.add(text)
81
+
82
+ const view = helpers.encodeText(text);
83
+ const dataRequest = WAT4WASM_ALLOC_DATA_BUFFER(wat, view.buffer);
84
+
85
+ block.dataOffset = dataRequest.offset;
86
+ block.viewLength = view.length;
87
+ block.strPreview = helpers.abstract(text);
88
+ block.strContent = text;
89
+ block.isExtended = true;
90
+
91
+ wat = dataRequest.modifiedRaw;
92
+ }
93
+ else {
94
+ block.isExtended = false;
95
+ }
86
96
  });
87
97
 
88
- textBlocks.forEach(block => {
98
+ textBlocks.filter(block => block.isExtended).forEach(block => {
89
99
  const growRequest = WAT4WASM_GROW_EXTERN_TABLE(wat);
90
100
  block.tableGetter = growRequest.getter.concat(`;; ${block.strPreview} \n`);
91
101
  block.tableSetter = growRequest.generateSetter(`
@@ -98,18 +108,20 @@ export default function (wat, WAT4WASM) {
98
108
  wat = growRequest.modifiedRaw;
99
109
  });
100
110
 
101
- textBlocks.forEach(block => {
102
- wat = wat.replaceAll(block.toString(), block.tableGetter)
111
+ textBlocks.filter(block => block.isExtended).forEach(block => {
112
+ wat = wat.replaceAll(block.toString(), block.tableGetter);
103
113
  });
104
114
 
105
- const oninit = textBlocks.map(block =>
115
+ const oninit = textBlocks.filter(block => block.isExtended).map(block =>
106
116
  TEXT_ONINIT_BLOCK(
107
117
  block.dataOffset,
108
118
  block.viewLength, block.tableSetter
109
119
  )
110
120
  ).join("\n");
111
121
 
112
- wat = APPEND_ON_INIT(wat, oninit);
122
+ if (oninit.trim()) {
123
+ wat = APPEND_ON_INIT(wat, oninit);
124
+ }
113
125
 
114
126
  return wat;
115
127
  }
@@ -239,14 +239,16 @@ export function DATA_WAT4WASM(wat) {
239
239
  });
240
240
  }
241
241
 
242
+
242
243
  export function WAT4WASM_ALLOC_DATA_BUFFER(wat, buffer) {
243
244
  const new_data = Buffer.from(buffer);
244
245
  const all_data = DATA_WAT4WASM(wat);
245
246
 
246
247
  let offset = all_data.buffer.indexOf(new_data);
247
248
  let modifiedRaw = wat;
249
+ let isAllocated = offset === -1;
248
250
 
249
- if (offset < 1) {
251
+ if (offset < 0) {
250
252
  offset = all_data.offset;
251
253
  all_data.buffer.writeUint32LE(offset + new_data.byteLength);
252
254
  modifiedRaw = all_data.replacedRaw(WAT4WASM_DATA(Buffer.concat([all_data.buffer, new_data])));
@@ -254,6 +256,7 @@ export function WAT4WASM_ALLOC_DATA_BUFFER(wat, buffer) {
254
256
 
255
257
  return {
256
258
  offset,
259
+ isAllocated,
257
260
  modifiedRaw,
258
261
  isRawModified: modifiedRaw.toString() !== wat.toString()
259
262
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wat4wasm",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "",
5
5
  "homepage": "https://github.com/central-network/wat4wasm#readme",
6
6
  "bugs": {
package/wat4wasm CHANGED
@@ -554,8 +554,15 @@ function wat4beauty(watContent, alignIndentsWith = "\t", exportPadStart = 90) {
554
554
  return "0x" + crypto.randomUUID().replace(/\-/g, "");
555
555
  },
556
556
  hasBlock(raw, keyword, filter) {
557
+ if (!filter && typeof keyword === "object") {
558
+ filter = keyword;
559
+ keyword = "";
560
+ }
557
561
  if (!keyword) { return raw.indexOf("(", 1) !== -1; };
558
562
  keyword = this.fixBlockKeyword(keyword, filter);
563
+ if (filter?.includes) {
564
+ return raw.includes(filter.includes);
565
+ }
559
566
  return raw.includes(keyword);
560
567
  },
561
568
  hasAnyBlock(raw) {
@@ -573,6 +580,19 @@ function wat4beauty(watContent, alignIndentsWith = "\t", exportPadStart = 90) {
573
580
  }
574
581
  return this.mask(block, "");
575
582
  }
583
+ maskAll(keyword, filter) {
584
+ let block;
585
+ while (block = this.lastBlockOf(keyword, filter)) {
586
+ this.mask(block);
587
+ }
588
+ return this
589
+ }
590
+ maskComments() {
591
+ this.input = this.input
592
+ .split(/\n/)
593
+ .map(l => l.split(";;").at(0))
594
+ .join("\n");
595
+ }
576
596
  mask(block, maskWith = block.uuid) {
577
597
  if (!block.uuid) {
578
598
  throw new Error(`Raw block needs uuid: ${block}`);
@@ -735,6 +755,10 @@ function wat4beauty(watContent, alignIndentsWith = "\t", exportPadStart = 90) {
735
755
  },
736
756
  lastBlockOf(raw, keyword, filter) {
737
757
  if (!raw) throw new Error(`no raw for block: ${keyword}`);
758
+ if (!filter && typeof keyword === "object") {
759
+ filter = keyword;
760
+ keyword = "";
761
+ }
738
762
  keyword = this.fixBlockKeyword(keyword, filter);
739
763
  raw = raw.toString();
740
764
  let begin = raw.lastIndexOf(keyword);
@@ -1381,6 +1405,7 @@ const TEXT_ONINIT_BLOCK = (offset, length, setter) => String(
1381
1405
  ${setter}
1382
1406
  )
1383
1407
  `).trim();
1408
+ const extern = new Set();
1384
1409
  function TEXT (wat, WAT4WASM) {
1385
1410
  const maskSet = new helpers.MaskSet(wat);
1386
1411
  const textBlocks = new Array();
@@ -1392,14 +1417,22 @@ function TEXT (wat, WAT4WASM) {
1392
1417
  wat = maskSet.restore();
1393
1418
  textBlocks.forEach(block => {
1394
1419
  const text = helpers.findQuotedText(block);
1395
- const view = helpers.encodeText(text);
1396
- const dataRequest = WAT4WASM_ALLOC_DATA_BUFFER(wat, view.buffer);
1397
- block.dataOffset = dataRequest.offset;
1398
- block.viewLength = view.length;
1399
- block.strPreview = helpers.abstract(text);
1400
- wat = dataRequest.modifiedRaw;
1420
+ if (extern.has(text) === false) {
1421
+ extern.add(text)
1422
+ const view = helpers.encodeText(text);
1423
+ const dataRequest = WAT4WASM_ALLOC_DATA_BUFFER(wat, view.buffer);
1424
+ block.dataOffset = dataRequest.offset;
1425
+ block.viewLength = view.length;
1426
+ block.strPreview = helpers.abstract(text);
1427
+ block.strContent = text;
1428
+ block.isExtended = true;
1429
+ wat = dataRequest.modifiedRaw;
1430
+ }
1431
+ else {
1432
+ block.isExtended = false;
1433
+ }
1401
1434
  });
1402
- textBlocks.forEach(block => {
1435
+ textBlocks.filter(block => block.isExtended).forEach(block => {
1403
1436
  const growRequest = WAT4WASM_GROW_EXTERN_TABLE(wat);
1404
1437
  block.tableGetter = growRequest.getter.concat(`;; ${block.strPreview} \n`);
1405
1438
  block.tableSetter = growRequest.generateSetter(`
@@ -1410,16 +1443,18 @@ function TEXT (wat, WAT4WASM) {
1410
1443
  )`).trim();
1411
1444
  wat = growRequest.modifiedRaw;
1412
1445
  });
1413
- textBlocks.forEach(block => {
1414
- wat = wat.replaceAll(block.toString(), block.tableGetter)
1446
+ textBlocks.filter(block => block.isExtended).forEach(block => {
1447
+ wat = wat.replaceAll(block.toString(), block.tableGetter);
1415
1448
  });
1416
- const oninit = textBlocks.map(block =>
1449
+ const oninit = textBlocks.filter(block => block.isExtended).map(block =>
1417
1450
  TEXT_ONINIT_BLOCK(
1418
1451
  block.dataOffset,
1419
1452
  block.viewLength, block.tableSetter
1420
1453
  )
1421
1454
  ).join("\n");
1422
- wat = APPEND_ON_INIT(wat, oninit);
1455
+ if (oninit.trim()) {
1456
+ wat = APPEND_ON_INIT(wat, oninit);
1457
+ }
1423
1458
  return wat;
1424
1459
  }
1425
1460
 
@@ -1614,13 +1649,15 @@ function WAT4WASM_ALLOC_DATA_BUFFER(wat, buffer) {
1614
1649
  const all_data = DATA_WAT4WASM(wat);
1615
1650
  let offset = all_data.buffer.indexOf(new_data);
1616
1651
  let modifiedRaw = wat;
1617
- if (offset < 1) {
1652
+ let isAllocated = offset === -1;
1653
+ if (offset < 0) {
1618
1654
  offset = all_data.offset;
1619
1655
  all_data.buffer.writeUint32LE(offset + new_data.byteLength);
1620
1656
  modifiedRaw = all_data.replacedRaw(WAT4WASM_DATA(Buffer.concat([all_data.buffer, new_data])));
1621
1657
  }
1622
1658
  return {
1623
1659
  offset,
1660
+ isAllocated,
1624
1661
  modifiedRaw,
1625
1662
  isRawModified: modifiedRaw.toString() !== wat.toString()
1626
1663
  };
@@ -1655,7 +1692,7 @@ function W4W (wat) {
1655
1692
  return calls;
1656
1693
  }
1657
1694
  function clean (wat) {
1658
- let block;
1695
+ let block, $name;
1659
1696
  block = FUNC_WAT4WASM_BLOCK_ONEXTERNREADY(wat);
1660
1697
  if (!block.hasAnyBlock) { wat = block.removedRaw(); }
1661
1698
  block = FUNC_WAT4WASM_BLOCK_ONTEXTREADY(wat);
@@ -1701,6 +1738,26 @@ function clean (wat) {
1701
1738
  .map(b => b.toString())
1702
1739
  .join("\n")
1703
1740
  );
1741
+ const funcMask = new helpers.MaskSet(wat);
1742
+ const unusedCalls = new Set();
1743
+ funcMask.maskAll("import");
1744
+ funcMask.maskComments();
1745
+ while (block = funcMask.lastBlockOf("func")) {
1746
+ funcMask.mask(block);
1747
+ if (($name = block.$name)) {
1748
+ if (wat.match(new RegExp(`\\\((call|start|ref\\.func)\\s+\\${$name}(\\s|\\\))`))) {
1749
+ continue;
1750
+ }
1751
+ if (unusedCalls.has($name) === false) {
1752
+ unusedCalls.add($name);
1753
+ }
1754
+ }
1755
+ }
1756
+ unusedCalls.forEach($name => {
1757
+ const begin = wat.lastIndexOf(`(func ${$name}`);
1758
+ const block = helpers.parseBlockAt(wat, begin);
1759
+ if (block) { wat = block.removedRaw() }
1760
+ });
1704
1761
  return wat;
1705
1762
  }
1706
1763
 
@@ -1841,7 +1898,7 @@ async function processCLI(compileCallback, PROCESS = process) {
1841
1898
  if (isJSTarget) {
1842
1899
  let wasmGenerator = ``;
1843
1900
  if (config.generateWASMFromHEXString && !config.generateWASMFromNumberArray) {
1844
- wasmGenerator = `Uint8Array.from(/${wasmhex}/.toString().match(/[a-f0-9]{2}/g).map(h => parseInt(h, 16)))`;
1901
+ wasmGenerator = `Uint8Array.from(\`${wasmhex}\`.match(/../g), $ => parseInt($, 16))`;
1845
1902
  }
1846
1903
  else if (!config.generateWASMFromHEXString && config.generateWASMFromNumberArray) {
1847
1904
  wasmGenerator = `Uint8Array.of(${wasmhex.toString().match(/[a-f0-9]{2}/g).map(h => parseInt(h, 16))})`;
@@ -1897,7 +1954,7 @@ async function processCLI(compileCallback, PROCESS = process) {
1897
1954
  const thenCall = thenCalls.length && String(`.then(wasm => [${thenCalls}])`) || String();
1898
1955
  let wasmGenerator = ``;
1899
1956
  if (config.generateWASMFromHEXString && !config.generateWASMFromNumberArray) {
1900
- wasmGenerator = `Uint8Array.from(/${wasmhex}/.toString().match(/[a-f0-9]{2}/g).map(h => parseInt(h, 16)))`;
1957
+ wasmGenerator = `Uint8Array.from(\`${wasmhex}\`.match(/../g), $ => parseInt($, 16))`;
1901
1958
  }
1902
1959
  else if (!config.generateWASMFromHEXString && config.generateWASMFromNumberArray) {
1903
1960
  wasmGenerator = `Uint8Array.of(${wasmhex.toString().match(/[a-f0-9]{2}/g).map(h => parseInt(h, 16))})`;
@@ -1935,7 +1992,6 @@ async function processCLI(compileCallback, PROCESS = process) {
1935
1992
 
1936
1993
 
1937
1994
  const processors = [
1938
- REPLACE_ALL,
1939
1995
  W4W,
1940
1996
  TEXT,
1941
1997
  ASYNC,
@@ -1947,6 +2003,9 @@ const processors = [
1947
2003
  REF_FUNC,
1948
2004
  START,
1949
2005
  STRING,
2006
+ REPLACE_ALL,
2007
+ REF_EXTERN,
2008
+ DATA,
1950
2009
  ];
1951
2010
  processCLI(async wat4 => {
1952
2011
  let wat2 = wat4, f, i = -1, llen, m = -1, c = 0, ci = 0;