Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor generation of tables/elements in wasm-smith #1426

Merged
merged 5 commits into from
Feb 27, 2024

Conversation

alexcrichton
Copy link
Member

This commit refactors wasm-smith and its generation of both table types and element segments. The goal is to help generate modules of shapes that Wasmtime does not currently support but should. Notably constant expressions are allowed to use global.get, even in element segments, and Wasmtime does not currently support this.

Furthermore this commit additionally enables generating tables with initialization expressions which was not previously supported by wasm-smith.

Internally this refactors a number of pieces of code that work with constant expressions to instead use a shared helper for generating constant expressions. This takes into account subtyping and such to try to generate interesting shapes of expressions when GC is enabled in particular.

This commit refactors `wasm-smith` and its generation of both table
types and element segments. The goal is to help generate modules of
shapes that Wasmtime does not currently support but should. Notably
constant expressions are allowed to use `global.get`, even in element
segments, and Wasmtime does not currently support this.

Furthermore this commit additionally enables generating tables with
initialization expressions which was not previously supported by
`wasm-smith`.

Internally this refactors a number of pieces of code that work with
constant expressions to instead use a shared helper for generating
constant expressions. This takes into account subtyping and such to try
to generate interesting shapes of expressions when GC is enabled in
particular.
alexcrichton added a commit to alexcrichton/wasmtime that referenced this pull request Feb 24, 2024
This commit updates Wasmtime to support `global.get` in constant
expressions when located in table initializers and element segments.
Pre-reference-types this never came up because there was no valid
`global.get` that would typecheck. After the reference-types proposal
landed however this became possible but Wasmtime did not support it.
This was surfaced in bytecodealliance#6705 when the spec test suite was updated and has
a new test that exercises this functionality.

This commit both updates the spec test suite and additionally adds
support for this new form of element segment and table initialization
expression.

The fact that Wasmtime hasn't supported this until now also means that
we have a gap in our fuzz-testing infrastructure. The `wasm-smith`
generator is being updated in bytecodealliance/wasm-tools#1426 to
generate modules with this particular feature and I've tested that with
that PR fuzzing here eventually generates an error before this PR.

Closes bytecodealliance#6705
Copy link
Member

@fitzgen fitzgen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Didn't realize we were missing this 😬

crates/wasm-smith/src/core.rs Outdated Show resolved Hide resolved
crates/wasm-smith/src/core.rs Outdated Show resolved Hide resolved
github-merge-queue bot pushed a commit to bytecodealliance/wasmtime that referenced this pull request Feb 26, 2024
This commit updates Wasmtime to support `global.get` in constant
expressions when located in table initializers and element segments.
Pre-reference-types this never came up because there was no valid
`global.get` that would typecheck. After the reference-types proposal
landed however this became possible but Wasmtime did not support it.
This was surfaced in #6705 when the spec test suite was updated and has
a new test that exercises this functionality.

This commit both updates the spec test suite and additionally adds
support for this new form of element segment and table initialization
expression.

The fact that Wasmtime hasn't supported this until now also means that
we have a gap in our fuzz-testing infrastructure. The `wasm-smith`
generator is being updated in bytecodealliance/wasm-tools#1426 to
generate modules with this particular feature and I've tested that with
that PR fuzzing here eventually generates an error before this PR.

Closes #6705
Don't pass around `type_ref_limit` as an explicit parameter but instead
track it in the `Module` state. This enables reusing
`self.arbitrary_ref_type` in `self.arbitrary_valtype` and preserves the
property where self-referential types may be generated.
Copy link
Member

@fitzgen fitzgen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really like this clean up, much better than threading the old type_ref_limit parameter everywhere!

Comment on lines +1585 to +1587
// TODO: fill out more GC types e.g `array.new` and
// `struct.new`
_ => {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessary to do in this PR, but we do have a self.super_to_sub_types map and self.{array,struct}_types arrays available here that should make implementing this relatively straightforward.

Comment on lines +572 to +584
self.max_type_limit = MaxTypeLimit::Num(type_ref_limit);
for _ in 0..rec_group_size {
let ty = self.arbitrary_sub_type(u, type_ref_limit)?;
let ty = self.arbitrary_sub_type(u)?;
self.add_type(ty);
}
} else {
let type_ref_limit = u32::try_from(self.types.len()).unwrap();
let ty = self.arbitrary_sub_type(u, type_ref_limit)?;
self.max_type_limit = MaxTypeLimit::Num(type_ref_limit);
let ty = self.arbitrary_sub_type(u)?;
self.add_type(ty);
}

self.max_type_limit = MaxTypeLimit::ModuleTypes;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be worth it to have

fn with_max_type_limit<T>(&mut self, limit: MaxTypeLimit, f: impl FnMut(&mut Self) -> T) -> T {
    ...
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With only one method that modifies the max type limit I think I'll stick to this for now because I never like to rename self to me or this, but if this grows in the future I agree a helper should be added

@alexcrichton alexcrichton added this pull request to the merge queue Feb 27, 2024
Merged via the queue into bytecodealliance:main with commit b920742 Feb 27, 2024
17 checks passed
@alexcrichton alexcrichton deleted the more-table-types branch February 27, 2024 19:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants