This issue is a follow up to #11230 and the discussion it spawned around Wasm guests like Rust and C++ that may want to use exceptions but will not use GC, and how we can allow Wasmtime to be tuned for these use cases when embedders know that will not also be running Wasm guests that use GC.
I think it makes sense to open the discussion by enumerating our constraints and desired properties and then analyze potential options through that lens.
Constraints:
-
We must implement the full Wasm exceptions standard. Separately, we can potentially have a (compile-time and/or runtime) configuration where exnrefs are disabled, for example, but Wasmtime must still provide an implementation of the full spec by default.
-
We must be able to collect exception-and-gc-object cycles. When GC is enabled, an exception can contain a GC reference to a (for example) a struct and that struct can have a reference to the exception. If either edge is an owning/rooting reference, then the cycle can never be collected. (Note that exceptions by themselves cannot form cycles, since they are immutable.)
-
We must only have one exceptions implementation. We do not have the engineering resources to maintain multiple, completely-disjoint implementations of the exceptions proposal. We can add knobs to turn certain subsets of functionality on or off, and tweak things here and there, but we can't realistically swap out the fundamental approach and representations.
Desired properties:
-
Small memory overheads. Fundamentally, exceptions must be stored somewhere and that will require memory. Additionally, they are dynamically sized and can have any number of payload fields, which further complicates things. But we shouldn't have to allocate the equivalent of a second full 4GiB linear memory for every LIME-style guest that uses exceptions and throws a couple of times during its execution, if it even throws at all.
-
Small code size. As always, all else being equal, smaller is better. Ideally we wouldn't have to include code in the binary for allocating structs, for example, in builds for embedders that will only ever run LIME+exceptions Wasm programs.
-
Fast. As always, all else being equal, faster runtime execution is better.
-
Simple. As always, all else being equal, simpler and easier to maintain is better.
-
Secure. Everything we add to Wasmtime must be absent known security vulnerabilities or fundamental flaws -- we would never accept an implementation with known use-after-free bugs or which fundamentally allows Wasm guests to escape the sandbox -- but, all else being equal, implementations with more security assurances are better than those with less assurances.
With that out of the way, I'll open up the issue for any ideas that people have!
This issue is a follow up to #11230 and the discussion it spawned around Wasm guests like Rust and C++ that may want to use exceptions but will not use GC, and how we can allow Wasmtime to be tuned for these use cases when embedders know that will not also be running Wasm guests that use GC.
I think it makes sense to open the discussion by enumerating our constraints and desired properties and then analyze potential options through that lens.
Constraints:
We must implement the full Wasm exceptions standard. Separately, we can potentially have a (compile-time and/or runtime) configuration where
exnrefs are disabled, for example, but Wasmtime must still provide an implementation of the full spec by default.We must be able to collect exception-and-gc-object cycles. When GC is enabled, an exception can contain a GC reference to a (for example) a
structand thatstructcan have a reference to the exception. If either edge is an owning/rooting reference, then the cycle can never be collected. (Note that exceptions by themselves cannot form cycles, since they are immutable.)We must only have one exceptions implementation. We do not have the engineering resources to maintain multiple, completely-disjoint implementations of the exceptions proposal. We can add knobs to turn certain subsets of functionality on or off, and tweak things here and there, but we can't realistically swap out the fundamental approach and representations.
Desired properties:
Small memory overheads. Fundamentally, exceptions must be stored somewhere and that will require memory. Additionally, they are dynamically sized and can have any number of payload fields, which further complicates things. But we shouldn't have to allocate the equivalent of a second full 4GiB linear memory for every LIME-style guest that uses exceptions and throws a couple of times during its execution, if it even throws at all.
Small code size. As always, all else being equal, smaller is better. Ideally we wouldn't have to include code in the binary for allocating
structs, for example, in builds for embedders that will only ever run LIME+exceptions Wasm programs.Fast. As always, all else being equal, faster runtime execution is better.
Simple. As always, all else being equal, simpler and easier to maintain is better.
Secure. Everything we add to Wasmtime must be absent known security vulnerabilities or fundamental flaws -- we would never accept an implementation with known use-after-free bugs or which fundamentally allows Wasm guests to escape the sandbox -- but, all else being equal, implementations with more security assurances are better than those with less assurances.
With that out of the way, I'll open up the issue for any ideas that people have!