* Refactor installation of C API and features supported
This commit overhauls and refactors the management of the building of
the C API. Instead of this being script-based it's now done entirely
through CMake and CMake is the primary focus for building the C API. For
example building the C API release artifacts is now done through CMake
instead of through a shell script's `cargo build` and manually moving
artifacts.
The benefits that this brings are:
* The C API now properly hides symbols in its header files that weren't
enabled at build time. This is done through a new build-time generated
`conf.h` templated on a `conf.h.in` file in the source tree.
* The C API's project now supports enabling/disabling Cargo features to
have finer-grained support over what's included (plus auto-management
of the header file).
* Building the C API and managing it is now exclusively done through
CMake. For example invoking `doxygen` now lives in CMake, installation
lives there, etc.
The `CMakeLists.txt` file for the C API is overhauled in the process of
doing this. The build now primarily matches on the Rust target being
built rather than the host target. Additionally installation will now
install both the static and shared libraries instead of just one.
Additionally during this refactoring various bits and pieces of
Android-specific code were all removed. Management of the C toolchain
feels best left in scope of the caller (e.g. configuring `CC_*` env vars
and such) rather than here.
prtest:full
* Don't use `option` for optional strings
* Invert release build check
Also adjust some indentation
* Fix more indentation
* Remove no-longer-used variable
* Reduce duplication in feature macro
* 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
* Add C API for GuestProfiler
* GuestProfiler C API: remove unsafe and add docs
* Fix clang-format complaints
* rename to wasmtime_guestprofiler_t for consistency, change to passing tuples by struct type, clarify docs
* rustfmt
* out is marked "own" too
* gate on profiling feature
This allows clangd to not import the headers in the wasmtime directory,
as not all of them include their dependencies correctly. This means that
clangd can import a header directly and it breaks the build, as the
order `wasmtime.h` #includes is important.
See: https://github.com/include-what-you-use/include-what-you-use/blob/master/docs/IWYUPragmas.md
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
* c-api: Add a feature for async
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
* c-api: Add support for async config
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
* c-api: Add support for calling async functions
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
* c-api: Add ability to yield execution of Wasm in a store
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
* c-api: Introduce wasmtime_linker_instantiate_async
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
* c-api: Support defining async host functions
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
* gitignore: ignore cmake cache for examples
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
* examples: Add example of async API in C
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
* 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 <rockwood@redpanda.com>
* c-api: Make async function safe
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
* c-api: Remove wasmtime_call_future_get_results
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
* c-api: Simplify CHostCallFuture
Move the result translation and hostcall_val_storage usage into an async
function
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
* 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 <rockwood@redpanda.com>
* c-api: Improve async.h documentation
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
* c-api: Cleanup from previous changes
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
* examples: Fix example
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
* 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 <rockwood@redpanda.com>
* c-api: Fix async.h documentation
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
* c-api: Fix documentation for async.h
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
* c-api: Review feedback
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
* examples: Downgrade async.cpp example to C++11
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
* c-api: initialize continuation with a panic callback
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
* prtest:full
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
---------
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
* Add several `WASMTIME_VERSION_*` macros to `wasmtime.h`.
* Update `scripts/publish.rs`
* To set these macros as per the new version in `./Cargo.toml` during
`./publish bump`.
* To verify the macros match the version in `./Cargo.toml` during
`./publish verify`.
Fix#5635
* Add cmake compatibility to c-api
* Add CMake documentation to wasmtime.h
* Add CMake instructions in examples
* Modify CI for CMake support
* Use correct rust in CI
* Trigger build
* Refactor run-examples
* Reintroduce example_to_run in run-examples
* Replace run-examples crate with cmake
* Fix markdown formatting in examples readme
* Fix cmake test quotes
* Build rust wasm before cmake tests
* Pass CTEST_OUTPUT_ON_FAILURE
* Another cmake test
* Handle os differences in cmake test
* Fix bugs in memory and multimemory examples
* Delete historical interruptable support in Wasmtime
This commit removes the `Config::interruptable` configuration along with
the `InterruptHandle` type from the `wasmtime` crate. The original
support for adding interruption to WebAssembly was added pretty early on
in the history of Wasmtime when there was no other method to prevent an
infinite loop from the host. Nowadays, however, there are alternative
methods for interruption such as fuel or epoch-based interruption.
One of the major downsides of `Config::interruptable` is that even when
it's not enabled it forces an atomic swap to happen when entering
WebAssembly code. This technically could be a non-atomic swap if the
configuration option isn't enabled but that produces even more branch-y
code on entry into WebAssembly which is already something we try to
optimize. Calling into WebAssembly is on the order of a dozens of
nanoseconds at this time and an atomic swap, even uncontended, can add
up to 5ns on some platforms.
The main goal of this PR is to remove this atomic swap on entry into
WebAssembly. This is done by removing the `Config::interruptable` field
entirely, moving all existing consumers to epochs instead which are
suitable for the same purposes. This means that the stack overflow check
is no longer entangled with the interruption check and perhaps one day
we could continue to optimize that further as well.
Some consequences of this change are:
* Epochs are now the only method of remote-thread interruption.
* There are no more Wasmtime traps that produces the `Interrupted` trap
code, although we may wish to move future traps to this so I left it
in place.
* The C API support for interrupt handles was also removed and bindings
for epoch methods were added.
* Function-entry checks for interruption are a tiny bit less efficient
since one check is performed for the stack limit and a second is
performed for the epoch as opposed to the `Config::interruptable`
style of bundling the stack limit and the interrupt check in one. It's
expected though that this is likely to not really be measurable.
* The old `VMInterrupts` structure is renamed to `VMRuntimeLimits`.
Implement Wasmtime's new API as designed by RFC 11. This is quite a large commit which has had lots of discussion externally, so for more information it's best to read the RFC thread and the PR thread.
* Bring back `Module::deserialize`
I thought I was being clever suggesting that `Module::deserialize` was
removed from #2791 by funneling all module constructors into
`Module::new`. As our studious fuzzers have found, though, this means
that `Module::new` is not safe currently to pass arbitrary user-defined
input into. Now one might pretty reasonable expect to be able to do
that, however, being a WebAssembly engine and all. This PR as a result
separates the `deserialize` part of `Module::new` back into
`Module::deserialize`.
This means that binary blobs created with `Module::serialize` and
`Engine::precompile_module` will need to be passed to
`Module::deserialize` to "rehydrate" them back into a `Module`. This
restores the property that it should be safe to pass arbitrary input to
`Module::new` since it's always expected to be a wasm module. This also
means that fuzzing will no longer attempt to fuzz `Module::deserialize`
which isn't something we want to do anyway.
* Fix an example
* Mark `Module::deserialize` as `unsafe`
* Ensure `store` is in the function names
* Don't abort the process on `add_fuel` when fuel isn't configured
* Allow learning about failure in both `add_fuel` and `fuel_consumed`
* Add an instance limit to `Config`
This commit adds a new parameter to `Config` which limits the number of
instances that can be created within a store connected to that `Config`.
The intention here is to provide a default safeguard against
module-linking modules that recursively create too many instances.
* Update crates/c-api/include/wasmtime.h
Co-authored-by: Peter Huene <peter@huene.dev>
Co-authored-by: Peter Huene <peter@huene.dev>
* Update WebAssembly C API submodule to latest commit.
This commit updates the WebAssembly C API submodule (for `wasm.h`) to the
latest commit out of master.
This fixes the behavior of `wasm_name_new_from_string` such that it no longer
copies the null character into the name, which caused unexpected failures when
using the Wasmtime linker as imports wouldn't resolve when the null was
present.
Along with this change were breaking changes to `wasm_func_call`, the host
callback signatures, and `wasm_instance_new` to take a vector type instead of a
pointer to an unsized array.
As a result, Wasmtime language bindings based on the C API will need to be
updated once this change is pulled in.
Fixes#2211.
Fixes#2131.
* Update Doxygen comments for wasm.h changes.
* Update the C API with module linking support
This commit does everything necessary (ideally) to support the module
linking proposal in the C API. The changes here are:
* New `wasm_{module,instance}type_t` types and accessors
* New `wasm_{module,instance}_type` functions
* Conversions between `wasm_extern_t` and `wasm_{instance,module}_t`, as
well as `wasm_externtype_t` and the new types.
* Addition of `WASM_EXTERN_{MODULE,INSTANCE}` constants
* New `wasm_config_t` modifier to enable/disable module linking
With these functions it should be possible to pass instances/modules to
instances and also acquire them from exports. Altogether this should
enable everything for module linking.
An important point for this is that I've opted to add all these items
under the `wasm_*` name prefix instead of `wasmtime_*`. I've done this
since they're all following the idioms of existing APIs and while not
standard the intention would be to standardize them (unlike many other
Wasmtime-specific APIs).
cc #2094
* Appease doxygen
* wasmtime-c-api: Only drop non-null `*mut wasm_ref_t`s
* wasmtime-c-api: Handle null refs in `wasm_val_t` to `Val` conversion
* wasmtime-c-api: Don't unwrap and rewrap `Option`s
The `unwrap` can panic, and there isn't any point to this unwrap+rewrap.
* wasmtime-c-api: Add conversions between `funcref` and `wasm_func_t`
* wasmtime-c-api: More ownership documentation for `wasmtime.h`
This commit fills out documentation for all remaining functions in the C
API, and additionally enables "warn if undocumented" which will fail CI
since warnings are also treated as errors.