Is there somewhere in the compiler codebase/documentation that I can’t find which describes the memory layout of extensible variants? From messing around a bit with -dlambda
:
type t = ..
type t += Foobar
(seq
(let (Foobar/268 = (makeblock 248 "Abc.Foobar" (caml_fresh_oo_id 0)))
(setfield_ptr(root-init) 0 (global Abc!) Foobar/268))
0)
It seems like they’re encoded as objects (tag 248) where the class field is a string that contains the name of the variant (here Abc.Foobar
) and the ID field being a unique ID generated by caml_fresh_oo_id
.
Are extensible variants the only case in which the class field of an object is a string?
The motivation here is the instability of unmarshalling extensible variants. I’m wondering if it’s possible to add a flag to Marshal.extern_flags
which raises if the input contains an extensible variant, similar to how the Marshal.to_{format}
functions raise when a closure is passed without the Closures
flag.