wat4wasm 1.1.1 → 1.1.3
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/build +1 -1
- package/lib/clean.js +27 -20
- package/lib/cli.js +34 -17
- package/lib/index.js +7 -4
- package/lib/processors/start.js +1 -1
- package/lib/processors/text.js +24 -6
- package/package.json +2 -3
- package/wat4wasm +84 -45
- package/test/boot.wat +0 -5
- package/test/test-output.html +0 -1
- package/test/test-output.js +0 -27
- package/test/test-output.wasm +0 -0
- package/test/test-output.wat +0 -1115
- package/test/test-sub.wat +0 -4
- package/test/test.wat +0 -64
- package/test/test_worker.js +0 -1
package/lib/build
CHANGED
|
@@ -4,7 +4,7 @@ import fs from "fs";
|
|
|
4
4
|
|
|
5
5
|
const headers = [`#!/usr/bin/env node`, `import fs from "fs";`, `import cp, { spawnSync } from "child_process";`].join("\n").concat("\n\n");
|
|
6
6
|
const index_js = fs.readFileSync("index.js", "utf8").split(/\n+/).filter(l => !l.startsWith("import") && !l.startsWith("#")).join("\n").concat("\n\n");
|
|
7
|
-
const cli_js = fs.readFileSync("cli.js", "utf8").split(/\n+/).filter(l => !l.startsWith("import")).join("\n").
|
|
7
|
+
const cli_js = fs.readFileSync("cli.js", "utf8").split(/\n+/).filter(l => !l.startsWith("import")).join("\n").replace("export ", "").concat("\n\n");
|
|
8
8
|
const helpers_js = fs.readFileSync("helpers.js", "utf8").split(/\n+/).filter(l => !l.startsWith("import") && !l.startsWith("export")).join("\n").concat("\n\n");
|
|
9
9
|
const clean_js = fs.readFileSync("clean.js", "utf8").split(/\n+/).filter(l => !l.startsWith("import")).join("\n").concat("\n\n").replaceAll("export default function", "function clean");
|
|
10
10
|
const imports = fs.readFileSync("index.js", "utf8").split(/\n+/).filter(l => l.startsWith("import") && l.includes("processors/")).map(i => i.split(/^import|\s+|from|\"|\.js/g).filter(Boolean))
|
package/lib/clean.js
CHANGED
|
@@ -25,7 +25,7 @@ function FUNC_WAT4WASM_START_CALLS(wat) {
|
|
|
25
25
|
return calls;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
export default function (wat) {
|
|
28
|
+
export default function (wat, config = {}) {
|
|
29
29
|
console.log("")
|
|
30
30
|
let block, $name;
|
|
31
31
|
block = FUNC_WAT4WASM_BLOCK_ONEXTERNREADY(wat);
|
|
@@ -41,6 +41,10 @@ export default function (wat) {
|
|
|
41
41
|
wat = wat.replace(`(start $wat4wasm)`, `(start ${$start})`);
|
|
42
42
|
console.log(`⚠️ replaced --> \x1b[34m(start \x1b[35m$wat4wasm\x1b[0m --> \x1b[35m${$start}\x1b[0m)\x1b[0m`);
|
|
43
43
|
}
|
|
44
|
+
else if ($starts.length === 0) {
|
|
45
|
+
console.log(`⚠️ removing --> \x1b[34m(start \x1b[35m$wat4wasm\x1b[0m)\x1b[0m`);
|
|
46
|
+
wat = wat.replace(`(start $wat4wasm)`, ``);
|
|
47
|
+
}
|
|
44
48
|
let $func = FUNC_WAT4WASM(wat);
|
|
45
49
|
if ($func) {
|
|
46
50
|
console.log(`⚠️ removing --> \x1b[34m(func \x1b[35m$wat4wasm\x1b[0m ...)\x1b[0m`);
|
|
@@ -82,28 +86,31 @@ export default function (wat) {
|
|
|
82
86
|
.map(b => b.toString())
|
|
83
87
|
.join("\n")
|
|
84
88
|
);
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
funcMask.
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
89
|
+
|
|
90
|
+
if (!config.keepUnusedFunctions) {
|
|
91
|
+
const funcMask = new helpers.MaskSet(wat);
|
|
92
|
+
const unusedCalls = new Set();
|
|
93
|
+
funcMask.maskAll("import");
|
|
94
|
+
funcMask.maskComments();
|
|
95
|
+
while (block = funcMask.lastBlockOf("func")) {
|
|
96
|
+
funcMask.mask(block);
|
|
97
|
+
if (($name = block.$name)) {
|
|
98
|
+
if (wat.match(new RegExp(`\\\((call|start|ref\\.func)\\s+\\${$name}(\\s|\\\))`))) {
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
if (unusedCalls.has($name) === false) {
|
|
102
|
+
unusedCalls.add($name);
|
|
103
|
+
}
|
|
97
104
|
}
|
|
98
105
|
}
|
|
106
|
+
unusedCalls.forEach($name => {
|
|
107
|
+
const begin = wat.lastIndexOf(`(func ${$name}`);
|
|
108
|
+
const block = helpers.parseBlockAt(wat, begin);
|
|
109
|
+
$name = $name.replace(".prototype.", ":")
|
|
110
|
+
console.log(`⚠️ removing unused --> \x1b[34m(func \x1b[32m${$name}\x1b[0m ...)\x1b[0m`);
|
|
111
|
+
if (block) { wat = block.removedRaw() }
|
|
112
|
+
});
|
|
99
113
|
}
|
|
100
|
-
unusedCalls.forEach($name => {
|
|
101
|
-
const begin = wat.lastIndexOf(`(func ${$name}`);
|
|
102
|
-
const block = helpers.parseBlockAt(wat, begin);
|
|
103
|
-
$name = $name.replace(".prototype.", ":")
|
|
104
|
-
console.log(`⚠️ removing unused --> \x1b[34m(func \x1b[32m${$name}\x1b[0m ...)\x1b[0m`);
|
|
105
|
-
if (block) { wat = block.removedRaw() }
|
|
106
|
-
});
|
|
107
114
|
const nonWat4WasmMemory = wat.replace(WAT4WASM_BLOCKS.memory, "");
|
|
108
115
|
if (nonWat4WasmMemory.match(/\(memory\s+(\$|\d)/)) {
|
|
109
116
|
console.log(`⚠️ removing --> \x1b[34m(memory \x1b[35m$wat4wasm\x1b[0m ...)\x1b[0m`);
|
package/lib/cli.js
CHANGED
|
@@ -26,6 +26,7 @@ export async function processCLI(compileCallback, PROCESS = process) {
|
|
|
26
26
|
printOnly: false,
|
|
27
27
|
passthroughArgs: [],
|
|
28
28
|
applyScripts: [],
|
|
29
|
+
keepUnusedFunctions: false
|
|
29
30
|
};
|
|
30
31
|
|
|
31
32
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -56,6 +57,8 @@ export async function processCLI(compileCallback, PROCESS = process) {
|
|
|
56
57
|
config.windowtagName &&= "";
|
|
57
58
|
} else if (arg === "--log-instance") {
|
|
58
59
|
config.consoleLogInstance = true;
|
|
60
|
+
} else if (arg === "--keep-unused-functions") {
|
|
61
|
+
config.keepUnusedFunctions = true;
|
|
59
62
|
} else if (arg === "--keep-window") {
|
|
60
63
|
config.keepWindowObjects = true;
|
|
61
64
|
} else if (arg === "--keep-chrome-global") {
|
|
@@ -117,21 +120,32 @@ export async function processCLI(compileCallback, PROCESS = process) {
|
|
|
117
120
|
}
|
|
118
121
|
|
|
119
122
|
const rawCode = fs.readFileSync(config.inputFile, "utf8");
|
|
123
|
+
const applyScripts = await Array.fromAsync(
|
|
124
|
+
config.applyScripts.map(script => Object({
|
|
125
|
+
basename: script.split("/").pop().split(".").reverse().slice(1).reverse().join("."),
|
|
126
|
+
fullpath: config.inputDirectory.concat(script)
|
|
127
|
+
})).map(async script => Object.assign(script, {
|
|
128
|
+
function: await import(script.fullpath).then(s => s.default)
|
|
129
|
+
}))
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
config.APPLY = async function APPLY(code) {
|
|
133
|
+
let script, i = applyScripts.length;
|
|
134
|
+
while (script = applyScripts[--i]) {
|
|
135
|
+
const wat2 = await script.function.call(null, code);
|
|
136
|
+
const func = script.basename;
|
|
137
|
+
const diff = code.toString().length - wat2.toString().length;
|
|
138
|
+
|
|
139
|
+
if (diff) {
|
|
140
|
+
console.log(`\x1b[0m\x1b[34m🎸 \x1b[35m${func}(\x1b[0mwat\x1b[35m)\x1b[0m \x1b[32m-->\x1b[0m \x1b[35m${diff}\x1b[0m byte(s)\x1b[0m`)
|
|
141
|
+
}
|
|
120
142
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
let applyScript, applyCount = config.applyScripts.length;
|
|
125
|
-
|
|
126
|
-
while (applyScript = config.applyScripts[--applyCount]) {
|
|
127
|
-
const baseName = applyScript.split("/").pop().split(".").reverse().slice(1).reverse().join(".");
|
|
128
|
-
console.log(`\x1b[0m\x1b[34m🎸 apply call[\x1b[35m${applyCount}\x1b[0m] \x1b[32m-->\x1b[0m \x1b[35m${baseName}\x1b[0m(wat)\x1b[0m`);
|
|
129
|
-
const { default: applyFunction } = await import(
|
|
130
|
-
config.inputDirectory.concat(applyScript)
|
|
131
|
-
);
|
|
132
|
-
compiled = await applyFunction(compiled);
|
|
143
|
+
code = wat2;
|
|
144
|
+
}
|
|
145
|
+
return code;
|
|
133
146
|
}
|
|
134
|
-
|
|
147
|
+
// 2. Call the provided compile function
|
|
148
|
+
const compiled = await compileCallback(rawCode, config);
|
|
135
149
|
console.log("\x1b[0m")
|
|
136
150
|
|
|
137
151
|
// 3. Handle Output
|
|
@@ -198,8 +212,8 @@ export async function processCLI(compileCallback, PROCESS = process) {
|
|
|
198
212
|
}
|
|
199
213
|
|
|
200
214
|
extension = "js";
|
|
201
|
-
filecontent =
|
|
202
|
-
const view = ${wasmGenerator};
|
|
215
|
+
filecontent = String(
|
|
216
|
+
`const view = ${wasmGenerator};
|
|
203
217
|
export let wasm = view.buffer;
|
|
204
218
|
|
|
205
219
|
wasm.module = null;
|
|
@@ -223,8 +237,11 @@ export async function processCLI(compileCallback, PROCESS = process) {
|
|
|
223
237
|
return instantiate();
|
|
224
238
|
};
|
|
225
239
|
|
|
226
|
-
export default wasm;
|
|
227
|
-
|
|
240
|
+
export default wasm;`);
|
|
241
|
+
|
|
242
|
+
filecontent = filecontent.replaceAll(
|
|
243
|
+
String(" ").repeat(filecontent.search(/\w/) - 1)
|
|
244
|
+
, "");
|
|
228
245
|
}
|
|
229
246
|
else {
|
|
230
247
|
extension = "html";
|
package/lib/index.js
CHANGED
|
@@ -37,11 +37,13 @@ const processors = [
|
|
|
37
37
|
];
|
|
38
38
|
|
|
39
39
|
|
|
40
|
-
processCLI(async wat4 => {
|
|
41
|
-
let wat2
|
|
40
|
+
processCLI(async (wat4, config) => {
|
|
41
|
+
let wat2, f, i = -1, llen, m = -1, c = 0, ci = 0;
|
|
42
|
+
|
|
43
|
+
wat2 = await config.APPLY(wat4, W4W);
|
|
42
44
|
|
|
43
45
|
while (f = processors[++i]) {
|
|
44
|
-
wat4 = f(wat2, W4W).toString();
|
|
46
|
+
wat4 = await f(wat2, W4W).toString();
|
|
45
47
|
|
|
46
48
|
const input = wat2;
|
|
47
49
|
const output = wat4;
|
|
@@ -90,8 +92,9 @@ processCLI(async wat4 => {
|
|
|
90
92
|
}
|
|
91
93
|
}
|
|
92
94
|
|
|
93
|
-
wat2 = clean(wat2);
|
|
95
|
+
wat2 = clean(wat2, config);
|
|
94
96
|
wat2 = wat4beauty(wat2, " ");
|
|
97
|
+
wat2 = await config.APPLY(wat2);
|
|
95
98
|
|
|
96
99
|
return wat2;
|
|
97
100
|
});
|
package/lib/processors/start.js
CHANGED
|
@@ -4,10 +4,10 @@ export const START_BLOCK_NAME = "start";
|
|
|
4
4
|
|
|
5
5
|
export default function (wat, WAT4WASM) {
|
|
6
6
|
let startCalls = [];
|
|
7
|
-
let removedWat = wat;
|
|
8
7
|
|
|
9
8
|
wat = wat.replaceAll(/\(main(\s+)(\$.[^\s]*)(\s)/g, `(start$1$2)\n\n(func$1$2$3`)
|
|
10
9
|
|
|
10
|
+
let removedWat = wat;
|
|
11
11
|
while (helpers.hasBlock(removedWat, START_BLOCK_NAME)) {
|
|
12
12
|
let block = helpers.lastBlockOf(removedWat, START_BLOCK_NAME);
|
|
13
13
|
removedWat = block.removedRaw();
|
package/lib/processors/text.js
CHANGED
|
@@ -59,12 +59,13 @@ const TEXT_ONINIT_BLOCK = (offset, length, setter) => String(
|
|
|
59
59
|
)
|
|
60
60
|
`).trim();
|
|
61
61
|
|
|
62
|
-
const extern = new Set();
|
|
63
62
|
|
|
64
|
-
|
|
63
|
+
function replaceAllText(wat, WAT4WASM) {
|
|
65
64
|
|
|
65
|
+
const extern = new Set();
|
|
66
66
|
const maskSet = new helpers.MaskSet(wat);
|
|
67
67
|
const textBlocks = new Array();
|
|
68
|
+
const textGetters = new Map();
|
|
68
69
|
|
|
69
70
|
while (maskSet.hasBlock(TEXT_BLOCK_NAME)) {
|
|
70
71
|
let block = maskSet.lastBlockOf(TEXT_BLOCK_NAME);
|
|
@@ -89,6 +90,8 @@ export default function (wat, WAT4WASM) {
|
|
|
89
90
|
block.isExtended = true;
|
|
90
91
|
|
|
91
92
|
wat = dataRequest.modifiedRaw;
|
|
93
|
+
|
|
94
|
+
textGetters.set(block.uuid, text)
|
|
92
95
|
}
|
|
93
96
|
else {
|
|
94
97
|
block.isExtended = false;
|
|
@@ -105,13 +108,10 @@ export default function (wat, WAT4WASM) {
|
|
|
105
108
|
(local.get $arguments) ;; ${block.strPreview}
|
|
106
109
|
)`).trim();
|
|
107
110
|
|
|
111
|
+
textGetters.set(textGetters.get(block.uuid), block.tableGetter)
|
|
108
112
|
wat = growRequest.modifiedRaw;
|
|
109
113
|
});
|
|
110
114
|
|
|
111
|
-
textBlocks.filter(block => block.isExtended).forEach(block => {
|
|
112
|
-
wat = wat.replaceAll(block.toString(), block.tableGetter);
|
|
113
|
-
});
|
|
114
|
-
|
|
115
115
|
const oninit = textBlocks.filter(block => block.isExtended).map(block =>
|
|
116
116
|
TEXT_ONINIT_BLOCK(
|
|
117
117
|
block.dataOffset,
|
|
@@ -123,5 +123,23 @@ export default function (wat, WAT4WASM) {
|
|
|
123
123
|
wat = APPEND_ON_INIT(wat, oninit);
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
+
while (helpers.hasBlock(wat, "text")) {
|
|
127
|
+
const block = helpers.lastBlockOf(wat, "text");
|
|
128
|
+
const text = helpers.findQuotedText(block);
|
|
129
|
+
const getter = textGetters.get(text);
|
|
130
|
+
|
|
131
|
+
if (getter) {
|
|
132
|
+
wat = block.replacedRaw(getter)
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return wat;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export default function (wat) {
|
|
140
|
+
while (helpers.hasBlock(wat, "text")) {
|
|
141
|
+
wat = replaceAllText(wat);
|
|
142
|
+
}
|
|
143
|
+
|
|
126
144
|
return wat;
|
|
127
145
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wat4wasm",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"description": "",
|
|
5
5
|
"homepage": "https://github.com/central-network/wat4wasm#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -18,9 +18,8 @@
|
|
|
18
18
|
},
|
|
19
19
|
"type": "module",
|
|
20
20
|
"scripts": {
|
|
21
|
-
"test": "cd test && wat4wasm test.wat --wat2wasm=wat2wasm --enable-threads --debug-names --output=test-output.wasm",
|
|
22
21
|
"rebuild": "cd lib && node build",
|
|
23
|
-
"
|
|
22
|
+
"test": "cd examples && ./shell-usages.sh",
|
|
24
23
|
"install": "cp wat4wasm /usr/local/bin/wat4wasm"
|
|
25
24
|
},
|
|
26
25
|
"bin": "wat4wasm",
|
package/wat4wasm
CHANGED
|
@@ -1277,8 +1277,8 @@ function REPLACE_ALL (wat) {
|
|
|
1277
1277
|
const START_BLOCK_NAME = "start";
|
|
1278
1278
|
function START (wat, WAT4WASM) {
|
|
1279
1279
|
let startCalls = [];
|
|
1280
|
-
let removedWat = wat;
|
|
1281
1280
|
wat = wat.replaceAll(/\(main(\s+)(\$.[^\s]*)(\s)/g, `(start$1$2)\n\n(func$1$2$3`)
|
|
1281
|
+
let removedWat = wat;
|
|
1282
1282
|
while (helpers.hasBlock(removedWat, START_BLOCK_NAME)) {
|
|
1283
1283
|
let block = helpers.lastBlockOf(removedWat, START_BLOCK_NAME);
|
|
1284
1284
|
removedWat = block.removedRaw();
|
|
@@ -1406,10 +1406,11 @@ const TEXT_ONINIT_BLOCK = (offset, length, setter) => String(
|
|
|
1406
1406
|
${setter}
|
|
1407
1407
|
)
|
|
1408
1408
|
`).trim();
|
|
1409
|
-
|
|
1410
|
-
|
|
1409
|
+
function replaceAllText(wat, WAT4WASM) {
|
|
1410
|
+
const extern = new Set();
|
|
1411
1411
|
const maskSet = new helpers.MaskSet(wat);
|
|
1412
1412
|
const textBlocks = new Array();
|
|
1413
|
+
const textGetters = new Map();
|
|
1413
1414
|
while (maskSet.hasBlock(TEXT_BLOCK_NAME)) {
|
|
1414
1415
|
let block = maskSet.lastBlockOf(TEXT_BLOCK_NAME);
|
|
1415
1416
|
maskSet.mask(block);
|
|
@@ -1428,6 +1429,7 @@ function TEXT (wat, WAT4WASM) {
|
|
|
1428
1429
|
block.strContent = text;
|
|
1429
1430
|
block.isExtended = true;
|
|
1430
1431
|
wat = dataRequest.modifiedRaw;
|
|
1432
|
+
textGetters.set(block.uuid, text)
|
|
1431
1433
|
}
|
|
1432
1434
|
else {
|
|
1433
1435
|
block.isExtended = false;
|
|
@@ -1442,11 +1444,9 @@ function TEXT (wat, WAT4WASM) {
|
|
|
1442
1444
|
(local.get $textDecoder)
|
|
1443
1445
|
(local.get $arguments) ;; ${block.strPreview}
|
|
1444
1446
|
)`).trim();
|
|
1447
|
+
textGetters.set(textGetters.get(block.uuid), block.tableGetter)
|
|
1445
1448
|
wat = growRequest.modifiedRaw;
|
|
1446
1449
|
});
|
|
1447
|
-
textBlocks.filter(block => block.isExtended).forEach(block => {
|
|
1448
|
-
wat = wat.replaceAll(block.toString(), block.tableGetter);
|
|
1449
|
-
});
|
|
1450
1450
|
const oninit = textBlocks.filter(block => block.isExtended).map(block =>
|
|
1451
1451
|
TEXT_ONINIT_BLOCK(
|
|
1452
1452
|
block.dataOffset,
|
|
@@ -1456,6 +1456,20 @@ function TEXT (wat, WAT4WASM) {
|
|
|
1456
1456
|
if (oninit.trim()) {
|
|
1457
1457
|
wat = APPEND_ON_INIT(wat, oninit);
|
|
1458
1458
|
}
|
|
1459
|
+
while (helpers.hasBlock(wat, "text")) {
|
|
1460
|
+
const block = helpers.lastBlockOf(wat, "text");
|
|
1461
|
+
const text = helpers.findQuotedText(block);
|
|
1462
|
+
const getter = textGetters.get(text);
|
|
1463
|
+
if (getter) {
|
|
1464
|
+
wat = block.replacedRaw(getter)
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
return wat;
|
|
1468
|
+
}
|
|
1469
|
+
function TEXT (wat) {
|
|
1470
|
+
while (helpers.hasBlock(wat, "text")) {
|
|
1471
|
+
wat = replaceAllText(wat);
|
|
1472
|
+
}
|
|
1459
1473
|
return wat;
|
|
1460
1474
|
}
|
|
1461
1475
|
|
|
@@ -1692,7 +1706,7 @@ function W4W (wat) {
|
|
|
1692
1706
|
}
|
|
1693
1707
|
return calls;
|
|
1694
1708
|
}
|
|
1695
|
-
function clean (wat) {
|
|
1709
|
+
function clean (wat, config = {}) {
|
|
1696
1710
|
console.log("")
|
|
1697
1711
|
let block, $name;
|
|
1698
1712
|
block = FUNC_WAT4WASM_BLOCK_ONEXTERNREADY(wat);
|
|
@@ -1708,6 +1722,10 @@ function clean (wat) {
|
|
|
1708
1722
|
wat = wat.replace(`(start $wat4wasm)`, `(start ${$start})`);
|
|
1709
1723
|
console.log(`⚠️ replaced --> \x1b[34m(start \x1b[35m$wat4wasm\x1b[0m --> \x1b[35m${$start}\x1b[0m)\x1b[0m`);
|
|
1710
1724
|
}
|
|
1725
|
+
else if ($starts.length === 0) {
|
|
1726
|
+
console.log(`⚠️ removing --> \x1b[34m(start \x1b[35m$wat4wasm\x1b[0m)\x1b[0m`);
|
|
1727
|
+
wat = wat.replace(`(start $wat4wasm)`, ``);
|
|
1728
|
+
}
|
|
1711
1729
|
let $func = FUNC_WAT4WASM(wat);
|
|
1712
1730
|
if ($func) {
|
|
1713
1731
|
console.log(`⚠️ removing --> \x1b[34m(func \x1b[35m$wat4wasm\x1b[0m ...)\x1b[0m`);
|
|
@@ -1749,28 +1767,30 @@ function clean (wat) {
|
|
|
1749
1767
|
.map(b => b.toString())
|
|
1750
1768
|
.join("\n")
|
|
1751
1769
|
);
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
funcMask.
|
|
1758
|
-
|
|
1759
|
-
if (
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
unusedCalls.
|
|
1770
|
+
if (!config.keepUnusedFunctions) {
|
|
1771
|
+
const funcMask = new helpers.MaskSet(wat);
|
|
1772
|
+
const unusedCalls = new Set();
|
|
1773
|
+
funcMask.maskAll("import");
|
|
1774
|
+
funcMask.maskComments();
|
|
1775
|
+
while (block = funcMask.lastBlockOf("func")) {
|
|
1776
|
+
funcMask.mask(block);
|
|
1777
|
+
if (($name = block.$name)) {
|
|
1778
|
+
if (wat.match(new RegExp(`\\\((call|start|ref\\.func)\\s+\\${$name}(\\s|\\\))`))) {
|
|
1779
|
+
continue;
|
|
1780
|
+
}
|
|
1781
|
+
if (unusedCalls.has($name) === false) {
|
|
1782
|
+
unusedCalls.add($name);
|
|
1783
|
+
}
|
|
1764
1784
|
}
|
|
1765
1785
|
}
|
|
1786
|
+
unusedCalls.forEach($name => {
|
|
1787
|
+
const begin = wat.lastIndexOf(`(func ${$name}`);
|
|
1788
|
+
const block = helpers.parseBlockAt(wat, begin);
|
|
1789
|
+
$name = $name.replace(".prototype.", ":")
|
|
1790
|
+
console.log(`⚠️ removing unused --> \x1b[34m(func \x1b[32m${$name}\x1b[0m ...)\x1b[0m`);
|
|
1791
|
+
if (block) { wat = block.removedRaw() }
|
|
1792
|
+
});
|
|
1766
1793
|
}
|
|
1767
|
-
unusedCalls.forEach($name => {
|
|
1768
|
-
const begin = wat.lastIndexOf(`(func ${$name}`);
|
|
1769
|
-
const block = helpers.parseBlockAt(wat, begin);
|
|
1770
|
-
$name = $name.replace(".prototype.", ":")
|
|
1771
|
-
console.log(`⚠️ removing unused --> \x1b[34m(func \x1b[32m${$name}\x1b[0m ...)\x1b[0m`);
|
|
1772
|
-
if (block) { wat = block.removedRaw() }
|
|
1773
|
-
});
|
|
1774
1794
|
const nonWat4WasmMemory = wat.replace(WAT4WASM_BLOCKS.memory, "");
|
|
1775
1795
|
if (nonWat4WasmMemory.match(/\(memory\s+(\$|\d)/)) {
|
|
1776
1796
|
console.log(`⚠️ removing --> \x1b[34m(memory \x1b[35m$wat4wasm\x1b[0m ...)\x1b[0m`);
|
|
@@ -1804,6 +1824,7 @@ async function processCLI(compileCallback, PROCESS = process) {
|
|
|
1804
1824
|
printOnly: false,
|
|
1805
1825
|
passthroughArgs: [],
|
|
1806
1826
|
applyScripts: [],
|
|
1827
|
+
keepUnusedFunctions: false
|
|
1807
1828
|
};
|
|
1808
1829
|
for (let i = 0; i < args.length; i++) {
|
|
1809
1830
|
const arg = args[i];
|
|
@@ -1833,6 +1854,8 @@ async function processCLI(compileCallback, PROCESS = process) {
|
|
|
1833
1854
|
config.windowtagName &&= "";
|
|
1834
1855
|
} else if (arg === "--log-instance") {
|
|
1835
1856
|
config.consoleLogInstance = true;
|
|
1857
|
+
} else if (arg === "--keep-unused-functions") {
|
|
1858
|
+
config.keepUnusedFunctions = true;
|
|
1836
1859
|
} else if (arg === "--keep-window") {
|
|
1837
1860
|
config.keepWindowObjects = true;
|
|
1838
1861
|
} else if (arg === "--keep-chrome-global") {
|
|
@@ -1887,17 +1910,29 @@ async function processCLI(compileCallback, PROCESS = process) {
|
|
|
1887
1910
|
throw new Error(`Input file not found: ${config.inputFile}`);
|
|
1888
1911
|
}
|
|
1889
1912
|
const rawCode = fs.readFileSync(config.inputFile, "utf8");
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1913
|
+
const applyScripts = await Array.fromAsync(
|
|
1914
|
+
config.applyScripts.map(script => Object({
|
|
1915
|
+
basename: script.split("/").pop().split(".").reverse().slice(1).reverse().join("."),
|
|
1916
|
+
fullpath: config.inputDirectory.concat(script)
|
|
1917
|
+
})).map(async script => Object.assign(script, {
|
|
1918
|
+
function: await import(script.fullpath).then(s => s.default)
|
|
1919
|
+
}))
|
|
1920
|
+
);
|
|
1921
|
+
config.APPLY = async function APPLY(code) {
|
|
1922
|
+
let script, i = applyScripts.length;
|
|
1923
|
+
while (script = applyScripts[--i]) {
|
|
1924
|
+
const wat2 = await script.function.call(null, code);
|
|
1925
|
+
const func = script.basename;
|
|
1926
|
+
const diff = code.toString().length - wat2.toString().length;
|
|
1927
|
+
if (diff) {
|
|
1928
|
+
console.log(`\x1b[0m\x1b[34m🎸 \x1b[35m${func}(\x1b[0mwat\x1b[35m)\x1b[0m \x1b[32m-->\x1b[0m \x1b[35m${diff}\x1b[0m byte(s)\x1b[0m`)
|
|
1929
|
+
}
|
|
1930
|
+
code = wat2;
|
|
1931
|
+
}
|
|
1932
|
+
return code;
|
|
1900
1933
|
}
|
|
1934
|
+
// 2. Call the provided compile function
|
|
1935
|
+
const compiled = await compileCallback(rawCode, config);
|
|
1901
1936
|
console.log("\x1b[0m")
|
|
1902
1937
|
// 3. Handle Output
|
|
1903
1938
|
if (config.printOnly) {
|
|
@@ -1947,9 +1982,9 @@ async function processCLI(compileCallback, PROCESS = process) {
|
|
|
1947
1982
|
wasmGenerator = `Uint8Array.of(${wasmhex.toString().match(/[a-f0-9]{2}/g).map(h => parseInt(h, 16))})`;
|
|
1948
1983
|
}
|
|
1949
1984
|
extension = "js";
|
|
1950
|
-
filecontent =
|
|
1951
|
-
const view = ${wasmGenerator};
|
|
1952
|
-
let wasm = view.buffer;
|
|
1985
|
+
filecontent = String(
|
|
1986
|
+
`const view = ${wasmGenerator};
|
|
1987
|
+
export let wasm = view.buffer;
|
|
1953
1988
|
|
|
1954
1989
|
wasm.module = null;
|
|
1955
1990
|
wasm.instances = new Array;
|
|
@@ -1972,8 +2007,10 @@ async function processCLI(compileCallback, PROCESS = process) {
|
|
|
1972
2007
|
return instantiate();
|
|
1973
2008
|
};
|
|
1974
2009
|
|
|
1975
|
-
default wasm;
|
|
1976
|
-
|
|
2010
|
+
export default wasm;`);
|
|
2011
|
+
filecontent = filecontent.replaceAll(
|
|
2012
|
+
String(" ").repeat(filecontent.search(/\w/) - 1)
|
|
2013
|
+
, "");
|
|
1977
2014
|
}
|
|
1978
2015
|
else {
|
|
1979
2016
|
extension = "html";
|
|
@@ -2050,10 +2087,11 @@ const processors = [
|
|
|
2050
2087
|
REF_EXTERN,
|
|
2051
2088
|
DATA,
|
|
2052
2089
|
];
|
|
2053
|
-
processCLI(async wat4 => {
|
|
2054
|
-
let wat2
|
|
2090
|
+
processCLI(async (wat4, config) => {
|
|
2091
|
+
let wat2, f, i = -1, llen, m = -1, c = 0, ci = 0;
|
|
2092
|
+
wat2 = await config.APPLY(wat4, W4W);
|
|
2055
2093
|
while (f = processors[++i]) {
|
|
2056
|
-
wat4 = f(wat2, W4W).toString();
|
|
2094
|
+
wat4 = await f(wat2, W4W).toString();
|
|
2057
2095
|
const input = wat2;
|
|
2058
2096
|
const output = wat4;
|
|
2059
2097
|
const inLines = input.split("\n").map(l => l.trim()).filter(Boolean);
|
|
@@ -2094,8 +2132,9 @@ processCLI(async wat4 => {
|
|
|
2094
2132
|
else { console.log("☘️ untouched raw \x1b[32m-->\x1b[0m finalizing..") }
|
|
2095
2133
|
}
|
|
2096
2134
|
}
|
|
2097
|
-
wat2 = clean(wat2);
|
|
2135
|
+
wat2 = clean(wat2, config);
|
|
2098
2136
|
wat2 = wat4beauty(wat2, " ");
|
|
2137
|
+
wat2 = await config.APPLY(wat2);
|
|
2099
2138
|
return wat2;
|
|
2100
2139
|
});
|
|
2101
2140
|
|
package/test/boot.wat
DELETED
package/test/test-output.html
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<body onload="[WebAssembly.instantiate(Uint8Array.from(/0061736d01000000013d0b6000016f60016f00600170016f60036f7f7f0060026f6f0060036f7f6f0060026f6f016f60056f7f7d7e7c0060036f6f6f0060036f6f6f016f60000002e1010f0473656c660473656c66036f000473656c66054172726179000006537472696e670c66726f6d43686172436f6465036f0007636f6e736f6c65036c6f670001054172726179026f660002075265666c65637403736574000307636f6e736f6c65036c6f670004075265666c656374037365740005054172726179026f66000607636f6e736f6c65047761726e0007075265666c656374036765740006075265666c656374056170706c79000807636f6e736f6c65056572726f720008075265666c65637409636f6e7374727563740006075265666c656374056170706c7900090307060a0a010a010a0404016f001805030100010606016f01d06f0b080110090701030003120f110c01030abe130602000b4a0041032500410143cdcc0c40420444000000000000f03f1007410a2500410925004108250041072500410625004104250023001006100cd2111002100cd20f1002100cd212100210090b0a00200020002000100a0bc61202056f037f02402300026f100024022302410041d40010032302410141e50010032302410241f80010032302410341f40010032302410441c40010032302410541e50010032302410641e30010032302410741ef0010032302410841e40010032302410941e50010032302410a41f20010032301d06f2302100cd06f24020b10082300100b21002000026f100024022302410041e40010032302410141e50010032302410241e30010032302410341ef0010032302410441e40010032302410541e50010032301d06f2302100cd06f24020b100821012300026f100024022302410041d50010032302410141e90010032302410241ee0010032302410341f400100323024104413810032302410541c10010032302410641f20010032302410741f20010032302410841e10010032302410941f90010032301d06f2302100cd06f24020b100821020b410041002802000240024041002105410421064108210710002103200341002007100320022003100b2104034020070440410020064101fc0802002004200541002d00001003200541016a2105200641016a2106200741016b21070c010b0b1000210320034100200410054101200120002003100c26000b024041002105410c21064106210710002103200341002007100320022003100b2104034020070440410020064101fc0802002004200541002d00001003200541016a2105200641016a2106200741016b21070c010b0b1000210320034100200410054102200120002003100c26000b024041002105411221064102210710002103200341002007100320022003100b2104034020070440410020064101fc0802002004200541002d00001003200541016a2105200641016a2106200741016b21070c010b0b1000210320034100200410054103200120002003100c26000b024041002105411421064107210710002103200341002007100320022003100b2104034020070440410020064101fc0802002004200541002d00001003200541016a2105200641016a2106200741016b21070c010b0b100021032003410020041005410b200120002003100c26000b024041002105411b21064109210710002103200341002007100320022003100b2104034020070440410020064101fc0802002004200541002d00001003200541016a2105200641016a2106200741016b21070c010b0b100021032003410020041005410c200120002003100c26000b024041002105412421064107210710002103200341002007100320022003100b2104034020070440410020064101fc0802002004200541002d00001003200541016a2105200641016a2106200741016b21070c010b0b100021032003410020041005410d200120002003100c26000b024041002105412b21064105210710002103200341002007100320022003100b2104034020070440410020064101fc0802002004200541002d00001003200541016a2105200641016a2106200741016b21070c010b0b100021032003410020041005410e200120002003100c26000b024041002105411b21064109210710002103200341002007100320022003100b2104034020070440410020064101fc0802002004200541002d00001003200541016a2105200641016a2106200741016b21070c010b0b100021032003410020041005410f200120002003100c26000b024041002105412421064107210710002103200341002007100320022003100b2104034020070440410020064101fc0802002004200541002d00001003200541016a2105200641016a2106200741016b21070c010b0b1000210320034100200410054110200120002003100c26000b024041002105413021064104210710002103200341002007100320022003100b2104034020070440410020064101fc0802002004200541002d00001003200541016a2105200641016a2106200741016b21070c010b0b1000210320034100200410054111200120002003100c26000b024041002105411b21064109210710002103200341002007100320022003100b2104034020070440410020064101fc0802002004200541002d00001003200541016a2105200641016a2106200741016b21070c010b0b1000210320034100200410054112200120002003100c26000b024041002105412421064107210710002103200341002007100320022003100b2104034020070440410020064101fc0802002004200541002d00001003200541016a2105200641016a2106200741016b21070c010b0b1000210320034100200410054113200120002003100c26000b02404100210541342106410b210710002103200341002007100320022003100b2104034020070440410020064101fc0802002004200541002d00001003200541016a2105200641016a2106200741016b21070c010b0b1000210320034100200410054114200120002003100c26000b024041002105413f2106410b210710002103200341002007100320022003100b2104034020070440410020064101fc0802002004200541002d00001003200541016a2105200641016a2106200741016b21070c010b0b1000210320034100200410054115200120002003100c26000b024041002105413f2106410b210710002103200341002007100320022003100b2104034020070440410020064101fc0802002004200541002d00001003200541016a2105200641016a2106200741016b21070c010b0b1000210320034100200410054116200120002003100c26000b02404100210541ca002106410a210710002103200341002007100320022003100b2104034020070440410020064101fc0802002004200541002d00001003200541016a2105200641016a2106200741016b21070c010b0b1000210320034100200410054117200120002003100c26000b0b024002404105230041172500100826000b02404106230041152500100826000b02404107230041152500100841142500100826000b024041082300410d25001008410c2500100841112500100826000b024041092300410d25001008410c25001008410e2500100826000b0240410a2300410d25001008410c25001008410b2500100826000b0b02404104026f100024022302410041211003410525002302100b240241210440410041002903000240410041213602000340410028020004404100410028020041016b360200410441002802004101fc0800002302410028020041042d000010030c010b0b0b3703000b2302d06f24020b26000b36020001100e0b14002000410225001008200041012500100810040b0600230010010b0b8d010301210061736d01000000010401600000030201000504010301010801000a040102000b0111636f6e736f6c652e6c6f672873656c6629015454000000696e7374616e63656d6f64756c656d6566696e616c6c7970726f746f7479706550726f6d69736563617463687468656e696e7374616e7469617465576562417373656d626c7955696e74384172726179/.toString().match(/[a-f0-9]{2}/g).map(h => parseInt(h, 16))), self).then(wasm => [console.warn(wasm),Array.from(document.children).forEach(i => i.remove()),self.chrome && (self.chrome = self),Reflect.defineProperty(__proto__, Symbol.toStringTag, {value: String.fromCharCode(55358,56715) }),Reflect.ownKeys(self).forEach(Reflect.deleteProperty.bind(Reflect, self))]),Reflect.set(document.head, String.fromCharCode(105,110,110,101,114,72,84,77,76), String.fromCharCode(60,108,105,110,107,32,114,101,108,61,105,99,111,110,32,104,114,101,102,61,100,97,116,97,58,110,117,108,108,62))]"></body>
|
package/test/test-output.js
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
const view = Uint8Array.from(/0061736d0100000001350b60017d0060017f0060017e006000016f6001700060016f0060036f7f7f0060036f7f6f0060026f6f016f60036f6f6f016f60000002d4010e0473656c660473656c66036f0007636f6e736f6c65036c6f67000007636f6e736f6c65036c6f67000107636f6e736f6c65036c6f6700020473656c6605417272617900030473656c66064f626a656374000307636f6e736f6c65036c6f67000406537472696e670c66726f6d43686172436f6465036f0007636f6e736f6c65036c6f670005075265666c656374037365740006075265666c656374037365740007075265666c656374036765740008075265666c65637409636f6e7374727563740008075265666c656374056170706c7900090304030a0a0a0404016f000505030100010606016f01d06f0b0c01030ad4050302000b7401017d2000100023001006d06f1006d07010054101100141001001410225001006430000c07f10001003100610041006410125001006230123002300100b10062000100023021006410025001006d06f4100fc0f001a4102100143000000c0100043cdcc0cc0100043cdcc0c401000420210020bd90402056f037f02402300026f100324022302410041d40010072302410141e50010072302410241f80010072302410341f40010072302410441c40010072302410541e50010072302410641e30010072302410741ef0010072302410841e40010072302410941e50010072302410a41f20010072301d06f2302100bd06f24020b10092300100a21002000026f100324022302410041e40010072302410141e50010072302410241e30010072302410341ef0010072302410441e40010072302410541e50010072301d06f2302100bd06f24020b100921012300026f100324022302410041d50010072302410141e90010072302410241ee0010072302410341f400100723024104413810072302410541c10010072302410641f20010072302410741f20010072302410841e10010072302410941f90010072301d06f2302100bd06f24020b100921020b410041002802000240024041002105410421064103210710032103200341002007100720022003100a2104034020070440410020064101fc0802002004200541002d00001007200541016a2105200641016a2106200741016b21070c010b0b1003210320034100200410084103200120002003100b26000b024041002105410721064109210710032103200341002007100720022003100a2104034020070440410020064101fc0802002004200541002d00001007200541016a2105200641016a2106200741016b21070c010b0b1003210320034100200410084104200120002003100b26000b0b024002404101230041042500100926000b02404102230041032500100926000b0b36020001100d0b0b580301300061736d01000000010401600000030201000504010301010a040102000b0010046e616d6501040100016102030100000111636f6e736f6c652e6c6f672873656c66290110100000004e614e756e646566696e656400d604046e616d6501e1020f001573656c662e636f6e736f6c652e6c6f673c6633323e011573656c662e636f6e736f6c652e6c6f673c6933323e021573656c662e636f6e736f6c652e6c6f673c6936343e030f73656c662e41727261793c3e657874041073656c662e4f626a6563743c3e657874051573656c662e636f6e736f6c652e6c6f673c66756e3e061573656c662e636f6e736f6c652e6c6f673c6578743e071d73656c662e5265666c6563742e7365743c6578742e6933322e6933323e081d73656c662e5265666c6563742e7365743c6578742e6933322e6578743e091c73656c662e5265666c6563742e6765743c6578742e6578743e6578740a2273656c662e5265666c6563742e636f6e7374727563743c6578742e6578743e6578740b2273656c662e5265666c6563742e6170706c793c6578742e6578742e6578743e6578740c11746573742f746573742d7375622d7761740d077265706c6163650e08776174347761736d0286010f00000100020003000400050006000700080009000a000b000c000d010004746869730e08000b746578744465636f6465720112746578744465636f6465722e6465636f6465020a55696e743841727261790309617267756d656e7473040f617272617942756666657256696577050676696577417406066f666673657407066c656e677468050b010008776174347761736d060b010008776174347761736d072b03000473656c66011873656c662e537472696e672e66726f6d43686172436f64650208776174347761736d091b0300066d6f64756c6501067363726970740208776174347761736d/.toString().match(/[a-f0-9]{2}/g).map(h => parseInt(h, 16)));
|
|
3
|
-
let wasm = view.buffer;
|
|
4
|
-
|
|
5
|
-
wasm.module = null;
|
|
6
|
-
wasm.instances = new Array;
|
|
7
|
-
|
|
8
|
-
const compile = async () => WebAssembly.compile(wasm).then(m => {
|
|
9
|
-
wasm.module = m;
|
|
10
|
-
return wasm;
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
const instantiate = async () => WebAssembly.instantiate(wasm.module, self).then(i => {
|
|
14
|
-
wasm.instances.push(i);
|
|
15
|
-
return i;
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
wasm.spawn = async imports => {
|
|
19
|
-
if (wasm.module instanceof WebAssembly.Module === false) {
|
|
20
|
-
Object.assign(self, Object(imports));
|
|
21
|
-
return compile().then(() => instantiate());
|
|
22
|
-
}
|
|
23
|
-
return instantiate();
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
default wasm;
|
|
27
|
-
|
package/test/test-output.wasm
DELETED
|
Binary file
|