Stream: git-wasmtime

Topic: wasmtime / Issue #2537 Make cranelift-codegen-shared no_std


view this post on Zulip Wasmtime GitHub notifications bot (Jan 03 2021 at 15:16):

tomaka commented on Issue #2537:

The CI failure looks unrelated to the PR:

rust-lld: error while loading shared libraries: libLLVM-11-rust-1.49.0-stable.so: cannot open shared object file: No such file or director

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

bjorn3 commented on Issue #2537:

This is for https://github.com/tomaka/redshirt, right?

view this post on Zulip Wasmtime GitHub notifications bot (Jan 03 2021 at 15:28):

tomaka commented on Issue #2537:

This is for https://github.com/tomaka/redshirt, right?

Indeed! My current plan to fork everything and add (back) no-std compatibility. I'm upstreaming a few changes which I think are uncontroversial.

Since redshirt isn't my actual job and the holiday season coming to an end, the chances of actually implementing no-std compatibility any time soon are pretty low, but I wanted to get something going.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 03 2021 at 15:28):

tomaka edited a comment on Issue #2537:

This is for https://github.com/tomaka/redshirt, right?

Indeed! My current plan to fork everything and add (back) no-std compatibility in hacky ways. I'm upstreaming a few changes which I think are uncontroversial.

Since redshirt isn't my actual job and the holiday season coming to an end, the chances of actually implementing no-std compatibility any time soon are pretty low, but I wanted to get something going.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 03 2021 at 15:29):

tomaka edited a comment on Issue #2537:

This is for https://github.com/tomaka/redshirt, right?

Indeed! My current plan to fork everything and add (back) no-std compatibility potentially in hacky ways (e.g. the thiserror dependency is fundamentally incompatible with no-std, so I'm changing it). I'm upstreaming a few changes which I think are uncontroversial.

Since redshirt isn't my actual job and the holiday season coming to an end, the chances of actually implementing no-std compatibility any time soon are pretty low, but I wanted to get something going.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 03 2021 at 15:29):

tomaka edited a comment on Issue #2537:

This is for https://github.com/tomaka/redshirt, right?

Indeed! My current plan to fork everything and add (back) no-std compatibility potentially in hacky ways (e.g. the thiserror dependency is fundamentally incompatible with no-std, so I'm changing it). I'm upstreaming a few changes which I think are uncontroversial.

Since redshirt isn't my actual job and the holiday season is coming to an end, the chances of actually implementing no-std compatibility any time soon are pretty low, but I wanted to get something going.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 04 2021 at 15:56):

alexcrichton commented on Issue #2537:

We have a somewhat lengthy documentation section about why #![no_std] isn't currently used, would you be able to comment as to how your use case fits into that?

view this post on Zulip Wasmtime GitHub notifications bot (Jan 04 2021 at 16:26):

tomaka commented on Issue #2537:

The patch to switch to #![no_std] is small, why not accept it?

Ah sorry, I've seen this but a long time ago, and forgot the existence of this section.

I'm building (on my free time) an operating system that executes Wasm programs on bare metal, directly in ring 0.

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.

I can somewhat easily implement mmap (assuming MAP_ANONYMOUS) and threads on bare metal, but implementing a shim of libc or standard library full of unimplemented!() expressions just for wasmtime to work seems kind of "wrong", and way more efforts than forking wasmtime and replacing the platform-specific code with my own.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 04 2021 at 16:27):

tomaka edited a comment on Issue #2537:

The patch to switch to #![no_std] is small, why not accept it?

Ah sorry, I've seen this but a long time ago, and forgot the existence of this section.

I'm building (on my free time) an operating system that executes Wasm programs on bare metal, directly in ring 0.
It's already functional, but terribly slow as it's using wasmi the interpreter.

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.

I can somewhat easily implement mmap (assuming MAP_ANONYMOUS) and threads on bare metal, but implementing a shim of libc or standard library full of unimplemented!() expressions just for wasmtime to work seems kind of "wrong", and way more efforts than forking wasmtime and replacing the platform-specific code with my own.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 04 2021 at 16:38):

alexcrichton commented on Issue #2537:

I would personally recommend for your use case that using std is the way to go. The standard library already has targets like wasm itself which return errors for any unsupported operations (like std::thread), and if you're using std then this and other crates (like wasmparser) would just work.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 04 2021 at 16:47):

bjorn3 commented on Issue #2537:

I would personally recommend for your use case that using std is the way to go.

That would require forking the standard library.

The standard library already has targets like wasm itself which return errors for any unsupported operations (like std::thread), and if you're using std then this and other crates (like wasmparser) would just work.

Honestly that just feels like a hack. It shouldn't be possible to call functions when the kind of action (threads, filesystem, processes) doesn't exist at all on the target. The benefit of the current core, alloc, std split is that you can somewhat guarantee that code only depends on things that they should depend on. If the target doesn't support env vars and cranelift depends on libstd it is very easy to introduce a use of an env var to for example enable debug output. This would then break running cranelift on that target. By having cranelift depend only on core and alloc, this isn't possible.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 04 2021 at 16:48):

tomaka commented on Issue #2537:

If the objective is for the std to compile for every single platform, how would wasmtime know that a certain feature is unimplemented! or not?

If I'm using wasmtime 0.68, how can I know that wasmtime 0.69 or one of its dependencies doesn't sometimes call std::fs::File::open, which is unimplemented! and unimplementable?

When it comes to wasm32-unknown-unknown, which is the one platform right now whose std has unimplemented!() portions, the outcome is that half of the Rust ecosystem uses #[cfg(not(target_os = "unknown")]] and uses Cargo features like wasm-bindgen or stdweb to know what to replace the std with.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 04 2021 at 16:49):

tomaka edited a comment on Issue #2537:

If the objective is for the std to compile for every single platform, how would wasmtime know that a certain feature is unimplemented! or not?

If I'm using wasmtime 0.68, how can I know that wasmtime 0.69 or one of its dependencies doesn't sometimes call std::fs::File::open, which is unimplemented! and unimplementable?

When it comes to wasm32-unknown-unknown, which is the one platform right now whose std has unimplemented!() portions, the outcome is that half of the Rust ecosystem uses #[cfg(not(target_os = "unknown")]] and uses Cargo features like wasm-bindgen or stdweb to know what to replace the std with. Instead of standardizing a list of features available to all crates, putting unimplemented!() causes an "un-standardization", as people replace the std with an alternative.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 04 2021 at 16:49):

tomaka edited a comment on Issue #2537:

If the objective is for the std to compile for every single platform, how would wasmtime know that a certain feature is unimplemented! or not?

If I'm using wasmtime 0.68, how can I know that wasmtime 0.69 or one of its dependencies doesn't sometimes call std::fs::File::open, which is unimplemented! and unimplementable?

When it comes to wasm32-unknown-unknown, which is the one platform right now whose std has unimplemented!() portions, the outcome is that half of the Rust ecosystem uses #[cfg(not(target_os = "unknown")]] and uses Cargo features like wasm-bindgen or stdweb to know what to replace the std with. Instead of standardizing a list of features available to all crates, putting unimplemented!() caused an "un-standardization", as people replace the std with an alternative.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 04 2021 at 16:49):

tomaka edited a comment on Issue #2537:

If the objective is for the std to compile for every single platform, how would wasmtime know that a certain feature is unimplemented! or not?

If I'm using wasmtime 0.68, how can I know that wasmtime 0.69 or one of its dependencies doesn't sometimes call std::fs::File::open, which is unimplemented! and unimplementable?

When it comes to wasm32-unknown-unknown, which is the one widely-used platform right now whose std has unimplemented!() portions, the outcome is that half of the Rust ecosystem uses #[cfg(not(target_os = "unknown")]] and uses Cargo features like wasm-bindgen or stdweb to know what to replace the std with. Instead of standardizing a list of features available to all crates, putting unimplemented!() caused an "un-standardization", as people replace the std with an alternative.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 04 2021 at 17:09):

alexcrichton commented on Issue #2537:

Call it a hack, call it a fork, the reality is that either libstd compiles for your platform or you force literally all users of your platform to not use std. Not using std has quite a large cost because there's lots of crates that would otherwise work (like this and wasmparser). Additionally not using std is not very idiomatic, weird workarounds, imports, etc, are required to get things compiling. Nothing is guaranteed to work anyway unless you're running on the platforms itself. I do not believe there is an objectively correct answer as to whether you should be able to call a function that always returns an error. @bjorn3 you think you shouldn't be able to do that, I disagree.

I don't know why std wouldn't have the objective of compiling for all platforms. How does wasmtime today know if a feature is unimplemented or not? Someone runs the code and sends a PR to handle their platform if it dooesn't work. You have no guarantee future versions will continue to work, but you never have a guarantee about that unless your target is added to Wasmtime's CI. In no way does using no_std here provide you with any degree of guarantee that things will always work into the future.

Overall I feel there's an imbalance here when a hobbyist's personal project impacts the idioms in a project like Wasmtime. Are all Rust ecosystem crates expected to cater to all hobbyist's whims?

view this post on Zulip Wasmtime GitHub notifications bot (Jan 04 2021 at 17:17):

bjorn3 commented on Issue #2537:

Overall I feel there's an imbalance here when a hobbyist's personal project impacts the idioms in a project like Wasmtime.

Wasmtime interacts a lot with the outside world due to memory mapping, filesystem accesses and terminal accesses. Cranelift on the other hand doesn't interact with the outside world. It only requires a memory allocator because using a large fixed size chunk of memory is inefficient and would complicate code. The Cranelift embedded may or may not interact with the outside world, but Cranelift itself is a observably equivalent to a function from clif ir to bytes. (ignoring OOM's)

view this post on Zulip Wasmtime GitHub notifications bot (Jan 04 2021 at 17:19):

tomaka commented on Issue #2537:

Overall I feel there's an imbalance here when a hobbyist's personal project impacts the idioms in a project like Wasmtime. Are all Rust ecosystem crates expected to cater to all hobbyist's whims?

I mentioned "so feel free to close this PR if it is inappropriate.". I legitimately didn't remember that there was a guideline against small no-std-compatibility PRs.

all it a hack, call it a fork, the reality is that either libstd compiles for your platform or you force literally all users of your platform to not use std. Not using std has quite a large cost because there's lots of crates that would otherwise work (like this and wasmparser). Additionally not using std is not very idiomatic, weird workarounds, imports, etc, are required to get things compiling.

I'm of the complete opposite view.

I have personally been some traumatised trying to make a big project work for wasm32-unknown-unknown that I've restarted the codebase from scratch with a strict no_std requirement, because in practice it's what works. Going through the hundreds of direct and indirect dependencies figuring out how they use their wasm-bindgen features and fixing issues because they use features that aren't implemented drove me insane. I have absolutely no intention of doing the same thing for wasmtime.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 04 2021 at 17:19):

tomaka edited a comment on Issue #2537:

Overall I feel there's an imbalance here when a hobbyist's personal project impacts the idioms in a project like Wasmtime. Are all Rust ecosystem crates expected to cater to all hobbyist's whims?

I mentioned "so feel free to close this PR if it is inappropriate.". I legitimately didn't remember that there was a guideline against small no-std-compatibility PRs.

all it a hack, call it a fork, the reality is that either libstd compiles for your platform or you force literally all users of your platform to not use std. Not using std has quite a large cost because there's lots of crates that would otherwise work (like this and wasmparser). Additionally not using std is not very idiomatic, weird workarounds, imports, etc, are required to get things compiling.

I'm of the complete opposite view.

I have personally been somewhat traumatised trying to make a big project work for wasm32-unknown-unknown that I've restarted the codebase from scratch with a strict no_std requirement, because in practice it's what works. Going through the hundreds of direct and indirect dependencies figuring out how they use their wasm-bindgen features and fixing issues because they use features that aren't implemented drove me insane. I have absolutely no intention of doing the same thing for wasmtime.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 04 2021 at 17:20):

tomaka edited a comment on Issue #2537:

Overall I feel there's an imbalance here when a hobbyist's personal project impacts the idioms in a project like Wasmtime. Are all Rust ecosystem crates expected to cater to all hobbyist's whims?

I mentioned "so feel free to close this PR if it is inappropriate.". I legitimately didn't remember that there was a guideline against small no-std-compatibility PRs.

all it a hack, call it a fork, the reality is that either libstd compiles for your platform or you force literally all users of your platform to not use std. Not using std has quite a large cost because there's lots of crates that would otherwise work (like this and wasmparser). Additionally not using std is not very idiomatic, weird workarounds, imports, etc, are required to get things compiling.

I'm of the complete opposite view.

I have personally been somewhat traumatised trying to make a big project work for wasm32-unknown-unknown that I've restarted the codebase from scratch with a strict no_std requirement, because in practice, I cannot stress it enough, it's what works. Going through the hundreds of direct and indirect dependencies figuring out how they use their wasm-bindgen features and fixing issues because they use features that aren't implemented drove me insane. I have absolutely no intention of doing the same thing for wasmtime.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 04 2021 at 17:20):

tomaka edited a comment on Issue #2537:

Overall I feel there's an imbalance here when a hobbyist's personal project impacts the idioms in a project like Wasmtime. Are all Rust ecosystem crates expected to cater to all hobbyist's whims?

I mentioned "so feel free to close this PR if it is inappropriate.". I legitimately didn't remember that there was a guideline against small no-std-compatibility PRs.

all it a hack, call it a fork, the reality is that either libstd compiles for your platform or you force literally all users of your platform to not use std. Not using std has quite a large cost because there's lots of crates that would otherwise work (like this and wasmparser). Additionally not using std is not very idiomatic, weird workarounds, imports, etc, are required to get things compiling.

I'm of the complete opposite view.

I have personally been somewhat traumatised trying to make a big project work for wasm32-unknown-unknown that I've restarted the codebase from scratch with a strict no_std requirement, because in practice, I cannot stress this enough, it's what works. Going through the hundreds of direct and indirect dependencies figuring out how they use their wasm-bindgen features and fixing issues because they use features that aren't implemented drove me insane. I have absolutely no intention of doing the same thing for wasmtime.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 04 2021 at 17:23):

tomaka commented on Issue #2537:

To repeat my opinion, as someone who now has a lot of experience in no_std compatibility, forking wasmtime to make it no-std-compatible seems tremendously easier and more sane than writing a custom std implementation full of shim functions.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 04 2021 at 17:24):

tomaka edited a comment on Issue #2537:

To repeat my opinion, as someone who now has a lot of experience in no_std compatibility, forking wasmtime to make it no-std-compatible (and, I guess, without upstreaming patches) seems tremendously easier and more sane than writing a custom std implementation full of shim functions.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 04 2021 at 17:46):

alexcrichton commented on Issue #2537:

To be clear, I'm speaking my personal opinions here, I don't represent all contributors to this project. I would recommend you prototype the std-based solution to get an idea for how hard it might be, there's been upstream work to make new targets very easy to add to std. There's also nothing set in stone for how hobbyist targets are handled in libstd, I'm happy to have a conversation about how to best support that if you'd like, but if you'd rather not have such a conversation that's ok too.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 04 2021 at 17:54):

cfallin commented on Issue #2537:

Speaking only about Cranelift, the effort to make the core compiler crates no_std (and keep them that way) does not seem too bad -- swap/add some use statements and maybe add a CI job to grep for std:: in certain directories -- and I'd be happy to review such a thing if others in the project were onboard. (This would need changes in the regalloc crate as well.) I can certainly see the value in having a nice, portable, minimal-dependencies JIT compiler library (as @bjorn3 says, in theory a compiler should need nothing other than memory allocation). I'd defer to others on the rest of Wasmtime; the runtime portability issue seems like a much more difficult question.


Last updated: Dec 23 2024 at 12:05 UTC