-
Notifications
You must be signed in to change notification settings - Fork 24
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
Using wasmer with context #4
Comments
So my current solution is the code below. Is this the best option right now? extern crate wasmer_runtime;
use std::str;
use std::ffi::c_void;
use wasmer_runtime::{
imports,
instantiate,
error,
Ctx,
};
// Make sure that the compiled wasm-sample-app is accessible at this path.
static WASM: &'static [u8] = include_bytes!("../wasm-sample-app/target/wasm32-unknown-unknown/release/wasm_sample_app.wasm");
fn main() -> error::Result<()> {
// Let's define the import object used to import our function
// into our webassembly sample application.
//
// We've defined a macro that makes it super easy.
//
// The signature tells the runtime what the signature (the parameter
// and return types) of the function we're defining here is.
// The allowed types are `i32`, `u32`, `i64`, `u64`,
// `f32`, and `f64`.
//
// Make sure to check this carefully!
let import_object = imports! {
// Define the "env" namespace that was implicitly used
// by our sample application.
"env" => {
// name // func // signature
"print_str" => print_str<[u32, u32] -> []>,
},
};
let mut boo = Boo { a: 42 };
// Compile our webassembly into an `Instance`.
let mut instance = instantiate(WASM, import_object)?;
instance.context_mut().data = &mut boo as *mut _ as *mut c_void;
// Call our exported function!
instance.call("hello_wasm", &[])?;
Ok(())
}
struct Boo {
a: u32
}
// Let's define our "print_str" function.
//
// The declaration must start with "extern" or "extern "C"".
extern fn print_str(ptr: u32, len: u32, ctx: &mut Ctx) {
// Get a slice that maps to the memory currently used by the webassembly
// instance.
//
// Webassembly only supports a single memory for now,
// but in the near future, it'll support multiple.
//
// Therefore, we don't assume you always just want to access first
// memory and force you to specify the first memory.
let memory = ctx.memory(0);
let boo: &mut Boo = unsafe { &mut *(ctx.data as *mut Boo) };
// Get a subslice that corresponds to the memory used by the string.
let str_slice = &memory[ptr as usize..(ptr + len) as usize];
// Convert the subslice to a `&str`.
let string = str::from_utf8(str_slice).unwrap();
// Print it!
println!("{} and a is {}", string, boo.a);
} |
Unfortunately, yes, that's the best way to go about this problem right now. We may be able to support importing rust closures into a wasm module in the future by use of our new let import_object = imports! {
"env" => {
"print_str" => func!(|ptr: u32, len: u32, ctx| boo.print_str(ptr, len, ctx)),
// or
"print_str" => Func::new(|ptr: u32, len: u32, ctx| boo.print_str(ptr, len, ctx)),
},
}; but this doesn't work currently. Speaking-of, in the new version of wasmer-runtime that we're about to release, the syntax used by the fn foo_bar(ctx: &mut Ctx) {}
let import_object = imports! {
"env" => {
"foo_bar" => func!(foo_bar),
},
}; |
@lachlansneff do closures work yet? |
cc @MarkMcCaskey As I am unsure if closures work? 🤔 |
@thedavidmeister Yes, we support closures now! I'll add it to my TODO list to update this example today and demonstrate them |
Okay, it should be updated in this repo now! I'll update the docs on our website, too! |
Closures support only Fn and not FnMut? |
Let's say I want to call WASM code using some context. For example, I have a struct Boo and I want to use "self.a" as part of the WASM execution. Is it possible to do?
Here is the modified example:
The text was updated successfully, but these errors were encountered: