Code Monkey home page Code Monkey logo

js_of_ocaml's Introduction

Js_of_ocaml (jsoo)

Build Status Update Web site - build Update Web site - deploy

Js_of_ocaml is a compiler from OCaml bytecode to JavaScript. It makes it possible to run pure OCaml programs in JavaScript environment like browsers and Node.js.

  • It is easy to install and use as it works with an existing installation of OCaml, with no need to recompile any library.
  • It comes with bindings for a large part of the browser APIs.
  • According to our benchmarks, the generated programs runs typically faster than with the OCaml bytecode interpreter.
  • We believe this compiler will prove much easier to maintain than a retargeted OCaml compiler, as the bytecode provides a very stable API.

Js_of_ocaml is composed of multiple packages:

  • js_of_ocaml-compiler, the compiler.
  • js_of_ocaml-ppx, a ppx syntax extension.
  • js_of_ocaml, the base library.
  • js_of_ocaml-ppx_deriving_json
  • js_of_ocaml-lwt, lwt support.
  • js_of_ocaml-tyxml, tyxml support.
  • js_of_ocaml-toplevel, lib and tools to build an ocaml toplevel to javascript.

Requirements

See opam file for version constraints.

optional

Toplevel requirements

  • tyxml, reactiveData
  • ocp-indent: needed to support indentation in the toplevel
  • higlo: needed to support Syntax highlighting in the toplevel
  • cohttp: needed to build the toplevel webserver

Installation

Opam

opam install js_of_ocaml js_of_ocaml-compiler js_of_ocaml-ppx

Usage

Your program must first be compiled using the OCaml bytecode compiler ocamlc. JavaScript bindings are provided by the js_of_ocaml package. The syntax extension is provided by js_of_ocaml-ppx package.

ocamlfind ocamlc -package js_of_ocaml -package js_of_ocaml-ppx -linkpkg -o cubes.byte cubes.ml

Then, run the js_of_ocaml compiler to produce JavaScript code:

js_of_ocaml cubes.byte

Features

Most of the OCaml standard library is supported. However,

  • Most of the Sys module is not supported.

Extra libraries distributed with OCaml (such as Thread) are not supported in general. However,

  • Bigarray: bigarrays are supported using Typed Arrays
  • Num: supported
  • Str: supported
  • Graphics: partially supported using canvas (see js_of_ocaml-lwt.graphics)
  • Unix: time related functions are supported

Tail call is not optimized in general. However, mutually recursive functions are optimized:

  • self recursive functions (when the tail calls are the function itself) are compiled using a loop.
  • trampolines are used otherwise. More about tail call optimization.

Effect handlers are supported with the --enable=effects flag.

Data representation

Data representation differs from the usual one. Most notably, integers are 32 bits (rather than 31 bits or 63 bits), which is their natural size in JavaScript, and floats are not boxed. As a consequence, marshalling, polymorphic comparison, and hashing functions can yield results different from usual:

  • marshalling floats might generate different output. Such output should not be unmarshalled using the standard ocaml runtime (native or bytecode).
  • the polymorphic hash function will not give the same results on datastructures containing floats;
  • these functions may be more prone to stack overflow.
OCaml javascript
int number (32bit int)
int32 number (32bit int)
nativeint number (32bit int)
int64 Object (MlInt64)
float number
string string or object (MlBytes)
bytes object (MlBytes)
"immediate" (e.g. true, false, None, ()) number (32bit int)
"block" array with tag as first element (e.g. C(1,2) => [tag,1,2])
array block with tag 0 (e.g. [|1;2|] => [0,1,2])
tuple block with tag 0 (e.g. (1,2) => [0,1,2])
record block (e.g. {x=1;y=2} => [0,1,2])
constructor with arguments block (e.g. C (1, 2) => [tag,1,2])
module block
exception and extensible variant block or immediate
function function

Toplevel

Contents of the distribution

Filename Description
LICENSE license and copyright notice
README this file
compiler/ compiler
examples/ small examples
lib/ library for interfacing with JavaScript APIs
ppx/ ppx syntax extensions
runtime/ runtime system
toplevel/ web-based OCaml toplevel

js_of_ocaml's People

Contributors

abbysmal avatar alainfrisch avatar balat avatar benozol avatar chambart avatar dbuenzli avatar drup avatar fxfactorial avatar gpetiot avatar hhugo avatar hnrgrgr avatar itszor avatar kakadu avatar keleshev avatar kit-ty-kate avatar let-def avatar little-arhat avatar monstasat avatar oliviernicole avatar phated avatar pmwhite avatar pveber avatar raphael-proust avatar rgrinberg avatar sagotch avatar slegrand45 avatar smorimoto avatar tyoverby avatar vasilisp avatar vouillon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

js_of_ocaml's Issues

caml_ml_input

The array bounds check should be

var l2 = chan.data.array.length - chan.data.offset;

This makes Streams work properly.

Use a module pattern to avoid global scope leaking

js_of_ocaml generates JS with a lot of global caml_* variables. This could be avoided by putting the code which interact with these functions in an IIFE and exporting only the useful ones and/or using a namespace, e.g.:

var caml = (function(global, ns) {
  ns.foo = function caml_foo() { /* … */ };
  ns.bar = function caml_bar() { /* … */ };
  function caml_global_function() { /* … */ };

  // export global functions
  global.caml_global_function = caml_global_function;

  // return caml object
  return ns;
})(this, {});

Then use:

caml.foo();
caml.bar();

caml_global_function();

joo_register_file/caml_ml_register_file

The psuedo-file system (from what I can gather) uses a call Js.register_file which in turn calls caml_ml_register_file (defined in js.ml).

The runtime defines a function joo_register_file (which is also mentioned in one place in the compiler). I believe joo_register_file and caml_ml_register_file should be the same thing.

To avoid re-compilation I have added

// missing?
function caml_ml_register_file(name,content) {
    joo_register_file(name,content)
}

to some custom javascript in my project and the filesystem stuff is somewhat working.

Uncaught TypeError: Cannot read property '1' of undefined

I'm experimenting with compiling a HTML parser using js_of_ocaml. I've looked at a few options, I'm currently working on Nethtml.

I managed to extract it from the Netsys / Unix dependencies, and aside from a few missing primitive warnings and the size of the JS file (200k) it works fairly well. In the 1.4 release.

Using the development branch (because -opt 3 fails for me in 1.4) I get the above TypeError. I tracked it down to code that first iterates over a list copying the values into a hashtable, and then runs List.assoc over the same list. It does more than that, but that seems to be the bulk of the cause.

I noticed in the dev branch, the JS generates long lists as separate arrays instead of using one big nested array. I confirmed this is related by shortening the list to 10 items which fits in a single JS array and doesn't trigger the issue.

I have simplified the replication case as follows:

let etable =
  [ "lt", 60;
  "gt", 62;
  "amp", 38;
  "quot", 34;
  "apos", 39;
  "nbsp", 160;
  "iexcl", 161;
  "cent", 162;
  "pound", 163;
  "curren", 164;

  (* comment this out to avoid the error *)
  "yen", 165;
  ]

let first_iter =
  let ht = Hashtbl.create 50 in
    List.iter (fun (name,value) -> (Hashtbl.add ht name value))
              etable

let second_assoc = List.assoc "lt" etable


(* just so the optimiser doesn't remove the above *)
let _ = (Js.Unsafe.coerce Dom_html.window)##table <- Js.wrap_callback (fun _ -> second_assoc)

(* this is here because I get "missing primitive caml_mul" if multiplication is never used *)
let _ = (Js.Unsafe.coerce Dom_html.window)##square <- Js.wrap_callback (fun x -> x * x)

I'll log the caml_mul thing as a separate issue.

Missing primitives result in errors even when the primitives are not called.

In order to avoid repetitions, we now generate code like: d8=caml_ml_output_char.
This fails when caml_ml_output_char is not defined.

I can see several way to fix that:

  • only share a primitive if the linkers knows about it;
  • output d8=this.caml_ml_output_char (but we will get puzzling error messages telling that d8 is not defined);
  • have the linker generate a short piece of code for each missing primitive.

The first option seems best. It should not be difficult to implement as the linker already has all the information during code generation.

float_of_string behavior (document or fix)

float_of_string "0o123" works with joo runtime where it fails with regular runtime
float_of_string "0xffffp2" fails with joo runtime where it succeed with regular runtime

Opam package seems extremely old

The current js_of_ocaml opam package seems extremely old.
Because of this, we cannot compile some codes in https://ocsigen.org/tutorial/tutowidgets, if we install js_of_ocaml via opam.
(* I'm sorry I cannot contribute because I don't know about opam packages at all. *)

The rest of this post is how I reached the conclution above.

I'm trying the tutorial https://ocsigen.org/tutorial/tutowidgets, and encountered an error Error: Unbound value Lwt_js_events.onload.
I installed js_of_ocaml by the command below.
$ opam update; opam install eliom
I found that the source codes here and those in my computer (~/.opam/3.12.1/lib/js_of_ocaml) are different, while the versions are the same (1.3.2).
The function Lwt_js_events.onload was added by the commit fb5e555, so I think the current js_of_ocaml opam package is built at least before May 03 2013.

thanks,

Bugs in Regexp module

Regexp.global_replace and Regexp.replace_first share the same implementation, which cannot be correct.

One needs to see how these functions should interact with Regexp.regexp_with_flag, which currently allow to set the global flag.

Warning

I don't know if it's related to js_of_ocaml, but I got this warning with the latest (69df95a) dev version of js_of_ocaml:

Use of getUserData() or setUserData() is deprecated.  Use WeakMap or element.dataset instead.

Bug with constant sharing

Constants are not compiled correctly.

This code:

    ["%int_mul", "caml_mul";
     "%int_div", "caml_div";
     "%int_mod", "caml_mod";
     "caml_int32_neg", "%int_neg";
     "caml_int32_add", "%int_add";
     "caml_int32_sub", "%int_sub";
     ....

is compiled into:

     _ayg_=
      [0,
       [0,_b_("caml_mul"),_b_("caml_mul")],
       [0,
        [0,_b_("caml_div"),_b_("caml_div")],
        [0,
         [0,_b_("caml_mod"),_b_("caml_mod")],
         [0,
          [0,_b_(_if_),_b_(_if_)],
          [0,
           [0,_b_(_g__),_b_(_g__)],
           [0,
            [0,_b_(_il_),_b_(_il_)],
            [0,
            ....

Missing primitive appears without debug flags

While compiling cumulus with the latest js_of_ocaml compiler (21ac186), I've been surprised by the following behavior:

$ js_of_ocaml -noruntime +js_of_ocaml/runtime.js +eliom.client/eliom_client.js +js_of_ocaml/weak.js +js_of_ocaml/classlist.js src/client/cumulus.byte -o src/client/cumulus.js
Missing primitives:
  __eliom_request_data
  …
$ js_of_ocaml -noruntime -pretty -debuginfo -noinline +js_of_ocaml/runtime.js +eliom.client/eliom_client.js +js_of_ocaml/weak.js +js_of_ocaml/classlist.js src/client/cumulus.byte -o src/client/cumulus.js
Missing primitives:
   …

Namely, the missing primitive __eliom_request_data appears only without the debug flags -pretty -debuginfo -noinline.

stdio redirection

I see that printf's are automatically redirected to the browser console which is nice (printf is still my debugging tool of choice).

Is that behaviour documented somewhere ? And is it possible to capture that output to redirect it somewhere else (e.g. to make it visible on the webpage). It couldn't find anything about that in the docs.

Issues with Javascript strings

  • Our JavaScript syntax tree should support two kind of strings: sequences of bytes (which is what is currently available) and UTF8 strings.
  • When outputting UTF8 strings, one does not need to escape bytes above 127.
  • The JavaScript parser should unescape the UTF8 parsed strings.
  • The JavaScript parser should unescape regular expressions.
  • When generating a regular expression literal, one should check whether it contains only allowed characters.

(See the ECMAScript spec for details on the syntax of literal strings and regular expressions.)

Use of Hashtbl.add causes Missing primitives: caml_mul

If Hashtbl.add is used in a simple project there's an unrecognised dependency on caml_mul. If I add explicit multiplication to force the dependency everything works.

This does not happen in the 1.4 release.

Code:

let table =
    let ht = Hashtbl.create 0 in
        Hashtbl.add ht 0 0;
        ht


let _ = (Js.Unsafe.coerce Dom_html.window)##table <- Js.wrap_callback (fun _ -> table)

(* uncomment this to work around the issue *)
(* let _ = (Js.Unsafe.coerce Dom_html.window)##square <- Js.wrap_callback (fun x -> x * x) *)

Type check of js method call in nested function is too tight

let ff a =
  let f c =
    c##prop1 <- true
  in
  f a;
  f a##prop2

This requires that a and a##prop2 have same type.

val ff : (< prop1 : < set : bool -> unit; .. > Js.gen_prop;
            prop2 : < get : 'a Js.t; .. > Js.gen_prop; .. >
            as 'a)
          Js.t -> unit

But this allows differet types.

let f1 c =
  c##prop1 <- true

let ff1 a =
  f1 a;
  f1 a##prop2


val ff1 : < prop1 : < set : bool -> unit; .. > Js.gen_prop;
            prop2 : < get : < prop1 : < set : bool -> unit; .. > Js.gen_prop; .. > Js.t;
                      .. > Js.gen_prop;
            .. >
          Js.t -> unit

Where does the missing primitive unix_inet_addr_of_string comes from ?

I got this missing primitive and I wanted to know where does it comes from. Because it should appears only if the unix package is used (directly or as a dependency) but I only use eliom.client.

$ js_of_ocaml -noruntime -pretty -debuginfo -noinline +js_of_ocaml/runtime.js +eliom.client/eliom_client.js +js_of_ocaml/weak.js +js_of_ocaml/classlist.js src/client/cumulus.byte -o src/client/cumulus.js
Missing primitives:
  …
  unix_inet_addr_of_string

Support for recursive modules

What are the ways to make Recursive modules to work ?
It seams to me that overriding part of CamlinternalMod could be a way ..
Does it seams feasible ? Are there any other ways ?

deriving json

Why is that here ? Isn't it possible to put the json parser into the deriving lib ? I find it confusing (plus it seems not to work when I want to derive both json and show for example).

topfind / #require

I would like to add support for topfind to iocamljs (with support from it's cousin iocamlserver).

This session is my first attempt at getting this working.

The .cmo file is loaded and parsed by the Topdirs.dir_load machinery, then fails in Parsebyte_code.compile while processing the SETGLOBAL instruction.

Any pointers on where to look next? I assume something along the lines of Parse_bytecode.from_channel needs to happen to set up a global environment?

install of js_of_caml.9999 fails due to boulderdash error

Hi,

opam install eliom wants to upgrade js_of_caml from 1.4.0 to 9999. During installation the error bwlow occurs. To me it seems like one of the examples failed. The error message which asks to use --infer can be found in the menhir source.

/Jörgen

root@raspberrypi:~# opam install eliom
The following actions will be performed:
 - install deriving.9999 [required by eliom]
 - install ocsigenserver.9999 [required by eliom]
 - upgrade js_of_ocaml.1.4.0 to 9999 [required by eliom]
 - install eliom.9999
3 to install | 0 to reinstall | 1 to upgrade | 0 to downgrade | 0 to remove
Do you want to continue ? [Y/n] 

=-=-= Removing Packages =-=-=
Removing js_of_ocaml.1.4.0.
  ocamlfind remove js_of_ocaml

=-=-= Installing deriving.9999 =-=-=
deriving.9999 Fetching https://github.com/ocsigen/deriving.git
Copying ~/.opam/repo/ocsigendev/packages/deriving.9999/files/eliom.install to ~/.opam/system/build/deriving.9999/
Building deriving.9999:
  make
  make install
Installing deriving.9999.

=-=-= Installing ocsigenserver.9999 =-=-=
ocsigenserver.9999 Fetching https://github.com/ocsigen/ocsigenserver.git
Copying ~/.opam/repo/ocsigendev/packages/ocsigenserver.9999/files/ocsigenserver.install to ~/.opam/system/build/ocsigenserver.9999/
Building ocsigenserver.9999:
  sh configure --prefix /root/.opam/system --ocsigen-user root --ocsigen-group root --commandpipe /root/.opam/system/lib/ocsigenserver/var/run/ocsigenserver_command --logdir /root/.opam/system/lib/ocsigenserver/var/log/ocsigenserver --mandir /root/.opam/system/man/man1 --docdir /root/.opam/system/lib/ocsigenserver/share/doc/ocsigenserver --commandpipe /root/.opam/system/lib/ocsigenserver/var/run/ocsigenserver_command --staticpagesdir /root/.opam/system/lib/ocsigenserver/var/www --datadir /root/.opam/system/lib/ocsigenserver/var/lib/ocsigenserver --sysconfdir /root/.opam/system/lib/ocsigenserver/etc/ocsigenserver
  make
  make install
Installing ocsigenserver.9999.

=-=-= Installing js_of_ocaml.9999 =-=-=
js_of_ocaml.9999 Fetching https://github.com/ocsigen/js_of_ocaml.git
Copying ~/.opam/repo/ocsigendev/packages/js_of_ocaml.9999/files/js_of_ocaml.install to ~/.opam/system/build/js_of_ocaml.9999/
Building js_of_ocaml.9999:
  make
  make install BINDIR=/root/.opam/system/bin
[ERROR] The compilation of js_of_ocaml.9999 failed.
Removing js_of_ocaml.9999.
  ocamlfind remove js_of_ocaml
  ocamlfind remove js_of_ocaml_compiler

[ERROR] Due to some errors while processing js_of_ocaml.9999, the following actions will NOT proceed:
 - install eliom.9999

=-=-= ERROR RECOVERY [js_of_ocaml.9999] =-=-=

=-=-= Installing js_of_ocaml.1.4.0 =-=-=
js_of_ocaml.1.4.0 Downloading http://ocsigen.org/download/js_of_ocaml-1.4.tar.gz
Copying ~/.opam/packages/js_of_ocaml/js_of_ocaml.1.4.0/files/js_of_ocaml.install to ~/.opam/system/build/js_of_ocaml.1.4.0/
Building js_of_ocaml.1.4.0:
  make
  make install BINDIR=/root/.opam/system/bin
Installing js_of_ocaml.1.4.0.

=-=-= Installing eliom.9999 =-=-=
eliom.9999 Fetching https://github.com/ocsigen/eliom.git
Copying ~/.opam/repo/ocsigendev/packages/eliom.9999/files/eliom.install to ~/.opam/system/build/eliom.9999/
Building eliom.9999:
  sh configure --prefix /root/.opam/system --mandir /root/.opam/system/man --docdir /root/.opam/system/lib/eliom/doc --datadir /root/.opam/system/lib/eliom/share
  make
  make install
[ERROR] The compilation of eliom.9999 failed.
Removing eliom.9999.
  rm -rf /root/.opam/system/lib/eliom /root/.opam/system/man/man1/eliomc.1 /root/.opam/system/man/man1/eliomopt.1 /root/.opam/system/man/man1/eliomcp.1 /root/.opam/system/man/man1/js_of_eliom.1 /root/.opam/system/man/man1/eliomdep.1 /root/.opam/system/man/man1/eliom-distillery.1

===== ERROR while upgrading to js_of_ocaml.9999 =====
# opam-version 1.1.0
# os           linux
# command      make
# path         /root/.opam/system/build/js_of_ocaml.9999
# compiler     system (4.01.0)
# exit-code    2
# env-file     /root/.opam/system/build/js_of_ocaml.9999/js_of_ocaml-10506-335865.env
# stdout-file  /root/.opam/system/build/js_of_ocaml.9999/js_of_ocaml-10506-335865.out
# stderr-file  /root/.opam/system/build/js_of_ocaml.9999/js_of_ocaml-10506-335865.err
### stdout ###
# ...[truncated]
# make[1]: Leaving directory `/root/.opam/system/build/js_of_ocaml.9999/doc'
# make -C examples
# make[1]: Entering directory `/root/.opam/system/build/js_of_ocaml.9999/examples'
# make -C boulderdash/
# make[2]: Entering directory `/root/.opam/system/build/js_of_ocaml.9999/examples/boulderdash'
# ocamlfind ocamlc -package lwt -pp "camlp4o ../../lib/syntax/pa_js.cmo" -I ../../lib -g -c boulderdash.ml
# ocamlfind ocamlc -package lwt -pp "camlp4o ../../lib/syntax/pa_js.cmo" -I ../../lib -g -linkpkg -o boulderdash.byte js_of_ocaml.cma boulderdash.cmo
# ../../compiler/js_of_ocaml -noruntime ../../runtime/runtime.js boulderdash.byte 
# make[2]: Leaving directory `/root/.opam/system/build/js_of_ocaml.9999/examples/boulderdash'
# make[1]: Leaving directory `/root/.opam/system/build/js_of_ocaml.9999/examples'
### stderr ###
# Warning: you are using the standard library and/or the %inline keyword. We
# recommend switching on --infer in order to avoid obscure type error messages.
# Warning: 12 states have shift/reduce conflicts.
# Warning: 47 shift/reduce conflicts were arbitrarily resolved.
# Warning: Class or class type event not found
# Fatal error: exception Failure("int_of_string")
# make[2]: *** [boulderdash.js] Fel 2
# make[1]: *** [boulderdash/] Fel 2
# make: *** [examples] Fel 2

The former state can be restored with opam switch import -f "/root/.opam/system/backup/state-20140004135256.export"
'opam install eliom' failed.

possible runtime feature: autoloading files from server

I think this is the only patch left I have to the runtime to enable topfind functionality.

function caml_sys_file_exists (name) {
  return (caml_global_data.files && caml_global_data.files[name.toString()]) ? 1 : 
      iocaml_request_file(name);
}

where iocaml_request_file will do a XmlHttmlRequest to the server and call caml_register_file.

I wonder if we could add a non-invasive feature like;

function caml_sys_file_exists (name) {
  return (caml_global_data.files && caml_global_data.files[name.toString()]) ? 1 : 
      (caml_global_data.auto_register_file === undefined ? 0 : 
                 caml_global_data.auto_register_file(name));
}

to allow user code to implement this.

Missing primitives for 4.01

With ocaml 4.01rc1, I got the following missing primitives (when compiling ocsimore):
caml_ml_output_char
caml_sys_exit
caml_weak_blit
caml_weak_create
caml_weak_get
caml_weak_set

The two primary primitives are usual, but the next ones aren't.

Improve curryfication

When we know a function is under-applied, we should create a local function that expects the additional arguments and performs the full application rather than going through caml_call_gen*, for instance, rewriting f(a,b) into function (x,y){f(a,b,x,y)} when the arity of f is 4.

Similarly, in case of over-application, we should split the application into multiple applications, turning for instance f(a,b,c,d) into f(a,b)(c,d) when the arity of f is 2.

Add a pa_deriving unsafe mode (to be use client side only) ..

.. so fake Json_something module (for parsing and printing) can be generated. It reduces the size of the generated javascript and should be faster.

type ty = { my_complex_type } deriving (Json)

could generate

module Json_ty = struct
  value to_string (a : ty) : string = Js.to_string (Json.output a);
  value from_string (s : string) : ty = Json.unsafe_input (Js.string s);
end

psuedo file system

I was hoping I could register a file, write to it, then read it back. Something like.

let () = Js.register_file ~name:"file2" ~content:""

let fout = open_out "file2"
let () = output_string fout "line 1\n"
let () = output_string fout "line 2\n"
let () = close_out fout

let fin = open_in "file2"
let a = input_line fin
let b = input_line fin
let c = input_line fin
let () = close_in fin

This leads to an exception on open_in

val fin : in_channel = 
Exception: End_of_file.

(This stuff is running in my hacked up js_of_ocaml top level)

new missing primitives since ocaml 4.01.0

Hello js_of_ocaml team.

I used to have this "warning" when compiling my program with ocaml 4.00.0 :

Missing primitives:
  caml_ml_output_char

I upgraded to 4.01.0 via opam yesterday, and my program did not changed, but I now have those messages when compiling :

Missing primitives:
  caml_ml_output_char
  caml_sys_const_big_endian
  caml_sys_const_ostype_cygwin
  caml_sys_const_ostype_unix
  caml_sys_const_ostype_win32
  caml_sys_const_word_size

The problem is that caml_ml_output_char did not prevent my program from running well, but these new errors do.

Is it a known issue ? Did I forget to upgrade something ?

NEXT RELEASE

What should be in the next release ?

I would release the latest commits

  • It will help to get more testing.
  • We can easily release minor versions with bug fixes if needed.

What about PR:

weak.js

I'm getting errors when using weak.js from js_of_ocaml. It seams to work with eliom's implementation (found in src/client/eliom_client.js).
The diff seams to come from this commit 87f958a.

The two implementations should be merged into js_of_ocaml.
we could add an option to js_of_ocaml compiler to link against weak.js as well.
we have to install weak.js.

Bigarray support

I see that JavaScript's typed array have now been bound to. Are there any plan to support bigarrays by implementing them on top of typed arrays ?

interface file 'Xxx' not found

If a .cmi file starts with a capital letter then it will not be found by js_of_ocaml.

I guess it's a bit unusual but Camlp4 does capitalize it's interface files. The ocaml toploop will search for interface files with both filenames.

The following change to parse_bytecode.ml seems to fix the problem.

          Tbl.iter
            (fun id num ->
               if id.Ident.flags = 1 then begin
                 let name = String.uncapitalize id.Ident.name ^ ".cmi" in
                 let file =
                   try
                     Util.find_in_paths paths name
                   with Not_found -> begin
                     let name = String.capitalize id.Ident.name ^ ".cmi" in
                     try
                       Util.find_in_paths paths name
                     with Not_found ->
                      Format.eprintf "%s: interface file '%s' not found@."
                        Sys.argv.(0) name;
                     exit 1
                   end
                 in
                 let s = Util.read_file file in
                 fs := (Pc (IString name),Pc (IString s)) :: !fs
               end) symb.num_tbl;

Improve source map generation

We should propagate more debugging information during the compilation process. In particular, there is currently no information attached to variable declarations.

The mapping is not very precise at the moment: a piece of code without debugging information will be mapped to the last piece of code with debugging information above.

Improve trampoline optimisation

Possible improvements:

  • Quite often, trampolines are added when there is in fact no mutually recursive tail-calls (because a let rec was used when it was not in fact necessary). This could be improved by having Generate.group_closures perform a topological sort of the functions.
  • Some wrappers are unused. We could detect that by counting how many times the corresponding function is called in tail position.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.