2012-09-09 22 views
6

Pregunta de novato. Estoy repasando el muy agradable libro Ocaml ORA. Cuando fui a jugar con el ejemplo magic_copy de la sección sobre Mariscal, que estaba más cerca de un navegador de un terminal, así que probé en la ocsigen toplevel in a browser, donde me sorprendió para obtener el resultado:Mariscal y magic_copy en 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 

Comprobando si algo ha cambiado entre ocaml 2 (versión actual cuando se escribió el libro) y ocaml 3.12.1, utilizado por el nivel instalado en mi máquina y por js_of_ocaml, probé el mismo ejemplo en el nivel normal instalado en mi máquina y obtuve el resultado explicado en el libro: una segfault debido a los problemas del sistema de comprobación de los valores de Marshaled.

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

Soy curioso: ¿por qué?

Veo que en tres casos, Marshal.to_string da la misma cadena: linux ordenando un int, js_of_ocaml marshalling e int, js_of_ocaml ordenando un float. El extraño-hombre-fuera es linux toplevel ordenando un flotador.

¿Esto se debe a algo sobre js_of_ocaml usando tipos de base de JavaScript? ¿O solo ... un comportamiento indefinido?

Respuesta

6

Sí, su problema proviene del hecho de que está probando en un nivel superior de JavaScript.

Cuando se utiliza el estándar ocaml de nivel superior, la operación +. opera en OCaml flota, es decir, un doble encajonado dentro de un bloque, se espera que los dos parámetros de +. ser punteros a dichas cajas. En su ejemplo, en lugar de un puntero, proporciona el entero OCaml 2 (internamente, se representa como 5, es decir, 2 < < 1 + 1), por lo que OCaml falla al tratar de leer el doble que debe estar en la posición 0x5 en la memoria ...

En el navegador js_of_ocaml, flotadores son los flotadores acaba de javascript, y los números enteros son números enteros de javascript, y +. es la adición de JavaScript, que es capaz de sumar enteros y flota (por la conversión automática de números enteros a los flotadores), ya que los valores están etiquetados por sus tipos.

Cuestiones relacionadas