summaryrefslogtreecommitdiff
path: root/src/wasm-interpreter.h
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2024-02-23 14:51:05 -0800
committerGitHub <noreply@github.com>2024-02-23 14:51:05 -0800
commit7cb213c7d9bf545f626050c293f0bd077584e65c (patch)
treee340e3e3ee94d23222a4681f0b3469f9209e6060 /src/wasm-interpreter.h
parent2fc33e65fff4e6312fbcc3716b16a740fb3dce61 (diff)
downloadbinaryen-7cb213c7d9bf545f626050c293f0bd077584e65c.tar.gz
binaryen-7cb213c7d9bf545f626050c293f0bd077584e65c.tar.bz2
binaryen-7cb213c7d9bf545f626050c293f0bd077584e65c.zip
Implement dropping of active Element Segments (#6343)
Also rename the existing droppedSegments to droppedDataSegments for clarity.
Diffstat (limited to 'src/wasm-interpreter.h')
-rw-r--r--src/wasm-interpreter.h27
1 files changed, 17 insertions, 10 deletions
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index 409bec9d8..f1b081e51 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -2696,7 +2696,8 @@ private:
// stack traces.
std::vector<Name> functionStack;
- std::unordered_set<Name> droppedSegments;
+ std::unordered_set<Name> droppedDataSegments;
+ std::unordered_set<Name> droppedElementSegments;
struct TableInterfaceInfo {
// The external interface in which the table is defined.
@@ -2746,6 +2747,8 @@ private:
Flow ret = self()->visit(segment->data[i]);
extInterface->tableStore(tableName, offset + i, ret.getSingleValue());
}
+
+ droppedElementSegments.insert(segment->name);
});
}
@@ -3630,7 +3633,7 @@ public:
Address offsetVal(uint32_t(offset.getSingleValue().geti32()));
Address sizeVal(uint32_t(size.getSingleValue().geti32()));
- if (offsetVal + sizeVal > 0 && droppedSegments.count(curr->segment)) {
+ if (offsetVal + sizeVal > 0 && droppedDataSegments.count(curr->segment)) {
trap("out of bounds segment access in memory.init");
}
if ((uint64_t)offsetVal + sizeVal > segment->data.size()) {
@@ -3652,7 +3655,7 @@ public:
}
Flow visitDataDrop(DataDrop* curr) {
NOTE_ENTER("DataDrop");
- droppedSegments.insert(curr->segment);
+ droppedDataSegments.insert(curr->segment);
return {};
}
Flow visitMemoryCopy(MemoryCopy* curr) {
@@ -3768,7 +3771,7 @@ public:
const auto& seg = *wasm.getDataSegment(curr->segment);
auto elemBytes = element.getByteSize();
auto end = offset + size * elemBytes;
- if ((size != 0ull && droppedSegments.count(curr->segment)) ||
+ if ((size != 0ull && droppedDataSegments.count(curr->segment)) ||
end > seg.data.size()) {
trap("out of bounds segment access in array.new_data");
}
@@ -3797,10 +3800,12 @@ public:
const auto& seg = *wasm.getElementSegment(curr->segment);
auto end = offset + size;
- // TODO: Handle dropped element segments once we support those.
if (end > seg.data.size()) {
trap("out of bounds segment access in array.new_elem");
}
+ if (end > 0 && droppedElementSegments.count(curr->segment)) {
+ trap("out of bounds segment access in array.new_elem");
+ }
contents.reserve(size);
for (Index i = offset; i < end; ++i) {
auto val = self()->visit(seg.data[i]).getSingleValue();
@@ -3848,7 +3853,7 @@ public:
if (offsetVal + readSize > seg->data.size()) {
trap("out of bounds segment access in array.init_data");
}
- if (offsetVal + sizeVal > 0 && droppedSegments.count(curr->segment)) {
+ if (offsetVal + sizeVal > 0 && droppedDataSegments.count(curr->segment)) {
trap("out of bounds segment access in array.init_data");
}
for (size_t i = 0; i < sizeVal; i++) {
@@ -3891,11 +3896,13 @@ public:
Module& wasm = *self()->getModule();
auto* seg = wasm.getElementSegment(curr->segment);
- if ((uint64_t)offsetVal + sizeVal > seg->data.size()) {
- trap("out of bounds segment access in array.init");
+ auto max = (uint64_t)offsetVal + sizeVal;
+ if (max > seg->data.size()) {
+ trap("out of bounds segment access in array.init_elem");
+ }
+ if (max > 0 && droppedElementSegments.count(curr->segment)) {
+ trap("out of bounds segment access in array.init_elem");
}
- // TODO: Check whether the segment has been dropped once we support
- // dropping element segments.
for (size_t i = 0; i < sizeVal; i++) {
// TODO: This is not correct because it does not preserve the identity
// of references in the table! ArrayNew suffers the same problem.