Indirect calls should work correctly with imported tables, imported base, and calls to Table.grow. Test below, prints the expected output without calls to table.grow, but calls the wrong functions after subsequent calls to grow.
What steps will reproduce the problem?
Run Test:
let builder = new WasmModuleBuilder();
let mul = builder.addFunction("mul", kSig_i_ii)
.addBody([
kExprGetLocal, 0,
kExprGetLocal, 1,
kExprI32Mul])
.exportAs("mul");
let add = builder.addFunction("add", kSig_i_ii)
.addBody([
kExprGetLocal, 0,
kExprGetLocal, 1,
kExprI32Add
]);
builder.addFunction("main", kSig_i_ii)
.addBody([
kExprI32Const, 10,
kExprGetLocal, 0,
kExprGetLocal, 1,
kExprCallIndirect, 0, kTableZero])
.exportAs("main");
builder.addImportedTable("q", "table", 10, 32);
let g = builder.addImportedGlobal("q", "base", kWasmI32);
builder.addFunctionTableInit(g, true, [mul.index, add.index]);
builder.addExportOfKind("table", kExternalTable, 0);
let module = new WebAssembly.Module(builder.toBuffer());
let t1 = new WebAssembly.Table({element: "anyfunc",
initial: 10, maximum: 30});
for (let i = 0; i < 5; i++) {
print("base = " + i);
let instance = new WebAssembly.Instance(module, {q: {base: i, table: t1}});
main = instance.exports.main;
print("1 * 10 = " + main(1, i));
print("2 + 10 = " + main(2, i+1));
t1.grow(5);
}
What is the expected result?
Should print:
1 * 10 = 10
2 + 10 = 12
base = 1
1 * 10 = 10
2 + 10 = 12
base = 2
1 * 10 = 10
2 + 10 = 12
base = 3
1 * 10 = 10
2 + 10 = 12
base = 4
1 * 10 = 10
2 + 10 = 12
What happens instead?
base = 0
1 * 10 = 10
2 + 10 = 12
10
base = 1
1 * 10 = 10
2 + 10 = 12
15
base = 2
1 * 10 = 11
wasm-function[2]:7: RuntimeError: function signature mismatch
Comment 1 by titzer@chromium.org
, Aug 17 2017