[wasm] Support table.copy for anyref tables
The table.copy instruction used the indirect_function_table_size field of the instance for bounds-checks. However, when Table 0 is of type anyref, this field is not set. Now we use the actual size of the table instead. R=clemensh@chromium.org Bug: chromium:977101 Change-Id: Idda9cfe228141877747ed9a824936a1232f58cf8 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1669695 Commit-Queue: Andreas Haas <ahaas@chromium.org> Reviewed-by: Clemens Hammacher <clemensh@chromium.org> Cr-Commit-Position: refs/heads/master@{#62315}
This commit is contained in:
parent
62a2a6efbc
commit
21719af9ae
@ -1778,7 +1778,9 @@ bool WasmInstanceObject::CopyTableEntries(Isolate* isolate,
|
||||
// TODO(titzer): multiple tables in TableCopy
|
||||
CHECK_EQ(0, table_src_index);
|
||||
CHECK_EQ(0, table_dst_index);
|
||||
auto max = instance->indirect_function_table_size();
|
||||
auto table = handle(
|
||||
WasmTableObject::cast(instance->tables().get(table_src_index)), isolate);
|
||||
uint32_t max = static_cast<uint32_t>(table->entries().length());
|
||||
bool copy_backward = src < dst && dst - src < count;
|
||||
bool ok = ClampToBounds(dst, &count, max);
|
||||
// Use & instead of && so the clamp is not short-circuited.
|
||||
@ -1790,9 +1792,6 @@ bool WasmInstanceObject::CopyTableEntries(Isolate* isolate,
|
||||
|
||||
if (dst == src || count == 0) return ok; // no-op
|
||||
|
||||
// TODO(titzer): multiple tables in TableCopy
|
||||
auto table = handle(
|
||||
WasmTableObject::cast(instance->tables().get(table_src_index)), isolate);
|
||||
// Broadcast table copy operation to all instances that import this table.
|
||||
Handle<FixedArray> dispatch_tables(table->dispatch_tables(), isolate);
|
||||
for (int i = 0; i < dispatch_tables->length();
|
||||
|
72
test/mjsunit/wasm/table-copy-anyref.js
Normal file
72
test/mjsunit/wasm/table-copy-anyref.js
Normal file
@ -0,0 +1,72 @@
|
||||
// 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 --experimental-wasm-anyref
|
||||
|
||||
load('test/mjsunit/wasm/wasm-module-builder.js');
|
||||
|
||||
let kTableSize = 5;
|
||||
|
||||
let table = new WebAssembly.Table(
|
||||
{element: 'anyref', initial: kTableSize, maximum: kTableSize});
|
||||
|
||||
let builder = new WasmModuleBuilder();
|
||||
builder.addImportedTable('m', 'table', kTableSize, kTableSize, kWasmAnyRef);
|
||||
builder.addTable(kWasmAnyFunc, 1000);
|
||||
|
||||
builder.addFunction('copy', kSig_v_iii)
|
||||
.addBody([
|
||||
kExprGetLocal, 0, kExprGetLocal, 1, kExprGetLocal, 2, kNumericPrefix,
|
||||
kExprTableCopy, kTableZero, kTableZero
|
||||
])
|
||||
.exportFunc();
|
||||
|
||||
const instance = builder.instantiate({m: {table: table}});
|
||||
|
||||
function resetTable() {
|
||||
table.set(0, 1000);
|
||||
table.set(1, 1001);
|
||||
table.set(2, 1002);
|
||||
table.set(3, 1003);
|
||||
table.set(4, 1004);
|
||||
}
|
||||
|
||||
function assertTable(values) {
|
||||
for (let i = 0; i < kTableSize; ++i) {
|
||||
assertEquals(table.get(i), values[i]);
|
||||
}
|
||||
}
|
||||
|
||||
resetTable();
|
||||
instance.exports.copy(0, 1, 1);
|
||||
assertTable([1001, 1001, 1002, 1003, 1004]);
|
||||
|
||||
resetTable();
|
||||
instance.exports.copy(0, 1, 2);
|
||||
assertTable([1001, 1002, 1002, 1003, 1004]);
|
||||
|
||||
resetTable();
|
||||
instance.exports.copy(3, 0, 2);
|
||||
assertTable([1000, 1001, 1002, 1000, 1001]);
|
||||
|
||||
// Non-overlapping, src < dst.
|
||||
resetTable();
|
||||
assertTraps(kTrapTableOutOfBounds, () => instance.exports.copy(3, 0, 3));
|
||||
assertTable([1000, 1001, 1002, 1000, 1001]);
|
||||
|
||||
// Non-overlapping, dst < src.
|
||||
resetTable();
|
||||
assertTraps(kTrapTableOutOfBounds, () => instance.exports.copy(0, 4, 2));
|
||||
assertTable([1004, 1001, 1002, 1003, 1004]);
|
||||
|
||||
// Overlapping, src < dst. This is required to copy backward, but the first
|
||||
// access will be out-of-bounds, so nothing changes.
|
||||
resetTable();
|
||||
assertTraps(kTrapTableOutOfBounds, () => instance.exports.copy(3, 0, 99));
|
||||
assertTable([1000, 1001, 1002, 1003, 1004]);
|
||||
|
||||
// Overlapping, dst < src.
|
||||
resetTable();
|
||||
assertTraps(kTrapTableOutOfBounds, () => instance.exports.copy(0, 1, 99));
|
||||
assertTable([1001, 1002, 1003, 1004, 1004]);
|
Loading…
Reference in New Issue
Block a user