2012-09-09 7 views
6

Domanda newbie. Sto esaminando il bellissimo libro Ocaml ORA. Quando sono andato a giocare con l'esempio magic_copy dalla sezione maresciallo, ero più vicino a un browser di un terminale, così ho provato in di ocsigen toplevel in a browser, dove sono rimasto sorpreso per ottenere il risultato:Marshal e 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 

Controllando se qualcosa è cambiato tra ocaml 2 (versione corrente quando il libro è stato scritto) e ocaml 3.12.1, usato dal toplevel installato sulla mia macchina e da js_of_ocaml, ho provato lo stesso esempio nel normale toplevel installato sulla mia macchina e ottenuto il risultato spiegato nel libro: un segfault dovuto al problema del sistema di controllo dei valori di Marshall.

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

Sono solo curioso: perché?

vedo che in tre casi, Marshal.to_string dà la stessa stringa: linux smistamento un int, js_of_ocaml smistamento e int, js_of_ocaml marshalling un galleggiante. L'odd-man-out è linux toplevel che esegue il marshalling di un float.

Ciò è dovuto a qualcosa di js_of_ocaml che utilizza i tipi di base di javascript? O solo ... comportamento indefinito?

risposta

6

Sì, il tuo problema deriva dal fatto che stai testando su un javascript di livello superiore.

Quando si utilizza lo standard ocaml toplevel, l'operazione +. opera sulla OCaml galleggia, cioè un doppio inscatolato all'interno di un blocco, i due parametri di +. dovrebbero essere puntatori a tali scatole. Nell'esempio, anziché un puntatore, si assegna il numero intero OCaml 2 (internamente, è rappresentato come 5, ovvero 2 < < 1 + 1), quindi OCaml segfaults durante il tentativo di leggere il doppio che dovrebbe essere nella posizione 0x5 nella memoria ...

Nel browser js_of_ocaml, galleggianti sono carri solo javascript, e interi sono numeri interi javascript, e +. è l'aggiunta javascript, che è in grado di aggiungere numeri interi e galleggia (convertendo automaticamente interi a galleggianti), perché i valori sono taggati dai loro tipi.

Problemi correlati