|
Revision tags: dev, v36.0.9, v44.0.1, v43.0.2, v36.0.8, v24.0.8, v44.0.0, v43.0.1, v42.0.2, v36.0.7, v24.0.7, v43.0.0, v42.0.1, v41.0.4, v42.0.0, v40.0.4, v36.0.6, v24.0.6 |
|
| #
332b4ce6 |
| 24-Feb-2026 |
Saúl Cabrera <[email protected]> |
fuzz: Enable winch-aarch64 (#12646)
As of https://github.com/bytecodealliance/wasmtime/pull/11051, Winch supports all of Core Wasm on aarch64. This commit enables fuzzing respectively.
|
|
Revision tags: v41.0.3, v41.0.2, v41.0.1, v36.0.5, v40.0.3, v41.0.0, v36.0.4, v39.0.2, v40.0.2, v40.0.1 |
|
| #
93d22fcd |
| 07-Jan-2026 |
Nick Fitzgerald <[email protected]> |
Migrate fuzzing to `wasmtime::error` (#12263)
* Migrate fuzzing to `wasmtime::error`
* fix
|
|
Revision tags: v40.0.0, v39.0.1, v39.0.0, v38.0.4, v37.0.3, v36.0.3, v24.0.5, v38.0.3, v38.0.2, v38.0.1, v37.0.2, v37.0.1, v37.0.0 |
|
| #
a631d20a |
| 04-Sep-2025 |
Paul Osborne <[email protected]> |
cranelift: stack-switching support (#11003)
* cranelift: stack-switching support
This initial commit represents the "pr2" base commit with minimal merge conflicts resolved. Due to OOB conflicts, t
cranelift: stack-switching support (#11003)
* cranelift: stack-switching support
This initial commit represents the "pr2" base commit with minimal merge conflicts resolved. Due to OOB conflicts, this commit is not functional as-is, but using it as a base in order to allow for easier reviewing of the delta from this commit to what will be used for the PR against upstream.
Co-authored-by: Daniel Hillerström <[email protected]> Co-authored-by: Paul Osborne <[email protected]>
* cranelift: stack-switching updates pass 1
This first set of changes updates the base pr in order to compiled and pass basic checks (compile, clippy, fmt) with the biggest part of the change being to eliminate injection of tracing/assertions in JIT'ed code.
* cranelift: stack-switching: restore original visibility for a few func_environ members
* cranelift: stack-switching conditional compilation
At this point, the only bit we really branch on is what we do in order to avoid problems tying into wasmtime_environ. This is basd on the approach and macro used by the gc code for converting presence/absence of the cranelift feature flag to cranelift compile time. This is a bit of a half-measure for now as we still compile most stack-switching code in cranelift, but this does enough to avoid causing problems with missing definitions in wasmtime_environ.
* cranelift: avoid "as" casts in stack-switching
Replace either with infallible From or fallible, panicing TryFrom alternatives where required.
* cranelift: cleanup stack-switching control_effect signatures
After removing emission of runtime trace logging and assertions, there were several unused parameters. Remove those from the ControlEffect signatures completely.
* cranelift: rename stack-switching VMArray to VMHostArray
This matches a change to the mirrored runtime type in the upstream changes.
* stack-switching: fix typo
Co-authored-by: Daniel Hillerström <[email protected]>
* stack-switching: used Index impl for get_stack_slot_data
* stack-switching: use smallvec over vec in several cases
* stack-switching: avoid resumetable naming confusion
* stack-switching: cleanup unused params from unchecked_get_continuation
The extra parameters here used to be used for emitting runtime assertions, but with those gone we just had unused params and lifetimes, clean those out.
* stack_switching: simplify store_data_entries assertion
* stack-switching: simplify translate_table_{grow,fill} control flow
* stack-switching: remove translate_resume_throw stub
There's already a stub elsewhere and this is not called, when exceptions are added and it is time to revisit, this method can be restored.
* stack-switching: compute control_context_size based on target triple
* stack-switching: VMHostArrayRef updates
Rename VMHostArray -> VMHostArrayRef Change impl to compute address with offset upfront rather than on each load.
* stack-switching: move cranelift code to live under func_environ
This matches the directory structure for gc and aids in visibility for a few members required by stack-switching code in cranelift.
* stack-switching: formatting fix
* stack-switching: reduce visibility on a few additional items
* stack-switching: simplify contobj fatptr con/de-struction
* stack-switching: add disas tests to cover new instructions
* stack-switching: fix layout of VMContObj
In the course of the various runtime updates, the layout of the runtime VMContObj got switched around. This resulted in failures when doing certain table operations on continuations.
This change fixes that layout problem and adds some tests with offsets to avoid the problem. Due to the way that we interact with the VMContObj in cranelift, we don't use these offsets outside of the tests.
* Fix formatting of merge conflict resolution
* cranelift: remove ir::function::get_stack_slot_data
This method isn't required as sized_stack_slots is already pub.
* stack-switching: reduce visibility of a couple func_environ methods
* stack-switching: define VMContObj as two words
This change migrates VMContObj and its usages in cranelift and runtime to work with the VMContObj fat pointer as two words in order to better target different architectures (still gated to x86_64 for now).
To support this, a size type was plumbed into the builtins function signature types (as is done for component types) that maps to usize.
* fixup! stack-switching: define VMContObj as two words
* stack-switching: add stub Val::ContRef
This type is not fully complete until continuation/gc integration is revisited (#10248) but without these changes, test cases are now failing on panics as we need some representation of continuation references in the runtime Val enumeration.
Runtime errors with TODO notes are added for the stubbed code paths to revisit later.
* fixup! stack-switching: add stub Val::ContRef
* fixup! stack-switching: add stub Val::ContRef
* fixup! stack-switching: define VMContObj as two words
prtest:full
* stack-switching: don't conflate host and target pointer sizes
Disas tests were failing on i686 targeting x86_64 as the size of the host pointer was leaking into what we were using to do codegen in a few paths. This patch is a bit of a hack as it seems like using a generic <T> for T: *mut u8 (as an example) is a bit questionable. To keep things small, I do a hacky typecheck to map pointers to the target pointer size here.
* stack-switching: VMHostArray entry sizes based off env PtrSize
Revisiting the previous commit with an approach that should be less brittle.
---------
Co-authored-by: Frank Emrich <[email protected]> Co-authored-by: Daniel Hillerström <[email protected]>
show more ...
|
|
Revision tags: v36.0.2, v36.0.1, v36.0.0, v35.0.0, v24.0.4, v33.0.2, v34.0.2 |
|
| #
eaa4632e |
| 15-Jul-2025 |
Chris Fallin <[email protected]> |
Implement exception objects. (#11230)
* WIP: Working exception objects
* Clean build with gc disabled (`cargo check -p wasmtime --no-default-features --features runtime`).
* Review feedback.
* St
Implement exception objects. (#11230)
* WIP: Working exception objects
* Clean build with gc disabled (`cargo check -p wasmtime --no-default-features --features runtime`).
* Review feedback.
* Stub out C-API support.
* Fix Clippy complaints.
* Fix dead-code warning in c-api build.
* Actually fix 27->26 reserved bit rename and test.
* Fix exnref doc-test.
* fix fuzzing build
* fix feature-flagging on Instance::id
* Bless disas test diff due to reserved-bits change.
* Review feedback.
show more ...
|
|
Revision tags: v34.0.1, v33.0.1, v24.0.3, v32.0.1, v34.0.0 |
|
| #
d3e7548e |
| 27-May-2025 |
Alex Crichton <[email protected]> |
Enable the `from_over_into` Clippy lint (#10837)
This requires implementing `From<T> for U` instead of `Into<U> for T`. While both trait impls are valid the `From` one is more useful because it imp
Enable the `from_over_into` Clippy lint (#10837)
This requires implementing `From<T> for U` instead of `Into<U> for T`. While both trait impls are valid the `From` one is more useful because it implies `Into` and additionally gives you `From`. This additionally then migrates the existing codebase to using the new style of impls.
show more ...
|
|
Revision tags: v33.0.0 |
|
| #
90ac295e |
| 19-May-2025 |
Alex Crichton <[email protected]> |
Update Wasmtime to the 2024 Rust Edition (#10806)
* Update Wasmtime to the 2024 Rust Edition
Now that our MSRV supports the 2024 edition it's possible to make this switch. This commit moves Wasmtim
Update Wasmtime to the 2024 Rust Edition (#10806)
* Update Wasmtime to the 2024 Rust Edition
Now that our MSRV supports the 2024 edition it's possible to make this switch. This commit moves Wasmtime to the 2024 Edition to keep up-to-date with Rust idioms and access many of the edition features exclusive to the 2024 edition.
prtest:full
* Reformat with the 2024 edition
show more ...
|
|
Revision tags: v32.0.0, v31.0.0 |
|
| #
5b9e8765 |
| 12-Mar-2025 |
Nick Fitzgerald <[email protected]> |
Enable the GC proposal during general fuzzing (#10332)
* Enable the GC proposal during general fuzzing
This allows us to fuzz Wasm GC in our fuzz targets that use the common config-generation infra
Enable the GC proposal during general fuzzing (#10332)
* Enable the GC proposal during general fuzzing
This allows us to fuzz Wasm GC in our fuzz targets that use the common config-generation infrastructure, such as the differential fuzz target.
Fixes #10328
* Make handling of non-deterministic errors more robust in differential fuzzer
* remove logging from functions that can be called from signal handlers
show more ...
|
|
Revision tags: v30.0.2, v30.0.1, v30.0.0, v29.0.1, v29.0.0, v28.0.1 |
|
| #
c78d44ef |
| 13-Jan-2025 |
Alex Crichton <[email protected]> |
Enable fuzzing for Pulley & Winch (#9966)
* Enable fuzzing for Pulley & Winch
This commit refactors the `wasmtime-fuzzing` crate to enable fuzzing the Pulley interpreter and the Winch compiler more
Enable fuzzing for Pulley & Winch (#9966)
* Enable fuzzing for Pulley & Winch
This commit refactors the `wasmtime-fuzzing` crate to enable fuzzing the Pulley interpreter and the Winch compiler more often. Winch has been feature-complete for much of wasm for a good amount of time now and Pulley now supports many wasm proposals as well. Both strategies have wasm proposals that are still disabled, however.
I've run fuzzers for a bit locally and haven't turned up too too much, but I'm sure OSS-Fuzz will chastise me and tell me all the places I'm forgetting to add various configs and tweaks.
* Fix test build
show more ...
|
| #
b3b50943 |
| 13-Jan-2025 |
Alex Crichton <[email protected]> |
Improve some logging in the differential fuzzer (#9982)
Clearly show "lhs" and "rhs" more often and then also swap the order of the arguments in `assert_error_match` to match the "lhs" and "rhs" ter
Improve some logging in the differential fuzzer (#9982)
Clearly show "lhs" and "rhs" more often and then also swap the order of the arguments in `assert_error_match` to match the "lhs" and "rhs" terminology of the original execution.
show more ...
|
|
Revision tags: v28.0.0, v27.0.0, v26.0.1, v25.0.3, v24.0.2, v26.0.0, v21.0.2, v22.0.1, v23.0.3, v25.0.2, v24.0.1 |
|
| #
ec3b2d22 |
| 30-Sep-2024 |
Nick Fitzgerald <[email protected]> |
Implement most `array.*` instructions for the GC proposal (#9326)
* Implement most `array.*` instructions for the GC proposal
This does not implement `array.copy` and `array.init_elem` yet, but imp
Implement most `array.*` instructions for the GC proposal (#9326)
* Implement most `array.*` instructions for the GC proposal
This does not implement `array.copy` and `array.init_elem` yet, but implements all other `array.*` instructions:
* `array.new` * `array.new_fixed` * `array.new_default` * `array.new_data` * `array.new_elem` * `array.fill` * `array.init_data` * `array.len` * `array.get` * `array.get_s` * `array.get_u` * `array.set`
Note that the initial plumbing for `array.{copy,init_elem}` is in place, but the instructions themselves are not implemented yet.
* Fix no-gc builds
* Fix some clippy warnings
* cargo fmt
* Fix another clippy error
* Fix more clippy errors
* Remove debug logging
* Add array.fill helper
* exit scope even on panic
show more ...
|
|
Revision tags: v25.0.1, v25.0.0 |
|
| #
7b744a9d |
| 13-Sep-2024 |
Alex Crichton <[email protected]> |
Make host trap handlers optional (#9230)
* Make host trap handlers optional
This commit introduces a new configuration option `Config::host_trap_handlers` which enables disabling the reliance on ho
Make host trap handlers optional (#9230)
* Make host trap handlers optional
This commit introduces a new configuration option `Config::host_trap_handlers` which enables disabling the reliance on host trap handlers (e.g. signal handlers on Unix) at runtime. This is intended to help increase portability in cases where signal handlers are otherwise difficult. This is achieved by plumbing the translation environment to more locations which now conditionally lowers to calls to a function to raise a trap instead of a trap instruction.
The caveats of this support are:
* This is not yet implemented for Winch * This requires disabling spectre mitigations * This does not yet support shared memories since it forces dynamic memories to be used.
These points are all possible to address but it might be best to see how this feature evolves over time. I'll also note that this is not an optimized implementation and likely has a fair bit of overhead. For example the solution in #6926 of a more optimized stub to jump-and-trap is not implemented yet.
Closes #6926
* Fix build
* Fix clippy warnings
* Review comments
* Ignore new test on miri
show more ...
|
|
Revision tags: v24.0.0, v23.0.2 |
|
| #
a0442ea0 |
| 05-Aug-2024 |
Hamir Mahal <[email protected]> |
Enforce `uninlined_format_args` for the workspace (#9065)
* Enforce `uninlined_format_args` for the workspace
* fix: failing `Monolith Checks` job
* fix: formatting
|
|
Revision tags: v23.0.1, v23.0.0, v22.0.0, v21.0.1, v21.0.0, v20.0.2, v20.0.1, v20.0.0, v17.0.3, v19.0.2, v18.0.4 |
|
| #
0fa13013 |
| 04-Apr-2024 |
Nick Fitzgerald <[email protected]> |
Add `GcRuntime` and `GcCompiler` traits; `i31ref` support (#8196)
\### The `GcRuntime` and `GcCompiler` Traits
This commit factors out the details of the garbage collector away from the rest of the
Add `GcRuntime` and `GcCompiler` traits; `i31ref` support (#8196)
\### The `GcRuntime` and `GcCompiler` Traits
This commit factors out the details of the garbage collector away from the rest of the runtime and the compiler. It does this by introducing two new traits, very similar to a subset of [those proposed in the Wasm GC RFC], although not all equivalent functionality has been added yet because Wasmtime doesn't support, for example, GC structs yet:
[those proposed in the Wasm GC RFC]: https://github.com/bytecodealliance/rfcs/blob/main/accepted/wasm-gc.md#defining-the-pluggable-gc-interface
1. The `GcRuntime` trait: This trait defines how to create new GC heaps, run collections within them, and execute the various GC barriers the collector requires.
Rather than monomorphize all of Wasmtime on this trait, we use it as a dynamic trait object. This does imply some virtual call overhead and missing some inlining (and resulting post-inlining) optimization opportunities. However, it is *much* less disruptive to the existing embedder API, results in a cleaner embedder API anyways, and we don't believe that VM runtime/embedder code is on the hot path for working with the GC at this time anyways (that would be the actual Wasm code, which has inlined GC barriers and direct calls and all of that). In the future, once we have optimized enough of the GC that such code is ever hot, we have options we can investigate at that time to avoid these dynamic virtual calls, like only enabling one single collector at build time and then creating a static type alias like `type TheOneGcImpl = ...;` based on the compile time configuration, and using this type alias in the runtime rather than a dynamic trait object.
The `GcRuntime` trait additionally defines a method to reset a GC heap, for use by the pooling allocator. This allows reuse of GC heaps across different stores. This integration is very rudimentary at the moment, and is missing all kinds of configuration knobs that we should have before deploying Wasm GC in production. This commit is large enough as it is already! Ideally, in the future, I'd like to make it so that GC heaps receive their memory region, rather than allocate/reserve it themselves, and let each slot in the pooling allocator's memory pool be *either* a linear memory or a GC heap. This would unask various capacity planning questions such as "what percent of memory capacity should we dedicate to linear memories vs GC heaps?". It also seems like basically all the same configuration knobs we have for linear memories apply equally to GC heaps (see also the "Indexed Heaps" section below).
2. The `GcCompiler` trait: This trait defines how to emit CLIF that implements GC barriers for various operations on GC-managed references. The Rust code calls into this trait dynamically via a trait object, but since it is customizing the CLIF that is generated for Wasm code, the Wasm code itself is not making dynamic, indirect calls for GC barriers. The `GcCompiler` implementation can inline the parts of GC barrier that it believes should be inline, and leave out-of-line calls to rare slow paths.
All that said, there is still only a single implementation of each of these traits: the existing deferred reference-counting (DRC) collector. So there is a bunch of code motion in this commit as the DRC collector was further isolated from the rest of the runtime and moved to its own submodule. That said, this was not *purely* code motion (see "Indexed Heaps" below) so it is worth not simply skipping over the DRC collector's code in review.
\### Indexed Heaps
This commit does bake in a couple assumptions that must be shared across all collector implementations, such as a shared `VMGcHeader` that all objects allocated within a GC heap must begin with, but the most notable and far-reaching of these assumptions is that all collectors will use "indexed heaps".
What we are calling indexed heaps are basically the three following invariants:
1. All GC heaps will be a single contiguous region of memory, and all GC objects will be allocated within this region of memory. The collector may ask the system allocator for additional memory, e.g. to maintain its free lists, but GC objects themselves will never be allocated via `malloc`.
2. A pointer to a GC-managed object (i.e. a `VMGcRef`) is a 32-bit offset into the GC heap's contiguous region of memory. We never hold raw pointers to GC objects (although, of course, we have to compute them and use them temporarily when actually accessing objects). This means that deref'ing GC pointers is equivalent to deref'ing linear memory pointers: we need to add a base and we also check that the GC pointer/index is within the bounds of the GC heap. Furthermore, compressing 64-bit pointers into 32 bits is a fairly common technique among high-performance GC implementations[^compressed-oops][^v8-ptr-compression] so we are in good company.
3. Anything stored inside the GC heap is untrusted. Even each GC reference that is an element of an `(array (ref any))` is untrusted, and bounds checked on access. This means that, for example, we do not store the raw pointer to an `externref`'s host object inside the GC heap. Instead an `externref` now stores an ID that can be used to index into a side table in the store that holds the actual `Box<dyn Any>` host object, and accessing that side table is always checked.
[^compressed-oops]: See ["Compressed OOPs" in OpenJDK.](https://wiki.openjdk.org/display/HotSpot/CompressedOops)
[^v8-ptr-compression]: See [V8's pointer compression](https://v8.dev/blog/pointer-compression).
The good news with regards to all the bounds checking that this scheme implies is that we can use all the same virtual memory tricks that linear memories use to omit explicit bounds checks. Additionally, (2) means that the sizes of GC objects is that much smaller (and therefore that much more cache friendly) because they are only holding onto 32-bit, rather than 64-bit, references to other GC objects. (We can, in the future, support GC heaps up to 16GiB in size without losing 32-bit GC pointers by taking advantage of `VMGcHeader` alignment and storing aligned indices rather than byte indices, while still leaving the bottom bit available for tagging as an `i31ref` discriminant. Should we ever need to support even larger GC heap capacities, we could go to full 64-bit references, but we would need explicit bounds checks.)
The biggest benefit of indexed heaps is that, because we are (explicitly or implicitly) bounds checking GC heap accesses, and because we are not otherwise trusting any data from inside the GC heap, we greatly reduce how badly things can go wrong in the face of collector bugs and GC heap corruption. We are essentially sandboxing the GC heap region, the same way that linear memory is a sandbox. GC bugs could lead to the guest program accessing the wrong GC object, or getting garbage data from within the GC heap. But only garbage data from within the GC heap, never outside it. The worse that could happen would be if we decided not to zero out GC heaps between reuse across stores (which is a valid trade off to make, since zeroing a GC heap is a defense-in-depth technique similar to zeroing a Wasm stack and not semantically visible in the absence of GC bugs) and then a GC bug would allow the current Wasm guest to read old GC data from the old Wasm guest that previously used this GC heap. But again, it could never access host data.
Taken altogether, this allows for collector implementations that are nearly free from `unsafe` code, and unsafety can otherwise be targeted and limited in scope, such as interactions with JIT code. Most importantly, we do not have to maintain critical invariants across the whole system -- invariants which can't be nicely encapsulated or abstracted -- to preserve memory safety. Such holistic invariants that refuse encapsulation are otherwise generally a huge safety problem with GC implementations.
\### `VMGcRef` is *NOT* `Clone` or `Copy` Anymore
`VMGcRef` used to be `Clone` and `Copy`. It is not anymore. The motivation here was to be sure that I was actually calling GC barriers at all the correct places. I couldn't be sure before. Now, you can still explicitly copy a raw GC reference without running GC barriers if you need to and understand why that's okay (aka you are implementing the collector), but that is something you have to opt into explicitly by calling `unchecked_copy`. The default now is that you can't just copy the reference, and instead call an explicit `clone` method (not *the* `Clone` trait, because we need to pass in the GC heap context to run the GC barriers) and it is hard to forget to do that accidentally. This resulted in a pretty big amount of churn, but I am wayyyyyy more confident that the correct GC barriers are called at the correct times now than I was before.
\### `i31ref`
I started this commit by trying to add `i31ref` support. And it grew into the whole traits interface because I found that I needed to abstract GC barriers into helpers anyways to avoid running them for `i31ref`s, so I figured that I might as well add the whole traits interface. In comparison, `i31ref` support is much easier and smaller than that other part! But it was also difficult to pull apart from this commit, sorry about that!
---------------------
Overall, I know this is a very large commit. I am super happy to have some synchronous meetings to walk through this all, give an overview of the architecture, answer questions directly, etc... to make review easier!
prtest:full
show more ...
|
|
Revision tags: v19.0.1, v19.0.0, v18.0.3, v18.0.2, v17.0.2, v18.0.1 |
|
| #
ff93bce0 |
| 20-Feb-2024 |
Nick Fitzgerald <[email protected]> |
Wasmtime: Finish support for the typed function references proposal (#7943)
* Wasmtime: Finish support for the typed function references proposal
While we supported the function references proposal
Wasmtime: Finish support for the typed function references proposal (#7943)
* Wasmtime: Finish support for the typed function references proposal
While we supported the function references proposal inside Wasm, we didn't support it on the "outside" in the Wasmtime embedder APIs. So much of the work here is exposing typed function references, and their type system updates, in the embedder API. These changes include:
* `ValType::FuncRef` and `ValType::ExternRef` are gone, replaced with the introduction of the `RefType` and `HeapType` types and a `ValType::Ref(RefType)` variant.
* `ValType` and `FuncType` no longer implement `Eq` and `PartialEq`. Instead there are `ValType::matches` and `FuncType::matches` methods which check directional subtyping. I also added `ValType::eq` and `FuncType::eq` static methods for the rare case where someone needs to check precise equality, but that is almost never actually the case, 99.99% of the time you want to check subtyping.
* There are also public `Val::matches_ty` predicates for checking if a value is an instance of a type, as well as internal helpers like `Val::ensure_matches_ty` that return a formatted error if the value does not match the given type. These helpers are used throughout Wasmtime internals now.
* There is now a dedicated `wasmtime::Ref` type that represents reference values. Table operations have been updated to take and return `Ref`s rather than `Val`s.
Furthermore, this commit also includes type registry changes to correctly manage lifetimes of types that reference other types. This wasn't previously an issue because the only thing that could reference types that reference other types was a Wasm module that added all the types that could reference each other at the same time and removed them all at the same time. But now that the previously discussed work to expose these things in the embedder API is done, type lifetime management in the registry becomes a little trickier because the embedder might grab a reference to a type that references another type, and then unload the Wasm module that originally defined that type, but then the user should still be able use that type and the other types it transtively references. Before, we were refcounting individual registry entries. Now, we still are refcounting individual entries, but now we are also accounting for type-to-type references and adding a new type to the registry will increment the refcounts of each of the types that it references, and removing a type from the registry will decrement the refcounts of each of the types it references, and then recursively (logically, not literally) remove any types whose refcount has now reached zero.
Additionally, this PR adds support for subtyping to `Func::typed`- and `Func::wrap`-style APIs. For result types, you can always use a supertype of the WebAssembly function's actual declared return type in `Func::typed`. And for param types, you can always use a subtype of the Wasm function's actual declared param type. Doing these things essentially erases information but is always correct. But additionally, for functions which take a reference to a concrete type as a parameter, you can also use the concrete type's supertype. Consider a WebAssembly function that takes a reference to a function with a concrete type: `(ref null <func type index>)`. In this scenario, there is no static `wasmtime::Foo` Rust type that corresponds to that particular Wasm-defined concrete reference type because Wasm modules are loaded dynamically at runtime. You *could* do `f.typed::<Option<NoFunc>, ()>()`, and while that is correctly typed and valid, it is often overly restrictive. The only value you could call the resulting typed function with is the null function reference, but we'd like to call it with non-null function references that happen to be of the correct type. Therefore, `f.typed<Option<Func>, ()>()` is also allowed in this case, even though `Option<Func>` represents `(ref null func)` which is the supertype, not subtype, of `(ref null <func type index>)`. This does imply some minimal dynamic type checks in this case, but it is supported for better ergonomics, to enable passing non-null references into the function.
We can investigate whether it is possible to use generic type parameters and combinators to define Rust types that precisely match concrete reference types in future, follow-up pull requests. But for now, we've made things usable, at least.
Finally, this also takes the first baby step towards adding support for the Wasm GC proposal. Right now the only thing that is supported is `nofunc` references, and this was mainly to make testing function reference subtyping easier. But that does mean that supporting `nofunc` references entailed also adding a `wasmtime::NoFunc` type as well as the `Config::wasm_gc(enabled)` knob. So we officially have an in-progress implementation of Wasm GC in Wasmtime after this PR lands!
Fixes https://github.com/bytecodealliance/wasmtime/issues/6455
* Fix WAT in test to be valid
* Check that dependent features are enabled for function-references and GC
* Remove unnecessary engine parameters from a few methods
Ever since `FuncType`'s internal `RegisteredType` holds onto its own `Engine`, we don't need these anymore.
Still useful to keep the `Engine` parameter around for the `ensure_matches` methods because that can be used to check correct store/engine usage for embedders.
* Add missing dependent feature enabling for some tests
* Remove copy-paste bit from test
* match self to show it is uninhabited
* Add a missing `is_v128` method
* Short circuit a few func type comparisons
* Turn comment into part of doc comment
* Add test for `Global::new` and subtyping
* Add tests for embedder API, tables, and subtyping
* Add an embedder API test for setting globals and subtyping
* Construct realloc's type from its index, rather than from scratch
* Help LLVM better optimize our dynamic type checks in `TypedFunc::call_raw`
* Fix call benchmark compilation
* Change `WasmParams::into_abi` to take the whole func type instead of iter of params
* Fix doc links
prtest:full
* Fix size assertion on s390x
show more ...
|
|
Revision tags: v18.0.0 |
|
| #
353dc273 |
| 14-Feb-2024 |
Alex Crichton <[email protected]> |
Fully enable Winch in the `differential` fuzzer (#7932)
This commit fully enables usage of Winch in the `differential` fuzzer against all other engines with no special cases. I attempted enabling wi
Fully enable Winch in the `differential` fuzzer (#7932)
This commit fully enables usage of Winch in the `differential` fuzzer against all other engines with no special cases. I attempted enabling winch for the other fuzzers as well but Winch doesn't currently implement all methods for generating various trampolines required so it's currently only limited to the `differential` fuzzer.
This adds Winch as an "engine" and additionally ensures that when configured various wasm proposals are disabled that Winch doesn't support (similar to how enabling `wasmi` disables proposals that `wasmi` doesn't support).
This does reduce fuzzing of Winch slightly in that the reference-types proposal is completely disabled for Winch rather than half-enabled where Winch doesn't implement `externref` operations yet but does implement `funcref` operations. This, however, enables integrating it more cleanly into the rest of the fuzzing infrastructure with fewer special cases.
show more ...
|
| #
04c03b31 |
| 12-Feb-2024 |
Alex Crichton <[email protected]> |
Update the wasm-tools family of crates (#7921)
* Update the wasm-tools family of crates
Pulling in some updates to improve how WIT is managed in this repository. No changes just yet, however, just
Update the wasm-tools family of crates (#7921)
* Update the wasm-tools family of crates
Pulling in some updates to improve how WIT is managed in this repository. No changes just yet, however, just pulling in the updates first.
* Fix tests
* Fix fuzzer build
show more ...
|
|
Revision tags: v17.0.1, v17.0.0, v16.0.0, v15.0.1, v15.0.0, v14.0.4, v14.0.3, v14.0.2, v13.0.1, v14.0.1, v14.0.0, minimum-viable-wasi-proxy-serve, v13.0.0, v12.0.2, v11.0.2, v10.0.2 |
|
| #
8d7a2b89 |
| 14-Sep-2023 |
Alex Crichton <[email protected]> |
Add support for `v128` to the typed function API (#7010)
* Add support for `v128` to the typed function API
This commit adds a Rust type `V128` which corresponds to the wasm `v128` type. This is in
Add support for `v128` to the typed function API (#7010)
* Add support for `v128` to the typed function API
This commit adds a Rust type `V128` which corresponds to the wasm `v128` type. This is intended to perhaps one day have accessors for lanes of various sizes but in the meantime only supports conversion back and forth between `u128`. The intention of this type is to allow platforms to perform typed between to functions that take or return `v128` wasm values.
Previously this was not implemented because it's a bit tricky ABI-wise. Typed functions work by passing arguments in registers which requires the calling convention to match in both Cranelift and in Rust. This should be the case for supported platforms and the default calling convention, especially now that the wasm calling convention is separate from the platform calling convention. This does mean, however, that this feature can only be supported on x86_64 and AArch64. Currently neither s390x nor RISC-V have a means of supporting the vector calling convention since the vector types aren't available on stable in Rust itself. This means that it's now unfortunately possible to write a Wasmtime embedding that compiles on x86_64 that doesn't compile on s390x for example, but given how niche this feature is that seems like an ok tradeoff for now and by the time it's a problem Rust might have native stable support for vector types on these platforms.
prtest:full
* Fix compile of C API
* Conditionally enable typed v128 tests
* Review comments
* Fix compiler warnings
show more ...
|
|
Revision tags: v12.0.1, v12.0.0, v11.0.1, v11.0.0, v10.0.1, v10.0.0, v9.0.4, v9.0.3, v9.0.2, v9.0.1, v9.0.0, v6.0.2, v7.0.1, v8.0.1 |
|
| #
4b703f9d |
| 24-Apr-2023 |
Alex Crichton <[email protected]> |
Fix differential fuzzing when Wasmtime hits an OOM (#6273)
OSS-Fuzz found a case where the `differential` fuzzer was failing and the underlying cause was that Wasmtime was hitting an OOM while Wasmi
Fix differential fuzzing when Wasmtime hits an OOM (#6273)
OSS-Fuzz found a case where the `differential` fuzzer was failing and the underlying cause was that Wasmtime was hitting an OOM while Wasmi wasn't. This meant that the two modules were producing "different results" since memories had differing lengths, but this isn't a failure we're interested in. This commit updates the differential fuzzer to discard the test case once the Wasmtime half reaches OOM.
show more ...
|
|
Revision tags: v8.0.0, v7.0.0, v6.0.1, v5.0.1, v4.0.1, v6.0.0, v5.0.0, v4.0.0, v3.0.1, v3.0.0, v1.0.2, v2.0.2 |
|
| #
2be457c2 |
| 10-Nov-2022 |
Alex Crichton <[email protected]> |
Change the return type of `SharedMemory::data` (#5240)
This commit is an attempt at improving the safety of using the return
value of the `SharedMemory::data` method. Previously this returned
`*mu
Change the return type of `SharedMemory::data` (#5240)
This commit is an attempt at improving the safety of using the return
value of the `SharedMemory::data` method. Previously this returned
`*mut [u8]` which, while correct, is unwieldy and unsafe to work with.
The new return value of `&[UnsafeCell<u8>]` has a few advantages:
* The lifetime of the returned data is now connected to the
`SharedMemory` itself, removing the possibility for a class of errors
of accidentally using the prior `*mut [u8]` beyond its original lifetime.
* It's not possibly to safely access `.len()` as opposed to requiring an
`unsafe` dereference before.
* The data internally within the slice is now what retains the `unsafe`
bits, namely indicating that accessing any memory inside of the
contents returned is `unsafe` but addressing it is safe.
I was inspired by the `wiggle`-based discussion on #5229 and felt it
appropriate to apply a similar change here.
show more ...
|
| #
2afaac51 |
| 02-Nov-2022 |
Alex Crichton <[email protected]> |
Return `anyhow::Error` from host functions instead of `Trap`, redesign `Trap` (#5149)
* Return `anyhow::Error` from host functions instead of `Trap`
This commit refactors how errors are modeled w
Return `anyhow::Error` from host functions instead of `Trap`, redesign `Trap` (#5149)
* Return `anyhow::Error` from host functions instead of `Trap`
This commit refactors how errors are modeled when returned from host
functions and additionally refactors how custom errors work with `Trap`.
At a high level functions in Wasmtime that previously worked with
`Result<T, Trap>` now work with `Result<T>` instead where the error is
`anyhow::Error`. This includes functions such as:
* Host-defined functions in a `Linker<T>`
* `TypedFunc::call`
* Host-related callbacks like call hooks
Errors are now modeled primarily as `anyhow::Error` throughout Wasmtime.
This subsequently removes the need for `Trap` to have the ability to
represent all host-defined errors as it previously did. Consequently the
`From` implementations for any error into a `Trap` have been removed
here and the only embedder-defined way to create a `Trap` is to use
`Trap::new` with a custom string.
After this commit the distinction between a `Trap` and a host error is
the wasm backtrace that it contains. Previously all errors in host
functions would flow through a `Trap` and get a wasm backtrace attached
to them, but now this only happens if a `Trap` itself is created meaning
that arbitrary host-defined errors flowing from a host import to the
other side won't get backtraces attached. Some internals of Wasmtime
itself were updated or preserved to use `Trap::new` to capture a
backtrace where it seemed useful, such as when fuel runs out.
The main motivation for this commit is that it now enables hosts to
thread a concrete error type from a host function all the way through to
where a wasm function was invoked. Previously this could not be done
since the host error was wrapped in a `Trap` that didn't provide the
ability to get at the internals.
A consequence of this commit is that when a host error is returned that
isn't a `Trap` we'll capture a backtrace and then won't have a `Trap` to
attach it to. To avoid losing the contextual information this commit
uses the `Error::context` method to attach the backtrace as contextual
information to ensure that the backtrace is itself not lost.
This is a breaking change for likely all users of Wasmtime, but it's
hoped to be a relatively minor change to workaround. Most use cases can
likely change `-> Result<T, Trap>` to `-> Result<T>` and otherwise
explicit creation of a `Trap` is largely no longer necessary.
* Fix some doc links
* add some tests and make a backtrace type public (#55)
* Trap: avoid a trailing newline in the Display impl
which in turn ends up with three newlines between the end of the
backtrace and the `Caused by` in the anyhow Debug impl
* make BacktraceContext pub, and add tests showing downcasting behavior of anyhow::Error to traps or backtraces
* Remove now-unnecesary `Trap` downcasts in `Linker::module`
* Fix test output expectations
* Remove `Trap::i32_exit`
This commit removes special-handling in the `wasmtime::Trap` type for
the i32 exit code required by WASI. This is now instead modeled as a
specific `I32Exit` error type in the `wasmtime-wasi` crate which is
returned by the `proc_exit` hostcall. Embedders which previously tested
for i32 exits now downcast to the `I32Exit` value.
* Remove the `Trap::new` constructor
This commit removes the ability to create a trap with an arbitrary error
message. The purpose of this commit is to continue the prior trend of
leaning into the `anyhow::Error` type instead of trying to recreate it
with `Trap`. A subsequent simplification to `Trap` after this commit is
that `Trap` will simply be an `enum` of trap codes with no extra
information. This commit is doubly-motivated by the desire to always use
the new `BacktraceContext` type instead of sometimes using that and
sometimes using `Trap`.
Most of the changes here were around updating `Trap::new` calls to
`bail!` calls instead. Tests which assert particular error messages
additionally often needed to use the `:?` formatter instead of the `{}`
formatter because the prior formats the whole `anyhow::Error` and the
latter only formats the top-most error, which now contains the
backtrace.
* Merge `Trap` and `TrapCode`
With prior refactorings there's no more need for `Trap` to be opaque or
otherwise contain a backtrace. This commit parse down `Trap` to simply
an `enum` which was the old `TrapCode`. All various tests and such were
updated to handle this.
The main consequence of this commit is that all errors have a
`BacktraceContext` context attached to them. This unfortunately means
that the backtrace is printed first before the error message or trap
code, but given all the prior simplifications that seems worth it at
this time.
* Rename `BacktraceContext` to `WasmBacktrace`
This feels like a better name given how this has turned out, and
additionally this commit removes having both `WasmBacktrace` and
`BacktraceContext`.
* Soup up documentation for errors and traps
* Fix build of the C API
Co-authored-by: Pat Hickey <[email protected]>
show more ...
|
|
Revision tags: v2.0.1, v2.0.0, v1.0.1, v1.0.0 |
|
| #
543a4879 |
| 06-Sep-2022 |
Alex Crichton <[email protected]> |
Throw out fewer fuzz inputs with differential fuzzer (#4859)
* Throw out fewer fuzz inputs with differential fuzzer
Prior to this commit the differential fuzzer would generate a module and
then
Throw out fewer fuzz inputs with differential fuzzer (#4859)
* Throw out fewer fuzz inputs with differential fuzzer
Prior to this commit the differential fuzzer would generate a module and
then select an engine to execute the module against Wasmtime. This
meant, however, that the candidate list of engines were filtered against
the configuration used to generate the module to ensure that the
selected engine could run the generated module.
This commit inverts this logic and instead selects an engine first,
allowing the engine to then tweak the module configuration to ensure
that the generated module is compatible with the engine selected. This
means that fewer fuzz inputs are discarded because every fuzz input will
result in an engine being executed.
Internally the engine constructors have all been updated to update the
configuration to work instead of filtering the configuration. Some other
fixes were applied for the spec interpreter as well to work around #4852
* Fix tests
show more ...
|
| #
10dbb199 |
| 02-Sep-2022 |
Alex Crichton <[email protected]> |
Various improvements to differential fuzzing (#4845)
* Improve wasmi differential fuzzer
* Support modules with a `start` function
* Implement trap-matching to ensure that wasmi and Wasmtime bot
Various improvements to differential fuzzing (#4845)
* Improve wasmi differential fuzzer
* Support modules with a `start` function
* Implement trap-matching to ensure that wasmi and Wasmtime both report
the same flavor of trap.
* Support differential fuzzing where no engines match
Locally I was attempting to run against just one wasm engine with
`ALLOWED_ENGINES=wasmi` but the fuzzer quickly panicked because the
generated test case didn't match wasmi's configuration. This commit
updates engine-selection in the differential fuzzer to return `None` if
no engine is applicable, throwing out the test case. This won't be hit
at all with oss-fuzz-based runs but for local runs it'll be useful to
have.
* Improve proposal support in differential fuzzer
* De-prioritize unstable wasm proposals such as multi-memory and
memory64 by making them more unlikely with `Unstructured::ratio`.
* Allow fuzzing multi-table (reference types) and multi-memory by
avoiding setting their maximums to 1 in `set_differential_config`.
* Update selection of the pooling strategy to unconditionally support
the selected module config rather than the other way around.
* Improve handling of traps in differential fuzzing
This commit fixes an issue found via local fuzzing where engines were
reporting different results but the underlying reason for this was that
one engine was hitting stack overflow before the other. To fix the
underlying issue I updated the execution to check for stack overflow
and, if hit, it discards the entire fuzz test case from then on.
The rationale behind this is that each engine can have unique limits for
stack overflow. One test case I was looking at for example would stack
overflow at less than 1000 frames with epoch interruption enabled but
would stack overflow at more than 1000 frames with it disabled. This
means that the state after the trap started to diverge and it looked
like the engines produced different results.
While I was at it I also improved the "function call returned a trap"
case to compare traps to make sure the same trap reason popped out.
* Fix fuzzer tests
show more ...
|
|
Revision tags: v0.40.1, v0.40.0 |
|
| #
fd98814b |
| 19-Aug-2022 |
Alex Crichton <[email protected]> |
Port v8 fuzzer to the new framework (#4739)
* Port v8 fuzzer to the new framework
This commit aims to improve the support for the new "meta" differential
fuzzer added in #4515 by ensuring that a
Port v8 fuzzer to the new framework (#4739)
* Port v8 fuzzer to the new framework
This commit aims to improve the support for the new "meta" differential
fuzzer added in #4515 by ensuring that all existing differential fuzzing
is migrated to this new fuzzer. This PR includes features such as:
* The V8 differential execution is migrated to the new framework.
* `Config::set_differential_config` no longer force-disables wasm
features, instead allowing them to be enabled as per the fuzz input.
* `DiffInstance::{hash, hash}` was replaced with
`DiffInstance::get_{memory,global}` to allow more fine-grained
assertions.
* Support for `FuncRef` and `ExternRef` have been added to `DiffValue`
and `DiffValueType`. For now though generating an arbitrary
`ExternRef` and `FuncRef` simply generates a null value.
* Arbitrary `DiffValue::{F32,F64}` values are guaranteed to use
canonical NaN representations to fix an issue with v8 where with the
v8 engine we can't communicate non-canonical NaN values through JS.
* `DiffEngine::evaluate` allows "successful failure" for cases where
engines can't support that particular invocation, for example v8 can't
support `v128` arguments or return values.
* Smoke tests were added for each engine to ensure that a simple wasm
module works at PR-time.
* Statistics printed from the main fuzzer now include percentage-rates
for chosen engines as well as percentage rates for styles-of-module.
There's also a few small refactorings here and there but mostly just
things I saw along the way.
* Update the fuzzing README
show more ...
|
| #
5ec92d59 |
| 19-Aug-2022 |
Andrew Brown <[email protected]> |
[fuzz] Add a meta-differential fuzz target (#4515)
* [fuzz] Add `Module` enum, refactor `ModuleConfig`
This change adds a way to create either a single-instruction module or a
regular (big) `was
[fuzz] Add a meta-differential fuzz target (#4515)
* [fuzz] Add `Module` enum, refactor `ModuleConfig`
This change adds a way to create either a single-instruction module or a
regular (big) `wasm-smith` module. It has some slight refactorings in
preparation for the use of this new code.
* [fuzz] Add `DiffValue` for differential evaluation
In order to evaluate functions with randomly-generated values, we needed
a common way to generate these values. Using the Wasmtime `Val` type is
not great because we would like to be able to implement various traits
on the new value type, e.g., to convert `Into` and `From` boxed values
of other engines we differentially fuzz against. This new type,
`DiffValue`, gives us a common ground for all the conversions and
comparisons between the other engine types.
* [fuzz] Add interface for differential engines
In order to randomly choose an engine to fuzz against, we expect all of
the engines to meet a common interface. The traits in this commit allow
us to instantiate a module from its binary form, evaluate exported
functions, and (possibly) hash the exported items of the instance.
This change has some missing pieces, though:
- the `wasm-spec-interpreter` needs some work to be able to create
instances, evaluate a function by name, and expose exported items
- the `v8` engine is not implemented yet due to the complexity of its
Rust lifetimes
* [fuzz] Use `ModuleFeatures` instead of existing configuration
When attempting to use both wasm-smith and single-instruction modules,
there is a mismatch in how we communicate what an engine must be able to
support. In the first case, we could use the `ModuleConfig`, a wrapper
for wasm-smith's `SwarmConfig`, but single-instruction modules do not
have a `SwarmConfig`--the many options simply don't apply. Here, we
instead add `ModuleFeatures` and adapt a `ModuleConfig` to that.
`ModuleFeatures` then becomes the way to communicate what features an
engine must support to evaluate functions in a module.
* [fuzz] Add a new fuzz target using the meta-differential oracle
This change adds the `differential_meta` target to the list of fuzz
targets. I expect that sometime soon this could replace the other
`differential*` targets, as it almost checks all the things those check.
The major missing piece is that currently it only chooses
single-instruction modules instead of also generating arbitrary modules
using `wasm-smith`.
Also, this change adds the concept of an ignorable error: some
differential engines will choke with certain inputs (e.g., `wasmi` might
have an old opcode mapping) which we do not want to flag as fuzz bugs.
Here we wrap those errors in `DiffIgnoreError` and then use a new helper
trait, `DiffIgnorable`, to downcast and inspect the `anyhow` error to
only panic on non-ignorable errors; the ignorable errors are converted
to one of the `arbitrary::Error` variants, which we already ignore.
* [fuzz] Compare `DiffValue` NaNs more leniently
Because arithmetic NaNs can contain arbitrary payload bits, checking
that two differential executions should produce the same result should
relax the comparison of the `F32` and `F64` types (and eventually `V128`
as well... TODO). This change adds several considerations, however, so
that in the future we make the comparison a bit stricter, e.g., re:
canonical NaNs. This change, however, just matches the current logic
used by other fuzz targets.
* review: allow hashing mutate the instance state
@alexcrichton requested that the interface be adapted to accommodate
Wasmtime's API, in which even reading from an instance could trigger
mutation of the store.
* review: refactor where configurations are made compatible
See @alexcrichton's
[suggestion](https://github.com/bytecodealliance/wasmtime/pull/4515#discussion_r928974376).
* review: convert `DiffValueType` using `TryFrom`
See @alexcrichton's
[comment](https://github.com/bytecodealliance/wasmtime/pull/4515#discussion_r928962394).
* review: adapt target implementation to Wasmtime-specific RHS
This change is joint work with @alexcrichton to adapt the structure of
the fuzz target to his comments
[here](https://github.com/bytecodealliance/wasmtime/pull/4515#pullrequestreview-1073247791).
This change:
- removes `ModuleFeatures` and the `Module` enum (for big and small
modules)
- upgrades `SingleInstModule` to filter out cases that are not valid for
a given `ModuleConfig`
- adds `DiffEngine::name()`
- constructs each `DiffEngine` using a `ModuleConfig`, eliminating
`DiffIgnoreError` completely
- prints an execution rate to the `differential_meta` target
Still TODO:
- `get_exported_function_signatures` could be re-written in terms of the
Wasmtime API instead `wasmparser`
- the fuzzer crashes eventually, we think due to the signal handler
interference between OCaml and Wasmtime
- the spec interpreter has several cases that we skip for now but could
be fuzzed with further work
Co-authored-by: Alex Crichton <[email protected]>
* fix: avoid SIGSEGV by explicitly initializing OCaml runtime first
* review: use Wasmtime's API to retrieve exported functions
Co-authored-by: Alex Crichton <[email protected]>
show more ...
|