| 
									
										
										
										
											2018-04-28 00:53:07 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Tobias Koppers @sokra | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2018-07-30 23:08:51 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-28 00:53:07 +08:00
										 |  |  | "use strict"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-30 23:08:51 +08:00
										 |  |  | const { RawSource } = require("webpack-sources"); | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | const { UsageState } = require("../ExportsInfo"); | 
					
						
							| 
									
										
										
										
											2018-04-28 00:53:07 +08:00
										 |  |  | const Generator = require("../Generator"); | 
					
						
							| 
									
										
										
										
											2019-11-05 04:05:17 +08:00
										 |  |  | const InitFragment = require("../InitFragment"); | 
					
						
							| 
									
										
										
										
											2018-11-05 21:36:15 +08:00
										 |  |  | const RuntimeGlobals = require("../RuntimeGlobals"); | 
					
						
							| 
									
										
										
										
											2018-04-28 00:53:07 +08:00
										 |  |  | const Template = require("../Template"); | 
					
						
							| 
									
										
										
										
											2020-08-07 23:05:48 +08:00
										 |  |  | const ModuleDependency = require("../dependencies/ModuleDependency"); | 
					
						
							| 
									
										
										
										
											2018-06-02 15:53:35 +08:00
										 |  |  | const WebAssemblyExportImportedDependency = require("../dependencies/WebAssemblyExportImportedDependency"); | 
					
						
							| 
									
										
										
										
											2018-07-30 23:08:51 +08:00
										 |  |  | const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency"); | 
					
						
							| 
									
										
										
										
											2018-04-28 00:53:07 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-21 00:17:51 +08:00
										 |  |  | /** @typedef {import("webpack-sources").Source} Source */ | 
					
						
							| 
									
										
										
										
											2020-08-03 02:09:36 +08:00
										 |  |  | /** @typedef {import("../Dependency")} Dependency */ | 
					
						
							| 
									
										
										
										
											2018-07-23 18:19:16 +08:00
										 |  |  | /** @typedef {import("../DependencyTemplates")} DependencyTemplates */ | 
					
						
							| 
									
										
										
										
											2018-07-18 00:57:03 +08:00
										 |  |  | /** @typedef {import("../Generator").GenerateContext} GenerateContext */ | 
					
						
							| 
									
										
										
										
											2024-02-17 01:39:12 +08:00
										 |  |  | /** @typedef {import("../Module")} Module */ | 
					
						
							| 
									
										
										
										
											2018-07-30 23:08:51 +08:00
										 |  |  | /** @typedef {import("../NormalModule")} NormalModule */ | 
					
						
							|  |  |  | /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */ | 
					
						
							| 
									
										
										
										
											2018-07-21 00:17:51 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 22:00:32 +08:00
										 |  |  | const TYPES = new Set(["webassembly"]); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-28 00:53:07 +08:00
										 |  |  | class WebAssemblyJavascriptGenerator extends Generator { | 
					
						
							| 
									
										
										
										
											2018-12-03 22:00:32 +08:00
										 |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2019-11-18 21:29:19 +08:00
										 |  |  | 	 * @param {NormalModule} module fresh module | 
					
						
							| 
									
										
										
										
											2018-12-03 22:00:32 +08:00
										 |  |  | 	 * @returns {Set<string>} available types (do not mutate) | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2019-11-18 21:29:19 +08:00
										 |  |  | 	getTypes(module) { | 
					
						
							| 
									
										
										
										
											2018-12-03 22:00:32 +08:00
										 |  |  | 		return TYPES; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-04 18:23:40 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {NormalModule} module the module | 
					
						
							|  |  |  | 	 * @param {string=} type source type | 
					
						
							|  |  |  | 	 * @returns {number} estimate size of the module | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	getSize(module, type) { | 
					
						
							| 
									
										
										
										
											2018-12-31 19:36:29 +08:00
										 |  |  | 		return 95 + module.dependencies.length * 5; | 
					
						
							| 
									
										
										
										
											2018-12-04 18:23:40 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-21 00:17:51 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {NormalModule} module module for which the code should be generated | 
					
						
							| 
									
										
										
										
											2018-07-18 00:57:03 +08:00
										 |  |  | 	 * @param {GenerateContext} generateContext context for generate | 
					
						
							| 
									
										
										
										
											2018-07-21 00:17:51 +08:00
										 |  |  | 	 * @returns {Source} generated code | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2019-11-05 04:05:17 +08:00
										 |  |  | 	generate(module, generateContext) { | 
					
						
							|  |  |  | 		const { | 
					
						
							|  |  |  | 			runtimeTemplate, | 
					
						
							|  |  |  | 			moduleGraph, | 
					
						
							|  |  |  | 			chunkGraph, | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 			runtimeRequirements, | 
					
						
							|  |  |  | 			runtime | 
					
						
							| 
									
										
										
										
											2019-11-05 04:05:17 +08:00
										 |  |  | 		} = generateContext; | 
					
						
							| 
									
										
										
										
											2023-05-26 02:31:28 +08:00
										 |  |  | 		/** @type {InitFragment<InitFragment<string>>[]} */ | 
					
						
							| 
									
										
										
										
											2019-11-05 04:05:17 +08:00
										 |  |  | 		const initFragments = []; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-20 18:32:12 +08:00
										 |  |  | 		const exportsInfo = moduleGraph.getExportsInfo(module); | 
					
						
							| 
									
										
										
										
											2018-04-28 00:53:07 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-02 15:53:35 +08:00
										 |  |  | 		let needExportsCopy = false; | 
					
						
							|  |  |  | 		const importedModules = new Map(); | 
					
						
							|  |  |  | 		const initParams = []; | 
					
						
							|  |  |  | 		let index = 0; | 
					
						
							|  |  |  | 		for (const dep of module.dependencies) { | 
					
						
							| 
									
										
										
										
											2020-08-07 23:05:48 +08:00
										 |  |  | 			const moduleDep = | 
					
						
							|  |  |  | 				dep && dep instanceof ModuleDependency ? dep : undefined; | 
					
						
							| 
									
										
										
										
											2018-07-24 21:30:37 +08:00
										 |  |  | 			if (moduleGraph.getModule(dep)) { | 
					
						
							|  |  |  | 				let importData = importedModules.get(moduleGraph.getModule(dep)); | 
					
						
							| 
									
										
										
										
											2018-06-02 15:53:35 +08:00
										 |  |  | 				if (importData === undefined) { | 
					
						
							|  |  |  | 					importedModules.set( | 
					
						
							| 
									
										
										
										
											2018-07-24 21:30:37 +08:00
										 |  |  | 						moduleGraph.getModule(dep), | 
					
						
							| 
									
										
										
										
											2018-06-02 15:53:35 +08:00
										 |  |  | 						(importData = { | 
					
						
							|  |  |  | 							importVar: `m${index}`, | 
					
						
							|  |  |  | 							index, | 
					
						
							| 
									
										
										
										
											2020-08-07 23:05:48 +08:00
										 |  |  | 							request: (moduleDep && moduleDep.userRequest) || undefined, | 
					
						
							| 
									
										
										
										
											2018-06-02 15:53:35 +08:00
										 |  |  | 							names: new Set(), | 
					
						
							|  |  |  | 							reexports: [] | 
					
						
							|  |  |  | 						}) | 
					
						
							|  |  |  | 					); | 
					
						
							|  |  |  | 					index++; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if (dep instanceof WebAssemblyImportDependency) { | 
					
						
							|  |  |  | 					importData.names.add(dep.name); | 
					
						
							|  |  |  | 					if (dep.description.type === "GlobalType") { | 
					
						
							|  |  |  | 						const exportName = dep.name; | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 						const importedModule = moduleGraph.getModule(dep); | 
					
						
							| 
									
										
										
										
											2018-04-28 00:53:07 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 						if (importedModule) { | 
					
						
							|  |  |  | 							const usedName = moduleGraph | 
					
						
							|  |  |  | 								.getExportsInfo(importedModule) | 
					
						
							|  |  |  | 								.getUsedName(exportName, runtime); | 
					
						
							| 
									
										
										
										
											2018-06-02 15:53:35 +08:00
										 |  |  | 							if (usedName) { | 
					
						
							|  |  |  | 								initParams.push( | 
					
						
							|  |  |  | 									runtimeTemplate.exportFromImport({ | 
					
						
							| 
									
										
										
										
											2018-08-07 01:39:43 +08:00
										 |  |  | 										moduleGraph, | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 										module: importedModule, | 
					
						
							| 
									
										
										
										
											2018-06-02 15:53:35 +08:00
										 |  |  | 										request: dep.request, | 
					
						
							|  |  |  | 										importVar: importData.importVar, | 
					
						
							|  |  |  | 										originModule: module, | 
					
						
							|  |  |  | 										exportName: dep.name, | 
					
						
							|  |  |  | 										asiSafe: true, | 
					
						
							|  |  |  | 										isCall: false, | 
					
						
							| 
									
										
										
										
											2018-11-17 01:18:44 +08:00
										 |  |  | 										callContext: null, | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | 										defaultInterop: true, | 
					
						
							| 
									
										
										
										
											2019-11-05 04:05:17 +08:00
										 |  |  | 										initFragments, | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 										runtime, | 
					
						
							| 
									
										
										
										
											2018-11-17 01:18:44 +08:00
										 |  |  | 										runtimeRequirements | 
					
						
							| 
									
										
										
										
											2018-06-02 15:53:35 +08:00
										 |  |  | 									}) | 
					
						
							|  |  |  | 								); | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if (dep instanceof WebAssemblyExportImportedDependency) { | 
					
						
							|  |  |  | 					importData.names.add(dep.name); | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 					const usedName = moduleGraph | 
					
						
							|  |  |  | 						.getExportsInfo(module) | 
					
						
							|  |  |  | 						.getUsedName(dep.exportName, runtime); | 
					
						
							| 
									
										
										
										
											2018-06-02 15:53:35 +08:00
										 |  |  | 					if (usedName) { | 
					
						
							| 
									
										
										
										
											2018-11-17 01:18:44 +08:00
										 |  |  | 						runtimeRequirements.add(RuntimeGlobals.exports); | 
					
						
							| 
									
										
										
										
											2018-10-24 17:24:39 +08:00
										 |  |  | 						const exportProp = `${module.exportsArgument}[${JSON.stringify( | 
					
						
							|  |  |  | 							usedName | 
					
						
							|  |  |  | 						)}]`;
 | 
					
						
							| 
									
										
										
										
											2018-06-02 15:53:35 +08:00
										 |  |  | 						const defineStatement = Template.asString([ | 
					
						
							| 
									
										
										
										
											2018-10-24 17:24:39 +08:00
										 |  |  | 							`${exportProp} = ${runtimeTemplate.exportFromImport({ | 
					
						
							| 
									
										
										
										
											2018-08-07 01:39:43 +08:00
										 |  |  | 								moduleGraph, | 
					
						
							| 
									
										
										
										
											2024-02-17 01:39:12 +08:00
										 |  |  | 								module: /** @type {Module} */ (moduleGraph.getModule(dep)), | 
					
						
							| 
									
										
										
										
											2018-06-02 15:53:35 +08:00
										 |  |  | 								request: dep.request, | 
					
						
							|  |  |  | 								importVar: importData.importVar, | 
					
						
							|  |  |  | 								originModule: module, | 
					
						
							|  |  |  | 								exportName: dep.name, | 
					
						
							|  |  |  | 								asiSafe: true, | 
					
						
							|  |  |  | 								isCall: false, | 
					
						
							| 
									
										
										
										
											2018-11-17 01:18:44 +08:00
										 |  |  | 								callContext: null, | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | 								defaultInterop: true, | 
					
						
							| 
									
										
										
										
											2019-11-05 04:05:17 +08:00
										 |  |  | 								initFragments, | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 								runtime, | 
					
						
							| 
									
										
										
										
											2018-11-17 01:18:44 +08:00
										 |  |  | 								runtimeRequirements | 
					
						
							| 
									
										
										
										
											2018-10-24 17:24:39 +08:00
										 |  |  | 							})};`,
 | 
					
						
							|  |  |  | 							`if(WebAssembly.Global) ${exportProp} = ` + | 
					
						
							|  |  |  | 								`new WebAssembly.Global({ value: ${JSON.stringify( | 
					
						
							|  |  |  | 									dep.valueType | 
					
						
							|  |  |  | 								)} }, ${exportProp});`
 | 
					
						
							| 
									
										
										
										
											2018-06-02 15:53:35 +08:00
										 |  |  | 						]); | 
					
						
							|  |  |  | 						importData.reexports.push(defineStatement); | 
					
						
							|  |  |  | 						needExportsCopy = true; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		const importsCode = Template.asString( | 
					
						
							|  |  |  | 			Array.from( | 
					
						
							|  |  |  | 				importedModules, | 
					
						
							|  |  |  | 				([module, { importVar, request, reexports }]) => { | 
					
						
							|  |  |  | 					const importStatement = runtimeTemplate.importStatement({ | 
					
						
							|  |  |  | 						module, | 
					
						
							| 
									
										
										
										
											2018-08-28 17:50:33 +08:00
										 |  |  | 						chunkGraph, | 
					
						
							| 
									
										
										
										
											2018-06-02 15:53:35 +08:00
										 |  |  | 						request, | 
					
						
							|  |  |  | 						importVar, | 
					
						
							| 
									
										
										
										
											2018-11-17 01:18:44 +08:00
										 |  |  | 						originModule: module, | 
					
						
							|  |  |  | 						runtimeRequirements | 
					
						
							| 
									
										
										
										
											2018-06-02 15:53:35 +08:00
										 |  |  | 					}); | 
					
						
							| 
									
										
										
										
											2020-05-15 22:24:11 +08:00
										 |  |  | 					return importStatement[0] + importStatement[1] + reexports.join("\n"); | 
					
						
							| 
									
										
										
										
											2018-06-02 15:53:35 +08:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			) | 
					
						
							|  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2018-04-28 15:57:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-17 01:18:44 +08:00
										 |  |  | 		const copyAllExports = | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 			exportsInfo.otherExportsInfo.getUsed(runtime) === UsageState.Unused && | 
					
						
							| 
									
										
										
										
											2019-03-14 19:06:59 +08:00
										 |  |  | 			!needExportsCopy; | 
					
						
							| 
									
										
										
										
											2018-11-17 01:18:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// need these globals
 | 
					
						
							|  |  |  | 		runtimeRequirements.add(RuntimeGlobals.module); | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | 		runtimeRequirements.add(RuntimeGlobals.moduleId); | 
					
						
							| 
									
										
										
										
											2018-11-17 01:18:44 +08:00
										 |  |  | 		runtimeRequirements.add(RuntimeGlobals.wasmInstances); | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 		if (exportsInfo.otherExportsInfo.getUsed(runtime) !== UsageState.Unused) { | 
					
						
							| 
									
										
										
										
											2018-11-17 01:18:44 +08:00
										 |  |  | 			runtimeRequirements.add(RuntimeGlobals.makeNamespaceObject); | 
					
						
							|  |  |  | 			runtimeRequirements.add(RuntimeGlobals.exports); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (!copyAllExports) { | 
					
						
							|  |  |  | 			runtimeRequirements.add(RuntimeGlobals.exports); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-28 15:57:21 +08:00
										 |  |  | 		// create source
 | 
					
						
							| 
									
										
										
										
											2018-04-28 00:53:07 +08:00
										 |  |  | 		const source = new RawSource( | 
					
						
							|  |  |  | 			[ | 
					
						
							|  |  |  | 				'"use strict";', | 
					
						
							|  |  |  | 				"// Instantiate WebAssembly module", | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | 				`var wasmExports = ${RuntimeGlobals.wasmInstances}[${module.moduleArgument}.id];`, | 
					
						
							| 
									
										
										
										
											2018-04-28 00:53:07 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 				exportsInfo.otherExportsInfo.getUsed(runtime) !== UsageState.Unused | 
					
						
							| 
									
										
										
										
											2018-11-05 21:36:15 +08:00
										 |  |  | 					? `${RuntimeGlobals.makeNamespaceObject}(${module.exportsArgument});` | 
					
						
							| 
									
										
										
										
											2018-06-02 15:53:35 +08:00
										 |  |  | 					: "", | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-28 15:57:21 +08:00
										 |  |  | 				// this must be before import for circular dependencies
 | 
					
						
							| 
									
										
										
										
											2018-04-28 00:53:07 +08:00
										 |  |  | 				"// export exports from WebAssembly module", | 
					
						
							| 
									
										
										
										
											2018-11-17 01:18:44 +08:00
										 |  |  | 				copyAllExports | 
					
						
							| 
									
										
										
										
											2018-05-09 22:19:31 +08:00
										 |  |  | 					? `${module.moduleArgument}.exports = wasmExports;` | 
					
						
							|  |  |  | 					: "for(var name in wasmExports) " + | 
					
						
							| 
									
										
										
										
											2024-01-14 09:41:34 +08:00
										 |  |  | 						`if(name) ` + | 
					
						
							|  |  |  | 						`${module.exportsArgument}[name] = wasmExports[name];`, | 
					
						
							| 
									
										
										
										
											2018-04-28 15:57:21 +08:00
										 |  |  | 				"// exec imports from WebAssembly module (for esm order)", | 
					
						
							| 
									
										
										
										
											2018-06-02 15:53:35 +08:00
										 |  |  | 				importsCode, | 
					
						
							|  |  |  | 				"", | 
					
						
							| 
									
										
										
										
											2018-04-28 15:57:21 +08:00
										 |  |  | 				"// exec wasm module", | 
					
						
							| 
									
										
										
										
											2019-02-20 18:32:12 +08:00
										 |  |  | 				`wasmExports[""](${initParams.join(", ")})` | 
					
						
							| 
									
										
										
										
											2018-04-28 00:53:07 +08:00
										 |  |  | 			].join("\n") | 
					
						
							|  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2019-11-05 04:05:17 +08:00
										 |  |  | 		return InitFragment.addToSource(source, initFragments, generateContext); | 
					
						
							| 
									
										
										
										
											2018-04-28 00:53:07 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports = WebAssemblyJavascriptGenerator; |