Refactor generation of tables/elements in wasm-smith#1426
Refactor generation of tables/elements in wasm-smith#1426alexcrichton merged 5 commits intobytecodealliance:mainfrom
Conversation
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 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
fitzgen
left a comment
There was a problem hiding this comment.
Thanks! Didn't realize we were missing this 😬
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.
5a5f7bc to
47cb9eb
Compare
fitzgen
left a comment
There was a problem hiding this comment.
I really like this clean up, much better than threading the old type_ref_limit parameter everywhere!
| // TODO: fill out more GC types e.g `array.new` and | ||
| // `struct.new` | ||
| _ => {} |
There was a problem hiding this comment.
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.
| 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; |
There was a problem hiding this comment.
Might be worth it to have
fn with_max_type_limit<T>(&mut self, limit: MaxTypeLimit, f: impl FnMut(&mut Self) -> T) -> T {
...
}There was a problem hiding this comment.
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
This commit refactors
wasm-smithand 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 useglobal.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.