Маршал и волшебная копия в js_of_ocaml

Вопрос новичка. Я просматриваю очень хорошую книгу Ocaml ORA. Когда я пошел поиграть с примером magic_copy из раздела Marshal, я был ближе к браузеру, чем к терминалу, поэтому я попробовал его на верхнем уровне 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

Проверяя, изменилось ли что-то между ocaml 2 (текущая версия, когда книга была написана) и ocaml 3.12.1, используемой на верхнем уровне, установленном на моей машине, и js_of_ocaml, я попробовал тот же пример на обычном верхнем уровне, установленном на моей машине, и получил результат, объясненный в книге: ошибка из-за проблемы системы типов с проверкой значений Marshaled.

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

Мне просто любопытно: почему?

Я вижу, что в трех случаях Marshal.to_string дает одну и ту же строку: linux, маршаллизирующий int, js_of_ocaml, маршаллинг и int, js_of_ocaml, маршаллизирующий float. Нечетным является то, что linux toplevel управляет флотом.

Это связано с тем, что js_of_ocaml использует базовые типы javascript? Или просто... неопределенное поведение?

1 ответ

Решение

Да, ваша проблема связана с тем, что вы тестируете на уровне javascript.

Когда вы используете стандарт ocaml на высшем уровне +. Операция работает на поплавках OCaml, то есть в двойном боксе внутри блока, два параметра +. Ожидается, что указатели на такие коробки. В вашем примере вместо указателя вы даете целое число OCaml 2 (внутренне он представлен как 5, то есть 2 << 1 + 1), поэтому OCaml segfaults при попытке прочитать двойное число, которое должно быть в позиции 0x5 в памяти...

в js_of_ocaml браузер, числа с плавающей точкой - это просто числа с плавающей точкой в ​​JavaScript, а целые числа - это целые числа из JavaScript, и +. это дополнение javascript, которое может добавлять целые числа и числа с плавающей точкой (путем автоматического преобразования целых чисел в числа с плавающей точкой), поскольку значения помечены их типами.

Другие вопросы по тегам