v8/test/mjsunit/wasm/table-copy.js
Ben Smith 787d83c57c [wasm] Update bulk-memory instruction immediates
* There are now two indexes for table.copy and memory.copy, one for the
source and the one for the destination table/memory. (see
https://github.com/WebAssembly/bulk-memory-operations/pull/43)

* Reverse the order of the table.init and memory.init indexes, so the
segment index is first and the table/memory index is second. (see
https://github.com/WebAssembly/bulk-memory-operations/pull/45)

Change-Id: I1781edd4200a7b693e3d0814999e6292aafa58d3
Reviewed-on: https://chromium-review.googlesource.com/c/1446149
Reviewed-by: Ben Titzer <titzer@chromium.org>
Commit-Queue: Ben Smith <binji@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59259}
2019-01-31 18:24:17 +00:00

280 lines
7.4 KiB
JavaScript

// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --experimental-wasm-bulk-memory
load("test/mjsunit/wasm/wasm-module-builder.js");
(function TestTableCopyInbounds() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig_v_iii = builder.addType(kSig_v_iii);
let kTableSize = 5;
builder.setTableBounds(kTableSize, kTableSize);
builder.addFunction("copy", sig_v_iii)
.addBody([
kExprGetLocal, 0,
kExprGetLocal, 1,
kExprGetLocal, 2,
kNumericPrefix, kExprTableCopy, kTableZero, kTableZero])
.exportAs("copy");
let instance = builder.instantiate();
let copy = instance.exports.copy;
for (let i = 0; i < kTableSize; i++) {
copy(0, 0, i); // nop
copy(0, i, kTableSize - i);
copy(i, 0, kTableSize - i);
}
})();
function addFunction(builder, k) {
let m = builder.addFunction("", kSig_i_v)
.addBody([...wasmI32Const(k)]);
return m;
}
function addFunctions(builder, count) {
let o = {};
for (var i = 0; i < count; i++) {
o[`f${i}`] = addFunction(builder, i);
}
return o;
}
function assertTable(obj, ...elems) {
for (var i = 0; i < elems.length; i++) {
assertEquals(elems[i], obj.get(i));
}
}
(function TestTableCopyElems() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig_v_iii = builder.addType(kSig_v_iii);
let kTableSize = 5;
builder.setTableBounds(kTableSize, kTableSize);
{
let o = addFunctions(builder, kTableSize);
builder.addElementSegment(0, false,
[o.f0.index, o.f1.index, o.f2.index, o.f3.index, o.f4.index]);
}
builder.addFunction("copy", sig_v_iii)
.addBody([
kExprGetLocal, 0,
kExprGetLocal, 1,
kExprGetLocal, 2,
kNumericPrefix, kExprTableCopy, kTableZero, kTableZero])
.exportAs("copy");
builder.addExportOfKind("table", kExternalTable, 0);
let instance = builder.instantiate();
let table = instance.exports.table;
let f0 = table.get(0), f1 = table.get(1), f2 = table.get(2),
f3 = table.get(3), f4 = table.get(4);
let copy = instance.exports.copy;
assertEquals(0, f0());
assertEquals(1, f1());
assertEquals(2, f2());
assertTable(table, f0, f1, f2, f3, f4);
copy(0, 1, 1);
assertTable(table, f1, f1, f2, f3, f4);
copy(0, 1, 2);
assertTable(table, f1, f2, f2, f3, f4);
copy(3, 0, 2);
assertTable(table, f1, f2, f2, f1, f2);
copy(1, 0, 2);
assertTable(table, f1, f1, f2, f1, f2);
})();
function assertCall(call, ...elems) {
for (var i = 0; i < elems.length; i++) {
assertEquals(elems[i], call(i));
}
}
(function TestTableCopyCalls() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig_v_iii = builder.addType(kSig_v_iii);
let sig_i_i = builder.addType(kSig_i_i);
let sig_i_v = builder.addType(kSig_i_v);
let kTableSize = 5;
builder.setTableBounds(kTableSize, kTableSize);
{
let o = addFunctions(builder, 5);
builder.addElementSegment(0, false,
[o.f0.index, o.f1.index, o.f2.index, o.f3.index, o.f4.index]);
}
builder.addFunction("copy", sig_v_iii)
.addBody([
kExprGetLocal, 0,
kExprGetLocal, 1,
kExprGetLocal, 2,
kNumericPrefix, kExprTableCopy, kTableZero, kTableZero])
.exportAs("copy");
builder.addFunction("call", sig_i_i)
.addBody([
kExprGetLocal, 0,
kExprCallIndirect, sig_i_v, kTableZero])
.exportAs("call");
let instance = builder.instantiate();
let copy = instance.exports.copy;
let call = instance.exports.call;
assertCall(call, 0, 1, 2, 3, 4);
copy(0, 1, 1);
assertCall(call, 1, 1, 2, 3, 4);
copy(0, 1, 2);
assertCall(call, 1, 2, 2, 3, 4);
copy(3, 0, 2);
assertCall(call, 1, 2, 2, 1, 2);
})();
(function TestTableCopyOob1() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig_v_iii = builder.addType(kSig_v_iii);
let kTableSize = 5;
builder.setTableBounds(kTableSize, kTableSize);
builder.addFunction("copy", sig_v_iii)
.addBody([
kExprGetLocal, 0,
kExprGetLocal, 1,
kExprGetLocal, 2,
kNumericPrefix, kExprTableCopy, kTableZero, kTableZero])
.exportAs("copy");
let instance = builder.instantiate();
let copy = instance.exports.copy;
copy(0, 0, 1); // nop
copy(0, 0, kTableSize); // nop
assertThrows(() => copy(0, 0, kTableSize+1));
assertThrows(() => copy(1, 0, kTableSize));
assertThrows(() => copy(0, 1, kTableSize));
{
let big = 1000000;
assertThrows(() => copy(big, 0, 0));
assertThrows(() => copy(0, big, 0));
}
for (let big = 4294967295; big > 1000; big >>>= 1) {
assertThrows(() => copy(big, 0, 1));
assertThrows(() => copy(0, big, 1));
assertThrows(() => copy(0, 0, big));
}
for (let big = -1000; big != 0; big <<= 1) {
assertThrows(() => copy(big, 0, 1));
assertThrows(() => copy(0, big, 1));
assertThrows(() => copy(0, 0, big));
}
})();
(function TestTableCopyShared() {
print(arguments.callee.name);
let kTableSize = 5;
let table = new WebAssembly.Table({element: "anyfunc",
initial: kTableSize,
maximum: kTableSize});
let module = (() => {
let builder = new WasmModuleBuilder();
let sig_v_iii = builder.addType(kSig_v_iii);
let sig_i_i = builder.addType(kSig_i_i);
let sig_i_v = builder.addType(kSig_i_v);
builder.addImportedTable("m", "table", kTableSize, kTableSize);
var g = builder.addImportedGlobal("m", "g", kWasmI32);
for (let i = 0; i < kTableSize; i++) {
let f = builder.addFunction("", kSig_i_v)
.addBody([
kExprGetGlobal, g,
...wasmI32Const(i),
kExprI32Add
]);
f.exportAs(`f${i}`);
}
builder.addFunction("copy", sig_v_iii)
.addBody([
kExprGetLocal, 0,
kExprGetLocal, 1,
kExprGetLocal, 2,
kNumericPrefix, kExprTableCopy, kTableZero, kTableZero])
.exportAs("copy");
builder.addFunction("call", sig_i_i)
.addBody([
kExprGetLocal, 0,
kExprCallIndirect, sig_i_v, kTableZero])
.exportAs("call");
return builder.toModule();
})();
// Two different instances with different globals, to verify that
// dispatch tables get updated with the right instance.
let x = new WebAssembly.Instance(module, {m: {g: 1000, table: table}});
let y = new WebAssembly.Instance(module, {m: {g: 2000, table: table}});
let x_call = x.exports.call;
let y_call = y.exports.call;
assertNotEquals(x.exports.f3, y.exports.f3);
table.set(0, x.exports.f0);
table.set(1, x.exports.f1);
table.set(2, x.exports.f2);
table.set(3, y.exports.f3);
table.set(4, y.exports.f4);
assertEquals(2003, table.get(3)(3));
assertEquals(2003, x_call(3));
assertEquals(2003, y_call(3));
// Check that calling copy on either of them updates the dispatch table
// on both of them.
assertCall(x_call, 1000, 1001, 1002, 2003, 2004);
assertCall(y_call, 1000, 1001, 1002, 2003, 2004);
x.exports.copy(0, 1, 1);
assertCall(x_call, 1001, 1001, 1002, 2003, 2004);
assertCall(y_call, 1001, 1001, 1002, 2003, 2004);
y.exports.copy(0, 1, 2);
assertCall(x_call, 1001, 1002, 1002, 2003, 2004);
assertCall(y_call, 1001, 1002, 1002, 2003, 2004);
x.exports.copy(3, 0, 2);
assertCall(x_call, 1001, 1002, 1002, 1001, 1002);
assertCall(y_call, 1001, 1002, 1002, 1001, 1002);
})();