I'm trying to determine if it's possible to pass a js callback / closure / function into rust. For some quick context I'm working on a toy interpreted language and I'm trying to provide "stdout" to it in a wasm build. A relatively simplified version of what I'm exporting with #[wasm_bindgen]
use laythem_vm::vm::Vm;
use was_bindgen::JsValue;
#[wasm_bindgen]
pub struct VmWasm(Vm);
impl VmWasm {
pub fn new() -> Self {
// build a vm and with hard code console.log as my "stdout"
}
// I'd like to add something here where I can specify an alternative
// stdout with the idea being to provide a hook into potentially an emulated terminal
pub fn with_stdout(js: &JsValue) {
// not sure if I pass in a value like this and then how I could call it?
}
// run some Laythe code
pub fn run(src: &str) {}
}
I'm currently wrapping both log_1
and error_1
in web_sys::console
and implementing the Write
trait as my stdout interface. All I really need is to someway call a function passed from the js world with a single string parameter. Over in js world this would be roughly what I'd like to do.
import { VmWasm } from 'laythe';
const output = document.getElementById('someId');
const stdout = (string) => output.textContent = string;
const vm = VmWasm.with_stdout(stdout);
vm.run(`print "hello world"`);
// someId now how text "hello world"
For now speed is not particularly about performance a concern as this is mostly a POC.
Unrelated to this post I have to say it's pretty incredible how easy it was to even get this far. I had decided early on to try to pass in my vm's io but still it only took me half a day to get it compiling and partially working. to the dev working on rust's wasm story.