Skip to content

Commit d94735b

Browse files
committed
WIP
1 parent c19b46d commit d94735b

28 files changed

+962
-561
lines changed

doc/dev/manual/bindings.wiki

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,55 @@ end
7979
=== Method name mangling
8080

8181
OCaml method names are transformed to JavaScript names using underscore
82-
conventions. This enables binding to capitalized names (use {{{_Foo}}} for
83-
{{{Foo}}}) and overloaded methods (use {{{foo_int}}} and {{{foo_string}}} for
84-
the same {{{foo}}} method).
82+
conventions. When accessing a field of an object, the name given in OCaml
83+
is transformed by:
84+
1. Removing a leading underscore (if present)
85+
2. Removing all characters starting from the last underscore
86+
87+
This enables:
88+
- **Capitalized names**: Use {{{_Foo}}} to refer to JavaScript's {{{Foo}}}
89+
- **Reserved words**: Use {{{_type}}} to refer to JavaScript's {{{type}}}
90+
- **Method overloading**: Use {{{foo_int}}} and {{{foo_string}}} for the same {{{foo}}} method
91+
92+
==== Examples
93+
94+
<<code language="ocaml"|
95+
class type canvas = object
96+
(* All three refer to the same JS method: drawImage *)
97+
method drawImage :
98+
imageElement Js.t -> int -> int -> unit Js.meth
99+
method drawImage_withSize :
100+
imageElement Js.t -> int -> int -> int -> int -> unit Js.meth
101+
method drawImage_fromCanvas :
102+
canvasElement Js.t -> int -> int -> unit Js.meth
103+
end
104+
>>
105+
106+
==== Full naming rules
107+
108+
<<code language="ocaml"|
109+
class type example = object
110+
(* All of these refer to JS field [meth] *)
111+
method meth : ..
112+
method meth_int : ..
113+
method _meth_ : ..
114+
method _meth_aa : ..
85115

86-
See <<a_manual chapter="library"|the library documentation>> for the full
87-
naming rules and examples.
116+
(* All of these refer to JS field [meth_a] *)
117+
method meth_a_int : ..
118+
method _meth_a_ : ..
119+
method _meth_a_b : ..
120+
121+
(* Refer to [Meth] (capitalized) *)
122+
method _Meth : ..
123+
124+
(* Refer to [_meth] (leading underscore in JS) *)
125+
method __meth : ..
126+
127+
(* Refer to [_] *)
128+
method __ : ..
129+
end
130+
>>
88131

89132
=== Binding constants from a class
90133

doc/dev/manual/build-toplevel.wiki

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,40 @@
1-
= How to build a toplevel =
1+
= Building a toplevel
22

33
First, initialize the toplevel using {{{Js_of_ocaml_toplevel.JsooTop.initialize}}}.
44

5-
Then, build your bytecode program with debug enabled (**-g**) and linkall (**-linkall**). You should obviously link in all the libraries you want accessible in the final toplevel.
5+
Then, build your bytecode program with debug enabled ({{{-g}}}) and linkall ({{{-linkall}}}). Link in all the libraries you want accessible in the final toplevel.
66

7-
Finally, compile your toplevel to JavaScript passing the {{{--toplevel}}} flags to the js_of_ocaml compiler.
7+
Finally, compile your toplevel to JavaScript passing the {{{--toplevel}}} flag to the js_of_ocaml compiler.
88

99
If you want to limit the set of modules available in the toplevel, you can explicitly pass a list of compilation units that should be accessible using the {{{--export FILE}}} flag.
10-
**FILE** must contain names of compilation unit to export - one per line. The **jsoo_listunits** tool, provided by the **js_of_ocaml-toplevel** opam package, can be used to generate this list
11-
from a set of findlib libraries.
10+
{{{FILE}}} must contain names of compilation units to export, one per line. The {{{jsoo_listunits}}} tool, provided by the {{{js_of_ocaml-toplevel}}} opam package, can be used to generate this list from a set of findlib libraries.
1211

13-
For example, the following command will create a file **FILE** containing all compilation unit names provided by the findlib libraries **stdlib** and **str**.
12+
For example, the following command will create a file containing all compilation unit names provided by the findlib libraries {{{stdlib}}} and {{{str}}}:
1413
{{{
15-
jsoo_listunits -o FILE stdlib str
14+
jsoo_listunits -o units.txt stdlib str
1615
}}}
1716

17+
= Using the Dynlink library
1818

19-
Note that toplevels currently cannot be built using separate compilation.
19+
OCaml supports dynlink of bytecode files using the {{{dynlink}}} library. To use it when compiled to JavaScript:
2020

21+
1. Link {{{js_of_ocaml-compiler.dynlink}}} to initialize dynlink support (initialization is automatic via side-effect)
22+
2. Build your bytecode program with debug enabled ({{{-g}}}) and linkall ({{{-linkall}}})
23+
3. Compile your program to JavaScript passing the {{{--dynlink}}} flag
2124

22-
= How to build a program using the **Dynlink** library =
25+
== Example
2326

24-
OCaml supports dynlink of bytecode files using the **dynlink** library. In order to work when compiled to JavaScript, one needs to follow the following steps:
25-
26-
First, make sure to link **js_of_ocaml-compiler.dynlink** to initialize the support for dynlink (the initialization is done automatically by side-effect).
27-
28-
Then, build your bytecode program with debug enabled (**-g**) and linkall (**-linkall**).
29-
30-
Finally, compile your program to JavaScript passing the {{{--dynlink}}} flags to the js_of_ocaml compiler.
31-
32-
Here is an example showing how to compile and use a program using Dynlink:
3327
{{{
34-
# cat main.ml
35-
let () = Dynlink.loadfile "./plugin.cmo"
28+
# main.ml
29+
let () = Dynlink.loadfile "./plugin.cmo"
3630

37-
# Compiling main program
38-
ocamlfind ocamlc -linkpkg -package dynlink -package js_of_ocaml-compiler.dynlink main.ml -o main.bc
39-
js_of_ocaml main.bc --dynlink
31+
# Compiling main program
32+
ocamlfind ocamlc -linkpkg -package dynlink -package js_of_ocaml-compiler.dynlink main.ml -o main.bc
33+
js_of_ocaml main.bc --dynlink
4034

41-
# Compiling plugin
42-
ocamlfind ocamlc -c plugin.ml
35+
# Compiling plugin
36+
ocamlfind ocamlc -c plugin.ml
4337

44-
# Test
45-
node ./main.js
38+
# Test
39+
node ./main.js
4640
}}}

doc/dev/manual/debug.wiki

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,11 @@ See <<a_manual chapter="errors"|Error handling>> for details on attaching
1717
JavaScript stack traces to OCaml exceptions using {{{OCAMLRUNPARAM=b=1}}} or
1818
the {{{--enable with-js-error}}} compiler flag.
1919

20-
== Breakpoint
21-
One can set breakpoints using developers tools (see https://developer.chrome.com/devtools/docs/javascript-debugging).
22-
Alternatively, one can set breakpoints programmatically by calling {{{Js.debugger ()}}}. Note that
23-
browsers will only stop at breakpoints when developers tools are in use.
20+
== Breakpoints
21+
22+
Set breakpoints using browser developer tools (see https://developer.chrome.com/docs/devtools/javascript).
23+
Alternatively, set breakpoints programmatically by calling {{{Js.debugger ()}}}. Note that
24+
browsers only stop at breakpoints when developer tools are open.
2425

2526
== Source map
2627
Source map is used to map the generated JavaScript code to original sources.
@@ -30,4 +31,4 @@ step through the code, and inspect variables directly in OCaml sources.
3031
== About Chrome DevTools
3132
Useful settings for Chrome DevTools:
3233
* Display variable values inline while debugging
33-
* Resolve variable names (hidden DevTools Experiments, see http://islegend.com/development/how-to-enable-devtools-experiments-within-google-chrome)
34+
* Resolve variable names (hidden DevTools Experiments, see https://developer.chrome.com/docs/devtools/settings/experiments)

doc/dev/manual/effects.wiki

Lines changed: 46 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,40 @@
1-
== Effect handlers ==
1+
= Effect handlers
22

3-
Js_of_ocaml supports effect handlers with the {{{--enable=effects}}}
4-
flag. This is based on partially transforming the program to
5-
continuation-passing style.
6-
As a consequence, [[tailcall|tail calls]] could be fully optimized (if CPS transformed).
7-
This is not the default for now since the generated code can be slower,
8-
larger and less readable.
9-
The transformation is based on an analysis to detect parts of the code that cannot involve effects and keep it in direct style.
10-
The analysis is especially effective on monomorphic code. It is not so effective when higher-order functions are heavily used ({{{Lwt}}}, {{{Async}}}, {{{incremental}}}).
11-
We hope to improve on this by trying alternative compilation
12-
strategies.
3+
Js_of_ocaml supports effect handlers with the {{{--effects=cps}}} flag.
4+
This is based on partially transforming the program to continuation-passing style.
5+
As a consequence, <<a_manual chapter="tailcall"|tail calls>> can be fully optimized
6+
(when CPS transformed).
137

14-
An alternative CPS transform is provided under the {{{--effects=double-translation}}} option. It keeps a direct-style version of the transformed functions in addition to the CPS version. The choice of running the CPS version is delayed to run time. Since CPS code is usually slower, this can avoid degradations. In addition, one can ensure that some code is run in direct style by using {{{Jsoo_runtime.Effect.assume_no_perform}}}.
8+
This is not the default because the generated code can be slower, larger, and
9+
less readable. The transformation uses an analysis to detect parts of the code
10+
that cannot involve effects and keeps them in direct style. The analysis is
11+
especially effective on monomorphic code but less effective when higher-order
12+
functions are heavily used ({{{Lwt}}}, {{{Async}}}, {{{Incremental}}}).
1513

16-
=== Dune integration ===
14+
== Double translation mode
1715

18-
Dune is aware of the {{{--enable effects}}} option. So, you can just add it to the Js_of_ocaml flags {{{(js_of_ocaml (flags ...))}}} wherever you want to use it.
16+
An alternative CPS transform is provided with {{{--effects=double-translation}}}.
17+
It keeps a direct-style version of the transformed functions in addition to the
18+
CPS version. The choice of running the CPS version is delayed to run time.
1919

20-
We're still working on dune support for the {{{--effects}}} option. For now, here are two possible setups.
20+
Since CPS code is usually slower, this can avoid performance degradations. You can
21+
also ensure that some code runs in direct style using
22+
{{{Jsoo_runtime.Effect.assume_no_perform}}}.
2123

22-
=== Whole dune workspace setup ===
24+
== Dune integration
25+
26+
Dune is aware of the {{{--effects}}} option. You can add it to the
27+
js_of_ocaml flags wherever you want to use it:
28+
29+
{{{
30+
(js_of_ocaml (flags ...))
31+
}}}
32+
33+
=== Whole workspace setup
34+
35+
To enable effects for the entire workspace, add this to a {{{dune}}} or
36+
{{{dune-workspace}}} file at the root:
2337

24-
Put the following in a {{{dune}}} (or {{{dune-workspace}}}) file at the root of the workspace
2538
{{{
2639
(env
2740
(_
@@ -30,25 +43,31 @@ Put the following in a {{{dune}}} (or {{{dune-workspace}}}) file at the root of
3043
(build_runtime_flags (:standard --effects=double-translation)))))
3144
}}}
3245

33-
With this setup, one can use both separate and whole program compilation.
46+
This setup supports both separate and whole program compilation.
3447

48+
=== Per-executable setup
3549

36-
=== Sub directory setup ===
50+
To enable effect handlers for specific binaries only, you need to use whole
51+
program compilation:
3752

38-
If you want to enable effect handlers for some binaries only, you'll
39-
have to give up separate compilation for now using:
4053
{{{
4154
(executable
42-
(name main)
43-
(js_of_ocaml
44-
(compilation_mode whole_program)
45-
(flags (:standard --effects=double-translation)))
46-
)
55+
(name main)
56+
(js_of_ocaml
57+
(compilation_mode whole_program)
58+
(flags (:standard --effects=double-translation))))
4759
}}}
4860

49-
Trying to use separate compilation would result in an error while attempting to link the final js file.
61+
Using separate compilation with effects enabled only for some executables will
62+
result in a linking error:
63+
5064
{{{
5165
js_of_ocaml: Error: Incompatible build info detected while linking.
5266
- test6.bc.runtime.js: effects=disabled
5367
- .cmphash.eobjs/byte/dune__exe.cmo.js: effects=double-translation
5468
}}}
69+
70+
== See also
71+
72+
* <<a_manual chapter="options"|Command line options>> - Full list of {{{--effects}}} modes
73+
* <<a_manual chapter="tailcall"|Tailcall optimization>> - How tail calls interact with effects

doc/dev/manual/files/boulderdash/boulderdash.bc.js

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

doc/dev/manual/files/cubes/cubes.bc.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

doc/dev/manual/files/graph_viewer/viewer_js.bc.js

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

doc/dev/manual/files/hyperbolic/hypertree.bc.js

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

doc/dev/manual/files/minesweeper/main.bc.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

doc/dev/manual/files/planet/planet.bc.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)