Browse Source
* Update Wasmtime's tier stability documentation Move some items between tiers and add a few misc items here and there. * Update platform support documentation Re-word lots of this since it was originally written, link to the tiers of support page, and rewrite the section on `no_std`. * Update the `min-platform` example with no_std This commit updates the preexisting `min-platform` example to no longer require Nightly Rust and instead use the `no_std` support now added to Wasmtime. This involved: * Change the build process to produce a staticlib which is then manually converted via `cc` into a shared library for the native Linux platform. * Compile the modules outside of the embedding and only `deserialize` within the embedding. * Update the `indexmap` dependency to pick up a bug fix required in `no_std` mode (apparently, it fails on indexmap@2.0.0 and passes at 2.2.6, I didn't dig much further). This commit additionally makes the `wasmtime-platform.h` header file generated by the example a release artifact for Wasmtime itself. The header itself is touched up a bit by configuring some more `cbindgen` options as well. * Fix clippy build prtest:full * Review comments * Pass gc-sections to linking the librarypull/8559/head
Alex Crichton
6 months ago
committed by
GitHub
17 changed files with 396 additions and 290 deletions
@ -1,139 +1,81 @@ |
|||||
# Platform Support |
# Platform Support |
||||
|
|
||||
The `wasmtime` project is a configurable and lightweight runtime for WebAssembly |
This page is intended to give a high-level overview of Wasmtime's platform |
||||
which has a number of ways it can be configured. Not all features are supported |
support along with some aspirations of Wasmtime. For more details see the |
||||
on all platforms, but it is intended that `wasmtime` can run in some capacity on |
documentation on [tiers of stability](./stability-tiers.md) which has specific |
||||
almost all platforms! The matrix of what's being tested, what works, and what's |
information about what's supported in Wasmtime on a per-matrix-combination |
||||
supported where is evolving over time, and this document hopes to capture a |
basis. |
||||
snapshot of what the current state of the world looks like. |
|
||||
|
Wasmtime strives to support hardware that anyone wants to run WebAssembly on. |
||||
All features of `wasmtime` should work on the following platforms: |
Maintainers of Wasmtime support a number of "major" platforms themselves but |
||||
|
porting work may be required to support platforms that maintainers are not |
||||
* Linux x86\_64 |
themselves familiar with. Out-of-the box Wasmtime supports: |
||||
* Linux aarch64 |
|
||||
* macOS x86\_64 |
* Linux x86\_64, aarch64, s390x, and riscv64 |
||||
|
* macOS x86\_64, aarch64 |
||||
* Windows x86\_64 |
* Windows x86\_64 |
||||
|
|
||||
For more detailed information about supported platforms, please check out the |
Other platforms such as Android, iOS, and the BSD family of OSes are not |
||||
sections below! |
built-in yet. PRs for porting are welcome and maintainers are happy to add more |
||||
|
entries to the CI matrix for these platforms. |
||||
|
|
||||
## JIT compiler support |
## Compiler Support |
||||
|
|
||||
The JIT compiler, backed by Cranelift, supports the x86\_64 and aarch64 |
Cranelift supports x86\_64, aarch64, s390x, and riscv64. No 32-bit platform is |
||||
architectures at this time. Support for at least ARM and x86 is planned as well. |
currently supported. Building a new backend for Cranelift is a relatively large |
||||
|
undertaking which maintainers are willing to help with but it's recommended to |
||||
|
reach out to Cranelift maintainers first to discuss this. |
||||
|
|
||||
Usage of the JIT compiler will require a host operating system which supports |
Winch supports x86\_64. The aarch64 backend is in development. Winch is built on |
||||
creating executable memory pages on-the-fly. In Rust terms this generally means |
Cranelift's support for emitting instructions so Winch's possible backend list |
||||
that `std` needs to be supported on this platform. |
is currently limited to what Cranelift supports. |
||||
|
|
||||
|
Usage of the Cranelift or Winch requires a host operating system which supports |
||||
|
creating executable memory pages on-the-fly. Support for statically linking in a |
||||
|
single precompiled module is not supported at this time. |
||||
|
|
||||
|
Both Cranelift and Winch can be used either in AOT or JIT mode. In AOT mode one |
||||
|
process precompiles a module/component and then loads it into another process. |
||||
|
In JIT mode this is all done within the same process. |
||||
|
|
||||
|
Neither Cranelift nor Winch support tiering at this time in the sense of having |
||||
|
a WebAssembly module start from a Winch compilation and automatically switch to |
||||
|
a Cranelift compilation. Modules are either entirely compiled with Winch or |
||||
|
Cranelift. |
||||
|
|
||||
## Interpreter support |
## Interpreter support |
||||
|
|
||||
At this time `wasmtime` does not have a mode in which it simply interprets |
At this time `wasmtime` does not have a mode in which it simply interprets |
||||
WebAssembly code. It is planned to add support for an interpreter, however, and |
WebAssembly code. It is desired to add support for an interpreter, however, and |
||||
this will have minimal system dependencies. It is planned that the system will |
this will have minimal system dependencies. It is planned that the system will |
||||
need to support some form of dynamic memory allocation, but other than that not |
need to support some form of dynamic memory allocation, but other than that not |
||||
much else will be needed. |
much else will be needed. |
||||
|
|
||||
## What about `#[no_std]`? |
## Support for `#![no_std]` |
||||
|
|
||||
The `wasmtime` project does not currently use `#[no_std]` for its crates, but |
The `wasmtime` crate supports being build on no\_std platforms in Rust, but |
||||
this is not because it won't support it! For information on building Wasmtime |
only for a subset of its compile-time Cargo features. Currently supported |
||||
for a custom target see [the minimal build |
Cargo features are: |
||||
documentation](./examples-minimal.md). Please [open an |
|
||||
issue](https://github.com/bytecodealliance/wasmtime/issues/new) on the |
* `runtime` |
||||
`wasmtime` repository to request support for a specific platform. |
* `gc` |
||||
|
* `component-model` |
||||
This is a common question we are asked, however, so to provide some more context |
|
||||
on why Wasmtime is the way it is, here's some responses to frequent points |
This notably does not include the `default` feature which means that when |
||||
raised about `#![no_std]`: |
depending on Wasmtime you'll need to specify `default-features = false`. This |
||||
|
also notably does not include Cranelift or Winch at this time meaning that |
||||
* **What if my platform doesn't have `std`?** - For platforms without support |
no\_std platforms must be used in AOT mode where the module is precompiled |
||||
for the Rust standard library the JIT compiler of Wasmtime often won't run on |
elsewhere. |
||||
the platform as well. The JIT compiler requires `mmap` (or an equivalent), and |
|
||||
presence of `mmap` often implies presence of a libc which means Rust's `std` |
Wasmtime's support for no\_std requires the embedder to implement the equivalent |
||||
library works. |
of a C header file to indicate how to perform basic OS operations such as |
||||
|
allocating virtual memory. This API can be found as `wasmtime-platform.h` in |
||||
Cargo's [`-Z build-std` feature][zbuild-std] feature is also intended to help |
Wasmtime's release artifacts or at |
||||
easily build the standard library for all platforms. With this feature you can |
`examples/min-platform/embedding/wasmtime-platform.h` in the source tree. Note |
||||
recompile the standard library (using Nightly Rust for now) with a [custom |
that this API is not guaranteed to be stable at this time, it'll need to be |
||||
target specification][custom-target] if necessary. Additionally the intention |
updated when Wasmtime is updated. |
||||
at this time is to get `std` building for all platforms, regardless of what |
|
||||
the platform actually supports. This change is taking time to implement, but |
Wasmtime's runtime will use the symbols defined in this file meaning that if |
||||
[rust-lang/rust#74033] is an example of this support growing over time. |
they're not defined then a link-time error will be generated. Embedders are |
||||
|
required to implement these functions in accordance with their documentation to |
||||
We're also interested in running Wasmtime without a JIT compiler in the |
enable Wasmtime to run on custom platforms. |
||||
future, but that is not implemented at this time. Implementing this will |
|
||||
require a lot more work than tagging crates `#![no_std]`. The Wasmtime |
|
||||
developers are also very interested in supporting as many targets as possible, |
|
||||
so if Wasmtime doesn't work on your platform yet we'd love to learn why and |
|
||||
what we can do to support that platform, but the conversation here is |
|
||||
typically more nuanced than simply making `wasmtime` compile without `std`. |
|
||||
|
|
||||
* **Doesn't `#![no_std]` have smaller binary sizes?** - There's a lot of factors |
|
||||
that affect binary size in Rust. Compilation options are a huge one but beyond |
|
||||
that idioms and libraries linked matter quite a lot as well. Code is not |
|
||||
inherently large when using `std` instead of `core`, it's just that often code |
|
||||
using `std` has more dependencies (like `std::thread`) which requires code to |
|
||||
bind. Code size improvements can be made to code using `std` and `core` |
|
||||
equally, and switching to `#![no_std]` is not a silver bullet for compile |
|
||||
sizes. |
|
||||
|
|
||||
* **The patch to switch to `#![no_std]` is small, why not accept it?** - PRs to |
|
||||
switch to `#![no_std]` are often relatively small or don't impact too many |
|
||||
parts of the system. There's a lot more to developing a `#![no_std]` |
|
||||
WebAssembly runtime than switching a few crates, however. Maintaining a |
|
||||
`#![no_std]` library over time has a number of costs associated with it: |
|
||||
|
|
||||
* Rust has no stable way to diagnose `no_std` errors in an otherwise `std` |
|
||||
build, which means that to support this feature it must be tested on CI with |
|
||||
a `no_std` target. This is costly in terms of CI time, CI maintenance, and |
|
||||
developers having to do extra builds to avoid CI errors. Note that this |
|
||||
isn't *more* costly than any other platform supported by Wasmtime, but it's |
|
||||
a cost nonetheless. |
|
||||
|
|
||||
* Idioms in `#![no_std]` are quite different than normal Rust code. You'll |
|
||||
import from different crates (`core` instead of `std`) and data structures |
|
||||
have to all be manually imported from `alloc`. These idioms are difficult to |
|
||||
learn for newcomers to the project and are not well documented in the |
|
||||
ecosystem. This cost of development and maintenance is not unique to |
|
||||
Wasmtime but in general affects the `#![no_std]` ecosystem at large, |
|
||||
unfortunately. |
|
||||
|
|
||||
* Currently Wasmtime does not have a target use case which requires |
|
||||
`#![no_std]` support, so it's hard to justify these costs of development. |
|
||||
We're very interested in supporting as many use cases and targets as |
|
||||
possible, but the decision to support a target needs to take into account |
|
||||
the costs associated so we can plan accordingly. Effectively we need to have |
|
||||
a goal in mind instead of taking on the costs of `#![no_std]` blindly. |
|
||||
|
|
||||
* At this time it's not clear whether `#![no_std]` will be needed long-term, |
|
||||
so eating short-term costs may not pay off in the long run. Features like |
|
||||
Cargo's [`-Z build-std`][zbuild-std] may mean that `#![no_std]` is less and |
|
||||
less necessary over time. |
|
||||
|
|
||||
* **How can Wasmtime support `#![no_std]` if it uses X?** - Wasmtime as-is today |
|
||||
is not suitable for many `#![no_std]` contexts. For example it might use |
|
||||
`mmap` for allocating JIT code memory, leverage threads for caching, or use |
|
||||
thread locals when calling into JIT code. These features are difficult to |
|
||||
support in their full fidelity on all platforms, but the Wasmtime developers |
|
||||
are very much aware of this! Wasmtime is intended to be configurable where |
|
||||
many of these features are compile-time or runtime options. For example caches |
|
||||
can be disabled, JITs can be removed and replaced with interpreters, or users |
|
||||
could provide a callback to allocate memory instead of using the OS. |
|
||||
This is sort of a long-winded way of saying that Wasmtime on the surface may |
|
||||
today look like it won't support `#![no_std]`, but this is almost always |
|
||||
simply a matter of time and development priorities rather than a fundamental |
|
||||
reason why Wasmtime *couldn't* support `#![no_std]`. |
|
||||
|
|
||||
Note that at this time these guidelines apply not only to Wasmtime but also to |
|
||||
some of its dependencies developed by the Bytecode Alliance such as the |
|
||||
[wasm-tools repository](https://github.com/bytecodealliance/wasm-tools). These |
|
||||
projects don't have the same runtime requirements as Wasmtime (e.g. `wasmparser` |
|
||||
doesn't need `mmap`), but we're following the same guidelines above at this |
|
||||
time. Patches to add `#![no_std]`, while possibly small, incur many of the same |
|
||||
costs and also have an unclear longevity as features like [`-Z |
|
||||
build-std`][zbuild-std] evolve. |
|
||||
|
|
||||
[zbuild-std]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-std |
|
||||
[custom-target]: https://doc.rust-lang.org/rustc/targets/custom.html |
|
||||
[rust-lang/rust#74033]: https://github.com/rust-lang/rust/pull/74033 |
|
||||
|
@ -1 +1,2 @@ |
|||||
libwasmtime-platform.so |
libwasmtime-platform.so |
||||
|
libembedding.so |
||||
|
@ -1,18 +0,0 @@ |
|||||
{ |
|
||||
"arch": "aarch64", |
|
||||
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", |
|
||||
"dynamic-linking": true, |
|
||||
"has-thread-local": true, |
|
||||
"is-builtin": false, |
|
||||
"llvm-target": "aarch64-unknown-linux-gnu", |
|
||||
"max-atomic-width": 64, |
|
||||
"os": "minwasmtime", |
|
||||
"position-independent-executables": true, |
|
||||
"panic-strategy": "abort", |
|
||||
"frame-pointer": "always", |
|
||||
"relro-level": "full", |
|
||||
"stack-probes": { |
|
||||
"kind": "inline" |
|
||||
}, |
|
||||
"target-pointer-width": "64" |
|
||||
} |
|
@ -0,0 +1,20 @@ |
|||||
|
language = "C" |
||||
|
include_guard = "_WASMTIME_PLATFORM_H" |
||||
|
include_version = true |
||||
|
cpp_compat = true |
||||
|
|
||||
|
header = """ |
||||
|
// Platform support for Wasmtime's `no_std` build. |
||||
|
// |
||||
|
// This header file is what Wasmtime will rely on when it does not otherwise |
||||
|
// have support for the native platform. This can happen with `no_std` binaries |
||||
|
// for example where the traditional Unix-or-Windows implementation is not |
||||
|
// suitable. |
||||
|
// |
||||
|
// Embedders are expected to implement the symbols defined in this header file. |
||||
|
// These symbols can be defined either in C/C++ or in Rust (using |
||||
|
// `#[no_mangle]`). |
||||
|
// |
||||
|
// Some more information about this header can additionally be found at |
||||
|
// <https://docs.wasmtime.dev/stability-platform-support.html>. |
||||
|
""" |
@ -0,0 +1,12 @@ |
|||||
|
#![cfg(not(unix))] // gets `cargo clippy` working
|
||||
|
|
||||
|
use core::panic::PanicInfo; |
||||
|
|
||||
|
#[panic_handler] |
||||
|
fn handler(_info: &PanicInfo) -> ! { |
||||
|
// NB: should ideally print something here but for this example this is left
|
||||
|
// out. A more complete embedding would likely turn `info` into a
|
||||
|
// stack-allocated string and then pass that as a message to the outer
|
||||
|
// system to get printed and trigger a failure.
|
||||
|
loop {} |
||||
|
} |
@ -1,20 +0,0 @@ |
|||||
{ |
|
||||
"arch": "x86_64", |
|
||||
"cpu": "x86-64", |
|
||||
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", |
|
||||
"features": "+sse4.2,+avx,+fma,+popcnt", |
|
||||
"dynamic-linking": true, |
|
||||
"has-thread-local": true, |
|
||||
"is-builtin": false, |
|
||||
"llvm-target": "x86_64-unknown-linux-gnu", |
|
||||
"max-atomic-width": 64, |
|
||||
"os": "minwasmtime", |
|
||||
"position-independent-executables": true, |
|
||||
"panic-strategy": "abort", |
|
||||
"frame-pointer": "always", |
|
||||
"relro-level": "full", |
|
||||
"stack-probes": { |
|
||||
"kind": "inline" |
|
||||
}, |
|
||||
"target-pointer-width": "64" |
|
||||
} |
|
Loading…
Reference in new issue