Stream: git-wasmtime

Topic: wasmtime / issue #3451 no_std support for my OS


view this post on Zulip Wasmtime GitHub notifications bot (Oct 14 2021 at 02:23):

ethindp opened issue #3451:

I'm working on a hobby operating system and want to develop my drivers in something other than native code. I'd really like to go for web assembly but there are no good web assembly runtimes for no_std, and the only one I know of -- Wasmi -- appears very confusing to use and to work with. This is (possibly another) use-case for no_std support. Can this be done right now or do I have to try to figure out wasmi? (I'm not aware of any other Wasm runtimes, but if there's one I just don't know about, well...).

view this post on Zulip Wasmtime GitHub notifications bot (Oct 14 2021 at 08:32):

bjorn3 commented on issue #3451:

Cranelift could get no_std support, but wasmtime can't as it depends on the OS for example for mapping memory with the right priveleges.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 14 2021 at 10:24):

tschneidereit commented on issue #3451:

Our docs contain a fairly long explanation of our current stance on no_std, and suggestions for alternative approaches. I wonder if the answer to the first question in that section might be of interest to you?

view this post on Zulip Wasmtime GitHub notifications bot (Oct 14 2021 at 15:37):

ethindp commented on issue #3451:

@bjorn3 They could easily just use a trait for host operations. Then they could define operations for when libstd is included and just use that, and when your in no_std, you have to write that code yourself.

@tschneidereit I don't consider the majority of arguments against no_std on that page valid arguments. The only one that is a legitimate concern and that would be hard to do is CI integration. But, the rest, one by one, can be countered thusly:

  1. For platforms that don't have std, use a trait for host operations and require the program to implement functionality for mmap themselves, as I explained above. Same for anything else that wasmtime depends on.
  2. This one is just an explanation to why including libstd increases binary sizes.
  3. This "cost" isn't much, and I'll explain why below. The CI no_std build environment is a bit of a problem, as I acknowledged above, but it can be resolved.
  4. The idioms in no_std can be made a lot similar using a crate like no-std-compat. For the majority of things you use std for, just keep on using them. The only things you'll miss are things like stdio, filesystem access, threading, etc., but that isn't necessary to run web assembly and so you could easily just exclude that. Using a crate like no-std-compat lowers the supposed "cost" to new developers (which doesn't really exist, given that a lot of things you import from std come from core and alloc anyway, and it'd just be a change from std to either core or alloc depending on whether what your importing uses memory allocation or not).
  5. You now do have a use-case for no_std -- this issue (and probably many others that I haven't dug around for). But I doubt I am the first to ask for this to be implemented.
  6. no_std will always be necessary. Unless libstd suddenly stops reexporting things from core and alloc and the three get fully merged into one and I get the ability to tell libstd what my kernel supports (which does not include networking, threading, FS APIs, processes, consoles, etc.), you will always need to be able to turn this off when either (1) building for a target that does not implement all the required functionality for libstd to work; (2) writing code for a new operating system or environment that is not yet supported by libstd; or (3) developing for an environment that supports everything libstd supports but does not have a C library of some kind available yet. There are other places where libstd is not a viable option (e.g. embedded systems with very small amounts of memory) but where executing something like Wasm may be nice for security purposes.

I know that getting no_std support in might be challenging, and figuring out CI will be difficult since you'd need to have some boilerplate to bring up the system into a state where it is ready and capable of executing Wasm (that is: MMU is active, paging is enabled and configured, etc.). But it is a doable, and the boilerplate I'm talking about is the kind of boilerplate where you can pretty much write it once, perfect it and then forget about it and only touch it when you absolutely have to. It doesn't even have to be fast or the best boilerplate ever written; all it has to do is prepare the system for wasmtime. Then your off to the races.

Thoughts about all of this? (This was a pretty long reply, sorry!)

view this post on Zulip Wasmtime GitHub notifications bot (Oct 14 2021 at 15:44):

ethindp commented on issue #3451:

Update: yes, the first answer is a bit useful, but as noted in the issue, it doesn't yet support JSON targets, and that's what I'm using.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 14 2021 at 15:49):

bjorn3 commented on issue #3451:

For platforms that don't have std, use a trait for host operations and require the program to implement functionality for mmap themselves, as I explained above. Same for anything else that wasmtime depends on.

This has a non-trivial cost. I would love fixing the no_std support of Cranelift as it doesn't depend on an OS at all and shouldn't do so no matter what. For Wasmtime it is too much tied to the OS, with everything from mmap, files, locks, stack unwinding, ... It also has a lot of dependencies that don't support no_std which you will have to convince to add no_std support too. For most of them using traits will likely not be accepted at all due to being bad for api usability on platforms that support std.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 14 2021 at 16:06):

ethindp commented on issue #3451:

@bjorn3 Oh okay, I understand now. I'm just trying to find a high performance interpreter with a (reasonably) good API that supports no_std but I can't seem to find one at all. I've found some written in other languages, but porting those to Rust would get pretty messy IMO.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 15 2021 at 05:22):

cfallin commented on issue #3451:

@ethindp I'll echo what others have said about the effort involved in porting Wasmtime due to its OS-specific use of memory mapping (mainly) facilities and all of the dependencies it pulls in that are also std; but I will also note that there are more than just the two extremes of "full industrial-strength VM runtime with JIT" and "simple interpreter". More specifically I think there is room for a barebones-simple Wasm-MVP-only runtime that still uses compiled code (from Cranelift). I can imagine designing things from scratch to rely only on a pre-allocated chunk of linear memory, and avoiding a lot of the complexity that Wasmtime-like VMs have in order to support demand-paging, asynchrony, and post-MVP Wasm features. I personally at least would find that really interesting, and it might be appealing for more embedded scenarios that still need high performance.

Maye a starting point for that could be to use the data structures that one of the "super-simple" interpreters has defined -- wasmi perhaps -- and then start to generate function bodies with Cranelift that use the same data structures.

Anyway, just a thought; best of luck with your project!

view this post on Zulip Wasmtime GitHub notifications bot (Oct 15 2021 at 05:23):

cfallin edited a comment on issue #3451:

@ethindp I'll echo what others have said about the effort involved in porting Wasmtime due to its OS-specific use of memory mapping (mainly) facilities and all of the dependencies it pulls in that are also std; but I will also note that there are more than just the two extremes of "full industrial-strength VM runtime with JIT" and "simple interpreter". More specifically I think there is room for a barebones-simple Wasm-MVP-only runtime that still uses compiled code (from Cranelift). I can imagine designing things from scratch to rely only on a pre-allocated chunk of linear memory, and avoiding a lot of the complexity that Wasmtime-like VMs have in order to support demand-paging, asynchrony, and post-MVP Wasm features. I personally at least would find that really interesting, and it might be appealing for more embedded scenarios that still need high performance.

Maybe a starting point for that could be to use the data structures that one of the "super-simple" interpreters has defined -- wasmi perhaps -- and then start to generate function bodies with Cranelift that use the same data structures.

Anyway, just a thought; best of luck with your project!

view this post on Zulip Wasmtime GitHub notifications bot (Apr 11 2024 at 20:56):

alexcrichton commented on issue #3451:

I realize it's been years since this was originally opened, but in case anyone cc'd on this issue is still interested I've opened https://github.com/bytecodealliance/wasmtime/issues/8341 with a proposal to add no_std support for wasmtime which would address this issue as-stated.

view this post on Zulip Wasmtime GitHub notifications bot (May 10 2024 at 02:12):

alexcrichton closed issue #3451:

I'm working on a hobby operating system and want to develop my drivers in something other than native code. I'd really like to go for web assembly but there are no good web assembly runtimes for no_std, and the only one I know of -- Wasmi -- appears very confusing to use and to work with. This is (possibly another) use-case for no_std support. Can this be done right now or do I have to try to figure out wasmi? (I'm not aware of any other Wasm runtimes, but if there's one I just don't know about, well...).

view this post on Zulip Wasmtime GitHub notifications bot (May 10 2024 at 02:12):

alexcrichton commented on issue #3451:

This is done now with documentation here to be released with Wasmtime 21, so closing.


Last updated: Dec 23 2024 at 12:05 UTC