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

Hello world sample #1

Open
autodidaddict opened this issue Jan 23, 2020 · 13 comments
Open

Hello world sample #1

autodidaddict opened this issue Jan 23, 2020 · 13 comments

Comments

@autodidaddict
Copy link

I'm struggling to find the right functions to call to make this work. I'd love to see a sample that utilizes the Rust bindings that:

  • supports namespaced imports (call a namespace-prefixed host function from inside wasm)
  • supports exports (call a wasm function from the host)
  • supports WASI (e.g. see a println!() work while under host interpretation.

If there are some docs or some other source of information you can point me at, I can take a stab at this.

@Veykril
Copy link
Collaborator

Veykril commented Jan 23, 2020

I have only started writing this wrapper very recently(2 days ago to be precise), so I have to look more into the implementation source before I'll be able to create something usable.
I'll try to get some examples working soon though 😄

@autodidaddict
Copy link
Author

I hope I didn't come across like I expected this stuff to be there after just a few days. I'd like to help with this if possible, though my FFI skills aren't as good as they could be.

@Veykril
Copy link
Collaborator

Veykril commented Jan 25, 2020

No worries, it didn't sound like that at all. Since there isn't really much to work with in the crate, helping seems rather difficult. But I'd be happy to take some helping hands once there is a rough structure.

@matiasinsaurralde
Copy link

matiasinsaurralde commented Jan 25, 2020

Very interesting, feel free to inspect my Go implementation in case it's useful, I have a few samples too (two of them use WASI):
https://github.com/matiasinsaurralde/go-wasm3

Best.

@Veykril
Copy link
Collaborator

Veykril commented Jan 25, 2020

Got far enough implementation-wise that it is now possible to call exported functions(though I have not tested it too much yet). Added a very small example to show how it works currently.

@autodidaddict
Copy link
Author

Took a look at the same and it definitely looks like bi-directional calls are working. It looks like there is no return value from a host function, and that the return value is the last parameter in the function list (e.g. the seconds to millis demo). So if I had a function that took 3 input parameters and had one return value, the signature for that host func (linked) would look like this:

unsafe extern "C" fn millis(
    _rt: ffi::IM3Runtime,
    p1: u64,
    p2: u64,
    p3: u64
    retval: *mut u64,
    _mem: *mut std::ffi::c_void,
) -> *const std::ffi::c_void {
    // do unsafe things...
    ffi::m3Err_none as _
}

?

@autodidaddict
Copy link
Author

My real goal is to be able to add a config feature flag to the wapc crate so that I can choose whether I want to compile that library using wasmtime (running on servers/server OSes) or wasm3 (running on limited/embedded devices)

@Veykril
Copy link
Collaborator

Veykril commented Jan 27, 2020

No, the signature of the extern function is always the same, you would have to retrieve the arguments from the stackpointer, which is the second argument to that function.

So something like this:

unsafe extern "C" fn millis(
    _rt: ffi::IM3Runtime,
    sp: *mut u64,
    _mem: *mut std::ffi::c_void,
) -> *const std::ffi::c_void {
    let p1 = *sp;
    let p2 = *sp.add(1);
    let p3 = *sp.add(2);
    *sp = MILLIS; // this is the return value, aka the first value on the stack will be it
    ffi::m3Err_none as _ // this is the result return, whether the call was successful(m3Err_none) or not(like returning a trap for example)
}

I am thinking about how to make this nicer to use so that the consumer doesn't have to dip into this extern mess themselves, but that most likely will involve some use of macros and im not sure about how I want to do this.

@Veykril
Copy link
Collaborator

Veykril commented Jan 27, 2020

I just added a small basic macro to aid in creating an extern wrapper function around a rust function that should help to avoid having to write this stuff manually. Should work in most cases I hope, haven't tested it too much yet. https://github.com/Veykril/wasm3-rs/blob/7915db91c4a7461cf827195e89124b9d91319727/examples/wasm_link.rs#L24-L27

You basically call the macro with the wrapper_function name followed by the to be wrapped functions signature. So if you have a function with the signature fn foo(bar: u64, baz: u32) -> f32 you'd call the macro with wasm3::make_func_wrapper!(foo_wrap: foo(bar: u64, baz: u32) -> f32);

@vshymanskyy
Copy link
Member

@Veykril what's the easiest way to run the examples?
I was able to:

python wasm_bin_builder.py ./examples/wasm/wasm_add
rustc examples/call_wasm.rs -L ./target/release/deps

But, it requires extern crate wasm3; on top of call_wasm.rs.
For wasm_print I also need to specify --cfg 'feature="wasi"' explicitly.

@Veykril
Copy link
Collaborator

Veykril commented Jun 6, 2021

@vshymanskyy You can simply run an example by invoking cargo run --example call_wasm, and cargo run --example wasm_print --features=wasi for the wasm_print example.

Cashmaney pushed a commit to scrtlabs/wasm3-rs that referenced this issue Jun 21, 2022
@imotai
Copy link

imotai commented Aug 23, 2022

@vshymanskyy You can simply run an example by invoking cargo run --example call_wasm, and cargo run --example wasm_print --features=wasi for the wasm_print example.

I have some errors when running example

$ python3 wasm_bin_builder.py examples/wasm/wasm_add
    Finished release [optimized] target(s) in 0.01s
$ RUST_BACKTRACE=1 cargo run --example call_wasm
   error: failed to run custom build command for `wasm3-sys v0.1.2 (/media/psf/Home/opensource/wasm3-rs/wasm3-sys)`

Caused by:
  process didn't exit successfully: `/media/psf/Home/opensource/wasm3-rs/target/debug/build/wasm3-sys-f63c8693949f9c0d/build-script-build` (exit status: 101)
  --- stderr
  thread 'main' panicked at 'Unable to generate bindings: Os { code: 2, kind: NotFound, message: "No such file or directory" }', wasm3-sys/build.rs:78:35
  stack backtrace:
     0: rust_begin_unwind
               at /rustc/f22819bcce4abaff7d1246a56eec493418f9f4ee/library/std/src/panicking.rs:584:5
     1: core::panicking::panic_fmt
               at /rustc/f22819bcce4abaff7d1246a56eec493418f9f4ee/library/core/src/panicking.rs:142:14
     2: core::result::unwrap_failed
               at /rustc/f22819bcce4abaff7d1246a56eec493418f9f4ee/library/core/src/result.rs:1814:5
     3: core::result::Result<T,E>::expect
               at /rustc/f22819bcce4abaff7d1246a56eec493418f9f4ee/library/core/src/result.rs:1064:23
     4: build_script_build::gen_bindings
               at ./build.rs:78:18
     5: build_script_build::main
               at ./build.rs:127:5
     6: core::ops::function::FnOnce::call_once
               at /rustc/f22819bcce4abaff7d1246a56eec493418f9f4ee/library/core/src/ops/function.rs:248:5
  note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

@Veykril
Copy link
Collaborator

Veykril commented Aug 23, 2022

Make sure you have initialized the submodule

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

5 participants