webpack/lib/wasm/WasmModuleTemplatePlugin.js

86 lines
2.8 KiB
JavaScript
Raw Normal View History

2017-10-30 20:56:57 +08:00
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const RawSource = require("webpack-sources").RawSource;
const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
2017-10-30 20:56:57 +08:00
class WasmModuleTemplatePlugin {
2017-10-30 20:56:57 +08:00
apply(moduleTemplate) {
2017-12-14 04:35:39 +08:00
moduleTemplate.hooks.content.tap("WasmModuleTemplatePlugin", (moduleSource, module, {
chunk
}) => {
2017-10-30 20:56:57 +08:00
if(module.type && module.type.startsWith("webassembly")) {
if(chunk.canBeInitial())
2018-02-09 18:25:22 +08:00
throw new Error("Sync WebAssembly compilation is not yet implemented");
const generateExports = () => {
if(Array.isArray(module.buildMeta.providedExports) && Array.isArray(module.usedExports)) {
// generate mangled exports
return module.buildMeta.providedExports.map(exp => {
const usedName = module.isUsed(exp);
if(usedName) {
return `${module.exportsArgument}[${JSON.stringify(usedName)}] = instance.exports[${JSON.stringify(exp)}];`;
} else {
return `// unused ${JSON.stringify(exp)} export`;
}
}).join("\n");
} else {
// generate simple export
return `${module.moduleArgument}.exports = instance.exports;`;
}
};
const generateImports = () => {
const depsByRequest = new Map();
for(const dep of module.dependencies) {
if(dep instanceof WebAssemblyImportDependency) {
const request = dep.request;
let array = depsByRequest.get(request);
if(!array) {
depsByRequest.set(request, array = []);
}
const exportName = dep.name;
const usedName = dep.module && dep.module.isUsed(exportName);
array.push({
exportName,
usedName,
module: dep.module
});
}
}
const importsCode = [];
for(const pair of depsByRequest) {
const properties = [];
for(const data of pair[1]) {
properties.push(`\n\t\t${JSON.stringify(data.exportName)}: __webpack_require__(${JSON.stringify(data.module.id)})[${JSON.stringify(data.usedName)}]`);
}
importsCode.push(`\n\t${JSON.stringify(pair[0])}: {${properties.join(",")}\n\t}`);
}
return importsCode.join(",");
2017-12-21 16:33:26 +08:00
};
2017-10-30 20:56:57 +08:00
const source = new RawSource([
"\"use strict\";",
"",
2018-02-09 18:25:22 +08:00
"// Instantiate WebAssembly module",
"var instance = new WebAssembly.Instance(__webpack_require__.w[module.i], {" + generateImports(),
"});",
2017-10-30 20:56:57 +08:00
"",
2018-02-09 18:25:22 +08:00
"// export exports from WebAssembly module",
2017-10-30 20:56:57 +08:00
// TODO rewrite this to getters depending on exports to support circular dependencies
generateExports()
2017-10-30 20:56:57 +08:00
].join("\n"));
return source;
} else {
return moduleSource;
}
});
2017-12-14 04:35:39 +08:00
moduleTemplate.hooks.hash.tap("WasmModuleTemplatePlugin", hash => {
hash.update("WasmModuleTemplatePlugin");
2017-10-30 20:56:57 +08:00
hash.update("1");
});
}
}
module.exports = WasmModuleTemplatePlugin;