|
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 |
|
| #
0dbb6f3d |
| 31-Mar-2026 |
Chris Fallin <[email protected]> |
Exceptions: implement C API. (#12861)
* Exceptions: implement C API.
This PR implements C (and C++) API support for Wasm exceptions, one final remaining hurdle (aside from fuzz-testing) for making
Exceptions: implement C API. (#12861)
* Exceptions: implement C API.
This PR implements C (and C++) API support for Wasm exceptions, one final remaining hurdle (aside from fuzz-testing) for making exceptions tier-1 and on-by-default.
* Review feedback, and add exnref case to `wasmtime_val_t`.
* Review feedback: GC feature guard.
* clang-format
* add docs to exn.hh.
* Remove tag size asserts: broken on 32-bit platforms, but not needed for correctness wrt C struct.
show more ...
|
|
Revision tags: v43.0.0, v42.0.1, v41.0.4, v42.0.0, v40.0.4, v36.0.6, v24.0.6, v41.0.3, v41.0.2, v41.0.1, v36.0.5, v40.0.3 |
|
| #
8c349a3d |
| 20-Jan-2026 |
Alex Crichton <[email protected]> |
Refactor core wasm host entrypoints (#12366)
* Refactor core wasm host entrypoints
This commit refactors the internals of how guest functions call out to the host. Previously Wasmtime had a split w
Refactor core wasm host entrypoints (#12366)
* Refactor core wasm host entrypoints
This commit refactors the internals of how guest functions call out to the host. Previously Wasmtime had a split where `Func::new`-style constructors used one entrypoint and `Func::wrap`-style entrypoints used a different entrypoint. This was required long ago when we had an array and native ABI calling convention, but nowadays this is no longer required. This refactors things to have a single base-level signature which is the narrow waist through which all other function entrypoints go through. This enables having a single function handle all the things like panicking, call hooks, etc, and everything further builds on top of it.
This commit additionally pushes the async-ness of a function down even further. Previously many `*_async` constructors would quickly delegate to their non-async counterpart, but this is expected to more-or-less become not the right way to do things as wasmtime moves into the future. Historical refactorings related to GC, for example, have pushed `async` further down within Wasmtime and this continues that trend. There's no immediate benefit just yet, but this is hoped to make future refactorings easier.
Along the way some minor API changes happened too:
* `*_unchecked` constructors now work with `MaybeUninit<ValRaw>` to correctly model how some values may not be initialized. * Some `*_async` functions picked up `T: Send` which should have in theory been required before and are now compiler-required. * Longstanding/old internal functions have been shuffled around/refactored.
Finally, another eventual goal of this work is to share more between core wasm and components in terms of implementation. Right now the component host function entrypoints are quite different than the core wasm ones and that ideally wouldn't endure forever.
* Fix c-api build
* Fix dead code
* Fix benchmarks build
* Review comments
show more ...
|
|
Revision tags: v41.0.0, v36.0.4, v39.0.2, v40.0.2, v40.0.1 |
|
| #
dc029724 |
| 07-Jan-2026 |
Nick Fitzgerald <[email protected]> |
Migrate C API to `wasmtime::error` (#12259)
|
|
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, v36.0.2, v36.0.1, v36.0.0, v35.0.0, v24.0.4, v33.0.2, v34.0.2, v34.0.1, v33.0.1, v24.0.3, v32.0.1, v34.0.0, 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, v30.0.2, v30.0.1, v30.0.0, v29.0.1, v29.0.0, v28.0.1 |
|
| #
ae84e6ed |
| 09-Jan-2025 |
Alex Crichton <[email protected]> |
Enable `unsafe-attr-outside-unsafe` 2024 edition lint (#9964)
* Enable `unsafe-attr-outside-unsafe` 2024 edition lint
This commit enables the `unsafe-attr-outside-unsafe` lint in rustc used in tran
Enable `unsafe-attr-outside-unsafe` 2024 edition lint (#9964)
* Enable `unsafe-attr-outside-unsafe` 2024 edition lint
This commit enables the `unsafe-attr-outside-unsafe` lint in rustc used in transitioning to the 2024 edition. This requires that the `#[no_mangle]` attribute is replaced in favor of `#[unsafe(no_mangle)]`. This mostly affects the C API of wasmtime and most of the changes here are a simple search/replace.
* Another attribute update
* Fix command adapter build
show more ...
|
|
Revision tags: v28.0.0 |
|
| #
8995bcc4 |
| 20-Nov-2024 |
Alex Crichton <[email protected]> |
Use a helper method to invoke `VMFuncRef::array_call` (#9630)
* Use a helper method to invoke `VMFuncRef::array_call`
This is intended to encapsulate the usage of a native raw pointer and in the fu
Use a helper method to invoke `VMFuncRef::array_call` (#9630)
* Use a helper method to invoke `VMFuncRef::array_call`
This is intended to encapsulate the usage of a native raw pointer and in the future act as a dispatch point for invoking Pulley instead of native code.
* Fix some callers
* More fixese
show more ...
|
|
Revision tags: 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, v25.0.1, v25.0.0, v24.0.0, v23.0.2 |
|
| #
0c0153c1 |
| 27-Jul-2024 |
Nick Fitzgerald <[email protected]> |
Enforce `clippy::clone_on_copy` for the workspace (#9025)
* Derive `Copy` for `Val`
* Fix `clippy::clone_on_copy` for the whole repo
* Enforce `clippy::clone_on_copy` for the workspace
* fix some
Enforce `clippy::clone_on_copy` for the workspace (#9025)
* Derive `Copy` for `Val`
* Fix `clippy::clone_on_copy` for the whole repo
* Enforce `clippy::clone_on_copy` for the workspace
* fix some more clippy::clone_on_copy that got missed
show more ...
|
|
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 |
|
| #
9187f2d9 |
| 15-Apr-2024 |
Alex Crichton <[email protected]> |
c-api: Create `RootScope` where necessary (#8374)
* c-api: Create `RootScope` where necessary
This commit changes the `wasmtime_val_t::{from_val, to_val}` methods to take a `RootScope` instead of a
c-api: Create `RootScope` where necessary (#8374)
* c-api: Create `RootScope` where necessary
This commit changes the `wasmtime_val_t::{from_val, to_val}` methods to take a `RootScope` instead of any `AsContextMut`. This then required a number of refactorings in callers to ensure that a `RootScope` was created for any function that needed one. This is required to ensure that GC references in the C API aren't forced to live for the entire lifetime of the store.
This additionally added `*_unrooted` variants which do the same thing but don't require `RootScope`. This was needed for when the C API calls out to the embedder through a function call because a new `RootScope` wouldn't work for return values (they're bound to a scope within the closure when we want them to outlive the closure). In these situations though we know a `RootScope` is already present at the entrypoint.
Closes #8367
* Review comments
show more ...
|
| #
420fc3d1 |
| 12-Apr-2024 |
Nick Fitzgerald <[email protected]> |
c-api: Better differentiate between `wasm.h` and `wasmtime.h` APIs (#8344)
This renames some types and adds some type aliases to help us better distinguish between `wasm.h` APIs and `wasmtime.h` API
c-api: Better differentiate between `wasm.h` and `wasmtime.h` APIs (#8344)
This renames some types and adds some type aliases to help us better distinguish between `wasm.h` APIs and `wasmtime.h` APIs, primarily for `Store`-related types. In general, `WasmFoo` is related to `wasm.h` and `WasmtimeFoo` is related to `wasmtime.h`.
* `StoreRef` -> `WasmStoreRef` * Introduce the `WasmStore[Data]` and `WasmStoreContext[Mut]` aliases * `StoreData` -> `WasmtimeStoreData` * `CStoreContext[Mut]` -> `WasmtimeStoreContext[Mut]` * Introduce the `Wasmtime{Store,Caller}` aliases
show more ...
|
|
Revision tags: v17.0.3, v19.0.2, v18.0.4, v19.0.1, v19.0.0, v18.0.3 |
|
| #
bd2ea901 |
| 06-Mar-2024 |
Nick Fitzgerald <[email protected]> |
Define garbage collection rooting APIs (#8011)
* Define garbage collection rooting APIs
Rooting prevents GC objects from being collected while they are actively being used.
We have a few sometimes
Define garbage collection rooting APIs (#8011)
* Define garbage collection rooting APIs
Rooting prevents GC objects from being collected while they are actively being used.
We have a few sometimes-conflicting goals with our GC rooting APIs:
1. Safety: It should never be possible to get a use-after-free bug because the user misused the rooting APIs, the collector "mistakenly" determined an object was unreachable and collected it, and then the user tried to access the object. This is our highest priority.
2. Moving GC: Our rooting APIs should moving collectors (such as generational and compacting collectors) where an object might get relocated after a collection and we need to update the GC root's pointer to the moved object. This means we either need cooperation and internal mutability from individual GC roots as well as the ability to enumerate all GC roots on the native Rust stack, or we need a level of indirection.
3. Performance: Our rooting APIs should generally be as low-overhead as possible. They definitely shouldn't require synchronization and locking to create, access, and drop GC roots.
4. Ergonomics: Our rooting APIs should be, if not a pleasure, then at least not a burden for users. Additionally, the API's types should be `Sync` and `Send` so that they work well with async Rust.
For example, goals (3) and (4) are in conflict when we think about how to support (2). Ideally, for ergonomics, a root would automatically unroot itself when dropped. But in the general case that requires holding a reference to the store's root set, and that root set needs to be held simultaneously by all GC roots, and they each need to mutate the set to unroot themselves. That implies `Rc<RefCell<...>>` or `Arc<Mutex<...>>`! The former makes the store and GC root types not `Send` and not `Sync`. The latter imposes synchronization and locking overhead. So we instead make GC roots indirect and require passing in a store context explicitly to unroot in the general case. This trades worse ergonomics for better performance and support for moving GC and async Rust.
Okay, with that out of the way, this module provides two flavors of rooting API. One for the common, scoped lifetime case, and another for the rare case where we really need a GC root with an arbitrary, non-LIFO/non-scoped lifetime:
1. `RootScope` and `Rooted<T>`: These are used for temporarily rooting GC objects for the duration of a scope. Upon exiting the scope, they are automatically unrooted. The internal implementation takes advantage of the LIFO property inherent in scopes, making creating and dropping `Rooted<T>`s and `RootScope`s super fast and roughly equivalent to bump allocation.
This type is vaguely similar to V8's [`HandleScope`].
[`HandleScope`]: https://v8.github.io/api/head/classv8_1_1HandleScope.html
Note that `Rooted<T>` can't be statically tied to its context scope via a lifetime parameter, unfortunately, as that would allow the creation and use of only one `Rooted<T>` at a time, since the `Rooted<T>` would take a borrow of the whole context.
This supports the common use case for rooting and provides good ergonomics.
2. `ManuallyRooted<T>`: This is the fully general rooting API used for holding onto non-LIFO GC roots with arbitrary lifetimes. However, users must manually unroot them. Failure to manually unroot a `ManuallyRooted<T>` before it is dropped will result in the GC object (and everything it transitively references) leaking for the duration of the `Store`'s lifetime.
This type is roughly similar to SpiderMonkey's [`PersistentRooted<T>`], although they avoid the manual-unrooting with internal mutation and shared references. (Our constraints mean we can't do those things, as mentioned explained above.)
[`PersistentRooted<T>`]: http://devdoc.net/web/developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS::PersistentRooted.html
At the end of the day, both `Rooted<T>` and `ManuallyRooted<T>` are just tagged indices into the store's `RootSet`. This indirection allows working with Rust's borrowing discipline (we use `&mut Store` to represent mutable access to the GC heap) while still allowing rooted references to be moved around without tying up the whole store in borrows. Additionally, and crucially, this indirection allows us to update the *actual* GC pointers in the `RootSet` and support moving GCs (again, as mentioned above).
* Reorganize GC-related submodules in `wasmtime-runtime`
* Reorganize GC-related submodules in `wasmtime`
* Use `Into<StoreContext[Mut]<'a, T>` for `Externref::data[_mut]` methods
* Run rooting tests under MIRI
* Make `into_abi` take an `AutoAssertNoGc`
* Don't use atomics to update externref ref counts anymore
* Try to make lifetimes/safety more-obviously correct
Remove some transmute methods, assert that `VMExternRef`s are the only valid `VMGcRef`, etc.
* Update extenref constructor examples
* Make `GcRefImpl::transmute_ref` a non-default trait method
* Make inline fast paths for GC LIFO scopes
* Make `RootSet::unroot_gc_ref` an `unsafe` function
* Move Hash and Eq for Rooted, move to impl methods
* Remove type parameter from `AutoAssertNoGc`
Just wrap a `&mut StoreOpaque` directly.
* Make a bunch of internal `ExternRef` methods that deal with raw `VMGcRef`s take `AutoAssertNoGc` instead of `StoreOpaque`
* Fix compile after rebase
* rustfmt
* revert unrelated egraph changes
* Fix non-gc build
* Mark `AutoAssertNoGc` methods inline
* review feedback
* Temporarily remove externref support from the C API
Until we can add proper GC rooting.
* Remove doxygen reference to temp deleted function
* Remove need to `allow(private_interfaces)`
* Fix call benchmark compilation
show more ...
|
|
Revision tags: 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 |
|
| #
8652011f |
| 09-Feb-2024 |
Nick Fitzgerald <[email protected]> |
Refactor `wasmtime::FuncType` to hold a handle to its registered type (#7892)
* Refactor `wasmtime::FuncType` to hold a handle to its registered type
Rather than holding a copy of the type directly
Refactor `wasmtime::FuncType` to hold a handle to its registered type (#7892)
* Refactor `wasmtime::FuncType` to hold a handle to its registered type
Rather than holding a copy of the type directly, it now holds a `RegisteredType` which internally is
* A `VMSharedTypeIndex` pointing into the engine's types registry. * An `Arc` handle to the engine's type registry. * An `Arc` handle to the actual type.
The last exists only to keep it so that accessing a `wasmtime::FuncType`'s parameters and results fast, avoiding any new locking on call hot paths.
This is helping set the stage for further types and `TypeRegistry` refactors needed for Wasm GC.
* Update the C API for the function types refactor
prtest:full
* rustfmt
* Fix benches 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 |
|
| #
37cf8e1e |
| 03-Oct-2023 |
Tyler Rockwood <[email protected]> |
Async support in the C API (#7106)
* c-api: Add a feature for async
Signed-off-by: Tyler Rockwood <[email protected]>
* c-api: Add support for async config
Signed-off-by: Tyler Rockwood <rock
Async support in the C API (#7106)
* c-api: Add a feature for async
Signed-off-by: Tyler Rockwood <[email protected]>
* c-api: Add support for async config
Signed-off-by: Tyler Rockwood <[email protected]>
* c-api: Add support for calling async functions
Signed-off-by: Tyler Rockwood <[email protected]>
* c-api: Add ability to yield execution of Wasm in a store
Signed-off-by: Tyler Rockwood <[email protected]>
* c-api: Introduce wasmtime_linker_instantiate_async
Signed-off-by: Tyler Rockwood <[email protected]>
* c-api: Support defining async host functions
Signed-off-by: Tyler Rockwood <[email protected]>
* gitignore: ignore cmake cache for examples
Signed-off-by: Tyler Rockwood <[email protected]>
* examples: Add example of async API in C
Signed-off-by: Tyler Rockwood <[email protected]>
* c-api: Consolidate async functionality into a single place
Put all the async stuff in it's own header and own rust source file
Also remove the wasmtime_async_continuation_new function, users can just allocate it directly.
Signed-off-by: Tyler Rockwood <[email protected]>
* c-api: Make async function safe
Signed-off-by: Tyler Rockwood <[email protected]>
* c-api: Remove wasmtime_call_future_get_results
Signed-off-by: Tyler Rockwood <[email protected]>
* c-api: Simplify CHostCallFuture
Move the result translation and hostcall_val_storage usage into an async function
Signed-off-by: Tyler Rockwood <[email protected]>
* c-api: Simplify C continuation implementation
Remove the caller, which means that we don't need another struct for the future implementation.
Signed-off-by: Tyler Rockwood <[email protected]>
* c-api: Improve async.h documentation
Signed-off-by: Tyler Rockwood <[email protected]>
* c-api: Cleanup from previous changes
Signed-off-by: Tyler Rockwood <[email protected]>
* examples: Fix example
Signed-off-by: Tyler Rockwood <[email protected]>
* c-api: Simplify continuation callback
This gives more duality with calling an async function and also means that the implementation can pretty much mirror the sync version.
Signed-off-by: Tyler Rockwood <[email protected]>
* c-api: Fix async.h documentation
Signed-off-by: Tyler Rockwood <[email protected]>
* c-api: Fix documentation for async.h
Signed-off-by: Tyler Rockwood <[email protected]>
* c-api: Review feedback
Signed-off-by: Tyler Rockwood <[email protected]>
* examples: Downgrade async.cpp example to C++11
Signed-off-by: Tyler Rockwood <[email protected]>
* c-api: initialize continuation with a panic callback
Signed-off-by: Tyler Rockwood <[email protected]>
* prtest:full
Signed-off-by: Tyler Rockwood <[email protected]>
---------
Signed-off-by: Tyler Rockwood <[email protected]>
show more ...
|
|
Revision tags: minimum-viable-wasi-proxy-serve, v13.0.0, v12.0.2, v11.0.2, v10.0.2, v12.0.1, v12.0.0, v11.0.1, v11.0.0, v10.0.1, v10.0.0 |
|
| #
8bec98da |
| 13-Jun-2023 |
Alex Crichton <[email protected]> |
Fix some beta warnings in the C API (#6578)
This'll make the future upgrade to Rust 1.71 that much more smoother.
|
|
Revision tags: v9.0.4, v9.0.3, v9.0.2, v9.0.1, v9.0.0 |
|
| #
ec92f8e4 |
| 09-May-2023 |
Alex Crichton <[email protected]> |
Make Wasmtime compatible with Stacked Borrows in MIRI (#6338)
* Make Wasmtime compatible with Stacked Borrows in MIRI
The fact that Wasmtime executes correctly under Tree Borrows but not Stacked B
Make Wasmtime compatible with Stacked Borrows in MIRI (#6338)
* Make Wasmtime compatible with Stacked Borrows in MIRI
The fact that Wasmtime executes correctly under Tree Borrows but not Stacked Borrows is a bit suspect and given what I've since learned about the aliasing models I wanted to give it a stab to get things working with Stacked Borrows. It turns out that this wasn't all that difficult, but required two underlying changes:
* First the implementation of `Instance::vmctx` is now specially crafted in an intentional way to preserve the provenance of the returned pointer. This way all `&Instance` pointers will return a `VMContext` pointer with the same provenance and acquiring the pointer won't accidentally invalidate all prior pointers.
* Second the conversion from `VMContext` to `Instance` has been updated to work with provenance and such. Previously the conversion looked like `&mut VMContext -> &mut Instance`, but I think this didn't play well with MIRI because `&mut VMContext` has no provenance over any data since it's zero-sized. Instead now the conversion is from `*mut VMContext` to `&mut Instance` where we know that `*mut VMContext` has provenance over the entire instance allocation. This shuffled a fair bit around to handle the new closure-based API to prevent escaping pointers, but otherwise no major change other than the structure and the types in play.
This commit additionally picks up a dependency on the `sptr` crate which is a crate for prototyping strict-provenance APIs in Rust. This is I believe intended to be upstreamed into Rust one day (it's in the standard library as a Nightly-only API right now) but in the meantime this is a stable alternative.
* Clean up manual `unsafe impl Send` impls
This commit adds a new wrapper type `SendSyncPtr<T>` which automatically impls the `Send` and `Sync` traits based on the `T` type contained. Otherwise it works similarly to `NonNull<T>`. This helps clean up a number of manual annotations of `unsafe impl {Send,Sync} for ...` throughout the runtime.
* Remove pointer-to-integer casts with tables
In an effort to enable MIRI's "strict provenance" mode this commit removes the integer-to-pointer casts in the runtime `Table` implementation for Wasmtime. Most of the bits were already there to track all this, so this commit plumbed around the various pointer types and with the help of the `sptr` crate preserves the provenance of all related pointers.
* Remove integer-to-pointer casts in CoW management
The `MemoryImageSlot` type stored a `base: usize` field mostly because I was too lazy to have a `Send`/`Sync` type as a pointer, so this commit updates it to use `SendSyncPtr<u8>` and then plumbs the pointer-ness throughout the implementation. This removes all integer-to-pointer casts and has pointers stores as actual pointers when they're at rest.
* Remove pointer-to-integer casts in "raw" representations
This commit changes the "raw" representation of `Func` and `ExternRef` to a `*mut c_void` instead of the previous `usize`. This is done to satisfy MIRI's requirements with strict provenance, properly marking the intermediate value as a pointer rather than round-tripping through integers.
* Minor remaining cleanups
* Switch to Stacked Borrows for MIRI on CI
Additionally enable the strict-provenance features to force warnings emitted today to become errors.
* Fix a typo
* Replace a negative offset with `sub`
* Comment the sentinel value
* Use NonNull::dangling
show more ...
|
| #
913efdf2 |
| 27-Apr-2023 |
Nick Fitzgerald <[email protected]> |
wasmtime: Overhaul trampolines (#6262)
This commit splits `VMCallerCheckedFuncRef::func_ptr` into three new function pointers: `VMCallerCheckedFuncRef::{wasm,array,native}_call`. Each one has a dedi
wasmtime: Overhaul trampolines (#6262)
This commit splits `VMCallerCheckedFuncRef::func_ptr` into three new function pointers: `VMCallerCheckedFuncRef::{wasm,array,native}_call`. Each one has a dedicated calling convention, so callers just choose the version that works for them. This is as opposed to the previous behavior where we would chain together many trampolines that converted between calling conventions, sometimes up to four on the way into Wasm and four more on the way back out. See [0] for details.
[0] https://github.com/bytecodealliance/rfcs/blob/main/accepted/tail-calls.md#a-review-of-our-existing-trampolines-calling-conventions-and-call-paths
Thanks to @bjorn3 for the initial idea of having multiple function pointers for different calling conventions.
This is generally a nice ~5-10% speed up to our call benchmarks across the board: both Wasm-to-host and host-to-Wasm. The one exception is typed calls from Wasm to the host, which have a minor regression. We hypothesize that this is because the old hand-written assembly trampolines did not maintain a call frame and do a tail call, but the new Cranelift-generated trampolines do maintain a call frame and do a regular call. The regression is only a couple nanoseconds, which seems well-explained by these differences explain, and ultimately is not a big deal.
However, this does lead to a ~5% code size regression for compiled modules. Before, we compiled a trampoline per escaping function's signature and we deduplicated these trampolines by signature. Now we compile two trampolines per escaping function: one for if the host calls via the array calling convention and one for it the host calls via the native calling convention. Additionally, we compile a trampoline for every type in the module, in case there is a native calling convention function from the host that we `call_indirect` of that type. Much of this is in the `.eh_frame` section in the compiled module, because each of our trampolines needs an entry there. Note that the `.eh_frame` section is not required for Wasmtime's correctness, and you can disable its generation to shrink compiled module code size; we just emit it to play nice with external unwinders and profilers. We believe there are code size gains available for follow up work to offset this code size regression in the future.
Backing up a bit: the reason each Wasm module needs to provide these Wasm-to-native trampolines is because `wasmtime::Func::wrap` and friends allow embedders to create functions even when there is no compiler available, so they cannot bring their own trampoline. Instead the Wasm module has to supply it. This in turn means that we need to look up and patch in these Wasm-to-native trampolines during roughly instantiation time. But instantiation is super hot, and we don't want to add more passes over imports or any extra work on this path. So we integrate with `wasmtime::InstancePre` to patch these trampolines in ahead of time.
Co-Authored-By: Jamey Sharp <[email protected]> Co-Authored-By: Alex Crichton <[email protected]>
prtest:full
show more ...
|
|
Revision tags: v6.0.2, v7.0.1, v8.0.1, 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 |
|
| #
9c73a448 |
| 14-Nov-2022 |
Alex Crichton <[email protected]> |
c-api: Fix `wasmtime_func_call_unchecked` to communicate all errors (#5262)
Change the return value of this function to a `wasmtime_error_t*`
instead of the prior `wasm_trap_t*`. This is a leftover
c-api: Fix `wasmtime_func_call_unchecked` to communicate all errors (#5262)
Change the return value of this function to a `wasmtime_error_t*`
instead of the prior `wasm_trap_t*`. This is a leftover from #5149.
Closes #5257
show more ...
|
|
Revision tags: v1.0.2, v2.0.2 |
|
| #
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, v0.40.1, v0.40.0, v0.39.1, v0.38.3, v0.38.2, v0.39.0, v0.38.1, v0.38.0 |
|
| #
f4b90209 |
| 01-Jun-2022 |
Alex Crichton <[email protected]> |
Change wasm-to-host trampolines to take the values_vec size (#4192)
* Change wasm-to-host trampolines to take the values_vec size
This commit changes the ABI of wasm-to-host trampolines, which ar
Change wasm-to-host trampolines to take the values_vec size (#4192)
* Change wasm-to-host trampolines to take the values_vec size
This commit changes the ABI of wasm-to-host trampolines, which are
only used right now for functions created with `Func::new`, to pass
along the size of the `values_vec` argument. Previously the trampoline
simply received `*mut ValRaw` and assumed that it was the appropriate
size. By receiving a size as well we can thread through `&mut [ValRaw]`
internally instead of `*mut ValRaw`.
The original motivation for this is that I'm planning to leverage these
trampolines for the component model for host-defined functions. Out of
an abundance of caution of making sure that everything lines up I wanted
to be able to write down asserts about the size received at runtime
compared to the size expected. This overall led me to the desire to
thread this size parameter through on the assumption that it would not
impact performance all that much.
I ran two benchmarks locally from the `call.rs` benchmark and got:
* `sync/no-hook/wasm-to-host - nop - unchecked` - no change
* `sync/no-hook/wasm-to-host - nop-params-and-results - unchecked` - 5%
slower
This is what I roughly expected in that if nothing actually reads the
new parameter (e.g. no arguments) then threading through the parameter
is effectively otherwise free. Otherwise though accesses to the `ValRaw`
storage is now bounds-checked internally in Wasmtime instead of assuming
it's valid, leading to the 5% slowdown (~9.6ns to ~10.3ns). If this
becomes a peformance bottleneck for a particular use case then we should
be fine to remove the bounds checking here or otherwise only bounds
check in debug mode, otherwise I plan on leaving this as-is.
Of particular note this also changes the C API for `*_unchecked`
functions where the C callback now receives the size of the array as
well.
* Add docs
show more ...
|
|
Revision tags: v0.37.0 |
|
| #
0a0c232a |
| 19-May-2022 |
Alex Crichton <[email protected]> |
Fix CI for Rust 1.61.0 (#4164)
A new version of rustc was released this morning and we have a few small
breakages on our CI which need fixing:
* A new warning was coming out of the c-api crate a
Fix CI for Rust 1.61.0 (#4164)
A new version of rustc was released this morning and we have a few small
breakages on our CI which need fixing:
* A new warning was coming out of the c-api crate about an unneeded
`unsafe` block.
* The panic message of a task in `cranelift-object` needed updating
since the standard library changed how it formats strings with the nul
byte.
show more ...
|
|
Revision tags: v0.36.0, v0.35.3 |
|
| #
7b5176ba |
| 04-Apr-2022 |
Alex Crichton <[email protected]> |
Upgrade all crates to the Rust 2021 edition (#3991)
* Upgrade all crates to the Rust 2021 edition
I've personally started using the new format strings for things like
`panic!("some message {foo}
Upgrade all crates to the Rust 2021 edition (#3991)
* Upgrade all crates to the Rust 2021 edition
I've personally started using the new format strings for things like
`panic!("some message {foo}")` or similar and have been upgrading crates
on a case-by-case basis, but I think it probably makes more sense to go
ahead and blanket upgrade everything so 2021 features are always
available.
* Fix compile of the C API
* Fix a warning
* Fix another warning
show more ...
|
|
Revision tags: v0.34.2, v0.35.2, v0.35.1, v0.35.0, v0.33.1, v0.34.1, v0.34.0, v0.33.0, v0.32.1, v0.32.0, v0.31.0 |
|
| #
bfdbd10a |
| 24-Sep-2021 |
Alex Crichton <[email protected]> |
Add `*_unchecked` variants of `Func` APIs for the C API (#3350)
* Add `*_unchecked` variants of `Func` APIs for the C API
This commit is what is hopefully going to be my last installment within
Add `*_unchecked` variants of `Func` APIs for the C API (#3350)
* Add `*_unchecked` variants of `Func` APIs for the C API
This commit is what is hopefully going to be my last installment within
the saga of optimizing function calls in/out of WebAssembly modules in
the C API. This is yet another alternative approach to #3345 (sorry) but
also contains everything necessary to make the C API fast. As in #3345
the general idea is just moving checks out of the call path in the same
style of `TypedFunc`.
This new strategy takes inspiration from previously learned attempts
effectively "just" exposes how we previously passed `*mut u128` through
trampolines for arguments/results. This storage format is formalized
through a new `ValRaw` union that is exposed from the `wasmtime` crate.
By doing this it made it relatively easy to expose two new APIs:
* `Func::new_unchecked`
* `Func::call_unchecked`
These are the same as their checked equivalents except that they're
`unsafe` and they work with `*mut ValRaw` rather than safe slices of
`Val`. Working with these eschews type checks and such and requires
callers/embedders to do the right thing.
These two new functions are then exposed via the C API with new
functions, enabling C to have a fast-path of calling/defining functions.
This fast path is akin to `Func::wrap` in Rust, although that API can't
be built in C due to C not having generics in the same way that Rust
has.
For some benchmarks, the benchmarks here are:
* `nop` - Call a wasm function from the host that does nothing and
returns nothing.
* `i64` - Call a wasm function from the host, the wasm function calls a
host function, and the host function returns an `i64` all the way out to
the original caller.
* `many` - Call a wasm function from the host, the wasm calls
host function with 5 `i32` parameters, and then an `i64` result is
returned back to the original host
* `i64` host - just the overhead of the wasm calling the host, so the
wasm calls the host function in a loop.
* `many` host - same as `i64` host, but calling the `many` host function.
All numbers in this table are in nanoseconds, and this is just one
measurement as well so there's bound to be some variation in the precise
numbers here.
| Name | Rust | C (before) | C (after) |
|-----------|------|------------|-----------|
| nop | 19 | 112 | 25 |
| i64 | 22 | 207 | 32 |
| many | 27 | 189 | 34 |
| i64 host | 2 | 38 | 5 |
| many host | 7 | 75 | 8 |
The main conclusion here is that the C API is significantly faster than
before when using the `*_unchecked` variants of APIs. The Rust
implementation is still the ceiling (or floor I guess?) for performance
The main reason that C is slower than Rust is that a little bit more has
to travel through memory where on the Rust side of things we can
monomorphize and inline a bit more to get rid of that. Overall though
the costs are way way down from where they were originally and I don't
plan on doing a whole lot more myself at this time. There's various
things we theoretically could do I've considered but implementation-wise
I think they'll be much more weighty.
* Tweak `wasmtime_externref_t` API comments
show more ...
|
| #
bcf35449 |
| 21-Sep-2021 |
Alex Crichton <[email protected]> |
Optimize `Func::call` and its C API (#3319)
* Optimize `Func::call` and its C API
This commit is an alternative to #3298 which achieves effectively the
same goal of optimizing the `Func::call` A
Optimize `Func::call` and its C API (#3319)
* Optimize `Func::call` and its C API
This commit is an alternative to #3298 which achieves effectively the
same goal of optimizing the `Func::call` API as well as its C API
sibling of `wasmtime_func_call`. The strategy taken here is different
than #3298 though where a new API isn't created, rather a small tweak to
an existing API is done. Specifically this commit handles the major
sources of slowness with `Func::call` with:
* Looking up the type of a function, to typecheck the arguments with and
use to guide how the results should be loaded, no longer hits the
rwlock in the `Engine` but instead each `Func` contains its own
`FuncType`. This can be an unnecessary allocation for funcs not used
with `Func::call`, so this is a downside of this implementation
relative to #3298. A mitigating factor, though, is that instance
exports are loaded lazily into the `Store` and in theory not too many
funcs are active in the store as `Func` objects.
* Temporary storage is amortized with a long-lived `Vec` in the `Store`
rather than allocating a new vector on each call. This is basically
the same strategy as #3294 only applied to different types in
different places. Specifically `wasmtime::Store` now retains a
`Vec<u128>` for `Func::call`, and the C API retains a `Vec<Val>` for
calling `Func::call`.
* Finally, an API breaking change is made to `Func::call` and its type
signature (as well as `Func::call_async`). Instead of returning
`Box<[Val]>` as it did before this function now takes a
`results: &mut [Val]` parameter. This allows the caller to manage the
allocation and we can amortize-remove it in `wasmtime_func_call` by
using space after the parameters in the `Vec<Val>` we're passing in.
This change is naturally a breaking change and we'll want to consider
it carefully, but mitigating factors are that most embeddings are
likely using `TypedFunc::call` instead and this signature taking a
mutable slice better aligns with `Func::new` which receives a mutable
slice for the results.
Overall this change, in the benchmark of "call a nop function from the C
API" is not quite as good as #3298. It's still a bit slower, on the
order of 15ns, because there's lots of capacity checks around vectors
and the type checks are slightly less optimized than before. Overall
though this is still significantly better than today because allocations
and the rwlock to acquire the type information are both avoided. I
personally feel that this change is the best to do because it has less
of an API impact than #3298.
* Rebase issues
show more ...
|
|
Revision tags: v0.30.0 |
|
| #
c7367355 |
| 03-Sep-2021 |
Alex Crichton <[email protected]> |
Avoid vector allocations in wasm->host calls (#3294)
This commit improves the runtime support for wasm-to-host invocations
for functions created with `Func::new` or `wasmtime_func_new` in the C
AP
Avoid vector allocations in wasm->host calls (#3294)
This commit improves the runtime support for wasm-to-host invocations
for functions created with `Func::new` or `wasmtime_func_new` in the C
API. Previously a `Vec` (sometimes a `SmallVec`) would be dynamically
allocated on each host call to store the arguments that are coming from
wasm and going to the host. In the case of the `wasmtime` crate we need
to decode the `u128`-stored values, and in the case of the C API we need
to decode the `Val` into the C API's `wasmtime_val_t`.
The technique used in this commit is to store a singular `Vec<T>` inside
the "store", be it the literal `Store<T>` or within the `T` in the case
of the C API, which can be reused across wasm->host calls. This means
that we're unlikely to actually perform dynamic memory allocation and
instead we should hit a faster path where the `Vec` always has enough
capacity.
Note that this is just a mild improvement for `Func::new`-based
functions. It's still the case that `Func::wrap` is much faster, but
unfortunately the C API doesn't have access to `Func::wrap`, so the main
motivation here is accelerating the C API.
show more ...
|
|
Revision tags: v0.29.0 |
|
| #
65378422 |
| 27-Jul-2021 |
Alex Crichton <[email protected]> |
Add a `wasmtime_linker_define_func` C API function (#3122)
This exposes the functionality of the `Linker` type where a
store-independent function can be created and inserted, allowing a
linker's f
Add a `wasmtime_linker_define_func` C API function (#3122)
This exposes the functionality of the `Linker` type where a
store-independent function can be created and inserted, allowing a
linker's functions to be used across many stores (instead of requiring
one linker-per-store).
Closes #3110
show more ...
|