UNPKG

4.8 kBJavaScriptView Raw
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5"use strict";
6
7const Generator = require("../Generator");
8const Template = require("../Template");
9const { RawSource } = require("webpack-sources");
10const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
11const WebAssemblyExportImportedDependency = require("../dependencies/WebAssemblyExportImportedDependency");
12
13/** @typedef {import("../NormalModule")} NormalModule */
14/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
15/** @typedef {import("webpack-sources").Source} Source */
16/** @typedef {import("../Dependency").DependencyTemplate} DependencyTemplate */
17
18class WebAssemblyJavascriptGenerator extends Generator {
19 /**
20 * @param {NormalModule} module module for which the code should be generated
21 * @param {Map<Function, DependencyTemplate>} dependencyTemplates mapping from dependencies to templates
22 * @param {RuntimeTemplate} runtimeTemplate the runtime template
23 * @param {string} type which kind of code should be generated
24 * @returns {Source} generated code
25 */
26 generate(module, dependencyTemplates, runtimeTemplate, type) {
27 const initIdentifer = Array.isArray(module.usedExports)
28 ? Template.numberToIdentifer(module.usedExports.length)
29 : "__webpack_init__";
30
31 let needExportsCopy = false;
32 const importedModules = new Map();
33 const initParams = [];
34 let index = 0;
35 for (const dep of module.dependencies) {
36 const depAsAny = /** @type {any} */ (dep);
37 if (dep.module) {
38 let importData = importedModules.get(dep.module);
39 if (importData === undefined) {
40 importedModules.set(
41 dep.module,
42 (importData = {
43 importVar: `m${index}`,
44 index,
45 request:
46 "userRequest" in depAsAny ? depAsAny.userRequest : undefined,
47 names: new Set(),
48 reexports: []
49 })
50 );
51 index++;
52 }
53 if (dep instanceof WebAssemblyImportDependency) {
54 importData.names.add(dep.name);
55 if (dep.description.type === "GlobalType") {
56 const exportName = dep.name;
57 const usedName = dep.module && dep.module.isUsed(exportName);
58
59 if (dep.module) {
60 if (usedName) {
61 initParams.push(
62 runtimeTemplate.exportFromImport({
63 module: dep.module,
64 request: dep.request,
65 importVar: importData.importVar,
66 originModule: module,
67 exportName: dep.name,
68 asiSafe: true,
69 isCall: false,
70 callContext: null
71 })
72 );
73 }
74 }
75 }
76 }
77 if (dep instanceof WebAssemblyExportImportedDependency) {
78 importData.names.add(dep.name);
79 const usedName = module.isUsed(dep.exportName);
80 if (usedName) {
81 const exportProp = `${module.exportsArgument}[${JSON.stringify(
82 usedName
83 )}]`;
84 const defineStatement = Template.asString([
85 `${exportProp} = ${runtimeTemplate.exportFromImport({
86 module: dep.module,
87 request: dep.request,
88 importVar: importData.importVar,
89 originModule: module,
90 exportName: dep.name,
91 asiSafe: true,
92 isCall: false,
93 callContext: null
94 })};`,
95 `if(WebAssembly.Global) ${exportProp} = ` +
96 `new WebAssembly.Global({ value: ${JSON.stringify(
97 dep.valueType
98 )} }, ${exportProp});`
99 ]);
100 importData.reexports.push(defineStatement);
101 needExportsCopy = true;
102 }
103 }
104 }
105 }
106 const importsCode = Template.asString(
107 Array.from(
108 importedModules,
109 ([module, { importVar, request, reexports }]) => {
110 const importStatement = runtimeTemplate.importStatement({
111 module,
112 request,
113 importVar,
114 originModule: module
115 });
116 return importStatement + reexports.join("\n");
117 }
118 )
119 );
120
121 // create source
122 const source = new RawSource(
123 [
124 '"use strict";',
125 "// Instantiate WebAssembly module",
126 "var wasmExports = __webpack_require__.w[module.i];",
127
128 !Array.isArray(module.usedExports)
129 ? `__webpack_require__.r(${module.exportsArgument});`
130 : "",
131
132 // this must be before import for circular dependencies
133 "// export exports from WebAssembly module",
134 Array.isArray(module.usedExports) && !needExportsCopy
135 ? `${module.moduleArgument}.exports = wasmExports;`
136 : "for(var name in wasmExports) " +
137 `if(name != ${JSON.stringify(initIdentifer)}) ` +
138 `${module.exportsArgument}[name] = wasmExports[name];`,
139 "// exec imports from WebAssembly module (for esm order)",
140 importsCode,
141 "",
142 "// exec wasm module",
143 `wasmExports[${JSON.stringify(initIdentifer)}](${initParams.join(
144 ", "
145 )})`
146 ].join("\n")
147 );
148 return source;
149 }
150}
151
152module.exports = WebAssemblyJavascriptGenerator;