1 |
|
2 |
|
3 |
|
4 |
|
5 | "use strict";
|
6 |
|
7 | const Generator = require("../Generator");
|
8 | const Template = require("../Template");
|
9 | const { RawSource } = require("webpack-sources");
|
10 | const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
|
11 | const WebAssemblyExportImportedDependency = require("../dependencies/WebAssemblyExportImportedDependency");
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 | class WebAssemblyJavascriptGenerator extends Generator {
|
19 | |
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
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 = (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 |
|
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 |
|
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 |
|
152 | module.exports = WebAssemblyJavascriptGenerator;
|