Is it possible today, do you think, to call say a Rust Wasm module from a dotnet (c#) module using witx-bindgen? I know witx-bindgen does not support dotnet, but maybe for a simple "getAnswer(i) => i" type function I could handcraft the binding. Just for fun.
I can create the c# side, changing the c#->llvm->wasm compilation as necessary
witx-bindgen
doesn't have access to anything embedders don't otherwise have access to, so you can always write the bindings code by hand, but it will quickly get painful as more advanced types are used.
@Alex Crichton do we have a witx-bindgen tool that takes a witx module, whether you're importing/exporting it, and then dumps the corresponding canonical ABI? that seems like something you'd really want if attempting to bind to canonical ABI things by hand like this
not currently, no, but it wouldn't be too hard to implement!
yeah, I would find that feature useful too
Thanks, I need to play more to understand what problems I'm going to hit. First though, this is my first day with rust....
use witx_bindgen_rust::export;
#[no_mangle]
pub extern "C" fn doubles(i : i32) -> i32 {
return i * 2;
}
export! (doubles);
Is this close? export! wants a string literal or TokenStream, so I've got that syntax wrong, but is it close?
Edit: sorry, ignore me, found some examples in the repo.
but with witx
doubles: function(i: s32) -> s32
the macro seems to produce an error
witx_bindgen_rust::export!("w1.witx");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `w1::W1` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
I replaced the macro with the code from https://bytecodealliance.github.io/witx-bindgen/ and that worked, so I guess I messed up type/trait/impl names somewere
ah yes as you've found the input to the macro is a *.witx
file path, but the error you got there seems like a bug in witx-bindgen itself, do you know how I can reproduce it?
I dont know if you want to waste time on this, as it was just me trying to get my rust right, but starting with this which works:
witx_bindgen_rust::export!("w1.witx");
struct W1;
impl w1::W1 for W1 {
fn doubles(i : i32) -> i32 {
return i * 2;
}
}
Change it to the bogus
witx_bindgen_rust::export!("w1.witx");
use w1::*;
struct Wasm;
impl w1::W1 for Wasm {
fn doubles(i : i32) -> i32 {
return i * 2;
}
}
and that should do it.
nah no worries, I'll dig in soon to see if I can make that error better
that's a pretty bad error to get when you're just starting ;_;
Scott Waye has marked this topic as resolved.
@Alex Crichton Cool it works. I cheated with this i32->i32 example by skipping the c# side as it would just be a straight passthrough, but the c# wasm calling out to the rust wasm worked. I couldn't get the Chrome Canary debugger to step into the rust source code. It loaded the rust source, but I couldn't set breakpoints nor step into it. The debugger just showed the wasm/wat.
image.png
strings next....
seems like a good start at least though1
I need to jit stuff in a portable way, so I though about using wasm instead of generating x86/arm directly. Is wasmtime good for this use-case? Does wasmtime have stuff to help write wasm on the fly, or is that outside the scope?
wasmtime just runs wasm
you can use wasm-encoder
to write wasm binaries
@Rom Grk if you need a JIT backend, then Cranelift (the default compiler backend used by Wasmtime) could be used directly; there is some infrastructure to support a relatively simple JIT scenario (the cranelift-jit
crate) and e.g. @bjorn3 uses this in the Rust cg_clif backend if I'm not mistaken
Last updated: Dec 23 2024 at 13:07 UTC