Expand doc section about "what about #![no_std]?" (#2024)
* Expand doc section about "what about `#![no_std]`?" This commit expands the `#![no_std]` section of the documentation with an FAQ-style set of words which explains in more detail about why we don't support `#![no_std]` at this time, and how we can support it in the future. * Review comments * Add some more words about -Zbuild-std
This commit is contained in:
@@ -42,3 +42,98 @@ cases for for what `#[no_std]` might entail, so if you're interested in this
|
|||||||
we'd love to hear about your use case! Feel free to [open an
|
we'd love to hear about your use case! Feel free to [open an
|
||||||
issue](https://github.com/bytecodealliance/wasmtime/issues/new) on the
|
issue](https://github.com/bytecodealliance/wasmtime/issues/new) on the
|
||||||
`wasmtime` repository to discuss this.
|
`wasmtime` repository to discuss this.
|
||||||
|
|
||||||
|
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
|
||||||
|
raised about `#![no_std]`:
|
||||||
|
|
||||||
|
* **What if my platform doesn't have `std`?** - For platforms without support
|
||||||
|
for the Rust standard library the JIT compiler of Wasmtime often won't run on
|
||||||
|
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`
|
||||||
|
library works.
|
||||||
|
|
||||||
|
Cargo's [`-Z build-std` feature][zbuild-std] feature is also intended to help
|
||||||
|
easily build the standard library for all platforms. With this feature you can
|
||||||
|
recompile the standard library (using Nightly Rust for now) with a [custom
|
||||||
|
target specification][custom-target] if necessary. Additionally the intention
|
||||||
|
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
|
||||||
|
[rust-lang/rust#74033] is an example of this support growing over time.
|
||||||
|
|
||||||
|
We're also interested in running Wasmtime without a JIT compiler in the
|
||||||
|
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 supoprt 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
|
||||||
|
|||||||
Reference in New Issue
Block a user