source: frontend/node_modules/webpack/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 8.7 KB
Line 
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const { RawSource } = require("webpack-sources");
9const Generator = require("../Generator");
10const InitFragment = require("../InitFragment");
11const { WEBASSEMBLY_TYPES } = require("../ModuleSourceTypeConstants");
12const RuntimeGlobals = require("../RuntimeGlobals");
13const Template = require("../Template");
14const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
15
16/** @typedef {import("webpack-sources").Source} Source */
17/** @typedef {import("./AsyncWebAssemblyModulesPlugin").AsyncWasmModuleClass} AsyncWasmModule */
18/** @typedef {import("../Generator").GenerateContext} GenerateContext */
19/** @typedef {import("../Module")} Module */
20/** @typedef {import("../Module").SourceType} SourceType */
21/** @typedef {import("../Module").SourceTypes} SourceTypes */
22/** @typedef {import("../NormalModule")} NormalModule */
23
24/**
25 * Represents the async web assembly javascript generator runtime component.
26 * @typedef {{ request: string, importVar: string, dependency: WebAssemblyImportDependency }} ImportObjRequestItem
27 */
28
29class AsyncWebAssemblyJavascriptGenerator extends Generator {
30 /**
31 * Returns the source types available for this module.
32 * @param {NormalModule} module fresh module
33 * @returns {SourceTypes} available types (do not mutate)
34 */
35 getTypes(module) {
36 return WEBASSEMBLY_TYPES;
37 }
38
39 /**
40 * Returns the estimated size for the requested source type.
41 * @param {NormalModule} module the module
42 * @param {SourceType=} type source type
43 * @returns {number} estimate size of the module
44 */
45 getSize(module, type) {
46 // it's only estimated so this number is probably fine
47 // Example: m.exports=s.v(e,_.id,"6db474f11db19c35388a")
48 if (/** @type {AsyncWasmModule} */ (module).phase === "source") {
49 return 44;
50 }
51
52 return 40 + module.dependencies.length * 10;
53 }
54
55 /**
56 * Generates generated code for this runtime module.
57 * @param {NormalModule} module module for which the code should be generated
58 * @param {GenerateContext} generateContext context for generate
59 * @returns {Source | null} generated code
60 */
61 generate(module, generateContext) {
62 const {
63 runtimeTemplate,
64 chunkGraph,
65 moduleGraph,
66 runtimeRequirements,
67 runtime
68 } = generateContext;
69
70 // Check if this is a source phase import
71 if (/** @type {AsyncWasmModule} */ (module).phase === "source") {
72 return this._generateSourcePhase(module, generateContext);
73 }
74
75 runtimeRequirements.add(RuntimeGlobals.module);
76 runtimeRequirements.add(RuntimeGlobals.moduleId);
77 runtimeRequirements.add(RuntimeGlobals.exports);
78 runtimeRequirements.add(RuntimeGlobals.instantiateWasm);
79 /** @type {InitFragment<GenerateContext>[]} */
80 const initFragments = [];
81 /** @type {Map<Module, ImportObjRequestItem>} */
82 const depModules = new Map();
83 /** @type {Map<string, WebAssemblyImportDependency[]>} */
84 const wasmDepsByRequest = new Map();
85 for (const dep of module.dependencies) {
86 if (dep instanceof WebAssemblyImportDependency) {
87 const module = /** @type {Module} */ (moduleGraph.getModule(dep));
88 if (!depModules.has(module)) {
89 depModules.set(module, {
90 request: dep.request,
91 importVar: `WEBPACK_IMPORTED_MODULE_${depModules.size}`,
92 dependency: dep
93 });
94 }
95 let list = wasmDepsByRequest.get(dep.request);
96 if (list === undefined) {
97 list = [];
98 wasmDepsByRequest.set(dep.request, list);
99 }
100 list.push(dep);
101 }
102 }
103
104 /** @type {string[]} */
105 const promises = [];
106
107 const importStatements = Array.from(
108 depModules,
109 ([importedModule, { request, importVar, dependency }]) => {
110 if (moduleGraph.isAsync(importedModule)) {
111 promises.push(importVar);
112 }
113 return runtimeTemplate.importStatement({
114 update: false,
115 module: importedModule,
116 moduleGraph,
117 chunkGraph,
118 request,
119 originModule: module,
120 importVar,
121 runtimeRequirements,
122 dependency
123 });
124 }
125 );
126 const importsCode = importStatements.map(([x]) => x).join("");
127 const importsCompatCode = importStatements.map(([_, x]) => x).join("");
128
129 const importObjRequestItems = Array.from(
130 wasmDepsByRequest,
131 ([request, deps]) => {
132 const exportItems = deps.map((dep) => {
133 const importedModule =
134 /** @type {Module} */
135 (moduleGraph.getModule(dep));
136 const importVar =
137 /** @type {ImportObjRequestItem} */
138 (depModules.get(importedModule)).importVar;
139 return `${JSON.stringify(
140 dep.name
141 )}: ${runtimeTemplate.exportFromImport({
142 moduleGraph,
143 module: importedModule,
144 chunkGraph,
145 request,
146 exportName: dep.name,
147 originModule: module,
148 asiSafe: true,
149 isCall: false,
150 callContext: false,
151 defaultInterop: true,
152 importVar,
153 initFragments,
154 runtime,
155 runtimeRequirements,
156 dependency: dep
157 })}`;
158 });
159 return Template.asString([
160 `${JSON.stringify(request)}: {`,
161 Template.indent(exportItems.join(",\n")),
162 "}"
163 ]);
164 }
165 );
166
167 const importsObj =
168 importObjRequestItems.length > 0
169 ? Template.asString([
170 "{",
171 Template.indent(importObjRequestItems.join(",\n")),
172 "}"
173 ])
174 : undefined;
175
176 const instantiateCall = `${RuntimeGlobals.instantiateWasm}(${module.exportsArgument}, ${
177 module.moduleArgument
178 }.id, ${JSON.stringify(
179 chunkGraph.getRenderedModuleHash(module, runtime)
180 )}${importsObj ? `, ${importsObj})` : ")"}`;
181
182 if (promises.length > 0) {
183 runtimeRequirements.add(RuntimeGlobals.asyncModule);
184 }
185
186 const source = new RawSource(
187 promises.length > 0
188 ? Template.asString([
189 `var __webpack_instantiate__ = ${runtimeTemplate.basicFunction(
190 `[${promises.join(", ")}]`,
191 `${importsCompatCode}return ${instantiateCall};`
192 )}`,
193 `${RuntimeGlobals.asyncModule}(${
194 module.moduleArgument
195 }, async ${runtimeTemplate.basicFunction(
196 "__webpack_handle_async_dependencies__, __webpack_async_result__",
197 [
198 "try {",
199 importsCode,
200 `var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([${promises.join(
201 ", "
202 )}]);`,
203 `var [${promises.join(
204 ", "
205 )}] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__;`,
206 `${importsCompatCode}await ${instantiateCall};`,
207 "__webpack_async_result__();",
208 "} catch(e) { __webpack_async_result__(e); }"
209 ]
210 )}, 1);`
211 ])
212 : `${importsCode}${importsCompatCode}module.exports = ${instantiateCall};`
213 );
214
215 return InitFragment.addToSource(source, initFragments, generateContext);
216 }
217
218 /**
219 * Generate code for source phase import (returns WebAssembly.Module)
220 * @param {NormalModule} module module for which the code should be generated
221 * @param {GenerateContext} generateContext context for generate
222 * @returns {Source} generated code
223 */
224 _generateSourcePhase(module, generateContext) {
225 const { chunkGraph, runtimeTemplate, runtimeRequirements, runtime } =
226 generateContext;
227
228 runtimeRequirements.add(RuntimeGlobals.module);
229 runtimeRequirements.add(RuntimeGlobals.moduleId);
230 runtimeRequirements.add(RuntimeGlobals.exports);
231 runtimeRequirements.add(RuntimeGlobals.compileWasm);
232 runtimeRequirements.add(RuntimeGlobals.asyncModule);
233 runtimeRequirements.add(RuntimeGlobals.definePropertyGetters);
234
235 // Source phase: export default WebAssembly.Module (via compileWasm)
236 const compileCall = `${RuntimeGlobals.compileWasm}(${
237 module.moduleArgument
238 }.id, ${JSON.stringify(chunkGraph.getRenderedModuleHash(module, runtime))})`;
239
240 // Use async module wrapper to handle the Promise from compileWasm
241 return new RawSource(
242 Template.asString([
243 `${RuntimeGlobals.asyncModule}(${
244 module.moduleArgument
245 }, async ${runtimeTemplate.basicFunction(
246 "__webpack_handle_async_dependencies__, __webpack_async_result__",
247 [
248 "try {",
249 `var __webpack_wasm_module__ = await ${compileCall};`,
250 `${RuntimeGlobals.definePropertyGetters}(${module.exportsArgument}, { "default": ${runtimeTemplate.returningFunction("__webpack_wasm_module__")} });`,
251 "__webpack_async_result__();",
252 "} catch(e) { __webpack_async_result__(e); }"
253 ]
254 )}, 1);`
255 ])
256 );
257 }
258
259 /**
260 * Generates fallback output for the provided error condition.
261 * @param {Error} error the error
262 * @param {NormalModule} module module for which the code should be generated
263 * @param {GenerateContext} generateContext context for generate
264 * @returns {Source | null} generated code
265 */
266 generateError(error, module, generateContext) {
267 return new RawSource(`throw new Error(${JSON.stringify(error.message)});`);
268 }
269}
270
271module.exports = AsyncWebAssemblyJavascriptGenerator;
Note: See TracBrowser for help on using the repository browser.