[wasm] table.copy: handle overlap and zero count cases
This CL fixes the zero-count and overlapping cases for the table.copy bytecode. R=mstarzinger@chromium.org CC=binji@chromium.org BUG=v8:7747 Change-Id: I6211e4c899621069ebf8bc088b3ab4e80c7bbd0a Reviewed-on: https://chromium-review.googlesource.com/c/1417172 Commit-Queue: Ben Titzer <titzer@chromium.org> Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Cr-Commit-Position: refs/heads/master@{#58887}
This commit is contained in:
parent
fa06d7071a
commit
cb4e772921
@ -1415,10 +1415,18 @@ Address WasmInstanceObject::GetCallTarget(uint32_t func_index) {
|
||||
namespace {
|
||||
void CopyTableEntriesImpl(Handle<WasmInstanceObject> instance, uint32_t dst,
|
||||
uint32_t src, uint32_t count) {
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
auto from_entry = IndirectFunctionTableEntry(instance, dst + i);
|
||||
auto to_entry = IndirectFunctionTableEntry(instance, src + i);
|
||||
from_entry.CopyFrom(to_entry);
|
||||
if (src < dst) {
|
||||
for (uint32_t i = count; i > 0; i--) {
|
||||
auto to_entry = IndirectFunctionTableEntry(instance, dst + i - 1);
|
||||
auto from_entry = IndirectFunctionTableEntry(instance, src + i - 1);
|
||||
to_entry.CopyFrom(from_entry);
|
||||
}
|
||||
} else {
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
auto to_entry = IndirectFunctionTableEntry(instance, dst + i);
|
||||
auto from_entry = IndirectFunctionTableEntry(instance, src + i);
|
||||
to_entry.CopyFrom(from_entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
@ -1429,9 +1437,11 @@ bool WasmInstanceObject::CopyTableEntries(Isolate* isolate,
|
||||
uint32_t table_index, uint32_t dst,
|
||||
uint32_t src, uint32_t count) {
|
||||
CHECK_EQ(0, table_index); // TODO(titzer): multiple tables in TableCopy
|
||||
if (count == 0) return true; // no-op
|
||||
auto max = instance->indirect_function_table_size();
|
||||
if (dst > max || count > (max - dst)) return false; // out-of-bounds
|
||||
if (src > max || count > (max - src)) return false; // out-of-bounds
|
||||
if (dst == src) return true; // no-op
|
||||
|
||||
if (!instance->has_table_object()) {
|
||||
// No table object, only need to update this instance.
|
||||
@ -1454,8 +1464,14 @@ bool WasmInstanceObject::CopyTableEntries(Isolate* isolate,
|
||||
|
||||
// Copy the function entries.
|
||||
Handle<FixedArray> functions(table->functions(), isolate);
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
functions->set(dst + i, functions->get(src + i));
|
||||
if (src < dst) {
|
||||
for (uint32_t i = count; i > 0; i--) {
|
||||
functions->set(dst + i - 1, functions->get(src + i - 1));
|
||||
}
|
||||
} else {
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
functions->set(dst + i, functions->get(src + i));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -30,6 +30,9 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
copy(0, i, kTableSize - i);
|
||||
copy(i, 0, kTableSize - i);
|
||||
}
|
||||
let big = 1000000;
|
||||
copy(big, 0, 0); // nop
|
||||
copy(0, big, 0); // nop
|
||||
})();
|
||||
|
||||
function addFunction(builder, k) {
|
||||
@ -94,6 +97,8 @@ function assertTable(obj, ...elems) {
|
||||
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) {
|
||||
|
Loading…
Reference in New Issue
Block a user