Stream: git-wasmtime

Topic: wasmtime / issue #13521 Computationally large element seg...


view this post on Zulip Wasmtime GitHub notifications bot (May 31 2026 at 16:59):

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 wasmtime from 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:

  1. 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).
  2. Independently of the wasm-smith issue this module taking 2s to instantiate seems a bit excessive. The slowdown is from re-interning ref.func $f on 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 a ref.func the 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

view this post on Zulip Wasmtime GitHub notifications bot (May 31 2026 at 16:59):

alexcrichton added the fuzz-bug label to Issue #13521.

view this post on Zulip Wasmtime GitHub notifications bot (May 31 2026 at 16:59):

alexcrichton added the wasm-proposal:gc label to Issue #13521.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 01 2026 at 15:53):

fitzgen commented on issue #13521:

  1. 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.

  1. Independently of the wasm-smith issue this module taking 2s to instantiate seems a bit excessive. The slowdown is from re-interning ref.func $f on 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 a ref.func the 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).

view this post on Zulip Wasmtime GitHub notifications bot (Jun 01 2026 at 16:09):

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_fuel is specified we unconditionally turn on limit_arrays_in_const_exprs in the config.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 01 2026 at 17:34):

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 wasmtime from 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:

  1. 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).
  2. Independently of the wasm-smith issue this module taking 2s to instantiate seems a bit excessive. The slowdown is from re-interning ref.func $f on 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 a ref.func the 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