Context: writing some serialization / deserialization routines for iframe/iframe communication. I am expecting a MessagePort, but instead got this monster:
(2) [0, 0]
0
:
0
1
:
Array(2)
0
:
2
1
:
MessagePort {onmessage: null, onmessageerror: null}
length
:
2
[[Prototype]]
:
Array(0)
length
:
2
[[Prototype]]
:
Array(0)
This looks like something that (list? array?) that contains a MessagePort but I am not sure what it is.
Figured it out. It was a situation where I wrote:
let x = ...
when I should have written a
let%bind x = ...
and I believe the printed out expr is the expr used for completed Async_Kernel.Deferred.IVar’s .
Ah but that’s not enough! We want to know which component’s type discipline is at fault here :–) In js_of_ocaml
APIs, values usually are sufficiently well-typed for these things not happen.
I screwed up because my OCaml/Rust FFI boundary was untyped.
iframeA (OCaml) gets a MessagePort from iframeB (OCaml)
iframeA (OCaml) gets this as a MessagePort Deferred.t – and because the OCaml/Rust FFI is untyped, passes a MessagePort Deferred.t to Rust , and Rust goes wtf.
1 Like
I’m getting a bit curious about your architecture. So you compile OCaml to JavaScript and interoperate JavaScript with (native?) rust. What’s your setup like (if you want to elaborate) ?
Everything runs in Chrome. Node is not used at runtime.
OCaml is compiled to JS via js_of_ocaml.
Rust is compiled to wasm32 via -target=wasm32-unknown-unknown
OCaml / Rust talk to each other via FFI (JS functions, JS calling convention) and MessagePort.
For FFI:
2 Likes