js_of_ocaml中的Marshal和magic_copy

ImA*_*reg 7 ocaml marshalling js-of-ocaml

新手问题.我正在阅读非常好的Ocaml ORA书.当我从Marshal的部分开始使用magic_copy示例时,我更接近浏览器而不是终端,所以我在ocsigen的浏览器中尝试了它,我很惊讶地得到了结果:

     (* 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
Run Code Online (Sandbox Code Playgroud)

检查ocaml 2(书写当前版本)和ocaml 3.12.1(由我的机器上安装的顶层和js_of_ocaml使用)之间是否有变化,我在我的机器上安装的普通顶层中尝试了相同的示例书中解释的结果是:由于类型系统检查Marshaled值而导致的段错误.

    (* Linux toplevel *)
# (ora_magic_copy 3: float) +. 2.1;;
Segmentation fault (core dumped)
Run Code Online (Sandbox Code Playgroud)

我只是好奇:为什么?

我看到在三种情况下,Marshal.to_string给出了相同的字符串:linux编组一个int,js_of_ocaml编组和int,js_of_ocaml编组一个浮点数.奇怪的是linux toplevel marshalling float.

这是由于js_of_ocaml使用javascript的基本类型吗?或者只是......未定义的行为?

Fab*_*ant 7

是的,您的问题来自于您正在使用javascript进行测试.

当你使用标准ocaml顶层时,+.操作在OCaml浮点数上运行,即一个块内的双重盒子,这两个参数+.预计是指向这些盒子的指针.在您的示例中,您不是指针,而是给出OCaml整数2(在内部,它表示为5,即2 << 1 + 1),因此OCaml在尝试读取应该在内存中位置0x5的双精度时发生段错误. ..

js_of_ocaml浏览器中,浮点数只是javascript浮点数,整数是javascript整数,并且+.是javascript加法,它可以添加整数和浮点数(通过自动将整数转换为浮点数),因为值由其类型标记.