* Introduce StackMemory and StackMemoryCreator
This allows custom implementations of stack memory to be plugged into
the async functionality for wasmtime. Currently, stacks are always
mmapped, and this custom allocator allows embedders to use any memory
they would like.
The new APIs are also exposed in the C api.
This has no effect on windows, as our hands are tied with fibers there.
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
* Add test for custom host memory
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
* fix allocator test
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
* Address review comments
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
* Fix lint warnings
prtest:full
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
* fix windows lint warning
prtest:full
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
---------
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>
This commit makes it so that the library type for core dumps is serializable
into the standard binary format for core dumps.
Additionally, this commit makes it so that we use the library type for
generating core dumps in the CLI. We previously were using a one-off
implementation of core dump generation that only had backtrace information and
no instances, modules, globals, or memories included. The library type has all
that information, so the core dumps produced by our CLI will both be more
featureful and be generated by shared code paths going forward.
Along the way, implementing all this required some new helper methods sprinkled
throughout `wasmtime` and `wasmtime-runtime`:
* `wasmtime::Instance::module`: get the module that a `wasmtime::Instance` is an
instance of. This is public, since it seems generally useful. This involved
adding a new return value from `ModuleRegistry::register_module` that is an
identifier that can be used to recover a reference to the registered module.
* `wasmtime::Instance::all_{globals,memories}`: get the full global/memory index
space. I made these `pub(crate)` out of caution. I don't think we want to commit
to exposing non-exported things in the public API, even if we internally need
them for debugging-related features like core dumps. These also needed
corresponding methods inside `wasmtime-runtime`.
* `wasmtime::{Global,Memory}::hash_key`: this was needed to work around the fact
that each time you call `{Global,Memory}::from_wasmtime`, it creates a new
entry in the `StoreData` and so you can get duplicates. But we need to key some
hash maps on globals and memories when constructing core dumps, so we can't
treat the underlying `Stored<T>` as a hash key because it isn't stable across
duplicate `StoreData` entries. So we have these new methods. They are only
`pub(crate)`, are definitely implementation details, and aren't exposed in the
public API.
* `wasmtime::FrameInfo::module`: Each frame in a backtrace now keeps a handle to
its associated module instead of just the name. This is publicly exposed
because it seems generally useful. This means I also deprecated
`wasmtime::FrameInfo::module_name` since you can now instead do
`frame.module().name()` to get that exact same info. I updated callers inside
the repo.
* 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
Running cargo license on the c-api crate reports that this crate is
unlicensed.
We use cargo-license to automate our license tracking for this library
in our C++ application and it'd be nice to just have a license in here.
I used the standard license that wasmtime uses, but happy to use
another.
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
This allows for running the generated make files directly if your
confirgure step wants to use a vendored cargo program.
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
* feat(wasmtime-cli): add async support flag
Within the wasmtime CLI, the current default behavior
is to only inject the synchronous functions to linkers.
This will add a flag called `--async` that will inject
the asynchronous one instead.
* chore: refactor wasi http crate
* feat(wasmtime-wasi): make in_tokio function public
* feat(wasi-http): define default feature called sync
* Revert "feat(wasmtime-cli): add async support flag"
This reverts commit b743ff2003a2e391972330aa8e8437c6356e580a.
* chore: improve flaky tests for wasi http
* feat(wasi-http): expose sync api for components
* chore: add tests for sync api of wasi http components
* feat(wasmtime-cli): restore support for wasi http module
* chore: revert change to outbound http request invalid test
* chore: have extra tracing to help debugging
* feat(wasi-http): allow modules with sync functions in linker
* fix(wasi-http): missing response body in sync api
* feat: include blocking for io streams
* chore: add tests for wasi http module in cli
* chore: disable preview2 flag in wasi http test
* chore: use preview2 flag in wasi http test
* fix(wasi-http): missing stream output in sync api
* chore: fix tests for wasi http
* chore: add tracing for poll oneoff call
* chore: send exit signal on wasi http test
* chore: swap println to tracing debug
* chore: set http server timeout to 50 secs by default
* chore: add test posting large file
* chore: revert formatting in cargo toml
* chore: fix wasi-http feature and skip failing tests
prtest:full
---------
Co-authored-by: Eduardo Rodrigues <eduardomourar@users.noreply.github.com>
* Change preview2 builder methods to use `&mut self`
This commit changes the `WasiCtxBuilder` for preview2 to use a builder
pattern more similar to `std::process::Command` where methods take `&mut
self` and return `&mut Self` instead of taking `self` and returning
`Self`. This pattern enables more easily building up configuration over
time throughout code where ownership transfer might otherwise be
awkward.
A small caveat to this is that the ergonomics of this pattern only
really work out well if the final "build" method takes `&mut self` as
well. In this situation it's difficult to try to figure out what's
supposed to happen if this method is called twice, so I left it to panic
for now so we can more easily update it in the future possibly.
* Synchronize preview1/preview2 builders
* Move preview1 builders to `&mut`-style
* Rename methods on preview2 builder to match names on the preview1 builders
* Fix C API
* Fix more tests
* Fix benchmark build
* Fix unused variable
* Change the call to unwrap to except with an error message
* Update crates/c-api/src/linker.rs
* Run rustfmt.
---------
Co-authored-by: Peter Huene <peter@huene.dev>
* Allow async yield from epoch interruption callback
When an epoch interruption deadline arrives, previously it was possible
to yield to the async executor, or to invoke a callback on the wasm
stack, but not both. This changes the API to allow callbacks to run and
then request yielding to the async executor.
* Fix Wasmtime C API implementation
This commit goes through all proc-macros we have in this repository and
ensures that they're all flagged with `test = false` and `doctest =
false`. This comes about as I was curious why CI time was 40m which felt
a little long and upon inspection the cross-compiled builders were
taking upwards of 30 minutes just to build everything (not including
running tests) where the non-cross-compiled builders took only about
10-15 minutes to build everything.
Further investigation into this discrepancy showed that a lot of crates
are being double-compiled in a cross-compiled situation. This is
expected at a base level and something Cargo transparently handles, for
example if a build script and the final binary need the same dependency
then it's gotta get compiled twice. What was odd is that large portions
of the Wasmtime crate graph were being compiled more than they should
be.
I tracked this down to some `dev-dependencies` for procedural macros
pointing at wasmtime crates. This makes sense for the `tests/*.rs`-style
tests which are always compiled for the target, but tests for the
proc-macro itself would be compiled for the host. By disabling tests and
doctests for the proc macro itself this removes the need for the
host-compiled version of these dependencies.
Overall this reduces a full compile of all tests from ~840 units of work
to 700 units of work according to Cargo. The set of extra crates
compiled in a cross-compiled workflow is not much smaller than in a
non-cross-compiled workflow and they all generally "make sense" as core
shared dependencies which are rooted in both Wasmtime and some
proc-macro's dependency tree, for example.
* 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
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 <jsharp@fastly.com>
Co-Authored-By: Alex Crichton <alex@alexcrichton.com>
prtest:full
* Add support for generating perf maps for simple perf profiling
* add missing enum entry in C code
* bugfix: use hexa when printing the code region's length too (thanks bjorn3!)
* sanitize file name + use bufwriter
* introduce --profile CLI flag for wasmtime
* Update doc and doc comments for new --profile option
* remove redundant FromStr import
* Apply review feedback: make_line receives a Write impl, report errors
* fix tests?
* better docs
* Add support for WASI sockets to C API
Add support for WASI sockets in the C API by adding a new API to handle
preopening sockets for clients. This uses HashMap instead of Vec for
preopened sockets to identify if caller has called in more than once
with the same FD number. If so, then we return false so caller is given
hint that they are attempting to overwrite an already existing socket
FD.
* Apply suggestions from code review
Co-authored-by: Peter Huene <peter@huene.dev>
* s/stdlistener/listener/
---------
Co-authored-by: Peter Huene <peter@huene.dev>
* Remove the need to have a `Store` for an `InstancePre`
This commit relaxes a requirement of the `InstancePre` API, notably its
construction via `Linker::instantiate_pre`. Previously this function
required a `Store<T>` to be present to be able to perform type-checking
on the contents of the linker, and now this requirement has been
removed.
Items stored within a linker are either a `HostFunc`, which has type
information inside of it, or an `Extern`, which doesn't have type
information inside of it. Due to the usage of `Extern` this is why a
`Store` was required during the `InstancePre` construction process, it's
used to extract the type of an `Extern`. This commit implements a
solution where the type information of an `Extern` is stored alongside
the `Extern` itself, meaning that the `InstancePre` construction process
no longer requires a `Store<T>`.
One caveat of this implementation is that some items, such as tables and
memories, technically have a "dynamic type" where during type checking
their current size is consulted to match against the minimum size
required of an import. This no longer works when using
`Linker::instantiate_pre` as the current size used is the one when it
was inserted into the linker rather than the one available at
instantiation time. It's hoped, however, that this is a relatively
esoteric use case that doesn't impact many real-world users.
Additionally note that this is an API-breaking change. Not only is the
`Store` argument removed from `Linker::instantiate_pre`, but some other
methods such as `Linker::define` grew a `Store` argument as the type
needs to be extracted when an item is inserted into a linker.
Closes#5675
* Fix the C API
* Fix benchmark compilation
* Add C API docs
* Update crates/wasmtime/src/linker.rs
Co-authored-by: Andrew Brown <andrew.brown@intel.com>
---------
Co-authored-by: Andrew Brown <andrew.brown@intel.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 release notes for 3.0.1
* Update some version directives for crates in Wasmtime
* Mark anything with `publish = false` as version 0.0.0
* Mark the icache coherence crate with the same version as Wasmtime
* Fix manifest directives
It seems they were mistakenly added to the `wasmtime_valunion` union whereas it is actually the `ValRaw` Rust type (represented by `wasmtime_val_raw`) that is affected by the change.
This commit adds the missing "out of fuel" trap code to the C API.
Without this, calls to `wasmtime_trap_code` will trigger an unreachable panic
on traps from running out of fuel.