-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
67 lines (61 loc) · 2.1 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
function trampoline(name, to) {
return `(function ${name}(...args) {
if (typeof ${to} !== "function") {
throw new Error('${to} expected to be a function');
}
return ${to}(...args);
})`;
}
function generateExports(exports) {
return exports.reduce((code, e) => {
if (e.kind === "function" || e.kind === "memory" || e.kind === "table") {
return (
code +
`module.exports["${e.name}"] = wasminstance.exports["${e.name}"];\n`
);
}
throw new Error("unimplemented export kind: " + e.kind);
}, '');
}
function generateImports(imports, basedir) {
// keep track of module we imported in generated code
const importedModule = {};
return imports.reduce((code, imp) => {
if (imp.kind !== "function") {
throw new Error("unimplemented import kind: " + imp.kind);
}
if (!importedModule[imp.module] && imp.module !== "env") {
code += `jsimports["${imp.module}"] = require(join("${basedir}", "${imp.module}"));\n`;
code += `wasmimports["${imp.module}"] = {}\n`;
importedModule[imp.module] = true;
}
code +=
`wasmimports["${imp.module}"]["${imp.name}"] = ` +
trampoline(imp.name, `jsimports["${imp.module}"]["${imp.name}"]`) +
';\n';
return code;
}, '');
}
require.extensions['.wasm'] = function (module, filename) {
const bin = require('fs').readFileSync(module.filename);
const m = new WebAssembly.Module(bin);
const wasmExports = WebAssembly.Module.exports(m);
const wasmImports = WebAssembly.Module.imports(m);
const { dirname } = require("path");
let code = `
const { join } = require("path");
const { readFileSync } = require("fs");
const bin = readFileSync("${module.filename}");
const m = new WebAssembly.Module(bin);
const wasmimports = {
"env": {
"now": Date.now
}
};
const jsimports = {};
`;
code += generateImports(wasmImports, dirname(filename));
code += `const wasminstance = new WebAssembly.Instance(m, wasmimports);\n`;
code += generateExports(wasmExports);
return module._compile(code, filename);
};