@@ -19,6 +19,8 @@ function compose(...fns) {
1919
2020// Utility functions
2121const isGlobalImport = moduleImport => moduleImport . descr . type === "GlobalType" ;
22+ const isFuncImport = moduleImport =>
23+ moduleImport . descr . type === "FuncImportDescr" ;
2224const initFuncId = t . identifier ( "__webpack_init__" ) ;
2325
2426// TODO replace with @callback
@@ -50,8 +52,8 @@ function getStartFuncIndex(ast) {
5052 let startAtFuncIndex ;
5153
5254 t . traverse ( ast , {
53- Start ( path ) {
54- startAtFuncIndex = path . node . index ;
55+ Start ( { node } ) {
56+ startAtFuncIndex = node . index ;
5557 }
5658 } ) ;
5759
@@ -78,23 +80,57 @@ function getImportedGlobals(ast) {
7880 return importedGlobals ;
7981}
8082
83+ function getCountImportedFunc ( ast ) {
84+ let count = 0 ;
85+
86+ t . traverse ( ast , {
87+ ModuleImport ( { node } ) {
88+ if ( isFuncImport ( node ) === true ) {
89+ count ++ ;
90+ }
91+ }
92+ } ) ;
93+
94+ return count ;
95+ }
96+
8197/**
82- * Get next func index
83- *
84- * Funcs are referenced by their index in the type section, we just return the
85- * next index.
98+ * Get next type index
8699 *
87100 * @param {Object } ast - Module's AST
88101 * @returns {t.IndexLiteral } - index
89102 */
90- function getNextFuncIndex ( ast ) {
103+ function getNextTypeIndex ( ast ) {
91104 const typeSectionMetadata = t . getSectionMetadata ( ast , "type" ) ;
92105
93106 if ( typeof typeSectionMetadata === "undefined" ) {
94107 return t . indexLiteral ( 0 ) ;
95108 }
96109
97- return t . indexLiteral ( typeSectionMetadata . vectorOfSize ) ;
110+ return t . indexLiteral ( typeSectionMetadata . vectorOfSize . value ) ;
111+ }
112+
113+ /**
114+ * Get next func index
115+ *
116+ * The Func section metadata provide informations for implemented funcs
117+ * in order to have the correct index we shift the index by number of external
118+ * functions.
119+ *
120+ * @param {Object } ast - Module's AST
121+ * @param {Number } countImportedFunc - number of imported funcs
122+ * @returns {t.IndexLiteral } - index
123+ */
124+ function getNextFuncIndex ( ast , countImportedFunc ) {
125+ const funcSectionMetadata = t . getSectionMetadata ( ast , "func" ) ;
126+
127+ if ( typeof funcSectionMetadata === "undefined" ) {
128+ return t . indexLiteral ( 0 + countImportedFunc ) ;
129+ }
130+
131+ const vectorOfSize = funcSectionMetadata . vectorOfSize . value ;
132+
133+ return t . indexLiteral ( vectorOfSize + countImportedFunc ) ;
98134}
99135
100136/**
@@ -145,13 +181,15 @@ const rewriteImportedGlobals = state => bin => {
145181 * @param {t.ModuleImport[] } state.importedGlobals list of imported globals
146182 * @param {* } state.funcSectionMetadata ??
147183 * @param {t.IndexLiteral } state.nextFuncIndex index of the next function
184+ * @param {t.IndexLiteral } state.nextTypeIndex index of the next type
148185 * @returns {ArrayBufferTransform } transform
149186 */
150187const addInitFunction = ( {
151188 startAtFuncIndex,
152189 importedGlobals,
153190 funcSectionMetadata,
154- nextFuncIndex
191+ nextFuncIndex,
192+ nextTypeIndex
155193} ) => bin => {
156194 const funcParams = importedGlobals . map ( importedGlobal => {
157195 // used for debugging
@@ -176,14 +214,19 @@ const addInitFunction = ({
176214
177215 const funcResults = [ ] ;
178216
217+ // Code section
179218 const func = t . func ( initFuncId , funcParams , funcResults , funcBody ) ;
180219
220+ // Type section
181221 const functype = t . typeInstructionFunc (
182222 func . signature . params ,
183223 func . signature . result
184224 ) ;
185- const funcindex = t . indexInFuncSection ( nextFuncIndex ) ;
186225
226+ // Func section
227+ const funcindex = t . indexInFuncSection ( nextTypeIndex ) ;
228+
229+ // Export section
187230 const moduleExport = t . moduleExport ( initFuncId . value , "Func" , nextFuncIndex ) ;
188231
189232 return add ( bin , [ func , moduleExport , funcindex , functype ] ) ;
@@ -193,14 +236,19 @@ class WebAssemblyGenerator extends Generator {
193236 generate ( module ) {
194237 const bin = module . originalSource ( ) . source ( ) ;
195238
239+ // FIXME(sven): this module is parsed twice, we could preserve the AST
240+ // from wasm/WebAssemblyParser.js
196241 const ast = decode ( bin , {
197- ignoreDataSection : true
242+ ignoreDataSection : true ,
243+ ignoreCodeSection : true
198244 } ) ;
199245
200246 const importedGlobals = getImportedGlobals ( ast ) ;
201247 const funcSectionMetadata = t . getSectionMetadata ( ast , "func" ) ;
248+ const countImportedFunc = getCountImportedFunc ( ast ) ;
202249 const startAtFuncIndex = getStartFuncIndex ( ast ) ;
203- const nextFuncIndex = getNextFuncIndex ( ast ) ;
250+ const nextFuncIndex = getNextFuncIndex ( ast , countImportedFunc ) ;
251+ const nextTypeIndex = getNextTypeIndex ( ast ) ;
204252
205253 const transform = compose (
206254 removeStartFunc ( { } ) ,
@@ -211,7 +259,8 @@ class WebAssemblyGenerator extends Generator {
211259 importedGlobals,
212260 funcSectionMetadata,
213261 startAtFuncIndex,
214- nextFuncIndex
262+ nextFuncIndex,
263+ nextTypeIndex
215264 } )
216265 ) ;
217266
0 commit comments