@@ -8,59 +8,96 @@ const Generator = require("../Generator");
88const Template = require ( "../Template" ) ;
99const { RawSource } = require ( "webpack-sources" ) ;
1010const WebAssemblyImportDependency = require ( "../dependencies/WebAssemblyImportDependency" ) ;
11-
12- function generateInitParams ( module ) {
13- const list = [ ] ;
14-
15- for ( const dep of module . dependencies ) {
16- if ( dep instanceof WebAssemblyImportDependency ) {
17- if ( dep . description . type === "GlobalType" ) {
18- const exportName = dep . name ;
19- const usedName = dep . module && dep . module . isUsed ( exportName ) ;
20-
21- if ( dep . module === null ) {
22- // Dependency was not found, an error will be thrown later
23- continue ;
24- }
25-
26- if ( usedName !== false ) {
27- list . push (
28- `__webpack_require__(${ JSON . stringify (
29- dep . module . id
30- ) } )[${ JSON . stringify ( usedName ) } ]`
31- ) ;
32- }
33- }
34- }
35- }
36-
37- return list ;
38- }
11+ const WebAssemblyExportImportedDependency = require ( "../dependencies/WebAssemblyExportImportedDependency" ) ;
3912
4013class WebAssemblyJavascriptGenerator extends Generator {
4114 generate ( module , dependencyTemplates , runtimeTemplate ) {
4215 const initIdentifer = Array . isArray ( module . usedExports )
4316 ? Template . numberToIdentifer ( module . usedExports . length )
4417 : "__webpack_init__" ;
4518
46- const generateImports = ( ) => {
47- const modules = new Map ( ) ;
48- for ( const dep of module . dependencies ) {
49- if ( dep . module ) modules . set ( dep . module , dep . userRequest ) ;
50- }
51- return Template . asString (
52- Array . from ( modules , ( [ m , r ] ) => {
53- return `${ runtimeTemplate . moduleRaw ( {
54- module : m ,
55- request : r
56- } ) } ;`;
57- } )
58- ) ;
59- } ;
19+ let needExportsCopy = false ;
20+ const importedModules = new Map ( ) ;
21+ const initParams = [ ] ;
22+ let index = 0 ;
23+ for ( const dep of module . dependencies ) {
24+ if ( dep . module ) {
25+ let importData = importedModules . get ( dep . module ) ;
26+ if ( importData === undefined ) {
27+ importedModules . set (
28+ dep . module ,
29+ ( importData = {
30+ importVar : `m${ index } ` ,
31+ index,
32+ request : dep . userRequest ,
33+ names : new Set ( ) ,
34+ reexports : [ ]
35+ } )
36+ ) ;
37+ index ++ ;
38+ }
39+ if ( dep instanceof WebAssemblyImportDependency ) {
40+ importData . names . add ( dep . name ) ;
41+ if ( dep . description . type === "GlobalType" ) {
42+ const exportName = dep . name ;
43+ const usedName = dep . module && dep . module . isUsed ( exportName ) ;
6044
61- // FIXME(sven): assert that the exports exists in the modules
62- // otherwise it will default to i32 0
63- const initParams = generateInitParams ( module ) . join ( "," ) ;
45+ if ( dep . module ) {
46+ if ( usedName ) {
47+ initParams . push (
48+ runtimeTemplate . exportFromImport ( {
49+ module : dep . module ,
50+ request : dep . request ,
51+ importVar : importData . importVar ,
52+ originModule : module ,
53+ exportName : dep . name ,
54+ asiSafe : true ,
55+ isCall : false ,
56+ callContext : null
57+ } )
58+ ) ;
59+ }
60+ }
61+ }
62+ }
63+ if ( dep instanceof WebAssemblyExportImportedDependency ) {
64+ importData . names . add ( dep . name ) ;
65+ const usedName = module . isUsed ( dep . exportName ) ;
66+ if ( usedName ) {
67+ const defineStatement = Template . asString ( [
68+ `${ module . exportsArgument } [${ JSON . stringify (
69+ usedName
70+ ) } ] = ${ runtimeTemplate . exportFromImport ( {
71+ module : dep . module ,
72+ request : dep . request ,
73+ importVar : importData . importVar ,
74+ originModule : module ,
75+ exportName : dep . name ,
76+ asiSafe : true ,
77+ isCall : false ,
78+ callContext : null
79+ } ) } ;`
80+ ] ) ;
81+ importData . reexports . push ( defineStatement ) ;
82+ needExportsCopy = true ;
83+ }
84+ }
85+ }
86+ }
87+ const importsCode = Template . asString (
88+ Array . from (
89+ importedModules ,
90+ ( [ module , { importVar, request, reexports } ] ) => {
91+ const importStatement = runtimeTemplate . importStatement ( {
92+ module,
93+ request,
94+ importVar,
95+ originModule : module
96+ } ) ;
97+ return importStatement + reexports . join ( "\n" ) ;
98+ }
99+ )
100+ ) ;
64101
65102 // create source
66103 const source = new RawSource (
@@ -69,18 +106,24 @@ class WebAssemblyJavascriptGenerator extends Generator {
69106 "// Instantiate WebAssembly module" ,
70107 "var wasmExports = __webpack_require__.w[module.i];" ,
71108
109+ ! Array . isArray ( module . usedExports )
110+ ? `__webpack_require__.r(${ module . exportsArgument } );`
111+ : "" ,
112+
72113 // this must be before import for circular dependencies
73114 "// export exports from WebAssembly module" ,
74- Array . isArray ( module . usedExports )
115+ Array . isArray ( module . usedExports ) && ! needExportsCopy
75116 ? `${ module . moduleArgument } .exports = wasmExports;`
76117 : "for(var name in wasmExports) " +
77118 `if(name != ${ JSON . stringify ( initIdentifer ) } ) ` +
78119 `${ module . exportsArgument } [name] = wasmExports[name];` ,
79120 "// exec imports from WebAssembly module (for esm order)" ,
80- generateImports ( ) ,
81-
121+ importsCode ,
122+ "" ,
82123 "// exec wasm module" ,
83- `wasmExports[${ JSON . stringify ( initIdentifer ) } ](${ initParams } )`
124+ `wasmExports[${ JSON . stringify ( initIdentifer ) } ](${ initParams . join (
125+ ", "
126+ ) } )`
84127 ] . join ( "\n" )
85128 ) ;
86129 return source ;
0 commit comments