Skip to content
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

Merged
merged 4 commits into from
Jan 12, 2020
Merged

Conversation

mystor
Copy link
Collaborator

@mystor mystor commented Jan 3, 2020

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.

@mystor mystor requested a review from hawkw January 3, 2020 01:51
@hawkw
Copy link
Owner

hawkw commented Jan 3, 2020

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");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:D :D :D :D

Copy link
Collaborator

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>) -> !
Copy link
Owner

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

Comment on lines +3 to +4
// FIXME: These should both be `u16`, and probably generated from the wasi
// snapshot_0 `witx` definitions.
Copy link
Owner

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?

Copy link
Collaborator Author

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(),
Copy link
Owner

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...

Copy link
Collaborator Author

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
Copy link
Owner

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?

Copy link
Collaborator Author

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 {
Copy link
Owner

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)

Copy link
Collaborator Author

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)?
Copy link
Owner

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!

Copy link
Collaborator Author

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);
Copy link
Owner

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?

Copy link
Collaborator Author

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.

Copy link
Owner

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?

@hawkw hawkw requested a review from iximeow January 4, 2020 21:10
Copy link
Owner

@hawkw hawkw left a 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
Copy link
Collaborator

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

Copy link
Collaborator Author

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.

Copy link
Collaborator

@iximeow iximeow left a 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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants