2012-09-09 13 views
6

Newbie Frage. Ich gehe durch das sehr nette Ocaml ORA Buch. Als ich mit dem magic_copy Beispiel aus dem Abschnitt über Marshal zu spielen, war ich zu einem Browser näher als ein Terminal, so dass ich versuchte es in ocsigen der toplevel in a browser, wo ich war überrascht, das Ergebnis zu erhalten:Marshal und magic_copy in js_of_ocaml

 (* 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 

Überprüfen, ob sich etwas zwischen Okamel 2 (aktuelle Version, als das Buch geschrieben wurde) und Okaml 3.12.1, die von der auf meinem Rechner installierten Toplevel und von js_of_ocaml verwendet wurde, versuchte ich das gleiche Beispiel in der normalen Toplevel auf meinem Rechner und bekam das Ergebnis, das im Buch erklärt wird: ein segfault aufgrund der Probleme des Typsystems mit der Überprüfung von Marshalled-Werten.

(* Linux toplevel *) 
# (ora_magic_copy 3: float) +. 2.1;; 
Segmentation fault (core dumped) 

Ich bin nur neugierig: warum?

Ich sehe, dass in drei Fällen Marshal.to_string die gleiche Zeichenfolge gibt: linux Marshalling ein Int, js_of_ocaml Marshalling und Int, js_of_ocaml Marsing ein Float. Der Odd-Man-Out ist ein Linux-Toplevel, der einen Float-Marshalling durchführt.

Ist das wegen etwas über js_of_ocaml mit Javascript Basistypen? Oder einfach ... undefiniertes Verhalten?

Antwort

6

Ja, Ihr Problem kommt von der Tatsache, dass Sie auf einem JavaScript-Toplevel testen.

Wenn Sie den Standard ocaml Toplevel verwenden, die +. Betrieb arbeitet auf OCaml schwimmt, das heißt einem Doppel innerhalb eines Blocks geboxt, die beiden Parameter von +. erwartet Zeiger auf solche Boxen zu sein. In Ihrem Beispiel geben Sie statt eines Zeigers die OCaml-Ganzzahl 2 (intern wird sie als 5 dargestellt, dh 2 < < 1 + 1), so dass OCaml segfaults versucht, das Double zu lesen, das an der Position 0x5 im Speicher sein sollte ...

im js_of_ocaml Browser, die Schwimmer sind nur Javascript schwimmt, und ganze Zahlen sind javascript ganze Zahlen sind, und +. ist die Javascript hinaus die in der Lage ist, ganze Zahlen zu addieren und schwimmt (durch automatisch ganzen Zahlen schwebt Umwandlung), da die Werte sind nach ihren Typen gekennzeichnet.