Skip to content

Instantly share code, notes, and snippets.

@andrewray
Last active August 29, 2015 13:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andrewray/9980135 to your computer and use it in GitHub Desktop.
Save andrewray/9980135 to your computer and use it in GitHub Desktop.
Loading core_kernel in js_of_ocaml
{"metadata":{"name":"","language":"ocaml"},"worksheets":[{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Loading core_kernel with js_of_ocaml\n\nThe following session is run using the iocamljs `min` kernel compiled using a 32 bit OCaml toolchain on a 64 bit host given [here](https://github.com/andrewray/opam/tree/master/compilers/4.01.0/4.01.0%2B32bit). The final `js_of_ocaml` compilation step is done with a 64 bit version of the `js_of_ocaml` compiler due to a [problem](https://github.com/ocsigen/js_of_ocaml/issues/133) with the 32 bit version.\n\nI have also been able to run the following to the same extent with a full 64 bit build, however, that requires various patches to bin_prot (32 bit bit patterns like `0x8000_0000` get marshalled in the `.cmo/a` files as 64 bit constants, which cannot be unmarshalled by js_of_ocaml - replacing them with code like `1 lsl 31` fixes it but it's a kludge)."},{"metadata":{},"input":"#use \"topfind\"","cell_type":"code","prompt_number":1,"outputs":[{"text":"- : unit = ()\n","output_type":"stream","stream":"stdout"},{"text":"Findlib has been successfully loaded. Additional directives:\n #require \"package\";; to load a package\n #list;; to list the available packages\n #camlp4o;; to load camlp4 (standard syntax)\n #camlp4r;; to load camlp4 (revised syntax)\n #predicates \"p,q,...\";; to set these predicates\n Topfind.reset();; to force that packages will be reloaded\n #thread;; to enable threads\n","output_type":"stream","stream":"stdout"},{"text":"\n","output_type":"stream","stream":"stdout"},{"text":"- : unit = ()\n","output_type":"stream","stream":"stdout"}],"language":"python","collapsed":false},{"metadata":{},"input":"#require \"unix,bigarray,dynlink,type_conv\"","cell_type":"code","prompt_number":2,"outputs":[{"text":"/home/andyman/.opam/4.01.0+32bit/lib/ocaml/unix.cma: loaded\n","output_type":"stream","stream":"stderr"},{"text":"/home/andyman/.opam/4.01.0+32bit/lib/ocaml/bigarray.cma: loaded\n","output_type":"stream","stream":"stderr"},{"text":"/home/andyman/.opam/4.01.0+32bit/lib/ocaml/dynlink.cma: loaded\n","output_type":"stream","stream":"stderr"},{"text":"/home/andyman/.opam/4.01.0+32bit/lib/ocaml/camlp4: added to search path\n","output_type":"stream","stream":"stderr"},{"text":"/home/andyman/.opam/4.01.0+32bit/lib/type_conv: added to search path\n","output_type":"stream","stream":"stderr"}],"language":"python","collapsed":false},{"metadata":{},"input":"#require \"bin_prot\"","cell_type":"code","prompt_number":3,"outputs":[{"text":"/home/andyman/.opam/4.01.0+32bit/lib/bin_prot: added to search path\n","output_type":"stream","stream":"stderr"},{"text":"/home/andyman/.opam/4.01.0+32bit/lib/bin_prot/bin_prot.cma: loaded\n","output_type":"stream","stream":"stderr"}],"language":"python","collapsed":false},{"metadata":{},"input":"#require \"variantslib,sexplib\"","cell_type":"code","prompt_number":4,"outputs":[{"text":"/home/andyman/.opam/4.01.0+32bit/lib/variantslib: added to search path\n","output_type":"stream","stream":"stderr"},{"text":"/home/andyman/.opam/4.01.0+32bit/lib/variantslib/variantslib.cma: loaded\n","output_type":"stream","stream":"stderr"},{"text":"/home/andyman/.opam/4.01.0+32bit/lib/sexplib: added to search path\n","output_type":"stream","stream":"stderr"},{"text":"/home/andyman/.opam/4.01.0+32bit/lib/sexplib/sexplib.cma: loaded\n","output_type":"stream","stream":"stderr"}],"language":"python","collapsed":false},{"metadata":{},"input":"#require \"fieldslib,pa_bench,oUnit,pa_ounit\"","cell_type":"code","prompt_number":5,"outputs":[{"text":"/home/andyman/.opam/4.01.0+32bit/lib/fieldslib: added to search path\n","output_type":"stream","stream":"stderr"},{"text":"/home/andyman/.opam/4.01.0+32bit/lib/fieldslib/fieldslib.cma: loaded\n","output_type":"stream","stream":"stderr"},{"text":"/home/andyman/.opam/4.01.0+32bit/lib/pa_bench: added to search path\n","output_type":"stream","stream":"stderr"},{"text":"/home/andyman/.opam/4.01.0+32bit/lib/pa_bench/pa_bench_lib.cma: loaded\n","output_type":"stream","stream":"stderr"},{"text":"/home/andyman/.opam/4.01.0+32bit/lib/oUnit: added to search path\n","output_type":"stream","stream":"stderr"},{"text":"/home/andyman/.opam/4.01.0+32bit/lib/oUnit/oUnitAdvanced.cma: loaded\n","output_type":"stream","stream":"stderr"},{"text":"/home/andyman/.opam/4.01.0+32bit/lib/oUnit/oUnit.cma: loaded\n","output_type":"stream","stream":"stderr"},{"text":"/home/andyman/.opam/4.01.0+32bit/lib/pa_ounit: added to search path\n","output_type":"stream","stream":"stderr"},{"text":"/home/andyman/.opam/4.01.0+32bit/lib/pa_ounit/pa_ounit_lib.cma: loaded\n","output_type":"stream","stream":"stderr"}],"language":"python","collapsed":false},{"metadata":{},"input":"#require \"typerep_lib\"","cell_type":"code","prompt_number":2,"outputs":[{"text":"/home/andyman/.opam/4.01.0+32bit/lib/typerep_lib: added to search path\n","output_type":"stream","stream":"stderr"},{"text":"/home/andyman/.opam/4.01.0+32bit/lib/typerep_lib/typerep_lib.cma: loaded\n","output_type":"stream","stream":"stderr"},{"text":"Exception: Failure \"TypeError: Cannot read property '1' of undefined\".\n","output_type":"stream","stream":"stdout"}],"language":"python","collapsed":false},{"metadata":{},"input":"#require \"core_kernel\"","cell_type":"code","prompt_number":7,"outputs":[{"text":"/home/andyman/.opam/4.01.0+32bit/lib/enumerate: added to search path\n","output_type":"stream","stream":"stderr"},{"text":"/home/andyman/.opam/4.01.0+32bit/lib/core_kernel: added to search path\n","output_type":"stream","stream":"stderr"},{"text":"/home/andyman/.opam/4.01.0+32bit/lib/core_kernel/raise_without_backtrace.cma: loaded\n","output_type":"stream","stream":"stderr"},{"text":"/home/andyman/.opam/4.01.0+32bit/lib/core_kernel/core_kernel.cma: loaded\n","output_type":"stream","stream":"stderr"},{"html":"<pre style=\"color:red;max-height:100px;overflow:hidden\" \nonclick=\"\nif (this.style.maxHeight === 'none') \n this.style.maxHeight = '100px';\nelse\n this.style.maxHeight = 'none'; \n\">File &quot;[7]&quot;, line 1:\nError: Reference to undefined global `Typerep_lib'\n</pre>","output_type":"pyout","prompt_number":7,"metadata":{}}],"language":"python","collapsed":false},{"metadata":{},"cell_type":"markdown","source":"So `typerep_lib` fails to load with a javascript exception which in turn stops core_kernel from loading."},{"metadata":{},"cell_type":"markdown","source":"# Buiding typerep_lib\n\nfrom `_build/_log`\n\n```\nocamlfind ocamlc -pack -g \n lib/named_intf.cmo \n lib/type_equal.cmo \n lib/typename.cmo \n lib/variant_and_record_intf.cmo \n lib/std_internal.cmo \n lib/make_typename.cmo \n lib/typerepable.cmo \n lib/type_abstract.cmo \n lib/type_generic_intf.cmo \n lib/type_generic.cmo \n lib/typerep_obj.cmo \n lib/std.cmo \n -o lib/typerep_lib.cmo\n```\n\nTry loading each of the `.cmo` files one at a time to find the bad module."},{"metadata":{},"input":"#directory \"/home/andyman/dev/github/forks/typerep/_build/lib\"","cell_type":"code","prompt_number":1,"outputs":[],"language":"python","collapsed":false},{"metadata":{},"input":"#load \"named_intf.cmo\"","cell_type":"code","prompt_number":2,"outputs":[],"language":"python","collapsed":false},{"metadata":{},"input":"#load \"type_equal.cmo\"","cell_type":"code","prompt_number":5,"outputs":[],"language":"python","collapsed":false},{"metadata":{},"input":"Type_equal.conv","cell_type":"code","prompt_number":6,"outputs":[{"html":"<pre style=\"color:slategray;max-height:100px;overflow:hidden\" \nonclick=\"\nif (this.style.maxHeight === 'none') \n this.style.maxHeight = '100px';\nelse\n this.style.maxHeight = 'none'; \n\">- : ('a, 'b) Type_equal.t -&gt; 'a -&gt; 'b = &lt;fun&gt;\n</pre>","output_type":"pyout","prompt_number":6,"metadata":{}}],"language":"python","collapsed":false},{"metadata":{},"input":"#load \"typename.cmo\"","cell_type":"code","prompt_number":7,"outputs":[],"language":"python","collapsed":false},{"metadata":{},"input":"#load \"variant_and_record_intf.cmo\"","cell_type":"code","prompt_number":8,"outputs":[],"language":"python","collapsed":false},{"metadata":{},"input":"#load \"std_internal.cmo\"","cell_type":"code","prompt_number":9,"outputs":[{"text":"Exception: Failure \"TypeError: Cannot read property '1' of undefined\".\n","output_type":"stream","stream":"stdout"}],"language":"python","collapsed":false},{"metadata":{},"cell_type":"markdown","source":"So our problems start in `std_internal.cmo`."},{"metadata":{},"input":"#load \"make_typename.cmo\"","cell_type":"code","outputs":[],"language":"python","collapsed":false},{"metadata":{},"input":"#load \"typerepable.cmo\"","cell_type":"code","outputs":[],"language":"python","collapsed":false},{"metadata":{},"input":"#load \"type_abstract.cmo\"","cell_type":"code","outputs":[],"language":"python","collapsed":false},{"metadata":{},"input":"#load \"type_generic_intf.cmo\"","cell_type":"code","outputs":[],"language":"python","collapsed":false},{"metadata":{},"input":"#load \"type_generic.cmo\"","cell_type":"code","outputs":[],"language":"python","collapsed":false},{"metadata":{},"input":"#load \"typerep_obj.cmo\"","cell_type":"code","outputs":[],"language":"python","collapsed":false},{"metadata":{},"input":"#load \"std.cmo\"","cell_type":"code","outputs":[],"language":"python","collapsed":false},{"metadata":{},"cell_type":"markdown","source":"My suspicion is it is the recursive module defined in `std_internal`. Lets have a play."},{"metadata":{},"input":"module Typename = struct\n type 'a t\nend\nmodule Type_equal = struct\n type ('a,'b) t\nend\n\nmodule rec Typerep : sig\n\n type _ t =\n | Int : int t\n | Int32 : int32 t\n | Int64 : int64 t\n | Nativeint : nativeint t\n | Char : char t\n | Float : float t\n | String : string t\n | Bool : bool t\n | Unit : unit t\n | Option : 'a t -> 'a option t\n | List : 'a t -> 'a list t\n | Array : 'a t -> 'a array t\n | Lazy : 'a t -> 'a Lazy.t t\n | Ref : 'a t -> 'a ref t\n (*| Function : ('dom t * 'rng t) -> ('dom -> 'rng) t\n | Tuple : 'a Typerep.Tuple.t -> 'a t\n | Record : 'a Typerep.Record.t -> 'a t\n | Variant : 'a Typerep.Variant.t -> 'a t\n | Named : ('a Typerep.Named.t * 'a t Lazy.t option) -> 'a t*)\n module Named : sig\n module type T0 = sig\n type named\n type t\n val typename_of_named : named Typename.t\n val typename_of_t : t Typename.t\n val witness : (t, named) Type_equal.t\n end\n type 'a t = T0 of (module T0 with type t = 'a)\n val arity : _ t -> int\n end\nend = struct\n\n type _ t =\n | Int : int t\n | Int32 : int32 t\n | Int64 : int64 t\n | Nativeint : nativeint t\n | Char : char t\n | Float : float t\n | String : string t\n | Bool : bool t\n | Unit : unit t\n | Option : 'a t -> 'a option t\n | List : 'a t -> 'a list t\n | Array : 'a t -> 'a array t\n | Lazy : 'a t -> 'a Lazy.t t\n | Ref : 'a t -> 'a ref t\n (*| Function : ('dom t * 'rng t) -> ('dom -> 'rng) t\n | Tuple : 'a Typerep.Tuple.t -> 'a t\n | Record : 'a Typerep.Record.t -> 'a t\n | Variant : 'a Typerep.Variant.t -> 'a t\n | Named : ('a Typerep.Named.t * 'a t Lazy.t option) -> 'a t*)\n\n module Named = struct\n module type T0 = sig\n type named\n type t\n val typename_of_named : named Typename.t\n val typename_of_t : t Typename.t\n val witness : (t, named) Type_equal.t\n end\n type 'a t = T0 of (module T0 with type t = 'a)\n let arity = function T0 _ -> 0 \n end\n \nend","cell_type":"code","prompt_number":25,"outputs":[{"html":"<pre style=\"color:slategray;max-height:100px;overflow:hidden\" \nonclick=\"\nif (this.style.maxHeight === 'none') \n this.style.maxHeight = '100px';\nelse\n this.style.maxHeight = 'none'; \n\">module Typename : sig type 'a t end\n</pre>","output_type":"pyout","prompt_number":25,"metadata":{}},{"html":"<pre style=\"color:slategray;max-height:100px;overflow:hidden\" \nonclick=\"\nif (this.style.maxHeight === 'none') \n this.style.maxHeight = '100px';\nelse\n this.style.maxHeight = 'none'; \n\">module Type_equal : sig type ('a, 'b) t end\n</pre>","output_type":"pyout","prompt_number":25,"metadata":{}},{"html":"<pre style=\"color:red;max-height:100px;overflow:hidden\" \nonclick=\"\nif (this.style.maxHeight === 'none') \n this.style.maxHeight = '100px';\nelse\n this.style.maxHeight = 'none'; \n\">Exception: Failure &quot;TypeError: Cannot read property '1' of undefined&quot;.\n</pre>","output_type":"pyout","prompt_number":25,"metadata":{}}],"language":"python","collapsed":false},{"metadata":{},"cell_type":"markdown","source":"The error comes with the addition of the `arity` function.\n\nLets try to simplify a bit."},{"metadata":{},"input":"module rec Typerep : sig\n module Named : sig\n module type T0 = sig\n type named\n type t\n end\n type 'a t = T0 of (module T0 with type t = 'a)\n val arity : _ t -> int\n end\nend = struct\n module Named = struct\n module type T0 = sig\n type named\n type t\n end\n type 'a t = T0 of (module T0 with type t = 'a)\n let arity = function T0 _ -> 0 \n end\n \nend","cell_type":"code","prompt_number":2,"outputs":[{"output_type":"pyout","prompt_number":2,"html":"<pre style=\"color:red;max-height:100px;overflow:hidden\" \nonclick=\"\nif (this.style.maxHeight === 'none') \n this.style.maxHeight = '100px';\nelse\n this.style.maxHeight = 'none'; \n\">Exception: Failure &quot;TypeError: Cannot read property '1' of undefined&quot;.\n</pre>","metadata":{}}],"language":"python","collapsed":false},{"metadata":{},"cell_type":"markdown","source":"Remove the `rec`"},{"metadata":{},"input":"module Typerep : sig\n module Named : sig\n module type T0 = sig\n type named\n type t\n end\n type 'a t = T0 of (module T0 with type t = 'a)\n val arity : _ t -> int\n end\nend = struct\n module Named = struct\n module type T0 = sig\n type named\n type t\n end\n type 'a t = T0 of (module T0 with type t = 'a)\n let arity = function T0 _ -> 0 \n end\n \nend","cell_type":"code","prompt_number":4,"outputs":[{"output_type":"pyout","prompt_number":4,"html":"<pre style=\"color:slategray;max-height:100px;overflow:hidden\" \nonclick=\"\nif (this.style.maxHeight === 'none') \n this.style.maxHeight = '100px';\nelse\n this.style.maxHeight = 'none'; \n\">module Typerep :\n sig\n module Named :\n sig\n module type T0 = sig type named type t end\n type 'a t = T0 of (module T0 with type t = 'a)\n val arity : 'a t -&gt; int\n end\n end\n</pre>","metadata":{}}],"language":"python","collapsed":false},{"metadata":{},"input":"","cell_type":"code","outputs":[],"language":"python","collapsed":false}],"metadata":{}}],"nbformat":3,"nbformat_minor":0}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment