From a957f00bea536233dfc60d941af4f79d1effdb2c Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 15 Jul 2020 08:48:23 -0700 Subject: [PATCH 1/3] 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. --- docs/stability-platform-support.md | 68 ++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/docs/stability-platform-support.md b/docs/stability-platform-support.md index 4d9f007848f2..0111707f644f 100644 --- a/docs/stability-platform-support.md +++ b/docs/stability-platform-support.md @@ -42,3 +42,71 @@ 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 issue](https://github.com/bytecodealliance/wasmtime/issues/new) on the `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. We're 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]` as well! 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: + + * There needs to be CI to ensure that when compiled with the right flags the + library does not actually use the Rust standard library. Currently there is + no stable way to do this in Rust, meaning that although a library may be + `#![no_std]` at one point in time it's easy to add a dependency that + accidentally sneaks in the `std` crate later. + + * 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. + +* **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. The + ambitious goals of Wasmtime take time and energy to implement, however, so we + need help from others in order to prioritize what's most important to tackle. + 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]`. From fdfee4f6e8d65348a81db0712ff2f0fe39bae46a Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 15 Jul 2020 11:15:37 -0700 Subject: [PATCH 2/3] Review comments --- docs/stability-platform-support.md | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/docs/stability-platform-support.md b/docs/stability-platform-support.md index 0111707f644f..70c514b19a04 100644 --- a/docs/stability-platform-support.md +++ b/docs/stability-platform-support.md @@ -74,11 +74,10 @@ raised about `#![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: - * There needs to be CI to ensure that when compiled with the right flags the - library does not actually use the Rust standard library. Currently there is - no stable way to do this in Rust, meaning that although a library may be - `#![no_std]` at one point in time it's easy to add a dependency that - accidentally sneaks in the `std` crate later. + * 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. * Idioms in `#![no_std]` are quite different than normal Rust code. You'll import from different crates (`core` instead of `std`) and data structures @@ -103,9 +102,7 @@ raised about `#![no_std]`: 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. The - ambitious goals of Wasmtime take time and energy to implement, however, so we - need help from others in order to prioritize what's most important to tackle. + 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 From 6866b4d74a7db1e339e4b4cbe16ede09f9b3856f Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 22 Jul 2020 07:25:19 -0700 Subject: [PATCH 3/3] Add some more words about -Zbuild-std --- docs/stability-platform-support.md | 38 ++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/docs/stability-platform-support.md b/docs/stability-platform-support.md index 70c514b19a04..acdceef07258 100644 --- a/docs/stability-platform-support.md +++ b/docs/stability-platform-support.md @@ -51,9 +51,19 @@ raised about `#![no_std]`: 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. We're 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]` as well! The Wasmtime + 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 @@ -77,7 +87,9 @@ raised about `#![no_std]`: * 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. + 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 @@ -94,6 +106,11 @@ raised about `#![no_std]`: 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 @@ -107,3 +124,16 @@ raised about `#![no_std]`: 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