Stream: cranelift

Topic: Use in no_std


view this post on Zulip Robin Lindner (Mar 28 2023 at 07:33):

Hey I am developing a little operating system. Is there some usage of cranelift/JIT in no_std and in kernel mode possible?

view this post on Zulip Till Schneidereit (Mar 28 2023 at 15:05):

hey Robin! As a policy, we don't support no_std in either Cranelift or Wasmtime: https://docs.wasmtime.dev/stability-platform-support.html?highlight=no_std#what-about-no_std You'll have to support enough of an environment for std to work, at least for the time being

view this post on Zulip fitzgen (he/him) (Mar 28 2023 at 15:06):

I'm not sure if cranelift works in no-std these days, it did at one point in time, but it is a pretty large burden on developers for miniscule gain

fwiw, you will probably get further implementing std for your OS, stubbing things out with panics as necessary, than by trying to make everything in your dep tree no-std

for context, this wasmtime doc describes some of the issues with no-std and burden on the developers: https://docs.wasmtime.dev/stability-platform-support.html#what-about-no_std

view this post on Zulip bjorn3 (Mar 28 2023 at 17:39):

Give that cranelift_codegen still uses #![no_std], rust-analyzer actually prefers auto importing from core and alloc instead of std. Other than using the std re-exports in many places, and hashmaps (for which we should probably use the no_std compatible FxHashMap type alias anyway), cranelift-codegen only uses libstd in a handful of places. As such I don't think there is any burden in supporting no_std for cranelift-codegen apart from a single refactor to stop using the std re-exports. For wasmtime and cranelift-module (and dependent crates) I do agree that it is a burden.

view this post on Zulip Jonas Kruckenberg (Jan 10 2025 at 12:52):

Heya (gonna revive this channel a bit hehe) I've been updating my cranelift fork today and thought I'd give the old upstreaming attempt another go if y'all are interested. This time around (I have a lot of practice in porting cranlift nowadays lol) I've broken up the no_std support into a bunch of smaller and hopefully easier to review PRs (9977, 9976, and 9975)

view this post on Zulip Jonas Kruckenberg (Jan 10 2025 at 12:53):

(that I've been spamming y'all with sorry for that)

view this post on Zulip Jonas Kruckenberg (Jan 10 2025 at 12:54):

the big blocker is still std::sync::OnceLock though :/

view this post on Zulip Alex Crichton (Jan 10 2025 at 15:29):

I might have already mentioned this but one tactic I did for wasmtime was to add a no_std version which basically panics on contention. So still safe in no_std and functional but non-functional in multi-threaded cases, which at leat for wasmtime's purposes is fine in that no_std typically doesn't have threads

view this post on Zulip Alex Crichton (Jan 10 2025 at 15:29):

(and thanks for this PRs!)

view this post on Zulip Jonas Kruckenberg (Jan 11 2025 at 07:50):

yeah that’s a fine approach for embedded sadly it doesn’t help my case where I plan on supporting multiple cores

view this post on Zulip Jonas Kruckenberg (Jan 11 2025 at 07:50):

but it might be a first step before removing the need for those oncelocks all together as someone mentioned in that pr way back

view this post on Zulip Chris Fallin (Jan 11 2025 at 08:38):

if you're putting in efforts to port and want to "do it right" slightly more, pushing on removing OnceLocks might be reasonable: they are only used to lazily initialize register configurations in ABI code; the configurations are nominally static, and are only created dynamically because they include Vecs; &'static slices (and hence letting the register environments be fully static data) would be reasonable alternatives I think. This does imply a change to regalloc2's MachineEnv type but that should be trivial I think

view this post on Zulip Jonas Kruckenberg (Jan 11 2025 at 21:40):

yeah going to try to do that next week actually, right now my cranelift fork uses spin but that has always really bothered me since i do have my own sync library

view this post on Zulip Jonas Kruckenberg (Jan 11 2025 at 21:41):

and having two of them just doesn’t feel right

view this post on Zulip bjorn3 (Jan 12 2025 at 07:24):

Maybe you can use the once-cell crate? With the critical-section feature enabled it allows you to provide your own synchronization primitive.

view this post on Zulip Jonas Kruckenberg (Jan 13 2025 at 06:49):

Chris Fallin said:

if you're putting in efforts to port and want to "do it right" slightly more, pushing on removing OnceLocks might be reasonable: they are only used to lazily initialize register configurations in ABI code; the configurations are nominally static, and are only created dynamically because they include Vecs; &'static slices (and hence letting the register environments be fully static data) would be reasonable alternatives I think. This does imply a change to regalloc2's MachineEnv type but that should be trivial I think

making MachineEnv take static slices and the necessary work on regalloc2s side indeed was quite easy, but I'm not quite sure what to do on the cranelift side

view this post on Zulip Jonas Kruckenberg (Jan 13 2025 at 06:51):

putting the whole MachineEnv into a static doesn't really work bc of the way they are constructed, and replacing all the non-const functions with const ones would mean readability = 0

view this post on Zulip Jonas Kruckenberg (Jan 13 2025 at 06:51):

on the other hand MachineEnv is 120 bytes in size, idk if cloning that around is the best idea either

view this post on Zulip Jonas Kruckenberg (Jan 13 2025 at 06:52):

Jonas Kruckenberg said:

putting the whole MachineEnv into a static doesn't really work bc of the way they are constructed, and replacing all the non-const functions with const ones would mean readability = 0

well plus it the construction kind of depends on runtime configuration

view this post on Zulip Chris Fallin (Jan 13 2025 at 07:29):

putting the whole MachineEnv into a static doesn't really work bc of the way they are constructed, and replacing all the non-const functions with const ones would mean readability = 0

Well, yes, but there are a small number of configs (two!) so we can create both statically and return the right one -- e.g. here for x64, here for aarch64, here for s390x. And riscv64 has only one. This should be very readable IMHO: if flag { &PINNED_REG_ENV } else { &DEFAULT_REG_ENV } or thereabouts.

A lightweight WebAssembly runtime that is fast, secure, and standards-compliant - bytecodealliance/wasmtime
A lightweight WebAssembly runtime that is fast, secure, and standards-compliant - bytecodealliance/wasmtime
A lightweight WebAssembly runtime that is fast, secure, and standards-compliant - bytecodealliance/wasmtime
A lightweight WebAssembly runtime that is fast, secure, and standards-compliant - bytecodealliance/wasmtime

view this post on Zulip Jonas Kruckenberg (Jan 13 2025 at 07:30):

aye alright yeah so the job is to make the machineenvs const constructible in a nice way

view this post on Zulip Jonas Kruckenberg (Jan 13 2025 at 07:30):

i can work with that

view this post on Zulip Chris Fallin (Jan 13 2025 at 07:33):

yeah, and in particular there's really just one level of helper (create_reg_env or equiv) and then some register newtype converters that should either already be const or can be trivially made so (hopefully!). You'd turn the helper's body into a static struct initializer more or less

view this post on Zulip Jonas Kruckenberg (Jan 13 2025 at 08:36):

yeah that's the plan!


Last updated: Jan 24 2025 at 00:11 UTC