[wasm][bulk-memory] Adjust table.copy to recent spec changes

With recent spec changes, table.copy of length 0 does not trap anymore,
and we copy backwards whenever src < dst.

R=binji@chromium.org

Change-Id: I48e2b65083565631abc41bf4fdf4971f80fdf440
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1706471
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Reviewed-by: Ben Smith <binji@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62797}
This commit is contained in:
Andreas Haas 2019-07-18 09:33:28 +02:00 committed by Commit Bot
parent 0c919c45e9
commit 6e281ec3e3
4 changed files with 14 additions and 23 deletions

View File

@ -1832,6 +1832,8 @@ bool WasmInstanceObject::CopyTableEntries(Isolate* isolate,
uint32_t table_src_index,
uint32_t dst, uint32_t src,
uint32_t count) {
// Copying 0 elements is a no-op.
if (count == 0) return true;
CHECK_LT(table_dst_index, instance->tables().length());
CHECK_LT(table_src_index, instance->tables().length());
auto table_dst = handle(
@ -1840,7 +1842,7 @@ bool WasmInstanceObject::CopyTableEntries(Isolate* isolate,
WasmTableObject::cast(instance->tables().get(table_src_index)), isolate);
uint32_t max_dst = static_cast<uint32_t>(table_dst->entries().length());
uint32_t max_src = static_cast<uint32_t>(table_src->entries().length());
bool copy_backward = src < dst && dst - src < count;
bool copy_backward = src < dst;
bool ok = ClampToBounds(dst, &count, max_dst);
// Use & instead of && so the clamp is not short-circuited.
ok &= ClampToBounds(src, &count, max_src);

View File

@ -776,34 +776,23 @@ void TestTableCopyOobWrites(ExecutionTier execution_tier, int table_dst,
CheckTable(isolate, table, f0, f1, f2, f3, f4);
// Non-overlapping, src < dst.
// Non-overlapping, src < dst. Because of src < dst, we copy backwards.
// Therefore the first access already traps, and the table is not changed.
r.CheckCallViaJS(0xDEADBEEF, 3, 0, 3);
CheckTable(isolate, table, f0, f1, f2, f0, f1);
CheckTable(isolate, table, f0, f1, f2, f3, f4);
// Non-overlapping, dst < src.
r.CheckCallViaJS(0xDEADBEEF, 0, 4, 2);
if (table_dst == table_src) {
CheckTable(isolate, table, f1, f1, f2, f0, f1);
} else {
CheckTable(isolate, table, f4, f1, f2, f0, f1);
}
CheckTable(isolate, table, f4, f1, f2, f3, f4);
// Overlapping, src < dst. This is required to copy backward, but the first
// access will be out-of-bounds, so nothing changes.
r.CheckCallViaJS(0xDEADBEEF, 3, 0, 99);
if (table_dst == table_src) {
CheckTable(isolate, table, f1, f1, f2, f0, f1);
} else {
CheckTable(isolate, table, f4, f1, f2, f0, f1);
}
CheckTable(isolate, table, f4, f1, f2, f3, f4);
// Overlapping, dst < src.
r.CheckCallViaJS(0xDEADBEEF, 0, 1, 99);
if (table_dst == table_src) {
CheckTable(isolate, table, f1, f2, f0, f1, f1);
} else {
CheckTable(isolate, table, f1, f2, f3, f4, f1);
}
CheckTable(isolate, table, f1, f2, f3, f4, f4);
}
WASM_EXEC_TEST(TableCopyOobWritesFrom0To0) {
@ -848,8 +837,8 @@ void TestTableCopyOob1(ExecutionTier execution_tier, int table_dst,
{
const uint32_t big = 1000000;
r.CheckCallViaJS(0xDEADBEEF, big, 0, 0);
r.CheckCallViaJS(0xDEADBEEF, 0, big, 0);
r.CheckCallViaJS(0, big, 0, 0);
r.CheckCallViaJS(0, 0, big, 0);
}
for (uint32_t big = 4294967295; big > 1000; big >>= 1) {

View File

@ -50,10 +50,11 @@ resetTable();
instance.exports.copy(3, 0, 2);
assertTable([1000, 1001, 1002, 1000, 1001]);
// Non-overlapping, src < dst.
// Non-overlapping, src < dst. Because of src < dst, we copy backwards.
// Therefore the first access already traps, and the table is not changed.
resetTable();
assertTraps(kTrapTableOutOfBounds, () => instance.exports.copy(3, 0, 3));
assertTable([1000, 1001, 1002, 1000, 1001]);
assertTable([1000, 1001, 1002, 1003, 1004]);
// Non-overlapping, dst < src.
resetTable();

View File

@ -17,7 +17,6 @@
# TODO(ahaas): Incorporate recent changes to the bulk-memory-operations
# proposal.
'tests/proposals/bulk-memory-operations/elem': [FAIL],
'tests/proposals/bulk-memory-operations/table_copy': [FAIL],
'tests/proposals/bulk-memory-operations/memory_fill': [FAIL],
'tests/proposals/bulk-memory-operations/bulk': [FAIL],
'tests/proposals/bulk-memory-operations/data': [FAIL],