What OCaml value does this JS value encode?

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