Skip to content

Commit 396ecae

Browse files
committed
fix(wasm): get next func index
1 parent 8319a63 commit 396ecae

File tree

1 file changed

+48
-10
lines changed

1 file changed

+48
-10
lines changed

lib/WebAssemblyGenerator.js

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ function compose(...fns) {
2323

2424
// Utility functions
2525
const isGlobalImport = moduleImport => moduleImport.descr.type === "GlobalType";
26+
const isFuncImport = moduleImport =>
27+
moduleImport.descr.type === "FuncImportDescr";
2628
const 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+
*/
4452
function 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+
*/
5670
function 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 => {
119160
const 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

Comments
 (0)