-
-
Notifications
You must be signed in to change notification settings - Fork 20
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
feat(wasm): run a "hello world" wasm under an interpreter #58
Conversation
holy cow |
src/lib.rs
Outdated
@@ -8,6 +8,10 @@ use hal_core::{boot::BootInfo, mem, Architecture}; | |||
|
|||
use alloc::vec::Vec; | |||
|
|||
mod wasm; | |||
|
|||
const HELLOWORLD_WASM: &[u8] = include_bytes!("helloworld.wasm"); |
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.
:D :D :D :D
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.
➕ ➕
mod wasm; | ||
|
||
const HELLOWORLD_WASM: &[u8] = include_bytes!("helloworld.wasm"); | ||
|
||
pub fn kernel_main<A>(bootinfo: &impl BootInfo<Arch = A>) -> ! |
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 clippy lint fires a lot of false positives on tracing macros, we should just turn it off
// FIXME: These should both be `u16`, and probably generated from the wasi | ||
// snapshot_0 `witx` definitions. |
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.
they appear to be u16s?
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.
Oops, yeah. I fixed that. Should probably remove this comment.
"unresolved global import" | ||
); | ||
Err(wasmi::Error::Instantiation( | ||
"unresolved global import".to_owned(), |
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.
there's no way for these error strings to be static strings, is there? I'm assuming the wasmi error type is not ours...
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.
Yup :-/. Every wasmi
error has a string allocation.
if we decide to hard-fork wasmi
and break the API, we could change the error type (and the lib in general) to be much less allocation-happy.
} | ||
|
||
host_funcs! { | ||
fn "wasi_unstable"::"fd_write"(fd: u32, iovs: u32, iovs_len: u32, nwritten: u32) -> u16 |
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.
TIOLI: seems like these could be idents rather than quoted?
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.
shrug probably.
I made them strings because I think theoretically wasm supports spaces in symbols. I'm not sure we'll ever declare a symbol which has spaces in it, though, so it's probably not reasonable.
} | ||
} | ||
|
||
macro_rules! host_funcs { |
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.
am i correct that this macro is generating all the wasi host calls (eventually)? it would be nice to have a little more documentation of all the stuff this generates & how it should be invoked (eventually)
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.
Yeah. I threw together this macro because I needed to write a boatload of boilerplate to declare even a single host method, and didn't want to have to do it again.
We might actually want to use witx
files and auto-generate the binding logic (similar to how wasmtime
does since bytecodealliance/wasmtime#707), but this was much easier to get started with.
|
||
macro_rules! host_funcs { | ||
($( | ||
fn $module:literal :: $name:literal ($($p:ident : $t:ident),*) $( -> $rt:ident)? |
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.
whoa, TIL that literal
is an acceptable thing to match against in a macro!
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.
Yeah, it's super handy, especially because it has an open FOLLOW set, so you don't need to be as careful with what you put after it!
Been around since ~2016 sometime, but was stabilized in rust-lang/rust#56072.
index: usize, | ||
args: wasmi::RuntimeArgs, | ||
) -> Result<Option<wasmi::RuntimeValue>, wasmi::Trap> { | ||
let span = tracing::trace_span!("invoke_index", index, ?args); |
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.
TIOLI: seems like we could just slap a #[tracing::instrument]
on the generated function?
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 is the method which I was poking you on Discord about yesterday which breaks when annotated with #[tracing::instrument]
due to rust messing up spans.
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.
ah gotcha. it would be nice to have a tracing issue for that (even though it's a compiler error), just so we can reference the related issue against the compiler?
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.
i'm not very familiar with the wasm stuff, but this seems good to me! @iximeow, do you want to take a look before merging?
;; | ||
;; wat2wasm helloworld.wast | ||
|
||
(module |
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.
could we wat2wasm when building the kernel? it seems super easy to accidentally end up with a binary wasm dep in the kernel that doesn't match some associated source
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.
That'd be pretty solid. We could also use a pure-rust wat2wasm converter (there are a few iirc) and just run it in our build script.
I just did it this way because it was the easiest, but not checking in binaries is probably a good plan.
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 is super awesome!
just the one comment about having a .wasm - i'm not sure if we even plan on later wasm blobs being built directly into the kernel. if wasms in-repo are temporary just for hello world reasons, that's fine by me!
This uses a fork of the
wasmi
crate as the interpreter: https://github.com/mystor/wasmi/tree/mycelium.This fork has been modified to run under our custom target, removing implicit
std
dependencies, and working around some missing soft-float intrinsics.