@@ -23,6 +23,8 @@ function compose(...fns) {
2323
2424// Utility functions
2525const isGlobalImport = moduleImport => moduleImport . descr . type === "GlobalType" ;
26+ const isFuncImport = moduleImport =>
27+ moduleImport . descr . type === "FuncImportDescr" ;
2628const initFuncId = t . identifier ( "__init__" ) ;
2729
2830/**
@@ -41,6 +43,12 @@ const removeStartFunc = state => bin => {
4143 } ) ;
4244} ;
4345
46+ /**
47+ * Retrieve the start function
48+ *
49+ * @param {Object } ast - Module's AST
50+ * @returns {t.Identifier | undefined } - node if any
51+ */
4452function getStartFuncIndex ( ast ) {
4553 let startAtFuncIndex ;
4654
@@ -53,6 +61,12 @@ function getStartFuncIndex(ast) {
5361 return startAtFuncIndex ;
5462}
5563
64+ /**
65+ * Get imported globals
66+ *
67+ * @param {Object } ast - Module's AST
68+ * @returns {Array<t.ModuleImport> } - nodes
69+ */
5670function getImportedGlobals ( ast ) {
5771 const importedGlobals = [ ] ;
5872
@@ -67,6 +81,33 @@ function getImportedGlobals(ast) {
6781 return importedGlobals ;
6882}
6983
84+ /**
85+ * Get next func index
86+ *
87+ * We need to respect the instantation order, first count the number of imported
88+ * func and func declared in the module.
89+ *
90+ * @param {Object } ast - Module's AST
91+ * @returns {t.indexLiteral } - index
92+ */
93+ function getNextFuncIndex ( ast ) {
94+ let count = 0 ;
95+
96+ t . traverse ( ast , {
97+ ModuleImport ( { node } ) {
98+ if ( isFuncImport ( node ) === true ) {
99+ count ++ ;
100+ }
101+ } ,
102+
103+ Func ( { node } ) {
104+ count ++ ;
105+ }
106+ } ) ;
107+
108+ return t . indexLiteral ( count ) ;
109+ }
110+
70111/**
71112 * Rewrite the import globals:
72113 * - removes the ModuleImport instruction
@@ -119,12 +160,11 @@ const rewriteImportedGlobals = state => bin => {
119160const addInitFunction = ( {
120161 startAtFuncIndex,
121162 importedGlobals,
122- funcSectionMetadata
163+ funcSectionMetadata,
164+ nextFuncIndex
123165} ) => bin => {
124166 debug ( "addInitFunction" ) ;
125167
126- const nextTypeIndex = funcSectionMetadata . vectorOfSize ;
127-
128168 const funcParams = importedGlobals . map ( importedGlobal => {
129169 // used for debugging
130170 const id = t . identifier ( `${ importedGlobal . module } .${ importedGlobal . name } ` ) ;
@@ -153,13 +193,9 @@ const addInitFunction = ({
153193 const func = t . func ( initFuncId , funcParams , funcResults , funcBody ) ;
154194
155195 const functype = t . typeInstructionFunc ( func . params , func . result ) ;
156- const funcindex = t . indexInFuncSection ( t . indexLiteral ( nextTypeIndex ) ) ;
196+ const funcindex = t . indexInFuncSection ( nextFuncIndex ) ;
157197
158- const moduleExport = t . moduleExport (
159- initFuncId . value ,
160- "Func" ,
161- t . indexLiteral ( nextTypeIndex )
162- ) ;
198+ const moduleExport = t . moduleExport ( initFuncId . value , "Func" , nextFuncIndex ) ;
163199
164200 return add ( bin , [ func , moduleExport , funcindex , functype ] ) ;
165201} ;
@@ -175,6 +211,7 @@ class WebAssemblyGenerator {
175211 const importedGlobals = getImportedGlobals ( ast ) ;
176212 const funcSectionMetadata = t . getSectionMetadata ( ast , "func" ) ;
177213 const startAtFuncIndex = getStartFuncIndex ( ast ) ;
214+ const nextFuncIndex = getNextFuncIndex ( ast ) ;
178215
179216 const transform = compose (
180217 removeStartFunc ( ) ,
@@ -184,7 +221,8 @@ class WebAssemblyGenerator {
184221 addInitFunction ( {
185222 importedGlobals,
186223 funcSectionMetadata,
187- startAtFuncIndex
224+ startAtFuncIndex,
225+ nextFuncIndex
188226 } )
189227 ) ;
190228
0 commit comments