summaryrefslogtreecommitdiff
path: root/node_modules/webpack/lib/wasm-sync
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/webpack/lib/wasm-sync')
-rw-r--r--node_modules/webpack/lib/wasm-sync/UnsupportedWebAssemblyFeatureError.js16
-rw-r--r--node_modules/webpack/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js403
-rw-r--r--node_modules/webpack/lib/wasm-sync/WasmFinalizeExportsPlugin.js93
-rw-r--r--node_modules/webpack/lib/wasm-sync/WebAssemblyGenerator.js515
-rw-r--r--node_modules/webpack/lib/wasm-sync/WebAssemblyInInitialChunkError.js106
-rw-r--r--node_modules/webpack/lib/wasm-sync/WebAssemblyJavascriptGenerator.js216
-rw-r--r--node_modules/webpack/lib/wasm-sync/WebAssemblyModulesPlugin.js152
-rw-r--r--node_modules/webpack/lib/wasm-sync/WebAssemblyParser.js203
-rw-r--r--node_modules/webpack/lib/wasm-sync/WebAssemblyUtils.js65
9 files changed, 1769 insertions, 0 deletions
diff --git a/node_modules/webpack/lib/wasm-sync/UnsupportedWebAssemblyFeatureError.js b/node_modules/webpack/lib/wasm-sync/UnsupportedWebAssemblyFeatureError.js
new file mode 100644
index 00000000..5174862c
--- /dev/null
+++ b/node_modules/webpack/lib/wasm-sync/UnsupportedWebAssemblyFeatureError.js
@@ -0,0 +1,16 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const WebpackError = require("../WebpackError");
+
+module.exports = class UnsupportedWebAssemblyFeatureError extends WebpackError {
+ /** @param {string} message Error message */
+ constructor(message) {
+ super(message);
+ this.name = "UnsupportedWebAssemblyFeatureError";
+ this.hideStack = true;
+ }
+};
diff --git a/node_modules/webpack/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js b/node_modules/webpack/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js
new file mode 100644
index 00000000..d5265c96
--- /dev/null
+++ b/node_modules/webpack/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js
@@ -0,0 +1,403 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+const { compareModulesByIdentifier } = require("../util/comparators");
+const WebAssemblyUtils = require("./WebAssemblyUtils");
+
+/** @typedef {import("@webassemblyjs/ast").Signature} Signature */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+
+// TODO webpack 6 remove the whole folder
+
+// Get all wasm modules
+/**
+ * @param {ModuleGraph} moduleGraph the module graph
+ * @param {ChunkGraph} chunkGraph the chunk graph
+ * @param {Chunk} chunk the chunk
+ * @returns {Module[]} all wasm modules
+ */
+const getAllWasmModules = (moduleGraph, chunkGraph, chunk) => {
+ const wasmModules = chunk.getAllAsyncChunks();
+ const array = [];
+ for (const chunk of wasmModules) {
+ for (const m of chunkGraph.getOrderedChunkModulesIterable(
+ chunk,
+ compareModulesByIdentifier
+ )) {
+ if (m.type.startsWith("webassembly")) {
+ array.push(m);
+ }
+ }
+ }
+
+ return array;
+};
+
+/**
+ * generates the import object function for a module
+ * @param {ChunkGraph} chunkGraph the chunk graph
+ * @param {Module} module the module
+ * @param {boolean | undefined} mangle mangle imports
+ * @param {string[]} declarations array where declarations are pushed to
+ * @param {RuntimeSpec} runtime the runtime
+ * @returns {string} source code
+ */
+const generateImportObject = (
+ chunkGraph,
+ module,
+ mangle,
+ declarations,
+ runtime
+) => {
+ const moduleGraph = chunkGraph.moduleGraph;
+ const waitForInstances = new Map();
+ const properties = [];
+ const usedWasmDependencies = WebAssemblyUtils.getUsedDependencies(
+ moduleGraph,
+ module,
+ mangle
+ );
+ for (const usedDep of usedWasmDependencies) {
+ const dep = usedDep.dependency;
+ const importedModule = moduleGraph.getModule(dep);
+ const exportName = dep.name;
+ const usedName =
+ importedModule &&
+ moduleGraph
+ .getExportsInfo(importedModule)
+ .getUsedName(exportName, runtime);
+ 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, chunkGraph.getModuleId(importedModule));
+ properties.push({
+ module,
+ name,
+ value: `${instanceVar}[${JSON.stringify(usedName)}]`
+ });
+ } else {
+ const params =
+ /** @type {Signature} */
+ (description.signature).params.map(
+ (param, k) => "p" + k + param.valtype
+ );
+
+ const mod = `${RuntimeGlobals.moduleCache}[${JSON.stringify(
+ chunkGraph.getModuleId(importedModule)
+ )}]`;
+ const modExports = `${mod}.exports`;
+
+ const cache = `wasmImportedFuncCache${declarations.length}`;
+ declarations.push(`var ${cache};`);
+
+ properties.push({
+ module,
+ name,
+ value: Template.asString([
+ (importedModule.type.startsWith("webassembly")
+ ? `${mod} ? ${modExports}[${JSON.stringify(usedName)}] : `
+ : "") + `function(${params}) {`,
+ Template.indent([
+ `if(${cache} === undefined) ${cache} = ${modExports};`,
+ `return ${cache}[${JSON.stringify(usedName)}](${params});`
+ ]),
+ "}"
+ ])
+ });
+ }
+ }
+
+ let importObject;
+ if (mangle) {
+ importObject = [
+ "return {",
+ Template.indent([
+ properties.map(p => `${JSON.stringify(p.name)}: ${p.value}`).join(",\n")
+ ]),
+ "};"
+ ];
+ } else {
+ /** @type {Map<string, Array<{ name: string, value: string }>>} */
+ 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")
+ ]),
+ "};"
+ ];
+ }
+
+ const moduleIdStringified = JSON.stringify(chunkGraph.getModuleId(module));
+ 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([
+ `${moduleIdStringified}: 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([
+ `${moduleIdStringified}: function() {`,
+ Template.indent([
+ `return promiseResolve().then(function() { return Promise.all([${promises}]); }).then(function(array) {`,
+ Template.indent([`var ${variables};`, ...importObject]),
+ "});"
+ ]),
+ "},"
+ ]);
+ } else {
+ return Template.asString([
+ `${moduleIdStringified}: function() {`,
+ Template.indent(importObject),
+ "},"
+ ]);
+ }
+};
+
+/**
+ * @typedef {Object} WasmChunkLoadingRuntimeModuleOptions
+ * @property {(path: string) => string} generateLoadBinaryCode
+ * @property {boolean} [supportsStreaming]
+ * @property {boolean} [mangleImports]
+ * @property {Set<string>} runtimeRequirements
+ */
+
+class WasmChunkLoadingRuntimeModule extends RuntimeModule {
+ /**
+ * @param {WasmChunkLoadingRuntimeModuleOptions} options options
+ */
+ constructor({
+ generateLoadBinaryCode,
+ supportsStreaming,
+ mangleImports,
+ runtimeRequirements
+ }) {
+ super("wasm chunk loading", RuntimeModule.STAGE_ATTACH);
+ this.generateLoadBinaryCode = generateLoadBinaryCode;
+ this.supportsStreaming = supportsStreaming;
+ this.mangleImports = mangleImports;
+ this._runtimeRequirements = runtimeRequirements;
+ }
+
+ /**
+ * @returns {string | null} runtime code
+ */
+ generate() {
+ const fn = RuntimeGlobals.ensureChunkHandlers;
+ const withHmr = this._runtimeRequirements.has(
+ RuntimeGlobals.hmrDownloadUpdateHandlers
+ );
+ const compilation = /** @type {Compilation} */ (this.compilation);
+ const { moduleGraph, outputOptions } = compilation;
+ const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph);
+ const chunk = /** @type {Chunk} */ (this.chunk);
+ const wasmModules = getAllWasmModules(moduleGraph, chunkGraph, chunk);
+ const { mangleImports } = this;
+ /** @type {string[]} */
+ const declarations = [];
+ const importObjects = wasmModules.map(module => {
+ return generateImportObject(
+ chunkGraph,
+ module,
+ mangleImports,
+ declarations,
+ chunk.runtime
+ );
+ });
+ const chunkModuleIdMap = chunkGraph.getChunkModuleIdMap(chunk, m =>
+ m.type.startsWith("webassembly")
+ );
+ /**
+ * @param {string} content content
+ * @returns {string} created import object
+ */
+ const createImportObject = content =>
+ mangleImports
+ ? `{ ${JSON.stringify(WebAssemblyUtils.MANGLED_MODULE)}: ${content} }`
+ : content;
+ const wasmModuleSrcPath = compilation.getPath(
+ JSON.stringify(outputOptions.webassemblyModuleFilename),
+ {
+ hash: `" + ${RuntimeGlobals.getFullHash}() + "`,
+ hashWithLength: length =>
+ `" + ${RuntimeGlobals.getFullHash}}().slice(0, ${length}) + "`,
+ module: {
+ id: '" + wasmModuleId + "',
+ hash: `" + ${JSON.stringify(
+ chunkGraph.getChunkModuleRenderedHashMap(chunk, m =>
+ m.type.startsWith("webassembly")
+ )
+ )}[chunkId][wasmModuleId] + "`,
+ hashWithLength(length) {
+ return `" + ${JSON.stringify(
+ chunkGraph.getChunkModuleRenderedHashMap(
+ chunk,
+ m => m.type.startsWith("webassembly"),
+ length
+ )
+ )}[chunkId][wasmModuleId] + "`;
+ }
+ },
+ runtime: chunk.runtime
+ }
+ );
+
+ const stateExpression = withHmr
+ ? `${RuntimeGlobals.hmrRuntimeStatePrefix}_wasm`
+ : undefined;
+
+ return Template.asString([
+ "// object to store loaded and loading wasm modules",
+ `var installedWasmModules = ${
+ stateExpression ? `${stateExpression} = ${stateExpression} || ` : ""
+ }{};`,
+ "",
+ // This function is used to delay reading the installed wasm module promises
+ // by a microtask. Sorting them doesn't help because there are edge cases 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(); }",
+ "",
+ Template.asString(declarations),
+ "var wasmImportObjects = {",
+ Template.indent(importObjects),
+ "};",
+ "",
+ `var wasmModuleMap = ${JSON.stringify(
+ chunkModuleIdMap,
+ undefined,
+ "\t"
+ )};`,
+ "",
+ "// object with all WebAssembly.instance exports",
+ `${RuntimeGlobals.wasmInstances} = {};`,
+ "",
+ "// Fetch + compile chunk loading for webassembly",
+ `${fn}.wasm = function(chunkId, promises) {`,
+ Template.indent([
+ "",
+ `var wasmModules = wasmModuleMap[chunkId] || [];`,
+ "",
+ "wasmModules.forEach(function(wasmModuleId, idx) {",
+ 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 && typeof importObject.then === 'function' && 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 && typeof importObject.then === 'function') {",
+ 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 ${RuntimeGlobals.wasmInstances}[wasmModuleId] = (res.instance || res).exports;`
+ ]),
+ "}));"
+ ]),
+ "}"
+ ]),
+ "});"
+ ]),
+ "};"
+ ]);
+ }
+}
+
+module.exports = WasmChunkLoadingRuntimeModule;
diff --git a/node_modules/webpack/lib/wasm-sync/WasmFinalizeExportsPlugin.js b/node_modules/webpack/lib/wasm-sync/WasmFinalizeExportsPlugin.js
new file mode 100644
index 00000000..7e566879
--- /dev/null
+++ b/node_modules/webpack/lib/wasm-sync/WasmFinalizeExportsPlugin.js
@@ -0,0 +1,93 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const formatLocation = require("../formatLocation");
+const UnsupportedWebAssemblyFeatureError = require("./UnsupportedWebAssemblyFeatureError");
+
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+
+class WasmFinalizeExportsPlugin {
+ /**
+ * Apply the plugin
+ * @param {Compiler} compiler the compiler instance
+ * @returns {void}
+ */
+ apply(compiler) {
+ compiler.hooks.compilation.tap("WasmFinalizeExportsPlugin", compilation => {
+ compilation.hooks.finishModules.tap(
+ "WasmFinalizeExportsPlugin",
+ modules => {
+ for (const module of modules) {
+ // 1. if a WebAssembly module
+ if (module.type.startsWith("webassembly") === true) {
+ const jsIncompatibleExports =
+ /** @type {BuildMeta} */
+ (module.buildMeta).jsIncompatibleExports;
+
+ if (jsIncompatibleExports === undefined) {
+ continue;
+ }
+
+ for (const connection of compilation.moduleGraph.getIncomingConnections(
+ module
+ )) {
+ // 2. is active and referenced by a non-WebAssembly module
+ if (
+ connection.isTargetActive(undefined) &&
+ /** @type {Module} */
+ (connection.originModule).type.startsWith("webassembly") ===
+ false
+ ) {
+ const referencedExports =
+ compilation.getDependencyReferencedExports(
+ /** @type {Dependency} */ (connection.dependency),
+ undefined
+ );
+
+ for (const info of referencedExports) {
+ const names = Array.isArray(info) ? info : info.name;
+ if (names.length === 0) continue;
+ const name = names[0];
+ if (typeof name === "object") continue;
+ // 3. and uses a func with an incompatible JS signature
+ if (
+ Object.prototype.hasOwnProperty.call(
+ jsIncompatibleExports,
+ name
+ )
+ ) {
+ // 4. error
+ const error = new UnsupportedWebAssemblyFeatureError(
+ `Export "${name}" with ${jsIncompatibleExports[name]} can only be used for direct wasm to wasm dependencies\n` +
+ `It's used from ${
+ /** @type {Module} */
+ (connection.originModule).readableIdentifier(
+ compilation.requestShortener
+ )
+ } at ${formatLocation(
+ /** @type {Dependency} */ (connection.dependency)
+ .loc
+ )}.`
+ );
+ error.module = module;
+ compilation.errors.push(error);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ );
+ });
+ }
+}
+
+module.exports = WasmFinalizeExportsPlugin;
diff --git a/node_modules/webpack/lib/wasm-sync/WebAssemblyGenerator.js b/node_modules/webpack/lib/wasm-sync/WebAssemblyGenerator.js
new file mode 100644
index 00000000..4c0bb031
--- /dev/null
+++ b/node_modules/webpack/lib/wasm-sync/WebAssemblyGenerator.js
@@ -0,0 +1,515 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { RawSource } = require("webpack-sources");
+const Generator = require("../Generator");
+const WebAssemblyUtils = require("./WebAssemblyUtils");
+
+const t = require("@webassemblyjs/ast");
+const { moduleContextFromModuleAST } = require("@webassemblyjs/ast");
+const { editWithAST, addWithAST } = require("@webassemblyjs/wasm-edit");
+const { decode } = require("@webassemblyjs/wasm-parser");
+
+const WebAssemblyExportImportedDependency = require("../dependencies/WebAssemblyExportImportedDependency");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../DependencyTemplates")} DependencyTemplates */
+/** @typedef {import("../Generator").GenerateContext} GenerateContext */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../NormalModule")} NormalModule */
+/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+/** @typedef {import("./WebAssemblyUtils").UsedWasmDependency} UsedWasmDependency */
+
+/**
+ * @typedef {(buf: ArrayBuffer) => ArrayBuffer} ArrayBufferTransform
+ */
+
+/**
+ * @template T
+ * @param {Function[]} fns transforms
+ * @returns {Function} composed transform
+ */
+const compose = (...fns) => {
+ return fns.reduce(
+ (prevFn, nextFn) => {
+ return value => nextFn(prevFn(value));
+ },
+ value => value
+ );
+};
+
+/**
+ * Removes the start instruction
+ *
+ * @param {Object} state unused state
+ * @returns {ArrayBufferTransform} transform
+ */
+const removeStartFunc = state => bin => {
+ return editWithAST(state.ast, bin, {
+ Start(path) {
+ path.remove();
+ }
+ });
+};
+
+/**
+ * Get imported globals
+ *
+ * @param {Object} ast Module's AST
+ * @returns {t.ModuleImport[]} - nodes
+ */
+const getImportedGlobals = ast => {
+ /** @type {t.ModuleImport[]} */
+ const importedGlobals = [];
+
+ t.traverse(ast, {
+ ModuleImport({ node }) {
+ if (t.isGlobalType(node.descr)) {
+ importedGlobals.push(node);
+ }
+ }
+ });
+
+ return importedGlobals;
+};
+
+/**
+ * Get the count for imported func
+ *
+ * @param {Object} ast Module's AST
+ * @returns {Number} - count
+ */
+const getCountImportedFunc = ast => {
+ let count = 0;
+
+ t.traverse(ast, {
+ ModuleImport({ node }) {
+ if (t.isFuncImportDescr(node.descr)) {
+ count++;
+ }
+ }
+ });
+
+ return count;
+};
+
+/**
+ * Get next type index
+ *
+ * @param {Object} ast Module's AST
+ * @returns {t.Index} - index
+ */
+const getNextTypeIndex = ast => {
+ const typeSectionMetadata = t.getSectionMetadata(ast, "type");
+
+ if (typeSectionMetadata === undefined) {
+ return t.indexLiteral(0);
+ }
+
+ return t.indexLiteral(typeSectionMetadata.vectorOfSize.value);
+};
+
+/**
+ * Get next func index
+ *
+ * The Func section metadata provide informations for implemented funcs
+ * in order to have the correct index we shift the index by number of external
+ * functions.
+ *
+ * @param {Object} ast Module's AST
+ * @param {Number} countImportedFunc number of imported funcs
+ * @returns {t.Index} - index
+ */
+const getNextFuncIndex = (ast, countImportedFunc) => {
+ const funcSectionMetadata = t.getSectionMetadata(ast, "func");
+
+ if (funcSectionMetadata === undefined) {
+ return t.indexLiteral(0 + countImportedFunc);
+ }
+
+ const vectorOfSize = funcSectionMetadata.vectorOfSize.value;
+
+ return t.indexLiteral(vectorOfSize + countImportedFunc);
+};
+
+/**
+ * Creates an init instruction for a global type
+ * @param {t.GlobalType} globalType the global type
+ * @returns {t.Instruction} init expression
+ */
+const createDefaultInitForGlobal = globalType => {
+ if (globalType.valtype[0] === "i") {
+ // create NumberLiteral global initializer
+ return t.objectInstruction("const", globalType.valtype, [
+ t.numberLiteralFromRaw(66)
+ ]);
+ } else if (globalType.valtype[0] === "f") {
+ // create FloatLiteral global initializer
+ return t.objectInstruction("const", globalType.valtype, [
+ t.floatLiteral(66, false, false, "66")
+ ]);
+ } else {
+ throw new Error("unknown type: " + globalType.valtype);
+ }
+};
+
+/**
+ * Rewrite the import globals:
+ * - removes the ModuleImport instruction
+ * - injects at the same offset a mutable global of the same type
+ *
+ * Since the imported globals are before the other global declarations, our
+ * indices will be preserved.
+ *
+ * Note that globals will become mutable.
+ *
+ * @param {Object} state unused state
+ * @returns {ArrayBufferTransform} transform
+ */
+const rewriteImportedGlobals = state => bin => {
+ const additionalInitCode = state.additionalInitCode;
+ /** @type {Array<t.Global>} */
+ const newGlobals = [];
+
+ bin = editWithAST(state.ast, bin, {
+ ModuleImport(path) {
+ if (t.isGlobalType(path.node.descr)) {
+ const globalType = path.node.descr;
+
+ globalType.mutability = "var";
+
+ const init = [
+ createDefaultInitForGlobal(globalType),
+ t.instruction("end")
+ ];
+
+ newGlobals.push(t.global(globalType, init));
+
+ path.remove();
+ }
+ },
+
+ // in order to preserve non-imported global's order we need to re-inject
+ // those as well
+ Global(path) {
+ const { node } = path;
+ const [init] = node.init;
+
+ if (init.id === "get_global") {
+ node.globalType.mutability = "var";
+
+ const initialGlobalIdx = init.args[0];
+
+ node.init = [
+ createDefaultInitForGlobal(node.globalType),
+ t.instruction("end")
+ ];
+
+ additionalInitCode.push(
+ /**
+ * get_global in global initializer only works for imported globals.
+ * They have the same indices as the init params, so use the
+ * same index.
+ */
+ t.instruction("get_local", [initialGlobalIdx]),
+ t.instruction("set_global", [t.indexLiteral(newGlobals.length)])
+ );
+ }
+
+ newGlobals.push(node);
+
+ path.remove();
+ }
+ });
+
+ // Add global declaration instructions
+ return addWithAST(state.ast, bin, newGlobals);
+};
+
+/**
+ * Rewrite the export names
+ * @param {Object} state state
+ * @param {Object} state.ast Module's ast
+ * @param {Module} state.module Module
+ * @param {ModuleGraph} state.moduleGraph module graph
+ * @param {Set<string>} state.externalExports Module
+ * @param {RuntimeSpec} state.runtime runtime
+ * @returns {ArrayBufferTransform} transform
+ */
+const rewriteExportNames =
+ ({ ast, moduleGraph, module, externalExports, runtime }) =>
+ bin => {
+ return editWithAST(ast, bin, {
+ ModuleExport(path) {
+ const isExternal = externalExports.has(path.node.name);
+ if (isExternal) {
+ path.remove();
+ return;
+ }
+ const usedName = moduleGraph
+ .getExportsInfo(module)
+ .getUsedName(path.node.name, runtime);
+ if (!usedName) {
+ path.remove();
+ return;
+ }
+ path.node.name = usedName;
+ }
+ });
+ };
+
+/**
+ * Mangle import names and modules
+ * @param {Object} state state
+ * @param {Object} state.ast Module's ast
+ * @param {Map<string, UsedWasmDependency>} state.usedDependencyMap mappings to mangle names
+ * @returns {ArrayBufferTransform} transform
+ */
+const rewriteImports =
+ ({ ast, usedDependencyMap }) =>
+ bin => {
+ return editWithAST(ast, bin, {
+ ModuleImport(path) {
+ const result = usedDependencyMap.get(
+ path.node.module + ":" + path.node.name
+ );
+
+ if (result !== undefined) {
+ path.node.module = result.module;
+ path.node.name = result.name;
+ }
+ }
+ });
+ };
+
+/**
+ * Add an init function.
+ *
+ * The init function fills the globals given input arguments.
+ *
+ * @param {Object} state transformation state
+ * @param {Object} state.ast Module's ast
+ * @param {t.Identifier} state.initFuncId identifier of the init function
+ * @param {t.Index} state.startAtFuncOffset index of the start function
+ * @param {t.ModuleImport[]} state.importedGlobals list of imported globals
+ * @param {t.Instruction[]} state.additionalInitCode list of addition instructions for the init function
+ * @param {t.Index} state.nextFuncIndex index of the next function
+ * @param {t.Index} state.nextTypeIndex index of the next type
+ * @returns {ArrayBufferTransform} transform
+ */
+const addInitFunction =
+ ({
+ ast,
+ initFuncId,
+ startAtFuncOffset,
+ importedGlobals,
+ additionalInitCode,
+ nextFuncIndex,
+ nextTypeIndex
+ }) =>
+ bin => {
+ const funcParams = importedGlobals.map(importedGlobal => {
+ // used for debugging
+ const id = t.identifier(
+ `${importedGlobal.module}.${importedGlobal.name}`
+ );
+
+ return t.funcParam(
+ /** @type {string} */ (importedGlobal.descr.valtype),
+ id
+ );
+ });
+
+ const funcBody = [];
+ importedGlobals.forEach((importedGlobal, index) => {
+ const args = [t.indexLiteral(index)];
+ const body = [
+ t.instruction("get_local", args),
+ t.instruction("set_global", args)
+ ];
+
+ funcBody.push(...body);
+ });
+
+ if (typeof startAtFuncOffset === "number") {
+ funcBody.push(
+ t.callInstruction(t.numberLiteralFromRaw(startAtFuncOffset))
+ );
+ }
+
+ for (const instr of additionalInitCode) {
+ funcBody.push(instr);
+ }
+
+ funcBody.push(t.instruction("end"));
+
+ /** @type {string[]} */
+ const funcResults = [];
+
+ // Code section
+ const funcSignature = t.signature(funcParams, funcResults);
+ const func = t.func(initFuncId, funcSignature, funcBody);
+
+ // Type section
+ const functype = t.typeInstruction(undefined, funcSignature);
+
+ // Func section
+ const funcindex = t.indexInFuncSection(nextTypeIndex);
+
+ // Export section
+ const moduleExport = t.moduleExport(
+ initFuncId.value,
+ t.moduleExportDescr("Func", nextFuncIndex)
+ );
+
+ return addWithAST(ast, bin, [func, moduleExport, funcindex, functype]);
+ };
+
+/**
+ * Extract mangle mappings from module
+ * @param {ModuleGraph} moduleGraph module graph
+ * @param {Module} module current module
+ * @param {boolean | undefined} mangle mangle imports
+ * @returns {Map<string, UsedWasmDependency>} mappings to mangled names
+ */
+const getUsedDependencyMap = (moduleGraph, module, mangle) => {
+ /** @type {Map<string, UsedWasmDependency>} */
+ const map = new Map();
+ for (const usedDep of WebAssemblyUtils.getUsedDependencies(
+ moduleGraph,
+ module,
+ mangle
+ )) {
+ const dep = usedDep.dependency;
+ const request = dep.request;
+ const exportName = dep.name;
+ map.set(request + ":" + exportName, usedDep);
+ }
+ return map;
+};
+
+const TYPES = new Set(["webassembly"]);
+
+/**
+ * @typedef {Object} WebAssemblyGeneratorOptions
+ * @property {boolean} [mangleImports] mangle imports
+ */
+
+class WebAssemblyGenerator extends Generator {
+ /**
+ * @param {WebAssemblyGeneratorOptions} options options
+ */
+ constructor(options) {
+ super();
+ this.options = options;
+ }
+
+ /**
+ * @param {NormalModule} module fresh module
+ * @returns {Set<string>} available types (do not mutate)
+ */
+ getTypes(module) {
+ return TYPES;
+ }
+
+ /**
+ * @param {NormalModule} module the module
+ * @param {string=} type source type
+ * @returns {number} estimate size of the module
+ */
+ getSize(module, type) {
+ const originalSource = module.originalSource();
+ if (!originalSource) {
+ return 0;
+ }
+ return originalSource.size();
+ }
+
+ /**
+ * @param {NormalModule} module module for which the code should be generated
+ * @param {GenerateContext} generateContext context for generate
+ * @returns {Source} generated code
+ */
+ generate(module, { moduleGraph, runtime }) {
+ const bin = /** @type {Source} */ (module.originalSource()).source();
+
+ const initFuncId = t.identifier("");
+
+ // parse it
+ const ast = decode(bin, {
+ ignoreDataSection: true,
+ ignoreCodeSection: true,
+ ignoreCustomNameSection: true
+ });
+
+ const moduleContext = moduleContextFromModuleAST(ast.body[0]);
+
+ const importedGlobals = getImportedGlobals(ast);
+ const countImportedFunc = getCountImportedFunc(ast);
+ const startAtFuncOffset = moduleContext.getStart();
+ const nextFuncIndex = getNextFuncIndex(ast, countImportedFunc);
+ const nextTypeIndex = getNextTypeIndex(ast);
+
+ const usedDependencyMap = getUsedDependencyMap(
+ moduleGraph,
+ module,
+ this.options.mangleImports
+ );
+ const externalExports = new Set(
+ module.dependencies
+ .filter(d => d instanceof WebAssemblyExportImportedDependency)
+ .map(d => {
+ const wasmDep = /** @type {WebAssemblyExportImportedDependency} */ (
+ d
+ );
+ return wasmDep.exportName;
+ })
+ );
+
+ /** @type {t.Instruction[]} */
+ const additionalInitCode = [];
+
+ const transform = compose(
+ rewriteExportNames({
+ ast,
+ moduleGraph,
+ module,
+ externalExports,
+ runtime
+ }),
+
+ removeStartFunc({ ast }),
+
+ rewriteImportedGlobals({ ast, additionalInitCode }),
+
+ rewriteImports({
+ ast,
+ usedDependencyMap
+ }),
+
+ addInitFunction({
+ ast,
+ initFuncId,
+ importedGlobals,
+ additionalInitCode,
+ startAtFuncOffset,
+ nextFuncIndex,
+ nextTypeIndex
+ })
+ );
+
+ const newBin = transform(bin);
+
+ const newBuf = Buffer.from(newBin);
+
+ return new RawSource(newBuf);
+ }
+}
+
+module.exports = WebAssemblyGenerator;
diff --git a/node_modules/webpack/lib/wasm-sync/WebAssemblyInInitialChunkError.js b/node_modules/webpack/lib/wasm-sync/WebAssemblyInInitialChunkError.js
new file mode 100644
index 00000000..9d78ed20
--- /dev/null
+++ b/node_modules/webpack/lib/wasm-sync/WebAssemblyInInitialChunkError.js
@@ -0,0 +1,106 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const WebpackError = require("../WebpackError");
+
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+/** @typedef {import("../RequestShortener")} RequestShortener */
+
+/**
+ * @param {Module} module module to get chains from
+ * @param {ModuleGraph} moduleGraph the module graph
+ * @param {ChunkGraph} chunkGraph the chunk graph
+ * @param {RequestShortener} requestShortener to make readable identifiers
+ * @returns {string[]} all chains to the module
+ */
+const getInitialModuleChains = (
+ module,
+ moduleGraph,
+ chunkGraph,
+ requestShortener
+) => {
+ const queue = [
+ { head: module, message: module.readableIdentifier(requestShortener) }
+ ];
+ /** @type {Set<string>} */
+ const results = new Set();
+ /** @type {Set<string>} */
+ const incompleteResults = new Set();
+ /** @type {Set<Module>} */
+ const visitedModules = new Set();
+
+ for (const chain of queue) {
+ const { head, message } = chain;
+ let final = true;
+ /** @type {Set<Module>} */
+ const alreadyReferencedModules = new Set();
+ for (const connection of moduleGraph.getIncomingConnections(head)) {
+ const newHead = connection.originModule;
+ if (newHead) {
+ if (!chunkGraph.getModuleChunks(newHead).some(c => c.canBeInitial()))
+ continue;
+ final = false;
+ if (alreadyReferencedModules.has(newHead)) continue;
+ alreadyReferencedModules.add(newHead);
+ const moduleName = newHead.readableIdentifier(requestShortener);
+ const detail = connection.explanation
+ ? ` (${connection.explanation})`
+ : "";
+ const newMessage = `${moduleName}${detail} --> ${message}`;
+ if (visitedModules.has(newHead)) {
+ incompleteResults.add(`... --> ${newMessage}`);
+ continue;
+ }
+ visitedModules.add(newHead);
+ queue.push({
+ head: newHead,
+ message: newMessage
+ });
+ } else {
+ final = false;
+ const newMessage = connection.explanation
+ ? `(${connection.explanation}) --> ${message}`
+ : message;
+ results.add(newMessage);
+ }
+ }
+ if (final) {
+ results.add(message);
+ }
+ }
+ for (const result of incompleteResults) {
+ results.add(result);
+ }
+ return Array.from(results);
+};
+
+module.exports = class WebAssemblyInInitialChunkError extends WebpackError {
+ /**
+ * @param {Module} module WASM module
+ * @param {ModuleGraph} moduleGraph the module graph
+ * @param {ChunkGraph} chunkGraph the chunk graph
+ * @param {RequestShortener} requestShortener request shortener
+ */
+ constructor(module, moduleGraph, chunkGraph, requestShortener) {
+ const moduleChains = getInitialModuleChains(
+ module,
+ moduleGraph,
+ chunkGraph,
+ requestShortener
+ );
+ const message = `WebAssembly module is included in initial chunk.
+This is not allowed, because WebAssembly download and compilation must happen asynchronous.
+Add an async split point (i. e. import()) somewhere between your entrypoint and the WebAssembly module:
+${moduleChains.map(s => `* ${s}`).join("\n")}`;
+
+ super(message);
+ this.name = "WebAssemblyInInitialChunkError";
+ this.hideStack = true;
+ this.module = module;
+ }
+};
diff --git a/node_modules/webpack/lib/wasm-sync/WebAssemblyJavascriptGenerator.js b/node_modules/webpack/lib/wasm-sync/WebAssemblyJavascriptGenerator.js
new file mode 100644
index 00000000..448ae7b7
--- /dev/null
+++ b/node_modules/webpack/lib/wasm-sync/WebAssemblyJavascriptGenerator.js
@@ -0,0 +1,216 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { RawSource } = require("webpack-sources");
+const { UsageState } = require("../ExportsInfo");
+const Generator = require("../Generator");
+const InitFragment = require("../InitFragment");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const Template = require("../Template");
+const ModuleDependency = require("../dependencies/ModuleDependency");
+const WebAssemblyExportImportedDependency = require("../dependencies/WebAssemblyExportImportedDependency");
+const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../DependencyTemplates")} DependencyTemplates */
+/** @typedef {import("../Generator").GenerateContext} GenerateContext */
+/** @typedef {import("../NormalModule")} NormalModule */
+/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
+
+const TYPES = new Set(["webassembly"]);
+
+class WebAssemblyJavascriptGenerator extends Generator {
+ /**
+ * @param {NormalModule} module fresh module
+ * @returns {Set<string>} available types (do not mutate)
+ */
+ getTypes(module) {
+ return TYPES;
+ }
+
+ /**
+ * @param {NormalModule} module the module
+ * @param {string=} type source type
+ * @returns {number} estimate size of the module
+ */
+ getSize(module, type) {
+ return 95 + module.dependencies.length * 5;
+ }
+
+ /**
+ * @param {NormalModule} module module for which the code should be generated
+ * @param {GenerateContext} generateContext context for generate
+ * @returns {Source} generated code
+ */
+ generate(module, generateContext) {
+ const {
+ runtimeTemplate,
+ moduleGraph,
+ chunkGraph,
+ runtimeRequirements,
+ runtime
+ } = generateContext;
+ /** @type {InitFragment<InitFragment<string>>[]} */
+ const initFragments = [];
+
+ const exportsInfo = moduleGraph.getExportsInfo(module);
+
+ let needExportsCopy = false;
+ const importedModules = new Map();
+ const initParams = [];
+ let index = 0;
+ for (const dep of module.dependencies) {
+ const moduleDep =
+ dep && dep instanceof ModuleDependency ? dep : undefined;
+ if (moduleGraph.getModule(dep)) {
+ let importData = importedModules.get(moduleGraph.getModule(dep));
+ if (importData === undefined) {
+ importedModules.set(
+ moduleGraph.getModule(dep),
+ (importData = {
+ importVar: `m${index}`,
+ index,
+ request: (moduleDep && moduleDep.userRequest) || undefined,
+ names: new Set(),
+ reexports: []
+ })
+ );
+ index++;
+ }
+ if (dep instanceof WebAssemblyImportDependency) {
+ importData.names.add(dep.name);
+ if (dep.description.type === "GlobalType") {
+ const exportName = dep.name;
+ const importedModule = moduleGraph.getModule(dep);
+
+ if (importedModule) {
+ const usedName = moduleGraph
+ .getExportsInfo(importedModule)
+ .getUsedName(exportName, runtime);
+ if (usedName) {
+ initParams.push(
+ runtimeTemplate.exportFromImport({
+ moduleGraph,
+ module: importedModule,
+ request: dep.request,
+ importVar: importData.importVar,
+ originModule: module,
+ exportName: dep.name,
+ asiSafe: true,
+ isCall: false,
+ callContext: null,
+ defaultInterop: true,
+ initFragments,
+ runtime,
+ runtimeRequirements
+ })
+ );
+ }
+ }
+ }
+ }
+ if (dep instanceof WebAssemblyExportImportedDependency) {
+ importData.names.add(dep.name);
+ const usedName = moduleGraph
+ .getExportsInfo(module)
+ .getUsedName(dep.exportName, runtime);
+ if (usedName) {
+ runtimeRequirements.add(RuntimeGlobals.exports);
+ const exportProp = `${module.exportsArgument}[${JSON.stringify(
+ usedName
+ )}]`;
+ const defineStatement = Template.asString([
+ `${exportProp} = ${runtimeTemplate.exportFromImport({
+ moduleGraph,
+ module: moduleGraph.getModule(dep),
+ request: dep.request,
+ importVar: importData.importVar,
+ originModule: module,
+ exportName: dep.name,
+ asiSafe: true,
+ isCall: false,
+ callContext: null,
+ defaultInterop: true,
+ initFragments,
+ runtime,
+ runtimeRequirements
+ })};`,
+ `if(WebAssembly.Global) ${exportProp} = ` +
+ `new WebAssembly.Global({ value: ${JSON.stringify(
+ dep.valueType
+ )} }, ${exportProp});`
+ ]);
+ importData.reexports.push(defineStatement);
+ needExportsCopy = true;
+ }
+ }
+ }
+ }
+ const importsCode = Template.asString(
+ Array.from(
+ importedModules,
+ ([module, { importVar, request, reexports }]) => {
+ const importStatement = runtimeTemplate.importStatement({
+ module,
+ chunkGraph,
+ request,
+ importVar,
+ originModule: module,
+ runtimeRequirements
+ });
+ return importStatement[0] + importStatement[1] + reexports.join("\n");
+ }
+ )
+ );
+
+ const copyAllExports =
+ exportsInfo.otherExportsInfo.getUsed(runtime) === UsageState.Unused &&
+ !needExportsCopy;
+
+ // need these globals
+ runtimeRequirements.add(RuntimeGlobals.module);
+ runtimeRequirements.add(RuntimeGlobals.moduleId);
+ runtimeRequirements.add(RuntimeGlobals.wasmInstances);
+ if (exportsInfo.otherExportsInfo.getUsed(runtime) !== UsageState.Unused) {
+ runtimeRequirements.add(RuntimeGlobals.makeNamespaceObject);
+ runtimeRequirements.add(RuntimeGlobals.exports);
+ }
+ if (!copyAllExports) {
+ runtimeRequirements.add(RuntimeGlobals.exports);
+ }
+
+ // create source
+ const source = new RawSource(
+ [
+ '"use strict";',
+ "// Instantiate WebAssembly module",
+ `var wasmExports = ${RuntimeGlobals.wasmInstances}[${module.moduleArgument}.id];`,
+
+ exportsInfo.otherExportsInfo.getUsed(runtime) !== UsageState.Unused
+ ? `${RuntimeGlobals.makeNamespaceObject}(${module.exportsArgument});`
+ : "",
+
+ // this must be before import for circular dependencies
+ "// export exports from WebAssembly module",
+ copyAllExports
+ ? `${module.moduleArgument}.exports = wasmExports;`
+ : "for(var name in wasmExports) " +
+ `if(name) ` +
+ `${module.exportsArgument}[name] = wasmExports[name];`,
+ "// exec imports from WebAssembly module (for esm order)",
+ importsCode,
+ "",
+ "// exec wasm module",
+ `wasmExports[""](${initParams.join(", ")})`
+ ].join("\n")
+ );
+ return InitFragment.addToSource(source, initFragments, generateContext);
+ }
+}
+
+module.exports = WebAssemblyJavascriptGenerator;
diff --git a/node_modules/webpack/lib/wasm-sync/WebAssemblyModulesPlugin.js b/node_modules/webpack/lib/wasm-sync/WebAssemblyModulesPlugin.js
new file mode 100644
index 00000000..ad31aa4d
--- /dev/null
+++ b/node_modules/webpack/lib/wasm-sync/WebAssemblyModulesPlugin.js
@@ -0,0 +1,152 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Generator = require("../Generator");
+const { WEBASSEMBLY_MODULE_TYPE_SYNC } = require("../ModuleTypeConstants");
+const WebAssemblyExportImportedDependency = require("../dependencies/WebAssemblyExportImportedDependency");
+const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
+const { compareModulesByIdentifier } = require("../util/comparators");
+const memoize = require("../util/memoize");
+const WebAssemblyInInitialChunkError = require("./WebAssemblyInInitialChunkError");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../../declarations/WebpackOptions").OutputNormalized} OutputOptions */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../ModuleTemplate")} ModuleTemplate */
+/** @typedef {import("../javascript/JavascriptModulesPlugin").RenderContext} RenderContext */
+
+const getWebAssemblyGenerator = memoize(() =>
+ require("./WebAssemblyGenerator")
+);
+const getWebAssemblyJavascriptGenerator = memoize(() =>
+ require("./WebAssemblyJavascriptGenerator")
+);
+const getWebAssemblyParser = memoize(() => require("./WebAssemblyParser"));
+
+const PLUGIN_NAME = "WebAssemblyModulesPlugin";
+
+/**
+ * @typedef {Object} WebAssemblyModulesPluginOptions
+ * @property {boolean} [mangleImports] mangle imports
+ */
+
+class WebAssemblyModulesPlugin {
+ /**
+ * @param {WebAssemblyModulesPluginOptions} options options
+ */
+ constructor(options) {
+ this.options = options;
+ }
+
+ /**
+ * Apply the plugin
+ * @param {Compiler} compiler the compiler instance
+ * @returns {void}
+ */
+ apply(compiler) {
+ compiler.hooks.compilation.tap(
+ PLUGIN_NAME,
+ (compilation, { normalModuleFactory }) => {
+ compilation.dependencyFactories.set(
+ WebAssemblyImportDependency,
+ normalModuleFactory
+ );
+
+ compilation.dependencyFactories.set(
+ WebAssemblyExportImportedDependency,
+ normalModuleFactory
+ );
+
+ normalModuleFactory.hooks.createParser
+ .for(WEBASSEMBLY_MODULE_TYPE_SYNC)
+ .tap(PLUGIN_NAME, () => {
+ const WebAssemblyParser = getWebAssemblyParser();
+
+ return new WebAssemblyParser();
+ });
+
+ normalModuleFactory.hooks.createGenerator
+ .for(WEBASSEMBLY_MODULE_TYPE_SYNC)
+ .tap(PLUGIN_NAME, () => {
+ const WebAssemblyJavascriptGenerator =
+ getWebAssemblyJavascriptGenerator();
+ const WebAssemblyGenerator = getWebAssemblyGenerator();
+
+ return Generator.byType({
+ javascript: new WebAssemblyJavascriptGenerator(),
+ webassembly: new WebAssemblyGenerator(this.options)
+ });
+ });
+
+ compilation.hooks.renderManifest.tap(PLUGIN_NAME, (result, options) => {
+ const { chunkGraph } = compilation;
+ const { chunk, outputOptions, codeGenerationResults } = options;
+
+ for (const module of chunkGraph.getOrderedChunkModulesIterable(
+ chunk,
+ compareModulesByIdentifier
+ )) {
+ if (module.type === WEBASSEMBLY_MODULE_TYPE_SYNC) {
+ const filenameTemplate =
+ /** @type {NonNullable<OutputOptions["webassemblyModuleFilename"]>} */
+ (outputOptions.webassemblyModuleFilename);
+
+ result.push({
+ render: () =>
+ codeGenerationResults.getSource(
+ module,
+ chunk.runtime,
+ "webassembly"
+ ),
+ filenameTemplate,
+ pathOptions: {
+ module,
+ runtime: chunk.runtime,
+ chunkGraph
+ },
+ auxiliary: true,
+ identifier: `webassemblyModule${chunkGraph.getModuleId(
+ module
+ )}`,
+ hash: chunkGraph.getModuleHash(module, chunk.runtime)
+ });
+ }
+ }
+
+ return result;
+ });
+
+ compilation.hooks.afterChunks.tap(PLUGIN_NAME, () => {
+ const chunkGraph = compilation.chunkGraph;
+ const initialWasmModules = new Set();
+ for (const chunk of compilation.chunks) {
+ if (chunk.canBeInitial()) {
+ for (const module of chunkGraph.getChunkModulesIterable(chunk)) {
+ if (module.type === WEBASSEMBLY_MODULE_TYPE_SYNC) {
+ initialWasmModules.add(module);
+ }
+ }
+ }
+ }
+ for (const module of initialWasmModules) {
+ compilation.errors.push(
+ new WebAssemblyInInitialChunkError(
+ module,
+ compilation.moduleGraph,
+ compilation.chunkGraph,
+ compilation.requestShortener
+ )
+ );
+ }
+ });
+ }
+ );
+ }
+}
+
+module.exports = WebAssemblyModulesPlugin;
diff --git a/node_modules/webpack/lib/wasm-sync/WebAssemblyParser.js b/node_modules/webpack/lib/wasm-sync/WebAssemblyParser.js
new file mode 100644
index 00000000..bebd276f
--- /dev/null
+++ b/node_modules/webpack/lib/wasm-sync/WebAssemblyParser.js
@@ -0,0 +1,203 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const t = require("@webassemblyjs/ast");
+const { moduleContextFromModuleAST } = require("@webassemblyjs/ast");
+const { decode } = require("@webassemblyjs/wasm-parser");
+const Parser = require("../Parser");
+const StaticExportsDependency = require("../dependencies/StaticExportsDependency");
+const WebAssemblyExportImportedDependency = require("../dependencies/WebAssemblyExportImportedDependency");
+const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
+
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").BuildInfo} BuildInfo */
+/** @typedef {import("../Module").BuildMeta} BuildMeta */
+/** @typedef {import("../Parser").ParserState} ParserState */
+/** @typedef {import("../Parser").PreparsedAst} PreparsedAst */
+
+const JS_COMPAT_TYPES = new Set(["i32", "i64", "f32", "f64"]);
+
+/**
+ * @param {t.Signature} signature the func signature
+ * @returns {null | string} the type incompatible with js types
+ */
+const getJsIncompatibleType = signature => {
+ for (const param of signature.params) {
+ if (!JS_COMPAT_TYPES.has(param.valtype)) {
+ return `${param.valtype} as parameter`;
+ }
+ }
+ for (const type of signature.results) {
+ if (!JS_COMPAT_TYPES.has(type)) return `${type} as result`;
+ }
+ return null;
+};
+
+/**
+ * TODO why are there two different Signature types?
+ * @param {t.FuncSignature} signature the func signature
+ * @returns {null | string} the type incompatible with js types
+ */
+const getJsIncompatibleTypeOfFuncSignature = signature => {
+ for (const param of signature.args) {
+ if (!JS_COMPAT_TYPES.has(param)) {
+ return `${param} as parameter`;
+ }
+ }
+ for (const type of signature.result) {
+ if (!JS_COMPAT_TYPES.has(type)) return `${type} as result`;
+ }
+ return null;
+};
+
+const decoderOpts = {
+ ignoreCodeSection: true,
+ ignoreDataSection: true,
+
+ // this will avoid having to lookup with identifiers in the ModuleContext
+ ignoreCustomNameSection: true
+};
+
+class WebAssemblyParser extends Parser {
+ /**
+ * @param {{}=} options parser options
+ */
+ constructor(options) {
+ super();
+ this.hooks = Object.freeze({});
+ this.options = options;
+ }
+
+ /**
+ * @param {string | Buffer | PreparsedAst} source the source to parse
+ * @param {ParserState} state the parser state
+ * @returns {ParserState} the parser state
+ */
+ parse(source, state) {
+ if (!Buffer.isBuffer(source)) {
+ throw new Error("WebAssemblyParser input must be a Buffer");
+ }
+
+ // flag it as ESM
+ /** @type {BuildInfo} */
+ (state.module.buildInfo).strict = true;
+ /** @type {BuildMeta} */
+ (state.module.buildMeta).exportsType = "namespace";
+
+ // parse it
+ const program = decode(source, decoderOpts);
+ const module = program.body[0];
+
+ const moduleContext = moduleContextFromModuleAST(module);
+
+ // extract imports and exports
+ /** @type {string[]} */
+ const exports = [];
+ let jsIncompatibleExports = (state.module.buildMeta.jsIncompatibleExports =
+ undefined);
+
+ /** @type {TODO[]} */
+ const importedGlobals = [];
+ t.traverse(module, {
+ ModuleExport({ node }) {
+ const descriptor = node.descr;
+
+ if (descriptor.exportType === "Func") {
+ const funcIdx = descriptor.id.value;
+
+ /** @type {t.FuncSignature} */
+ const funcSignature = moduleContext.getFunction(funcIdx);
+
+ const incompatibleType =
+ getJsIncompatibleTypeOfFuncSignature(funcSignature);
+
+ if (incompatibleType) {
+ if (jsIncompatibleExports === undefined) {
+ jsIncompatibleExports =
+ state.module.buildMeta.jsIncompatibleExports = {};
+ }
+ jsIncompatibleExports[node.name] = incompatibleType;
+ }
+ }
+
+ exports.push(node.name);
+
+ if (node.descr && node.descr.exportType === "Global") {
+ const refNode = importedGlobals[node.descr.id.value];
+ if (refNode) {
+ const dep = new WebAssemblyExportImportedDependency(
+ node.name,
+ refNode.module,
+ refNode.name,
+ refNode.descr.valtype
+ );
+
+ state.module.addDependency(dep);
+ }
+ }
+ },
+
+ Global({ node }) {
+ const init = node.init[0];
+
+ let importNode = null;
+
+ if (init.id === "get_global") {
+ const globalIdx = init.args[0].value;
+
+ if (globalIdx < importedGlobals.length) {
+ importNode = importedGlobals[globalIdx];
+ }
+ }
+
+ importedGlobals.push(importNode);
+ },
+
+ ModuleImport({ node }) {
+ /** @type {false | string} */
+ let onlyDirectImport = false;
+
+ if (t.isMemory(node.descr) === true) {
+ onlyDirectImport = "Memory";
+ } else if (t.isTable(node.descr) === true) {
+ onlyDirectImport = "Table";
+ } else if (t.isFuncImportDescr(node.descr) === true) {
+ const incompatibleType = getJsIncompatibleType(
+ /** @type {t.Signature} */ (node.descr.signature)
+ );
+ if (incompatibleType) {
+ onlyDirectImport = `Non-JS-compatible Func Signature (${incompatibleType})`;
+ }
+ } else if (t.isGlobalType(node.descr) === true) {
+ const type = /** @type {string} */ (node.descr.valtype);
+ if (!JS_COMPAT_TYPES.has(type)) {
+ onlyDirectImport = `Non-JS-compatible Global Type (${type})`;
+ }
+ }
+
+ const dep = new WebAssemblyImportDependency(
+ node.module,
+ node.name,
+ node.descr,
+ onlyDirectImport
+ );
+
+ state.module.addDependency(dep);
+
+ if (t.isGlobalType(node.descr)) {
+ importedGlobals.push(node);
+ }
+ }
+ });
+
+ state.module.addDependency(new StaticExportsDependency(exports, false));
+
+ return state;
+ }
+}
+
+module.exports = WebAssemblyParser;
diff --git a/node_modules/webpack/lib/wasm-sync/WebAssemblyUtils.js b/node_modules/webpack/lib/wasm-sync/WebAssemblyUtils.js
new file mode 100644
index 00000000..b68f851a
--- /dev/null
+++ b/node_modules/webpack/lib/wasm-sync/WebAssemblyUtils.js
@@ -0,0 +1,65 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Template = require("../Template");
+const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
+
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../ModuleGraph")} ModuleGraph */
+
+/** @typedef {Object} UsedWasmDependency
+ * @property {WebAssemblyImportDependency} dependency the dependency
+ * @property {string} name the export name
+ * @property {string} module the module name
+ */
+
+const MANGLED_MODULE = "a";
+
+/**
+ * @param {ModuleGraph} moduleGraph the module graph
+ * @param {Module} module the module
+ * @param {boolean | undefined} mangle mangle module and export names
+ * @returns {UsedWasmDependency[]} used dependencies and (mangled) name
+ */
+const getUsedDependencies = (moduleGraph, module, mangle) => {
+ /** @type {UsedWasmDependency[]} */
+ const array = [];
+ let importIndex = 0;
+ for (const dep of module.dependencies) {
+ if (dep instanceof WebAssemblyImportDependency) {
+ if (
+ dep.description.type === "GlobalType" ||
+ moduleGraph.getModule(dep) === null
+ ) {
+ continue;
+ }
+
+ const exportName = dep.name;
+ // TODO add the following 3 lines when removing of ModuleExport is possible
+ // const importedModule = moduleGraph.getModule(dep);
+ // const usedName = importedModule && moduleGraph.getExportsInfo(importedModule).getUsedName(exportName, runtime);
+ // if (usedName !== false) {
+ if (mangle) {
+ array.push({
+ dependency: dep,
+ name: Template.numberToIdentifier(importIndex++),
+ module: MANGLED_MODULE
+ });
+ } else {
+ array.push({
+ dependency: dep,
+ name: exportName,
+ module: dep.request
+ });
+ }
+ }
+ }
+ return array;
+};
+
+exports.getUsedDependencies = getUsedDependencies;
+exports.MANGLED_MODULE = MANGLED_MODULE;