1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | "use strict";
|
7 |
|
8 | const { RawSource } = require("webpack-sources");
|
9 | const { UsageState } = require("../ExportsInfo");
|
10 | const Generator = require("../Generator");
|
11 | const InitFragment = require("../InitFragment");
|
12 | const RuntimeGlobals = require("../RuntimeGlobals");
|
13 | const Template = require("../Template");
|
14 | const ModuleDependency = require("../dependencies/ModuleDependency");
|
15 | const WebAssemblyExportImportedDependency = require("../dependencies/WebAssemblyExportImportedDependency");
|
16 | const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 | const TYPES = new Set(["webassembly"]);
|
26 |
|
27 | class WebAssemblyJavascriptGenerator extends Generator {
|
28 | |
29 |
|
30 |
|
31 |
|
32 | getTypes(module) {
|
33 | return TYPES;
|
34 | }
|
35 |
|
36 | |
37 |
|
38 |
|
39 |
|
40 |
|
41 | getSize(module, type) {
|
42 | return 95 + module.dependencies.length * 5;
|
43 | }
|
44 |
|
45 | |
46 |
|
47 |
|
48 |
|
49 |
|
50 | generate(module, generateContext) {
|
51 | const {
|
52 | runtimeTemplate,
|
53 | moduleGraph,
|
54 | chunkGraph,
|
55 | runtimeRequirements,
|
56 | runtime
|
57 | } = generateContext;
|
58 |
|
59 | const initFragments = [];
|
60 |
|
61 | const exportsInfo = moduleGraph.getExportsInfo(module);
|
62 |
|
63 | let needExportsCopy = false;
|
64 | const importedModules = new Map();
|
65 | const initParams = [];
|
66 | let index = 0;
|
67 | for (const dep of module.dependencies) {
|
68 | const moduleDep =
|
69 | dep && dep instanceof ModuleDependency ? dep : undefined;
|
70 | if (moduleGraph.getModule(dep)) {
|
71 | let importData = importedModules.get(moduleGraph.getModule(dep));
|
72 | if (importData === undefined) {
|
73 | importedModules.set(
|
74 | moduleGraph.getModule(dep),
|
75 | (importData = {
|
76 | importVar: `m${index}`,
|
77 | index,
|
78 | request: (moduleDep && moduleDep.userRequest) || undefined,
|
79 | names: new Set(),
|
80 | reexports: []
|
81 | })
|
82 | );
|
83 | index++;
|
84 | }
|
85 | if (dep instanceof WebAssemblyImportDependency) {
|
86 | importData.names.add(dep.name);
|
87 | if (dep.description.type === "GlobalType") {
|
88 | const exportName = dep.name;
|
89 | const importedModule = moduleGraph.getModule(dep);
|
90 |
|
91 | if (importedModule) {
|
92 | const usedName = moduleGraph
|
93 | .getExportsInfo(importedModule)
|
94 | .getUsedName(exportName, runtime);
|
95 | if (usedName) {
|
96 | initParams.push(
|
97 | runtimeTemplate.exportFromImport({
|
98 | moduleGraph,
|
99 | module: importedModule,
|
100 | request: dep.request,
|
101 | importVar: importData.importVar,
|
102 | originModule: module,
|
103 | exportName: dep.name,
|
104 | asiSafe: true,
|
105 | isCall: false,
|
106 | callContext: null,
|
107 | defaultInterop: true,
|
108 | initFragments,
|
109 | runtime,
|
110 | runtimeRequirements
|
111 | })
|
112 | );
|
113 | }
|
114 | }
|
115 | }
|
116 | }
|
117 | if (dep instanceof WebAssemblyExportImportedDependency) {
|
118 | importData.names.add(dep.name);
|
119 | const usedName = moduleGraph
|
120 | .getExportsInfo(module)
|
121 | .getUsedName(dep.exportName, runtime);
|
122 | if (usedName) {
|
123 | runtimeRequirements.add(RuntimeGlobals.exports);
|
124 | const exportProp = `${module.exportsArgument}[${JSON.stringify(
|
125 | usedName
|
126 | )}]`;
|
127 | const defineStatement = Template.asString([
|
128 | `${exportProp} = ${runtimeTemplate.exportFromImport({
|
129 | moduleGraph,
|
130 | module: moduleGraph.getModule(dep),
|
131 | request: dep.request,
|
132 | importVar: importData.importVar,
|
133 | originModule: module,
|
134 | exportName: dep.name,
|
135 | asiSafe: true,
|
136 | isCall: false,
|
137 | callContext: null,
|
138 | defaultInterop: true,
|
139 | initFragments,
|
140 | runtime,
|
141 | runtimeRequirements
|
142 | })};`,
|
143 | `if(WebAssembly.Global) ${exportProp} = ` +
|
144 | `new WebAssembly.Global({ value: ${JSON.stringify(
|
145 | dep.valueType
|
146 | )} }, ${exportProp});`
|
147 | ]);
|
148 | importData.reexports.push(defineStatement);
|
149 | needExportsCopy = true;
|
150 | }
|
151 | }
|
152 | }
|
153 | }
|
154 | const importsCode = Template.asString(
|
155 | Array.from(
|
156 | importedModules,
|
157 | ([module, { importVar, request, reexports }]) => {
|
158 | const importStatement = runtimeTemplate.importStatement({
|
159 | module,
|
160 | chunkGraph,
|
161 | request,
|
162 | importVar,
|
163 | originModule: module,
|
164 | runtimeRequirements
|
165 | });
|
166 | return importStatement[0] + importStatement[1] + reexports.join("\n");
|
167 | }
|
168 | )
|
169 | );
|
170 |
|
171 | const copyAllExports =
|
172 | exportsInfo.otherExportsInfo.getUsed(runtime) === UsageState.Unused &&
|
173 | !needExportsCopy;
|
174 |
|
175 |
|
176 | runtimeRequirements.add(RuntimeGlobals.module);
|
177 | runtimeRequirements.add(RuntimeGlobals.moduleId);
|
178 | runtimeRequirements.add(RuntimeGlobals.wasmInstances);
|
179 | if (exportsInfo.otherExportsInfo.getUsed(runtime) !== UsageState.Unused) {
|
180 | runtimeRequirements.add(RuntimeGlobals.makeNamespaceObject);
|
181 | runtimeRequirements.add(RuntimeGlobals.exports);
|
182 | }
|
183 | if (!copyAllExports) {
|
184 | runtimeRequirements.add(RuntimeGlobals.exports);
|
185 | }
|
186 |
|
187 |
|
188 | const source = new RawSource(
|
189 | [
|
190 | '"use strict";',
|
191 | "// Instantiate WebAssembly module",
|
192 | `var wasmExports = ${RuntimeGlobals.wasmInstances}[${module.moduleArgument}.id];`,
|
193 |
|
194 | exportsInfo.otherExportsInfo.getUsed(runtime) !== UsageState.Unused
|
195 | ? `${RuntimeGlobals.makeNamespaceObject}(${module.exportsArgument});`
|
196 | : "",
|
197 |
|
198 |
|
199 | "// export exports from WebAssembly module",
|
200 | copyAllExports
|
201 | ? `${module.moduleArgument}.exports = wasmExports;`
|
202 | : "for(var name in wasmExports) " +
|
203 | `if(name) ` +
|
204 | `${module.exportsArgument}[name] = wasmExports[name];`,
|
205 | "// exec imports from WebAssembly module (for esm order)",
|
206 | importsCode,
|
207 | "",
|
208 | "// exec wasm module",
|
209 | `wasmExports[""](${initParams.join(", ")})`
|
210 | ].join("\n")
|
211 | );
|
212 | return InitFragment.addToSource(source, initFragments, generateContext);
|
213 | }
|
214 | }
|
215 |
|
216 | module.exports = WebAssemblyJavascriptGenerator;
|