Reuse JavaScript stubs with wasm_of_ocaml

I would use JavaScript stubs with wasm_of_ocaml. Let’s consider the following OCaml file bar.ml:

external foo : unit -> int = "caml_foo"

let () = 
  Format.printf "%d@." (foo ())

and the JavaScript stub runtime.js:

//Provides: caml_foo
function caml_foo() {
  return 42;
}

I produce a script as follows:

ocamlc -no-check-prims -noautolink bar.ml -o bar.bc-for-jsoo
js_of_ocaml -o bar.bc.js runtime.js bar.bc-for-jsoo

and node ./bar.bc.js works as expected.

Now, I want a wasm executable. I can proceed as follows: I wrote another stub in wat runtime.wat:

(module
  (func (export "caml_foo") (param (ref eq)) (result (ref eq))
    (ref.i31 (i32.const 42))))

and I produce the wasm binary as follows:

ocamlc -no-check-prims -noautolink bar.ml -o bar.bc-for-jsoo
wasm_of_ocaml -o bar.bc.wasm.js runtime.wat bar.bc-for-jsoo

and node ./bar.bc.wasm.js works.

Now, I want to reuse my JavaScript stubs instead of rewriting them in wat. I tried

wasm_of_ocaml -o bar.bc.wasm.js runtime.js bar.bc-for-jsoo

but the primitive caml_foo is not available in the wasm linker. I believe that I have to write a small runtime.wat file to declare and export the JavaScript function but I don’t know wasm at all.

Any idea?

The doc says in Writing Wasm primitives

To use JavaScript functions in your Wasm primitives, import them using the js namespace:

(import "js" "add" (func $add (param f64) (param f64) (result f64)))

You should be able to use

(import "js" "caml_foo" (func $caml_foo (param ..) (result ..)))