-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Expand doc section about "what about #![no_std]
?"
#2024
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
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. | ||
|
||
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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I personally feel like Crates like that also seem to be taking the fundamental stance of "std will never attempt to fix any of these problems, right?" when in fact PRs like rust-lang/rust#74033 will basically fix the issue for us. If all you want is code to compile using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree, I'm just considering the perspective of a user of Wasmtime asking about There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you think it's worth explicitly calling this out in the documentation here? Basically adding my comment as a new "what about There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If rust-lang/rust#74033 means that our options will change in the not too distant future, one option here is to replace the above paragraph with one that links to that, and points out that we'd prefer to avoid the thrash of updating all the files to a temporary solution when a better one is one the way. Then I don't think we'd even need to mention There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should at least link to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Also, I think it's reasonable to ask people who want to do There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One thing I don't really understand though is in what context we're writing this information down. This section is under the question "the patch is small, why not?" and this sub-point is "the idioms are different enough that it's nontrivial to do so". I don't get the impression that people are frequently sending patches with If y'all want I can write an explicit bullet saying " Also, unrelated to this PR itself, but do y'all think that we should be moving to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree we shouldn't do The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just left another comment on the first question with a suggestion for how this might be structured. Also agreed that mentioning |
||
|
||
* 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This argument doesn't entirely cover other crates than Wasmtime in this repository, or in other repositories, such as
wasm-tools
. Would it make sense to include another question below, along the lines of "The crate I want to use withoutstd
works with small changes, why not accept those"?After that one, yet another question could be "But I can't use
std
; what are my options?", where the answer could link tobuild-std
, pointing out that it's Nightly-only for now, but progressing.