Commit 6b650574 authored by Andreas Haas's avatar Andreas Haas Committed by Commit Bot

[wasm] Allow multi-table initialization in the wasm-module-builder

This CL just adds a parameter to addElementSegment and adjusts all
existing tests.

Note that addElementSegment contains some convenience code to construct
one initial table if it does not exist yet. I did not extend that code
to multiple tables. If you want to use multiple tables, you have to
create them first before calling addElementSegment.

R=clemensh@chromium.org

Bug: v8:7581
Change-Id: Ie131fd5dc19856703ab5cfb2fa8f7d576f70a18b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1520709Reviewed-by: 's avatarClemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60211}
parent 02810201
......@@ -24,7 +24,7 @@ let builder1 = new WasmModuleBuilder();
builder1.setName('module_1');
builder1.addFunction('main', kSig_i_v).addBody([kExprUnreachable]);
builder1.addImportedTable('z', 'table');
builder1.addElementSegment(0, false, [0], true);
builder1.addElementSegment(0, 0, false, [0], true);
let module1 = new WebAssembly.Module(builder1.toBuffer());
let instance1 =
new WebAssembly.Instance(module1, {z: {table: instance0.exports.table}});
......
......@@ -11,7 +11,7 @@ let q_table = builder.addImportedTable("q", "table")
let q_base = builder.addImportedGlobal("q", "base", kWasmI32);
let q_fun = builder.addImport("q", "fun", kSig_v_v);
builder.addType(kSig_i_ii);
builder.addElementSegment(q_base, true, [ q_fun ])
builder.addElementSegment(0, q_base, true, [ q_fun ])
let module = new WebAssembly.Module(builder.toBuffer());
let table = new WebAssembly.Table({
element: "anyfunc",
......
......@@ -19,6 +19,6 @@ const builder2 = new WasmModuleBuilder();
const mul_import = builder2.addImport('q', 'wasm_mul', kSig_i_ii);
builder2.addImportedTable('q', 'table');
const glob_import = builder2.addImportedGlobal('q', 'glob', kWasmI32);
builder2.addElementSegment(glob_import, true, [mul_import]);
builder2.addElementSegment(0, glob_import, true, [mul_import]);
builder2.instantiate(
{q: {glob: 0, js_div: i => i, wasm_mul: mul, table: table}});
......@@ -32,7 +32,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
kExprCallIndirect, 0, kTableZero
])
.exportFunc();
builder.addElementSegment(0, false, [0, 1, 1, 0]);
builder.addElementSegment(0, 0, false, [0, 1, 1, 0]);
return builder.instantiate({q: {f2: i1.exports.f2, f1: i1.exports.f1}});
})();
......
......@@ -409,7 +409,7 @@ function getMemoryFill(mem) {
(function TestElemDropActive() {
const builder = new WasmModuleBuilder();
builder.setTableBounds(5, 5);
builder.addElementSegment(0, false, [0, 0, 0]);
builder.addElementSegment(0, 0, false, [0, 0, 0]);
builder.addFunction('drop', kSig_v_v)
.addBody([
kNumericPrefix, kExprElemDrop,
......
......@@ -218,7 +218,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
.exportAs("main");
builder.setTableBounds(kTableSize, kTableSize);
builder.addElementSegment(0, false, [f1.index]);
builder.addElementSegment(0, 0, false, [f1.index]);
builder.addExportOfKind("table", kExternalTable, 0);
return new WebAssembly.Module(builder.toBuffer());
......@@ -239,7 +239,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
.exportAs("main");
builder.addImportedTable("z", "table", kTableSize, kTableSize);
builder.addElementSegment(1, false, [f2.index], true);
builder.addElementSegment(0, 1, false, [f2.index], true);
var m2_bytes = builder.toBuffer();
var m2 = new WebAssembly.Module(m2_bytes);
......
......@@ -41,8 +41,8 @@ let kTableSize = 50;
let f17 = addConstFunc(builder, 17);
builder.addExport("f15", f15);
builder.addExport("f17", f17);
builder.addElementSegment(15, false, [f15], true);
builder.addElementSegment(1, false, [call.index], true);
builder.addElementSegment(0, 15, false, [f15], true);
builder.addElementSegment(0, 1, false, [call.index], true);
var mod1 = builder.toModule();
}
......@@ -62,10 +62,10 @@ let kTableSize = 50;
])
.exportAs("call");
let f26 = addConstFunc(builder, 26);
builder.addElementSegment(17, false, [f17], true);
builder.addElementSegment(21, false, [f21], true);
builder.addElementSegment(26, false, [f26], true);
builder.addElementSegment(5, false, [call.index], true);
builder.addElementSegment(0, 17, false, [f17], true);
builder.addElementSegment(0, 21, false, [f21], true);
builder.addElementSegment(0, 26, false, [f26], true);
builder.addElementSegment(0, 5, false, [call.index], true);
var mod2 = builder.toModule();
}
......@@ -113,8 +113,8 @@ function addConstFuncUsingGlobal(builder, val) {
let f18 = addConstFuncUsingGlobal(builder, 18);
builder.addExport("f14", f14);
builder.addExport("f18", f18);
builder.addElementSegment(14, false, [f14], true);
builder.addElementSegment(1, false, [call.index], true);
builder.addElementSegment(0, 14, false, [f14], true);
builder.addElementSegment(0, 1, false, [call.index], true);
var mod1 = builder.toModule();
}
......@@ -134,10 +134,10 @@ function addConstFuncUsingGlobal(builder, val) {
])
.exportAs("call");
let f28 = addConstFuncUsingGlobal(builder, 28);
builder.addElementSegment(18, false, [f18], true);
builder.addElementSegment(22, false, [f22], true);
builder.addElementSegment(28, false, [f28], true);
builder.addElementSegment(5, false, [call.index], true);
builder.addElementSegment(0, 18, false, [f18], true);
builder.addElementSegment(0, 22, false, [f22], true);
builder.addElementSegment(0, 28, false, [f28], true);
builder.addElementSegment(0, 5, false, [call.index], true);
var mod2 = builder.toModule();
}
......@@ -193,8 +193,8 @@ function addConstFuncUsingMemory(builder, val) {
let f19 = addConstFuncUsingMemory(builder, 19);
builder.addExport("f13", f13);
builder.addExport("f19", f19);
builder.addElementSegment(13, false, [f13], true);
builder.addElementSegment(1, false, [call.index], true);
builder.addElementSegment(0, 13, false, [f13], true);
builder.addElementSegment(0, 1, false, [call.index], true);
var mod1 = builder.toModule();
}
......@@ -216,10 +216,10 @@ function addConstFuncUsingMemory(builder, val) {
])
.exportAs("call");
let f29 = addConstFuncUsingMemory(builder, 29);
builder.addElementSegment(19, false, [f19], true);
builder.addElementSegment(23, false, [f23], true);
builder.addElementSegment(29, false, [f29], true);
builder.addElementSegment(5, false, [call.index], true);
builder.addElementSegment(0, 19, false, [f19], true);
builder.addElementSegment(0, 23, false, [f23], true);
builder.addElementSegment(0, 29, false, [f29], true);
builder.addElementSegment(0, 5, false, [call.index], true);
var mod2 = builder.toModule();
}
......
......@@ -169,7 +169,7 @@ function AddFunctions(builder) {
.exportAs("main");
builder.setTableBounds(length, length);
builder.addElementSegment(base, false, [f.add.index, f.sub.index, f.mul.index]);
builder.addElementSegment(0, base, false, [f.add.index, f.sub.index, f.mul.index]);
return builder.instantiate();
}
......@@ -207,7 +207,7 @@ function AddFunctions(builder) {
builder.setTableBounds(10, 10);
var g = builder.addImportedGlobal("fff", "base", kWasmI32);
builder.addElementSegment(g, true, [f.mul.index, f.add.index, f.sub.index]);
builder.addElementSegment(0, g, true, [f.mul.index, f.add.index, f.sub.index]);
var module = new WebAssembly.Module(builder.toBuffer());
......
......@@ -51,7 +51,7 @@ function js_div(a, b) { return (a / b) | 0; }
builder.setTableBounds(10, 10);
let g = builder.addImportedGlobal("q", "base", kWasmI32);
builder.addElementSegment(
g, true, [f.mul.index, f.add.index, f.sub.index, d]);
0, g, true, [f.mul.index, f.add.index, f.sub.index, d]);
builder.addExportOfKind("table", kExternalTable, 0);
let module = new WebAssembly.Module(builder.toBuffer());
......@@ -110,7 +110,7 @@ function js_div(a, b) { return (a / b) | 0; }
builder.setTableBounds(kTableSize, kTableSize);
let g = builder.addImportedGlobal("q", "base", kWasmI32);
builder.addElementSegment(
g, true, [f.mul.index, f.add.index, f.sub.index, d]);
0, g, true, [f.mul.index, f.add.index, f.sub.index, d]);
builder.addExportOfKind("table", kExternalTable, 0);
let m1 = new WebAssembly.Module(builder.toBuffer());
......@@ -180,7 +180,7 @@ function js_div(a, b) { return (a / b) | 0; }
let g = builder.addImportedGlobal("q", "base", kWasmI32);
let f = AddFunctions(builder);
builder.addElementSegment(
g, true, [f.mul.index, f.add.index, f.sub.index, d]);
0, g, true, [f.mul.index, f.add.index, f.sub.index, d]);
builder.addFunction("main", kSig_i_ii)
.addBody([
kExprI32Const, 55, // --
......@@ -256,7 +256,7 @@ function js_div(a, b) { return (a / b) | 0; }
kExprGetLocal, 0,
kExprCallIndirect, sig_index, kTableZero]) // --
.exportAs("main");
builder.addElementSegment(g, true, [f.index]);
builder.addElementSegment(0, g, true, [f.index]);
let module = new WebAssembly.Module(builder.toBuffer());
......@@ -297,7 +297,7 @@ function js_div(a, b) { return (a / b) | 0; }
.exportAs("main");
builder.setTableBounds(kTableSize, kTableSize);
builder.addElementSegment(0, false, [f1.index]);
builder.addElementSegment(0, 0, false, [f1.index]);
builder.addExportOfKind("table", kExternalTable, 0);
var m1 = new WebAssembly.Module(builder.toBuffer());
......@@ -316,7 +316,7 @@ function js_div(a, b) { return (a / b) | 0; }
.exportAs("main");
builder.addImportedTable("z", "table", kTableSize, kTableSize);
builder.addElementSegment(1, false, [f2.index], true);
builder.addElementSegment(0, 1, false, [f2.index], true);
var m2 = new WebAssembly.Module(builder.toBuffer());
......@@ -411,7 +411,7 @@ function js_div(a, b) { return (a / b) | 0; }
kExprGetLocal, 0,
kExprCallIndirect, sig_index, kTableZero]) // --
.exportAs("main");
builder.addElementSegment(g, true, [g]);
builder.addElementSegment(0, g, true, [g]);
let module = new WebAssembly.Module(builder.toBuffer());
var instances = [];
......@@ -542,7 +542,7 @@ function js_div(a, b) { return (a / b) | 0; }
let offset = i + 1;
let len = i + 2;
let index = indexes[i];
builder.addElementSegment(offset, false, new Array(len).fill(index));
builder.addElementSegment(0, offset, false, new Array(len).fill(index));
}
let instance = builder.instantiate();
......@@ -586,7 +586,7 @@ function js_div(a, b) { return (a / b) | 0; }
builder1.setName('module_1');
builder1.addFunction('f', kSig_i_i).addBody([kExprGetLocal, 0]);
builder1.addImportedTable('z', 'table');
builder1.addElementSegment(0, false, [0], true);
builder1.addElementSegment(0, 0, false, [0], true);
let module1 = new WebAssembly.Module(builder1.toBuffer());
let instance1 =
new WebAssembly.Instance(module1, {z: {table: instance0.exports.table}});
......@@ -624,7 +624,7 @@ function js_div(a, b) { return (a / b) | 0; }
builder = new WasmModuleBuilder();
builder.addFunction('main', kSig_i_v).addBody([kExprI32Const, 0, kExprI32LoadMem, 0, 0]);
builder.addImportedTable('', 'table');
builder.addElementSegment(0, false, [0], true);
builder.addElementSegment(0, 0, false, [0], true);
builder.addImportedMemory('', 'memory', 1);
......@@ -732,7 +732,7 @@ function js_div(a, b) { return (a / b) | 0; }
builder.setTableBounds(10, 10);
let g = builder.addImportedGlobal("q", "base", kWasmI32);
builder.addElementSegment(g, true, [j, w]);
builder.addElementSegment(0, g, true, [j, w]);
let module = new WebAssembly.Module(builder.toBuffer());
for (var i = 0; i < 5; i++) {
......@@ -781,7 +781,7 @@ function js_div(a, b) { return (a / b) | 0; }
.exportAs("main");
let g = builder.addImportedGlobal("q", "base", kWasmI32);
builder.addElementSegment(g, true, [j, w]);
builder.addElementSegment(0, g, true, [j, w]);
let module = new WebAssembly.Module(builder.toBuffer());
for (var i = 0; i < 5; i++) {
......@@ -820,7 +820,7 @@ function js_div(a, b) { return (a / b) | 0; }
kExprCallIndirect, 0, kTableZero
])
.exportFunc();
builder.addElementSegment(0, false, [0, 1, 1, 0]);
builder.addElementSegment(0, 0, false, [0, 1, 1, 0]);
return builder.instantiate({q: {f2: i1.exports.f2, f1: i1.exports.f1}});
})();
......@@ -882,7 +882,7 @@ function js_div(a, b) { return (a / b) | 0; }
])
.exportFunc();
builder.exportMemoryAs("memory");
builder.addElementSegment(0, false, [0, 1, 2, 3]);
builder.addElementSegment(0, 0, false, [0, 1, 2, 3]);
var instance = builder.instantiate({q: {f1: f100, f2: f200, f3: f300}});
setMemI32(instance, 0, 5000000);
setMemI32(instance, 4, 6000000);
......
......@@ -537,7 +537,7 @@ function checkStack(stack, expected_lines) {
const builder1 = new WasmModuleBuilder();
builder1.addFunction('main', kSig_i_v).addBody([kExprUnreachable]);
builder1.addImportedTable('z', 'table');
builder1.addElementSegment(0, false, [0], true);
builder1.addElementSegment(0, 0, false, [0], true);
const module1 = new WebAssembly.Module(builder1.toBuffer());
const instance1 =
new WebAssembly.Instance(module1, {z: {table: instance0.exports.table}});
......
......@@ -135,7 +135,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
let pick = builder.addImport("q", "pick", sig_i_iii);
const tableIndex = 3; // Arbitrary location of import
builder.addElementSegment(tableIndex,false,[pick]);
builder.addElementSegment(0, tableIndex,false,[pick]);
let main = builder.addFunction("main", kSig_i_iii)
.addBody([
......
......@@ -62,7 +62,7 @@ function assertTable(obj, ...elems) {
{
let o = addFunctions(builder, kTableSize);
builder.addElementSegment(0, false,
builder.addElementSegment(0, 0, false,
[o.f0.index, o.f1.index, o.f2.index, o.f3.index, o.f4.index]);
}
......@@ -116,7 +116,7 @@ function assertCall(call, ...elems) {
{
let o = addFunctions(builder, 5);
builder.addElementSegment(0, false,
builder.addElementSegment(0, 0, false,
[o.f0.index, o.f1.index, o.f2.index, o.f3.index, o.f4.index]);
}
......@@ -158,7 +158,7 @@ function assertCall(call, ...elems) {
{
let o = addFunctions(builder, kTableSize);
builder.addElementSegment(0, false,
builder.addElementSegment(0, 0, false,
[o.f0.index, o.f1.index, o.f2.index]);
}
......
......@@ -11,7 +11,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
const f1 = builder.addFunction('f', kSig_i_v).addBody([kExprI32Const, 11]);
const f2 = builder.addFunction('f', kSig_i_v).addBody([kExprI32Const, 22]);
const offset = 3;
builder.addElementSegment(offset, false, [f1.index, f2.index], false);
builder.addElementSegment(0, offset, false, [f1.index, f2.index], false);
const instance = builder.instantiate();
......@@ -27,7 +27,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
const f2 = builder.addFunction('f', kSig_i_v).addBody([kExprI32Const, 22])
.exportAs("f2");
const offset = 3;
builder.addElementSegment(offset, false, [f1.index, f2.index], false);
builder.addElementSegment(0, offset, false, [f1.index, f2.index], false);
const instance = builder.instantiate();
......@@ -42,8 +42,8 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
const f1 = builder.addFunction('f', kSig_i_v).addBody([kExprI32Const, 11]);
const f2 = builder.addFunction('f', kSig_i_v).addBody([kExprI32Const, 22]);
const offset = 3;
builder.addElementSegment(offset, false, [f1.index, f2.index], false);
builder.addElementSegment(offset + 1, false, [f1.index, f2.index], false);
builder.addElementSegment(0, offset, false, [f1.index, f2.index], false);
builder.addElementSegment(0, offset + 1, false, [f1.index, f2.index], false);
const instance = builder.instantiate();
......@@ -58,7 +58,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
const f1 = builder.addFunction('f', kSig_i_v).addBody([kExprI32Const, 11]).exportAs("f1");
const f2 = builder.addFunction('f', kSig_i_v).addBody([kExprI32Const, 22]);
const offset = 3;
builder.addElementSegment(offset, false, [f1.index, f1.index, f1.index], false);
builder.addElementSegment(0, offset, false, [f1.index, f1.index, f1.index], false);
const instance = builder.instantiate();
......@@ -78,7 +78,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
const f1 = builder.addFunction('f', kSig_i_v).addBody([kExprI32Const, 11]);
const f2 = builder.addFunction('f', kSig_i_v).addBody([kExprI32Const, 22]);
const offset = 3;
builder.addElementSegment(offset, false, [f1.index, f1.index, f1.index], false);
builder.addElementSegment(0, offset, false, [f1.index, f1.index, f1.index], false);
const instance = builder.instantiate();
......@@ -97,7 +97,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
const f1 = builder.addFunction('f', kSig_i_v).addBody([kExprI32Const, 11]);
const f2 = builder.addFunction('f', kSig_i_v).addBody([kExprI32Const, 22]);
const offset = 3;
builder.addElementSegment(offset, false, [f1.index, f1.index, f1.index], false);
builder.addElementSegment(0, offset, false, [f1.index, f1.index, f1.index], false);
const instance = builder.instantiate();
assertEquals(null, instance.exports.table.get(offset - 1));
......@@ -111,7 +111,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
const f1 = builder.addFunction('f', kSig_i_v).addBody([kExprI32Const, 11]);
const f2 = builder.addFunction('f', kSig_i_v).addBody([kExprI32Const, 22]);
const offset = 3;
builder.addElementSegment(offset, false, [f1.index, f1.index, f1.index], false);
builder.addElementSegment(0, offset, false, [f1.index, f1.index, f1.index], false);
const instance = builder.instantiate();
assertThrows(() => instance.exports.table.get(size + 3), RangeError);
......@@ -125,7 +125,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
const import1 = builder.addImport("q", "fun", kSig_i_ii);
const f1 = builder.addFunction('f', kSig_i_v).addBody([kExprI32Const, 11]);
const offset = 3;
builder.addElementSegment(offset, false, [f1.index, import1], false);
builder.addElementSegment(0, offset, false, [f1.index, import1], false);
const instance = builder.instantiate({q: {fun: () => 33}});
assertEquals(33, instance.exports.table.get(offset + 1)());
......
......@@ -132,7 +132,7 @@ let id = (() => { // identity exported function
builder.addImportedTable("q", "table", 5, 32);
let g = builder.addImportedGlobal("q", "base", kWasmI32);
builder.addElementSegment(g, true,
builder.addElementSegment(0, g, true,
[funcs.mul.index, funcs.add.index, funcs.sub.index]);
builder.addExportOfKind("table", kExternalTable, 0);
let module = new WebAssembly.Module(builder.toBuffer());
......@@ -179,9 +179,9 @@ let id = (() => { // identity exported function
let t = builder.addImport("q", "exp_ten", sig_i_v);
builder.setTableBounds(7, 35);
// builder.addElementSegment(g1, true,
// builder.addElementSegment(0, g1, true,
// [funcs.mul.index, funcs.add.index, funcs.sub.index]);
builder.addElementSegment(g1, true, [a, i, t]);
builder.addElementSegment(0, g1, true, [a, i, t]);
builder.addExportOfKind("table", kExternalTable, 0);
let module = new WebAssembly.Module(builder.toBuffer());
......@@ -214,7 +214,7 @@ let id = (() => { // identity exported function
let funcs = addFunctions(builder1);
builder1.addImportedTable("q", "table", 6, 36);
builder1.addElementSegment(g, true,
builder1.addElementSegment(0, g, true,
[funcs.mul.index, funcs.add.index, funcs.sub.index]);
let module1 = new WebAssembly.Module(builder1.toBuffer());
......@@ -266,7 +266,7 @@ let id = (() => { // identity exported function
kExprGetLocal, 0,
kExprCallIndirect, index_i_ii, kTableZero])
.exportAs("main");
builder.addElementSegment(0, false, [0], true);
builder.addElementSegment(0, 0, false, [0], true);
return new WebAssembly.Module(builder.toBuffer());
}
......
......@@ -863,11 +863,11 @@ class WasmModuleBuilder {
this.exports.push({name: name, kind: kExternalMemory, index: 0});
}
addElementSegment(base, is_global, array, is_import = false) {
addElementSegment(table, base, is_global, array, is_import = false) {
if (this.tables.length + this.num_imported_tables == 0) {
this.addTable(kWasmAnyFunc, 0);
}
this.element_segments.push({base: base, is_global: is_global,
this.element_segments.push({table: table, base: base, is_global: is_global,
array: array, is_active: true});
if (!is_global) {
var length = base + array.length;
......@@ -895,7 +895,7 @@ class WasmModuleBuilder {
if (this.tables.length == 0) {
this.addTable(kWasmAnyFunc, 0);
}
return this.addElementSegment(this.tables[0].initial_size, false, array);
return this.addElementSegment(0, this.tables[0].initial_size, false, array);
}
setTableBounds(min, max = undefined) {
......@@ -1113,7 +1113,10 @@ class WasmModuleBuilder {
for (let init of inits) {
if (init.is_active) {
// Active segment.
section.emit_u8(0); // table index / flags
// TODO(ahaas): Adjust the encoding of != 0 table indices once
// the anyref proposal and the bulk-memory-operations proposal
// agree on it.
section.emit_u32v(init.table); // table index / flags
if (init.is_global) {
section.emit_u8(kExprGetGlobal);
} else {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment