Skip to content

Commit e3a687f

Browse files
authored
Merge pull request webpack#7221 from xtuc/fix-wasm-transformation
Fix wasm transformation
2 parents 839e80a + 4237954 commit e3a687f

File tree

2 files changed

+40
-8
lines changed

2 files changed

+40
-8
lines changed

lib/wasm/WebAssemblyGenerator.js

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ function compose(...fns) {
1919

2020
// Utility functions
2121
const isGlobalImport = moduleImport => moduleImport.descr.type === "GlobalType";
22+
const isFuncImport = moduleImport =>
23+
moduleImport.descr.type === "FuncImportDescr";
2224
const 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,6 +80,20 @@ 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
/**
8298
* Get next type index
8399
*
@@ -97,17 +113,24 @@ function getNextTypeIndex(ast) {
97113
/**
98114
* Get next func index
99115
*
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+
*
100120
* @param {Object} ast - Module's AST
121+
* @param {Number} countImportedFunc - number of imported funcs
101122
* @returns {t.IndexLiteral} - index
102123
*/
103-
function getNextFuncIndex(ast) {
124+
function getNextFuncIndex(ast, countImportedFunc) {
104125
const funcSectionMetadata = t.getSectionMetadata(ast, "func");
105126

106127
if (typeof funcSectionMetadata === "undefined") {
107-
return t.indexLiteral(0);
128+
return t.indexLiteral(0 + countImportedFunc);
108129
}
109130

110-
return t.indexLiteral(funcSectionMetadata.vectorOfSize.value);
131+
const vectorOfSize = funcSectionMetadata.vectorOfSize.value;
132+
133+
return t.indexLiteral(vectorOfSize + countImportedFunc);
111134
}
112135

113136
/**
@@ -191,14 +214,19 @@ const addInitFunction = ({
191214

192215
const funcResults = [];
193216

217+
// Code section
194218
const func = t.func(initFuncId, funcParams, funcResults, funcBody);
195219

220+
// Type section
196221
const functype = t.typeInstructionFunc(
197222
func.signature.params,
198223
func.signature.result
199224
);
225+
226+
// Func section
200227
const funcindex = t.indexInFuncSection(nextTypeIndex);
201228

229+
// Export section
202230
const moduleExport = t.moduleExport(initFuncId.value, "Func", nextFuncIndex);
203231

204232
return add(bin, [func, moduleExport, funcindex, functype]);
@@ -217,8 +245,9 @@ class WebAssemblyGenerator extends Generator {
217245

218246
const importedGlobals = getImportedGlobals(ast);
219247
const funcSectionMetadata = t.getSectionMetadata(ast, "func");
248+
const countImportedFunc = getCountImportedFunc(ast);
220249
const startAtFuncIndex = getStartFuncIndex(ast);
221-
const nextFuncIndex = getNextFuncIndex(ast);
250+
const nextFuncIndex = getNextFuncIndex(ast, countImportedFunc);
222251
const nextTypeIndex = getNextTypeIndex(ast);
223252

224253
const transform = compose(

test/cases/wasm/table/index.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
// the message is inconsistency between some nodejs versions
2+
const UNKNOWN_FUNCTION_TABLE = /invalid index into function table|invalid function/;
3+
14
it("should support tables", function() {
25
return import("./wasm-table.wasm").then(function(wasm) {
36
expect(wasm.callByIndex(0)).toEqual(42);
47
expect(wasm.callByIndex(1)).toEqual(13);
5-
expect(() => wasm.callByIndex(2)).toThrow("invalid function");
8+
expect(() => wasm.callByIndex(2)).toThrow(UNKNOWN_FUNCTION_TABLE);
69
});
710
});
811

@@ -23,6 +26,6 @@ it("should support imported tables", function() {
2326
return import("./wasm-table-imported.wasm").then(function(wasm) {
2427
expect(wasm.callByIndex(0)).toEqual(42);
2528
expect(wasm.callByIndex(1)).toEqual(13);
26-
expect(() => wasm.callByIndex(2)).toThrow("invalid function");
29+
expect(() => wasm.callByIndex(2)).toThrow(UNKNOWN_FUNCTION_TABLE);
2730
});
2831
});

0 commit comments

Comments
 (0)