diff options
Diffstat (limited to 'node_modules/webpack/lib/wasm/WasmMainTemplatePlugin.js')
-rw-r--r-- | node_modules/webpack/lib/wasm/WasmMainTemplatePlugin.js | 341 |
1 files changed, 0 insertions, 341 deletions
diff --git a/node_modules/webpack/lib/wasm/WasmMainTemplatePlugin.js b/node_modules/webpack/lib/wasm/WasmMainTemplatePlugin.js deleted file mode 100644 index 494c8ec..0000000 --- a/node_modules/webpack/lib/wasm/WasmMainTemplatePlugin.js +++ /dev/null @@ -1,341 +0,0 @@ -/* - MIT License http://www.opensource.org/licenses/mit-license.php - Author Tobias Koppers @sokra -*/ -"use strict"; - -const Template = require("../Template"); -const WebAssemblyUtils = require("./WebAssemblyUtils"); - -/** @typedef {import("../Module")} Module */ -/** @typedef {import("../MainTemplate")} MainTemplate */ - -// Get all wasm modules -const getAllWasmModules = chunk => { - const wasmModules = chunk.getAllAsyncChunks(); - const array = []; - for (const chunk of wasmModules) { - for (const m of chunk.modulesIterable) { - if (m.type.startsWith("webassembly")) { - array.push(m); - } - } - } - - return array; -}; - -/** - * generates the import object function for a module - * @param {Module} module the module - * @param {boolean} mangle mangle imports - * @returns {string} source code - */ -const generateImportObject = (module, mangle) => { - const waitForInstances = new Map(); - const properties = []; - const usedWasmDependencies = WebAssemblyUtils.getUsedDependencies( - module, - mangle - ); - for (const usedDep of usedWasmDependencies) { - const dep = usedDep.dependency; - const importedModule = dep.module; - const exportName = dep.name; - const usedName = importedModule && importedModule.isUsed(exportName); - const description = dep.description; - const direct = dep.onlyDirectImport; - - const module = usedDep.module; - const name = usedDep.name; - - if (direct) { - const instanceVar = `m${waitForInstances.size}`; - waitForInstances.set(instanceVar, importedModule.id); - properties.push({ - module, - name, - value: `${instanceVar}[${JSON.stringify(usedName)}]` - }); - } else { - const params = description.signature.params.map( - (param, k) => "p" + k + param.valtype - ); - - const mod = `installedModules[${JSON.stringify(importedModule.id)}]`; - const func = `${mod}.exports[${JSON.stringify(usedName)}]`; - - properties.push({ - module, - name, - value: Template.asString([ - (importedModule.type.startsWith("webassembly") - ? `${mod} ? ${func} : ` - : "") + `function(${params}) {`, - Template.indent([`return ${func}(${params});`]), - "}" - ]) - }); - } - } - - let importObject; - if (mangle) { - importObject = [ - "return {", - Template.indent([ - properties.map(p => `${JSON.stringify(p.name)}: ${p.value}`).join(",\n") - ]), - "};" - ]; - } else { - const propertiesByModule = new Map(); - for (const p of properties) { - let list = propertiesByModule.get(p.module); - if (list === undefined) { - propertiesByModule.set(p.module, (list = [])); - } - list.push(p); - } - importObject = [ - "return {", - Template.indent([ - Array.from(propertiesByModule, ([module, list]) => { - return Template.asString([ - `${JSON.stringify(module)}: {`, - Template.indent([ - list.map(p => `${JSON.stringify(p.name)}: ${p.value}`).join(",\n") - ]), - "}" - ]); - }).join(",\n") - ]), - "};" - ]; - } - - if (waitForInstances.size === 1) { - const moduleId = Array.from(waitForInstances.values())[0]; - const promise = `installedWasmModules[${JSON.stringify(moduleId)}]`; - const variable = Array.from(waitForInstances.keys())[0]; - return Template.asString([ - `${JSON.stringify(module.id)}: function() {`, - Template.indent([ - `return promiseResolve().then(function() { return ${promise}; }).then(function(${variable}) {`, - Template.indent(importObject), - "});" - ]), - "}," - ]); - } else if (waitForInstances.size > 0) { - const promises = Array.from( - waitForInstances.values(), - id => `installedWasmModules[${JSON.stringify(id)}]` - ).join(", "); - const variables = Array.from( - waitForInstances.keys(), - (name, i) => `${name} = array[${i}]` - ).join(", "); - return Template.asString([ - `${JSON.stringify(module.id)}: function() {`, - Template.indent([ - `return promiseResolve().then(function() { return Promise.all([${promises}]); }).then(function(array) {`, - Template.indent([`var ${variables};`, ...importObject]), - "});" - ]), - "}," - ]); - } else { - return Template.asString([ - `${JSON.stringify(module.id)}: function() {`, - Template.indent(importObject), - "}," - ]); - } -}; - -class WasmMainTemplatePlugin { - constructor({ generateLoadBinaryCode, supportsStreaming, mangleImports }) { - this.generateLoadBinaryCode = generateLoadBinaryCode; - this.supportsStreaming = supportsStreaming; - this.mangleImports = mangleImports; - } - - /** - * @param {MainTemplate} mainTemplate main template - * @returns {void} - */ - apply(mainTemplate) { - mainTemplate.hooks.localVars.tap( - "WasmMainTemplatePlugin", - (source, chunk) => { - const wasmModules = getAllWasmModules(chunk); - if (wasmModules.length === 0) return source; - const importObjects = wasmModules.map(module => { - return generateImportObject(module, this.mangleImports); - }); - return Template.asString([ - source, - "", - "// object to store loaded and loading wasm modules", - "var installedWasmModules = {};", - "", - // This function is used to delay reading the installed wasm module promises - // by a microtask. Sorting them doesn't help because there are egdecases where - // sorting is not possible (modules splitted into different chunks). - // So we not even trying and solve this by a microtask delay. - "function promiseResolve() { return Promise.resolve(); }", - "", - "var wasmImportObjects = {", - Template.indent(importObjects), - "};" - ]); - } - ); - mainTemplate.hooks.requireEnsure.tap( - "WasmMainTemplatePlugin", - (source, chunk, hash) => { - const webassemblyModuleFilename = - mainTemplate.outputOptions.webassemblyModuleFilename; - - const chunkModuleMaps = chunk.getChunkModuleMaps(m => - m.type.startsWith("webassembly") - ); - if (Object.keys(chunkModuleMaps.id).length === 0) return source; - const wasmModuleSrcPath = mainTemplate.getAssetPath( - JSON.stringify(webassemblyModuleFilename), - { - hash: `" + ${mainTemplate.renderCurrentHashCode(hash)} + "`, - hashWithLength: length => - `" + ${mainTemplate.renderCurrentHashCode(hash, length)} + "`, - module: { - id: '" + wasmModuleId + "', - hash: `" + ${JSON.stringify( - chunkModuleMaps.hash - )}[wasmModuleId] + "`, - hashWithLength(length) { - const shortChunkHashMap = Object.create(null); - for (const wasmModuleId of Object.keys(chunkModuleMaps.hash)) { - if (typeof chunkModuleMaps.hash[wasmModuleId] === "string") { - shortChunkHashMap[wasmModuleId] = chunkModuleMaps.hash[ - wasmModuleId - ].substr(0, length); - } - } - return `" + ${JSON.stringify( - shortChunkHashMap - )}[wasmModuleId] + "`; - } - } - } - ); - const createImportObject = content => - this.mangleImports - ? `{ ${JSON.stringify( - WebAssemblyUtils.MANGLED_MODULE - )}: ${content} }` - : content; - return Template.asString([ - source, - "", - "// Fetch + compile chunk loading for webassembly", - "", - `var wasmModules = ${JSON.stringify( - chunkModuleMaps.id - )}[chunkId] || [];`, - "", - "wasmModules.forEach(function(wasmModuleId) {", - Template.indent([ - "var installedWasmModuleData = installedWasmModules[wasmModuleId];", - "", - '// a Promise means "currently loading" or "already loaded".', - "if(installedWasmModuleData)", - Template.indent(["promises.push(installedWasmModuleData);"]), - "else {", - Template.indent([ - `var importObject = wasmImportObjects[wasmModuleId]();`, - `var req = ${this.generateLoadBinaryCode(wasmModuleSrcPath)};`, - "var promise;", - this.supportsStreaming - ? Template.asString([ - "if(importObject instanceof Promise && typeof WebAssembly.compileStreaming === 'function') {", - Template.indent([ - "promise = Promise.all([WebAssembly.compileStreaming(req), importObject]).then(function(items) {", - Template.indent([ - `return WebAssembly.instantiate(items[0], ${createImportObject( - "items[1]" - )});` - ]), - "});" - ]), - "} else if(typeof WebAssembly.instantiateStreaming === 'function') {", - Template.indent([ - `promise = WebAssembly.instantiateStreaming(req, ${createImportObject( - "importObject" - )});` - ]) - ]) - : Template.asString([ - "if(importObject instanceof Promise) {", - Template.indent([ - "var bytesPromise = req.then(function(x) { return x.arrayBuffer(); });", - "promise = Promise.all([", - Template.indent([ - "bytesPromise.then(function(bytes) { return WebAssembly.compile(bytes); }),", - "importObject" - ]), - "]).then(function(items) {", - Template.indent([ - `return WebAssembly.instantiate(items[0], ${createImportObject( - "items[1]" - )});` - ]), - "});" - ]) - ]), - "} else {", - Template.indent([ - "var bytesPromise = req.then(function(x) { return x.arrayBuffer(); });", - "promise = bytesPromise.then(function(bytes) {", - Template.indent([ - `return WebAssembly.instantiate(bytes, ${createImportObject( - "importObject" - )});` - ]), - "});" - ]), - "}", - "promises.push(installedWasmModules[wasmModuleId] = promise.then(function(res) {", - Template.indent([ - `return ${mainTemplate.requireFn}.w[wasmModuleId] = (res.instance || res).exports;` - ]), - "}));" - ]), - "}" - ]), - "});" - ]); - } - ); - mainTemplate.hooks.requireExtensions.tap( - "WasmMainTemplatePlugin", - (source, chunk) => { - if (!chunk.hasModuleInGraph(m => m.type.startsWith("webassembly"))) { - return source; - } - return Template.asString([ - source, - "", - "// object with all WebAssembly.instance exports", - `${mainTemplate.requireFn}.w = {};` - ]); - } - ); - mainTemplate.hooks.hash.tap("WasmMainTemplatePlugin", hash => { - hash.update("WasmMainTemplatePlugin"); - hash.update("2"); - }); - } -} - -module.exports = WasmMainTemplatePlugin; |