diff options
author | Alon Zakai <azakai@google.com> | 2024-02-23 14:51:05 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-23 14:51:05 -0800 |
commit | 7cb213c7d9bf545f626050c293f0bd077584e65c (patch) | |
tree | e340e3e3ee94d23222a4681f0b3469f9209e6060 /src/wasm-interpreter.h | |
parent | 2fc33e65fff4e6312fbcc3716b16a740fb3dce61 (diff) | |
download | binaryen-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.h | 27 |
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. |