@@ -2696,7 +2696,8 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
26962696 // stack traces.
26972697 std::vector<Name> functionStack;
26982698
2699- std::unordered_set<Name> droppedSegments;
2699+ std::unordered_set<Name> droppedDataSegments;
2700+ std::unordered_set<Name> droppedElementSegments;
27002701
27012702 struct TableInterfaceInfo {
27022703 // The external interface in which the table is defined.
@@ -2746,6 +2747,8 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
27462747 Flow ret = self ()->visit (segment->data [i]);
27472748 extInterface->tableStore (tableName, offset + i, ret.getSingleValue ());
27482749 }
2750+
2751+ droppedElementSegments.insert (segment->name );
27492752 });
27502753 }
27512754
@@ -3630,7 +3633,7 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
36303633 Address offsetVal (uint32_t (offset.getSingleValue ().geti32 ()));
36313634 Address sizeVal (uint32_t (size.getSingleValue ().geti32 ()));
36323635
3633- if (offsetVal + sizeVal > 0 && droppedSegments .count (curr->segment )) {
3636+ if (offsetVal + sizeVal > 0 && droppedDataSegments .count (curr->segment )) {
36343637 trap (" out of bounds segment access in memory.init" );
36353638 }
36363639 if ((uint64_t )offsetVal + sizeVal > segment->data .size ()) {
@@ -3652,7 +3655,7 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
36523655 }
36533656 Flow visitDataDrop (DataDrop* curr) {
36543657 NOTE_ENTER (" DataDrop" );
3655- droppedSegments .insert (curr->segment );
3658+ droppedDataSegments .insert (curr->segment );
36563659 return {};
36573660 }
36583661 Flow visitMemoryCopy (MemoryCopy* curr) {
@@ -3768,7 +3771,7 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
37683771 const auto & seg = *wasm.getDataSegment (curr->segment );
37693772 auto elemBytes = element.getByteSize ();
37703773 auto end = offset + size * elemBytes;
3771- if ((size != 0ull && droppedSegments .count (curr->segment )) ||
3774+ if ((size != 0ull && droppedDataSegments .count (curr->segment )) ||
37723775 end > seg.data .size ()) {
37733776 trap (" out of bounds segment access in array.new_data" );
37743777 }
@@ -3797,10 +3800,12 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
37973800
37983801 const auto & seg = *wasm.getElementSegment (curr->segment );
37993802 auto end = offset + size;
3800- // TODO: Handle dropped element segments once we support those.
38013803 if (end > seg.data .size ()) {
38023804 trap (" out of bounds segment access in array.new_elem" );
38033805 }
3806+ if (end > 0 && droppedElementSegments.count (curr->segment )) {
3807+ trap (" out of bounds segment access in array.new_elem" );
3808+ }
38043809 contents.reserve (size);
38053810 for (Index i = offset; i < end; ++i) {
38063811 auto val = self ()->visit (seg.data [i]).getSingleValue ();
@@ -3848,7 +3853,7 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
38483853 if (offsetVal + readSize > seg->data .size ()) {
38493854 trap (" out of bounds segment access in array.init_data" );
38503855 }
3851- if (offsetVal + sizeVal > 0 && droppedSegments .count (curr->segment )) {
3856+ if (offsetVal + sizeVal > 0 && droppedDataSegments .count (curr->segment )) {
38523857 trap (" out of bounds segment access in array.init_data" );
38533858 }
38543859 for (size_t i = 0 ; i < sizeVal; i++) {
@@ -3891,11 +3896,13 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
38913896 Module& wasm = *self ()->getModule ();
38923897
38933898 auto * seg = wasm.getElementSegment (curr->segment );
3894- if ((uint64_t )offsetVal + sizeVal > seg->data .size ()) {
3895- trap (" out of bounds segment access in array.init" );
3899+ auto max = (uint64_t )offsetVal + sizeVal;
3900+ if (max > seg->data .size ()) {
3901+ trap (" out of bounds segment access in array.init_elem" );
3902+ }
3903+ if (max > 0 && droppedElementSegments.count (curr->segment )) {
3904+ trap (" out of bounds segment access in array.init_elem" );
38963905 }
3897- // TODO: Check whether the segment has been dropped once we support
3898- // dropping element segments.
38993906 for (size_t i = 0 ; i < sizeVal; i++) {
39003907 // TODO: This is not correct because it does not preserve the identity
39013908 // of references in the table! ArrayNew suffers the same problem.
0 commit comments