Reputation: 655
Newbie question. I'm going through the very nice Ocaml ORA book. When I went to play with the magic_copy example from the section on Marshal, I was closer to a browser than a terminal, so I tried it out in ocsigen's toplevel in a browser, where I was surprised to get the result:
(* js_of_ocaml *)
# let ora_magic_copy a =
let s = Marshal.to_string a [Marshal.Closures] in
Marshal.from_string s 0;;
val ora_magic_copy : 'a -> 'b = <fun>
# (ora_magic_copy 2 : float) +. 3.1;;
- : float = 5.1
Checking if something has changed between ocaml 2 (current version when the book was written) and ocaml 3.12.1, used by the toplevel installed on my machine and by js_of_ocaml, I tried the same example in the normal toplevel installed on my machine and got the result explained in the book: a segfault due to the typesystem's trouble with checking Marshaled values.
(* Linux toplevel *)
# (ora_magic_copy 3: float) +. 2.1;;
Segmentation fault (core dumped)
I'm just curious: why?
I see that in three cases, Marshal.to_string gives the same string: linux marshalling an int, js_of_ocaml marshalling and int, js_of_ocaml marshalling a float. The odd-man-out is linux toplevel marshalling a float.
Is this due to something about js_of_ocaml using javascript's base types? Or just... undefined behavior?
Upvotes: 7
Views: 499
Reputation: 4284
Yes, your problem comes from the fact that you are testing on a javascript toplevel.
When you use the standard ocaml
toplevel, the +.
operation operates on OCaml floats, i.e. a double boxed inside a block, the two parameters of +.
are expected to be pointers to such boxes. In your example, instead of a pointer, you give the OCaml integer 2
(internally, it is represented as 5, i.e. 2 << 1 + 1), so OCaml segfaults while trying to read the double that should be at position 0x5 in memory...
In the js_of_ocaml
browser, floats are just javascript floats, and integers are javascript integers, and +.
is the javascript addition, which is able to add integers and floats (by automatically converting integers to floats), because values are tagged by their types.
Upvotes: 7