Wasm: pass js callback into rust

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;

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. :clap: to the dev working on rust's wasm story.

Have a look at js_sys::Function.

  pub fn with_stdout(f: &Function) {
      f.call1(&JsValue::NULL, &JsValue::from_str("Hello world!"));
1 Like

:+1: for some reason I had convinced myself you could only pass JsValues over the interface. Glad this was even easier than I thought.

The traits behind this magic are documented here: wasm_bindgen::convert.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.