mirror of https://github.com/webpack/webpack.git
feat: try with a Table
This commit is contained in:
parent
faff92c52b
commit
5c6c50bd2e
|
@ -22,6 +22,12 @@ function compose(...fns) {
|
|||
}, value => value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility functions
|
||||
*/
|
||||
const isGlobalImport = moduleImport => moduleImport.descr.type === "GlobalType";
|
||||
const isInstructionOfName = name => instr => instr.id === name;
|
||||
|
||||
/**
|
||||
* Export the start function and removes the start instruction
|
||||
*/
|
||||
|
@ -51,74 +57,109 @@ function rewriteStartFunc(bin) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Replaces global imports by func imports
|
||||
* (which will return the globals at runtime)
|
||||
* Import the WebAssembly.Table used for interop with other modules managed by
|
||||
* Webpack.
|
||||
*
|
||||
* Also needs to update the calls instructions `get_global` and `set_global`
|
||||
* which become function calls.
|
||||
* @param {ArrayBuffer} bin
|
||||
* @returns {ArrayBuffer} bin'
|
||||
*
|
||||
* FIXME(sven): I abrirary choose these names but that might cause conflicts with
|
||||
* the user's code, example if a module is called webpack?
|
||||
*
|
||||
* TODO(sven): what should be the TableDescriptor? We can infer the exact initial
|
||||
* value from the number of imports.
|
||||
*/
|
||||
function rewriteGlobalImports(bin) {
|
||||
debug("rewriteGlobalImports");
|
||||
function addImportInteropTable(bin) {
|
||||
return add(bin, [
|
||||
t.moduleImport("webpack", "interoptable", t.table("anyfunc", t.limits(10)))
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the ModuleImport for globals because they will be reachable throught
|
||||
* the interoptable now.
|
||||
*
|
||||
* @param {ArrayBuffer} bin
|
||||
* @returns {ArrayBuffer} bin'
|
||||
*
|
||||
* FIXME(sven): breaks the non-exported globals because their offset will be
|
||||
* shifted by i-(number of import removed). We can either shift the index or
|
||||
* replace by stub ones (non-imported)?
|
||||
*/
|
||||
function removeImportedGlobals(bin) {
|
||||
return edit(bin, {
|
||||
ModuleImport(path) {
|
||||
if (isGlobalImport(path.node) === true) {
|
||||
debug("remove import", path.node.module, path.node.name);
|
||||
path.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the type definition and update every `get_global` to `call_indirect`.
|
||||
*
|
||||
* FIXME(sven): that also breaks the non-import global since they will be
|
||||
* rewriting to calls
|
||||
*
|
||||
* @param {ArrayBuffer} bin
|
||||
* @returns {ArrayBuffer} bin'
|
||||
*/
|
||||
function rewriteGlobalToInteroptable(bin) {
|
||||
const ast = decode(bin, {
|
||||
ignoreCodeSection: true,
|
||||
ignoreDataSection: true
|
||||
});
|
||||
|
||||
const funcType = t.typeInstructionFunc([], ["i32"]);
|
||||
/**
|
||||
* Add the functypes corresponding to the global imported
|
||||
*/
|
||||
const functypes = [];
|
||||
|
||||
// get next func index
|
||||
let nextFuncindex = 0;
|
||||
t.traverse(ast, {
|
||||
Func() {
|
||||
nextFuncindex++;
|
||||
},
|
||||
|
||||
ModuleImport({ node }) {
|
||||
if (node.descr.type === "Func") {
|
||||
nextFuncindex++;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const funcTypeIndex = t.indexLiteral(nextFuncindex);
|
||||
|
||||
bin = add(bin, [funcType]);
|
||||
|
||||
let importedGlobalIndex = 0;
|
||||
const mapGlobalAndFuncIndex = {};
|
||||
|
||||
bin = edit(bin, {
|
||||
/**
|
||||
* import global of type t1
|
||||
* type = () => t1
|
||||
*/
|
||||
ModuleImport(path) {
|
||||
const { node } = path;
|
||||
if (isGlobalImport(path.node) === true) {
|
||||
const { valtype } = path.node.descr;
|
||||
const functype = t.typeInstructionFunc([], [valtype]);
|
||||
|
||||
// is importing a global
|
||||
if (node.descr.type === "GlobalType") {
|
||||
node.name = "_global_get_" + node.name;
|
||||
|
||||
node.descr = t.funcImportDescr(
|
||||
funcTypeIndex,
|
||||
funcType.functype.params,
|
||||
funcType.functype.results
|
||||
);
|
||||
|
||||
mapGlobalAndFuncIndex[importedGlobalIndex] = funcTypeIndex;
|
||||
|
||||
importedGlobalIndex++;
|
||||
functypes.push(functype);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Update accessers
|
||||
debug("add functypes", functypes.map(x => x.functype));
|
||||
|
||||
bin = add(bin, functypes);
|
||||
|
||||
/**
|
||||
* Rewrite get_global
|
||||
*/
|
||||
const isGetGlobalInstruction = isInstructionOfName("get_global");
|
||||
|
||||
bin = edit(bin, {
|
||||
Instr(path) {
|
||||
const [firstArg] = path.node.args;
|
||||
const funcIndex = mapGlobalAndFuncIndex[firstArg.value];
|
||||
if (isGetGlobalInstruction(path.node) === true) {
|
||||
const [globalIndex] = path.node.args;
|
||||
const functypeIndex = functypes[globalIndex.value];
|
||||
|
||||
debug(`rename get_global ${firstArg.value} to call ${funcIndex.value}`);
|
||||
if (typeof functypeIndex === "undefined") {
|
||||
throw new Error(
|
||||
"Internal failure: can not find the functype for global at index " +
|
||||
globalIndex.value
|
||||
);
|
||||
}
|
||||
|
||||
const newNode = t.callInstruction(funcIndex);
|
||||
path.replaceWith(newNode);
|
||||
const callIndirectInstruction = t.callIndirectInstructionIndex(
|
||||
t.indexLiteral(globalIndex.value)
|
||||
);
|
||||
|
||||
path.replaceWith(callIndirectInstruction);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -126,7 +167,9 @@ function rewriteGlobalImports(bin) {
|
|||
}
|
||||
|
||||
const transform = compose(
|
||||
rewriteGlobalImports,
|
||||
removeImportedGlobals,
|
||||
rewriteGlobalToInteroptable,
|
||||
addImportInteropTable,
|
||||
|
||||
rewriteStartFunc
|
||||
);
|
||||
|
@ -139,7 +182,8 @@ class WebAssemblyGenerator {
|
|||
const newBin = transform(bin);
|
||||
debug("__________________________________________________________");
|
||||
|
||||
// console.log(print(decode(newBin)))
|
||||
// decode(newBin, { dump: true });
|
||||
// console.log(print(decode(newBin)));
|
||||
|
||||
return new RawSource(newBin);
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ class FetchCompileWasmMainTemplatePlugin {
|
|||
}
|
||||
|
||||
if (data.description.type === "GlobalType") {
|
||||
data.exportName = "_global_get_" + data.exportName;
|
||||
data.exportName = "_global_get_" + data.exportName;
|
||||
|
||||
result = `__webpack_require__(${JSON.stringify(
|
||||
data.module.id
|
||||
|
@ -99,6 +99,10 @@ class FetchCompileWasmMainTemplatePlugin {
|
|||
`\n\t${JSON.stringify(pair[0])}: {${properties.join(",")}\n\t}`
|
||||
);
|
||||
}
|
||||
|
||||
// Add interoptable
|
||||
importsCode.push(`\n\t"webpack": { "interoptable": interoptable }\n\t`);
|
||||
|
||||
return (
|
||||
JSON.stringify(module.id) + ": {" + importsCode.join(",") + "\n}"
|
||||
);
|
||||
|
@ -142,6 +146,12 @@ class FetchCompileWasmMainTemplatePlugin {
|
|||
"",
|
||||
"// Fetch + compile chunk loading for webassembly",
|
||||
"",
|
||||
"var interoptable = new WebAssembly.Table({",
|
||||
Template.indent(["element: 'anyfunc',", "initial: 0"]),
|
||||
"})",
|
||||
"",
|
||||
"interoptable.set(0, () => console.log('called'))",
|
||||
"",
|
||||
"var importObjects = {",
|
||||
Template.indent([importObjects]),
|
||||
"}",
|
||||
|
|
|
@ -5,9 +5,10 @@
|
|||
"description": "Packs CommonJs/AMD modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand. Support loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@webassemblyjs/ast": "^1.0.0",
|
||||
"@webassemblyjs/wasm-edit": "^1.1.2-y.0",
|
||||
"@webassemblyjs/ast": "1.1.2-y.6",
|
||||
"@webassemblyjs/wasm-edit": "1.1.2-y.6",
|
||||
"@webassemblyjs/wasm-parser": "^1.0.0",
|
||||
"@webassemblyjs/wast-printer": "^1.1.2-y.0",
|
||||
"acorn": "^5.0.0",
|
||||
"acorn-dynamic-import": "^3.0.0",
|
||||
"ajv": "^6.1.0",
|
||||
|
|
102
yarn.lock
102
yarn.lock
|
@ -16,7 +16,7 @@
|
|||
esutils "^2.0.2"
|
||||
js-tokens "^3.0.0"
|
||||
|
||||
"@webassemblyjs/ast@1.0.0", "@webassemblyjs/ast@^1.0.0":
|
||||
"@webassemblyjs/ast@1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.0.0.tgz#e6953dd785b6827ac5ce2fab479b1358f35f7df4"
|
||||
dependencies:
|
||||
|
@ -32,9 +32,17 @@
|
|||
webassembly-floating-point-hex-parser "0.1.2"
|
||||
webassemblyjs "1.1.2-y.0"
|
||||
|
||||
"@webassemblyjs/helper-buffer@1.1.2-y.0":
|
||||
version "1.1.2-y.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.1.2-y.0.tgz#25e8b7d133be147fe70f522263491da2b36f5259"
|
||||
"@webassemblyjs/ast@1.1.2-y.6":
|
||||
version "1.1.2-y.6"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.1.2-y.6.tgz#48cd46498cbcf3ad0873c311a68ef11c6bd98ef1"
|
||||
dependencies:
|
||||
"@webassemblyjs/wast-parser" "1.1.2-y.6"
|
||||
webassembly-floating-point-hex-parser "0.1.2"
|
||||
webassemblyjs "1.1.2-y.6"
|
||||
|
||||
"@webassemblyjs/helper-buffer@1.1.2-y.6":
|
||||
version "1.1.2-y.6"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.1.2-y.6.tgz#1f0e88d29c61cf8e5c310e612ddfc7af41c3d53f"
|
||||
|
||||
"@webassemblyjs/helper-leb128@1.1.2-y.0":
|
||||
version "1.1.2-y.0"
|
||||
|
@ -42,37 +50,47 @@
|
|||
dependencies:
|
||||
leb "^0.3.0"
|
||||
|
||||
"@webassemblyjs/helper-leb128@1.1.2-y.6":
|
||||
version "1.1.2-y.6"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-leb128/-/helper-leb128-1.1.2-y.6.tgz#ad48ed8e91cd291a5daab1cf9b157ce68d4725b4"
|
||||
dependencies:
|
||||
leb "^0.3.0"
|
||||
|
||||
"@webassemblyjs/helper-wasm-bytecode@1.1.2-y.0":
|
||||
version "1.1.2-y.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.1.2-y.0.tgz#d50c40200fc5ab6a4ab0c080f9ff4c815c2f0302"
|
||||
|
||||
"@webassemblyjs/helper-wasm-section@1.1.2-y.0":
|
||||
version "1.1.2-y.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.1.2-y.0.tgz#28acfd9c1f1aeb3864031f15b4398f9c9ffac8dc"
|
||||
dependencies:
|
||||
"@webassemblyjs/ast" "1.1.2-y.0"
|
||||
"@webassemblyjs/helper-buffer" "1.1.2-y.0"
|
||||
"@webassemblyjs/helper-wasm-bytecode" "1.1.2-y.0"
|
||||
"@webassemblyjs/wasm-gen" "1.1.2-y.0"
|
||||
"@webassemblyjs/helper-wasm-bytecode@1.1.2-y.6":
|
||||
version "1.1.2-y.6"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.1.2-y.6.tgz#52f68cc36eba2f2e90ab98d602186a1feb37887c"
|
||||
|
||||
"@webassemblyjs/wasm-edit@^1.1.2-y.0":
|
||||
version "1.1.2-y.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.1.2-y.0.tgz#9145814a40b4e1ef023a6b644dab8832d7c62531"
|
||||
"@webassemblyjs/helper-wasm-section@1.1.2-y.6":
|
||||
version "1.1.2-y.6"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.1.2-y.6.tgz#9bd6fccdb8955b0f847a5f11b8672634298ea494"
|
||||
dependencies:
|
||||
"@webassemblyjs/ast" "1.1.2-y.0"
|
||||
"@webassemblyjs/helper-buffer" "1.1.2-y.0"
|
||||
"@webassemblyjs/helper-wasm-bytecode" "1.1.2-y.0"
|
||||
"@webassemblyjs/helper-wasm-section" "1.1.2-y.0"
|
||||
"@webassemblyjs/wasm-gen" "1.1.2-y.0"
|
||||
"@webassemblyjs/wasm-parser" "1.1.2-y.0"
|
||||
"@webassemblyjs/ast" "1.1.2-y.6"
|
||||
"@webassemblyjs/helper-buffer" "1.1.2-y.6"
|
||||
"@webassemblyjs/helper-wasm-bytecode" "1.1.2-y.6"
|
||||
"@webassemblyjs/wasm-gen" "1.1.2-y.6"
|
||||
|
||||
"@webassemblyjs/wasm-gen@1.1.2-y.0":
|
||||
version "1.1.2-y.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.1.2-y.0.tgz#38f103f25eff059b0a2c436e7e345b0bd216fff5"
|
||||
"@webassemblyjs/wasm-edit@1.1.2-y.6":
|
||||
version "1.1.2-y.6"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.1.2-y.6.tgz#8ae7646094f9aa3ae2c4cb8f5bff42ce1c2d6bba"
|
||||
dependencies:
|
||||
"@webassemblyjs/ast" "1.1.2-y.0"
|
||||
"@webassemblyjs/helper-leb128" "1.1.2-y.0"
|
||||
"@webassemblyjs/helper-wasm-bytecode" "1.1.2-y.0"
|
||||
"@webassemblyjs/ast" "1.1.2-y.6"
|
||||
"@webassemblyjs/helper-buffer" "1.1.2-y.6"
|
||||
"@webassemblyjs/helper-wasm-bytecode" "1.1.2-y.6"
|
||||
"@webassemblyjs/helper-wasm-section" "1.1.2-y.6"
|
||||
"@webassemblyjs/wasm-gen" "1.1.2-y.6"
|
||||
"@webassemblyjs/wasm-parser" "1.1.2-y.6"
|
||||
|
||||
"@webassemblyjs/wasm-gen@1.1.2-y.6":
|
||||
version "1.1.2-y.6"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.1.2-y.6.tgz#ea960b44712303b22d6a75d176f56109ada90b00"
|
||||
dependencies:
|
||||
"@webassemblyjs/ast" "1.1.2-y.6"
|
||||
"@webassemblyjs/helper-leb128" "1.1.2-y.6"
|
||||
"@webassemblyjs/helper-wasm-bytecode" "1.1.2-y.6"
|
||||
|
||||
"@webassemblyjs/wasm-parser@1.0.0", "@webassemblyjs/wasm-parser@^1.0.0":
|
||||
version "1.0.0"
|
||||
|
@ -92,6 +110,16 @@
|
|||
"@webassemblyjs/wasm-parser" "1.1.2-y.0"
|
||||
webassemblyjs "1.1.2-y.0"
|
||||
|
||||
"@webassemblyjs/wasm-parser@1.1.2-y.6":
|
||||
version "1.1.2-y.6"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.1.2-y.6.tgz#029ca09e016280cfcee7306989c32f8202a31914"
|
||||
dependencies:
|
||||
"@webassemblyjs/ast" "1.1.2-y.6"
|
||||
"@webassemblyjs/helper-leb128" "1.1.2-y.6"
|
||||
"@webassemblyjs/helper-wasm-bytecode" "1.1.2-y.6"
|
||||
"@webassemblyjs/wasm-parser" "1.1.2-y.6"
|
||||
webassemblyjs "1.1.2-y.6"
|
||||
|
||||
"@webassemblyjs/wast-parser@1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.0.0.tgz#d874e2dcb1726d31868518be7807f8f2ff358425"
|
||||
|
@ -112,6 +140,16 @@
|
|||
webassembly-floating-point-hex-parser "0.1.2"
|
||||
webassemblyjs "1.1.2-y.0"
|
||||
|
||||
"@webassemblyjs/wast-parser@1.1.2-y.6":
|
||||
version "1.1.2-y.6"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.1.2-y.6.tgz#e32a0f14861e9bf9c8e1a720b25f36a928dfd802"
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.0.0-beta.36"
|
||||
"@webassemblyjs/ast" "1.1.2-y.6"
|
||||
long "^3.2.0"
|
||||
webassembly-floating-point-hex-parser "0.1.2"
|
||||
webassemblyjs "1.1.2-y.6"
|
||||
|
||||
"@webassemblyjs/wast-printer@^1.1.2-y.0":
|
||||
version "1.1.2-y.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.1.2-y.0.tgz#9212f81e9e8b25a7d35f51d97f43b64c1e7eb655"
|
||||
|
@ -4783,6 +4821,16 @@ webassemblyjs@1.1.2-y.0:
|
|||
long "^3.2.0"
|
||||
webassembly-floating-point-hex-parser "0.1.2"
|
||||
|
||||
webassemblyjs@1.1.2-y.6:
|
||||
version "1.1.2-y.6"
|
||||
resolved "https://registry.yarnpkg.com/webassemblyjs/-/webassemblyjs-1.1.2-y.6.tgz#6cf604bf52ecf7b2449ff370f3eb37ced001689e"
|
||||
dependencies:
|
||||
"@webassemblyjs/ast" "1.1.2-y.6"
|
||||
"@webassemblyjs/wasm-parser" "1.1.2-y.6"
|
||||
"@webassemblyjs/wast-parser" "1.1.2-y.6"
|
||||
long "^3.2.0"
|
||||
webassembly-floating-point-hex-parser "0.1.2"
|
||||
|
||||
webpack-dev-middleware@^1.9.0:
|
||||
version "1.12.2"
|
||||
resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-1.12.2.tgz#f8fc1120ce3b4fc5680ceecb43d777966b21105e"
|
||||
|
|
Loading…
Reference in New Issue