Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/wasm/wasm-ir-builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2250,6 +2250,16 @@ Result<> IRBuilder::makeStructWait(HeapType type, Index index) {
if (!type.isStruct()) {
return Err{"expected struct type annotation on struct.wait"};
}
// This is likely checked in the caller by the `fieldidx` parser.
if (index >= type.getStruct().fields.size()) {
return Err{"struct.wait field index out of bounds"};
}

if (type.getStruct().fields.at(index).packedType !=
Field::PackedType::WaitQueue) {
return Err{"struct.wait field index must contain a `waitqueue`"};
}

StructWait curr(wasm.allocator);
curr.index = index;
CHECK_ERR(ChildPopper{*this}.visitStructWait(&curr, type));
Expand Down
25 changes: 6 additions & 19 deletions src/wasm/wasm-validator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3517,25 +3517,12 @@ void FunctionValidator::visitStructWait(StructWait* curr) {
curr,
"struct.wait timeout must be an i64");

if (curr->ref->type == Type::unreachable || curr->ref->type.isNull()) {
return;
}

// In practice this likely fails during parsing instead.
if (!shouldBeTrue(curr->index <
curr->ref->type.getHeapType().getStruct().fields.size(),
curr,
"struct.wait index immediate should be less than the field "
"count of the struct")) {
return;
}

shouldBeTrue(curr->ref->type.getHeapType()
.getStruct()
.fields.at(curr->index)
.packedType == Field::WaitQueue,
curr,
"struct.wait struct field must be a waitqueue");
// Checks to the ref argument's type are done in IRBuilder where we have the
// type annotation immediate available. We check that
// * The reference arg is a subtype of the type immediate
// * The index immediate is a valid field index of the type immediate (and
// thus valid for the reference's type too)
// * The index points to a packed waitqueue field
}

void FunctionValidator::visitArrayNew(ArrayNew* curr) {
Expand Down
4 changes: 2 additions & 2 deletions test/spec/waitqueue.wast
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
(func (param $expected i32) (param $timeout i64) (result i32)
(struct.wait $t 0 (ref.null $t) (local.get $expected) (local.get $timeout))
)
) "struct.wait struct field must be a waitqueue"
) "struct.wait struct field index must contain a `waitqueue`"
)

(assert_invalid
Expand Down Expand Up @@ -38,7 +38,7 @@

;; unreachable is allowed
(module
(type $t (struct (field i32)))
(type $t (struct (field waitqueue)))
(func (param $expected i32) (param $timeout i64) (result i32)
(struct.wait $t 0 (unreachable) (local.get $expected) (local.get $timeout))
)
Expand Down
Loading