alexcrichton opened issue #13521:
I've reduced this timeout to more-or-less this input:
(module (type $a (array (mut funcref))) (type $s (struct (field anyref))) (table 1 structref (ref.null struct)) (elem structref (item (struct.new $s (array.new $a (ref.func $f) (i32.const 171472957))))) (func $f) )Locally with a release build of
wasmtimefrom main this takes ~2s to instantiate. I've confirmed that with all the recent refactorings this is indeed respecting-Wtimeout=...(epochs kick in) and-Wfuel=...(fuel is checked). Despite this though there's two major issues happening here which are compounding together to surface this during fuzzing:
- Primarily the fuel mechanism for wasm-smith is not kicking in. Notably there's no tracking for fuel in constant expressions, especially constant expressions that consume a dynamic amount of fuel (e.g.
array.new). With differential fuzzing we rely on wasm-smith's fuel to both guarantee similar behavior across engines but additionally prevent infinite loops and resource consumption. We'd need to change wasm-smith's generation strategy for wasm const exprs to handle this case differently, for example. (e.g. back to questions about the top-down approach instead of bottom-up).- Independently of the wasm-smith issue this module taking 2s to instantiate seems a bit excessive. The slowdown is from re-interning
ref.func $fon each iteration of the loop, but naturally it's going to get the same intern'd value from each iteration of the loop. We should probably implement an optimization such that when filling an array with aref.functhe interning only happens once instead of once-per-element-filled. I suspect that would also resolve this fuzz bug, but the fuzz bug might resurface with a slightly different shape due to the inherent wasm-smith limitations.cc @fitzgen do you have thoughts on this? I'm tempted to see how (2) fares on oss-fuzz and see if that basically resolves this
alexcrichton added the fuzz-bug label to Issue #13521.
alexcrichton added the wasm-proposal:gc label to Issue #13521.
fitzgen commented on issue #13521:
- Primarily the fuel mechanism for wasm-smith is not kicking in.
Yeah, not too much we can do here, unfortunately, other than simply not generating large constant expressions when
wasm-smith's fuel is enabled (well, rewrite to ensure that the constant expressions are small in its post-processing pass).We'd need to change wasm-smith's generation strategy for wasm const exprs to handle this case differently, for example. (e.g. back to questions about the top-down approach instead of bottom-up).
I'm not sure I follow. It seems like a fundamental limitation of const expressions that we can't use the instructions that we need to insert our fuel checks in a constant environment. I'm not sure what top-down or bottom-up has to do with it.
- Independently of the wasm-smith issue this module taking 2s to instantiate seems a bit excessive. The slowdown is from re-interning
ref.func $fon each iteration of the loop, but naturally it's going to get the same intern'd value from each iteration of the loop. We should probably implement an optimization such that when filling an array with aref.functhe interning only happens once instead of once-per-element-filled.Yeah we should probably special case the cases where we are filling a single value to avoid the interning on each iteration of the loop.
Ideally we would just inline enough into Wasm that Cranelift's GVN+LICM could do this automatically for us, but the actual interning of funcrefs is the part that is hardest to inline (as opposed to getting the funcref for an interned id or whatever).
alexcrichton commented on issue #13521:
Ah yeah sorry, what I meant is that with top-down generation of constant expressions we know when we're generating the array length so we could tweak the logic to say "generate a limited i32" instead of an arbitrary i32. Turns out const-expr generation already works that way, so one fix for this issue is at https://github.com/bytecodealliance/wasm-tools/pull/2536 which I believe should be relatively easy to integrate into Wasmtime, basically here if
default_fuelis specified we unconditionally turn onlimit_arrays_in_const_exprsin the config.
alexcrichton closed issue #13521:
I've reduced this timeout to more-or-less this input:
(module (type $a (array (mut funcref))) (type $s (struct (field anyref))) (table 1 structref (ref.null struct)) (elem structref (item (struct.new $s (array.new $a (ref.func $f) (i32.const 171472957))))) (func $f) )Locally with a release build of
wasmtimefrom main this takes ~2s to instantiate. I've confirmed that with all the recent refactorings this is indeed respecting-Wtimeout=...(epochs kick in) and-Wfuel=...(fuel is checked). Despite this though there's two major issues happening here which are compounding together to surface this during fuzzing:
- Primarily the fuel mechanism for wasm-smith is not kicking in. Notably there's no tracking for fuel in constant expressions, especially constant expressions that consume a dynamic amount of fuel (e.g.
array.new). With differential fuzzing we rely on wasm-smith's fuel to both guarantee similar behavior across engines but additionally prevent infinite loops and resource consumption. We'd need to change wasm-smith's generation strategy for wasm const exprs to handle this case differently, for example. (e.g. back to questions about the top-down approach instead of bottom-up).- Independently of the wasm-smith issue this module taking 2s to instantiate seems a bit excessive. The slowdown is from re-interning
ref.func $fon each iteration of the loop, but naturally it's going to get the same intern'd value from each iteration of the loop. We should probably implement an optimization such that when filling an array with aref.functhe interning only happens once instead of once-per-element-filled. I suspect that would also resolve this fuzz bug, but the fuzz bug might resurface with a slightly different shape due to the inherent wasm-smith limitations.cc @fitzgen do you have thoughts on this? I'm tempted to see how (2) fares on oss-fuzz and see if that basically resolves this
Last updated: Jul 29 2026 at 05:03 UTC