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

Example for string/vec u8 transfer #41

Open
DragonicUA opened this issue Apr 20, 2022 · 4 comments
Open

Example for string/vec u8 transfer #41

DragonicUA opened this issue Apr 20, 2022 · 4 comments

Comments

@DragonicUA
Copy link

Is there an example that can show passing a String or a Vec both ways?

@Machine-Jonte
Copy link

Did you figure it out?

@Machine-Jonte
Copy link

From Discord channel:

ElegantBeef:
I've not done this in C or Rust, but the way I do it is call the malloc, then us m3GetMemory and copyMem
https://github.com/beef331/wasm3/blob/master/src/wasm3.nim#L180-L192
In Nim it looks like this
When used it looks like https://github.com/beef331/aiarena/blob/master/src/core/wasmenvs.nim#L48-L53
But that doesnt matter in your case 😄

Machine-Jonte:
I'm taking a look. I think I get the general idea of it! I missed the part that the wasm module can give the environment as an argument. I'm really rookie when it comes to wasm so I'm trying to digest as much info as possible... And now some Nim I guess 😂 Only heard good things about it so 🙂

Wildbook — Today at 3:26 PM
I'll (maybe) save you some time. I haven't used wasm3 for anything in ages so take what I say with a grain of salt, but it might still be useful. There might also have been changes I'm not aware of since then.

The Rust bindings last I looked at the did not have the pointer type (signature *) hooked up as a valid argument type, so you'll most likely want to either modify the library to allow for that by implementing the WasmArgs trait for *const T and *mut T or instead pass the pointer as u64 (which I wouldn't recommend but it'd make your life easier since you wouldn't need to modify the library).

The main reason against implementing WasmArgs for *_ T is that it confuses the concept of WASM pointers with the concept of native pointers, so you might want to instead introduce a new WasmPtr type. Whichever you do you want to give it the signature token *. Past that you'll want to write a utility function that calls Runtime::memory / Runtime::memory_mut with the pointer / WasmPtr as argument and returns a native pointer to the memory it references. How you decide to perform bounds checks and uphold ownership and aliasing rules past that is up to you..

The WasmArgs trait is defined here: https://github.com/wasm3/wasm3-rs/blob/master/src/ty.rs

If I remember correctly it should be reasonably easy to implement it for a new pointer-esque type, but I don't remember the details around how you'd do so and still keep your stack and slots valid. I don't think it'll be hard to, but I'm not going to pretend I know that it's simple.

You can find example function with pointer arguments if you look at the wasm3 built-in uvwasi implementation:

Hence you expose a function that allocates from within to ensure that the allocator on the inside is fully aware of what's going on and fully responsible for managing all the in-WASM memory. Same goes for freeing that memory.

Machine-Jonte — Today at 3:39 PM
Thanks @wildbook . This definitely will save me a lot of time. It is true the pointer type do not impl for WasmArgs/WasmType.

Wildbook — Today at 3:41 PM
Ah right, WasmType is the one defining the signature and so on

Machine-Jonte — Today at 3:42 PM
How far behind is the rust bindings from the latest wasm3? And is the rust bindings still in development? I could see the repo is looking for maintainer

Wildbook — Today at 3:46 PM
Afraid I don't know. I don't think wasm3 changes a lot in general API-wise but I might be wrong on that. The original Rust bindings were written by Veykril around when I was working with wasm3 in Rust and due to unrelated reasons I ended up unable to use WASM in the project I planned to use it in. Since I didn't end up using it I've been out of the loop for the past year or two and all I know is that he's not actively maintaining it anymore, no idea if someone else does.
My general impression is that the Rust bindings aren't really out of date but more just immature / missing features, the core parts seem to be there and work from my (now quite old) experience with it

Machine-Jonte — Today at 3:58 PM
Alright! That's good news. So far the Rust bindings have been ergonomic and nice to use so I'll see if I can manage to expand on them with the ptr type.
Hmm... but I'm not really sure how I access the memory of the module in the host function...? Do I need adding that as a global variable or can I somehow send that as an argument as well? I.e. the wasm mem

Wildbook — Today at 4:02 PM
That's a good point 😅
The function gets a pointer to the runtime (and context) when it's called but judging by the make_func_wrapper macro those are discarded before the wrapped function is called. You'll probably want to modify that to allow passing it on in one way or another, but considering that the Runtime struct expects ownership of the runtime (and destroys it once it's dropped) you can't really just create a temporary Runtime from the pointer alone without modifying that too.
I guess this'd require more changes than I first thought it would.
Alternatively I guess you could just pass the runtime pointer as-is as an argument to the function and call the raw C api to get the memory (basically copy the Runtime type's memory / memory_mut functions), or write your own RuntimeWithinCallback or something (or modify the existing one to not always assume ownership). In general you'd have to either sidestep or significantly extend the bindings from what I can tell. That sucks a bit.

@grantshandy
Copy link

WebAssembly does not have String or Vec types, only number types. If you want to read a datatype like this, you'll have to pass in a pointer and the length of the item then serialize/deserialize it after "sending it across the wire".

@spangaer
Copy link

spangaer commented Sep 3, 2024

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

No branches or pull requests

4 participants