Skip to content

[wasm] Option to implement OCaml strings with JavaScript strings #1772

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 27 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
f6a077a
Wasm_of_ocaml: support JavaScript strings in prelude code
vouillon Dec 17, 2024
aa61a26
Flag use-js-string default to false for wasm_of_ocaml
vouillon Dec 18, 2024
aa6dca4
CI: use node v8 canary
vouillon Dec 17, 2024
b11b902
Wat file preprocessor: support use-js-string
vouillon Dec 17, 2024
89f61e0
Wasm_of_ocaml: implement use-js-string flag
vouillon Dec 16, 2024
606f565
Test: enable JS string
vouillon Dec 19, 2024
135391a
Revert "Flag use-js-string default to false for wasm_of_ocaml"
vouillon Mar 21, 2025
9017e1b
testing
OlivierNicole Jun 3, 2025
5b4adeb
fixes after rebase
OlivierNicole Jun 12, 2025
02da6b7
CR: fixes
vouillon Jun 13, 2025
d3f89c6
fix
OlivierNicole Jun 13, 2025
92acdca
CR: Fixes
vouillon Jun 13, 2025
d7ead8a
Fixes and pin packages that require adaptations
OlivierNicole Jun 18, 2025
0b992c2
CR: Fixes
OlivierNicole Jun 18, 2025
0a8712d
Re-enable benchmarks and promote test
OlivierNicole Jun 18, 2025
204becd
Fix CI
OlivierNicole Jun 19, 2025
7596764
FIX: Temporarily disable CAMLboy benchmark
OlivierNicole Jun 20, 2025
85067fc
Fix error in rebase
OlivierNicole Jul 1, 2025
29ca97d
[TMP] Reinstate caml_utf16_of_utf8 and its inverse
OlivierNicole Jul 2, 2025
2c1b2ac
Improve error reporting in benchmark-ocamlc/
OlivierNicole Jul 2, 2025
e32d048
[TMP] Re-enable CAMLboy and disable buggy PRT benchmark
OlivierNicole Jul 3, 2025
d543c05
Fix CAMLboy
OlivierNicole Jul 3, 2025
cddd2f0
Fix caml_hash_mix_string/bytes
OlivierNicole Jul 4, 2025
3d348e4
Re-enable partial_render_table bench
OlivierNicole Jul 4, 2025
0e9d3a6
Fix...
OlivierNicole Jul 4, 2025
bf364ee
Integrate bin_prot benchmark into JS packages pins
OlivierNicole Jul 9, 2025
876980a
Remove comment in Makefile
OlivierNicole Jul 9, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/wasm_of_ocaml.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ jobs:
- name: Set-up Node.js
uses: actions/setup-node@v4
with:
node-version: latest
node-version: 'v24.0.0-v8-canary202412116884e26428'

- name: Set-up OCaml ${{ matrix.ocaml-compiler }}
uses: ocaml/setup-ocaml@v3
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/benchmark-camlboy/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

export NAME=Camlboy

SHELL=/bin/bash -o pipefail
SHELL=/usr/bin/env bash -o pipefail

DIR=CAMLBOY
SCRIPT=$(DIR)/_build/default/bin/web/bench_node.bc
Expand Down
4 changes: 2 additions & 2 deletions benchmarks/benchmark-fiat-crypto/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

export NAME=Fiat-Crypto

SHELL=/bin/bash -o pipefail
SHELL=/usr/bin/env bash -o pipefail

bench:
@date -u +"%FT%TZ - $(NAME): starting"
Expand All @@ -11,7 +11,7 @@ bench:
@date -u +"%FT%TZ - $(NAME): done"

perform: bedrock2_fiat_crypto.byte
/usr/bin/time -f "%E %R" $(COMPILER) --debug times --source-map $(EXTRA_ARGS) $< -o out.js 2>&1 | \
env time -f "%E %R" $(COMPILER) --debug times --source-map $(EXTRA_ARGS) $< -o out.js 2>&1 | \
ocaml -I +str str.cma ../utils/compilation_metrics.ml $(COMPILER) $(NAME) out.js | \
sh ../utils/aggregate.sh $(KIND)

Expand Down
8 changes: 5 additions & 3 deletions benchmarks/benchmark-ocamlc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

export NAME=Ocamlc

SHELL=/bin/bash -o pipefail
SHELL=/usr/bin/env bash -o pipefail

bench:
@date -u +"%FT%TZ - $(NAME): starting"
Expand All @@ -14,9 +14,11 @@ bench:
ARGS=ml/*.ml ml/*.ml ml/*.ml ml/*.ml ml/*.ml ml/*.ml ml/*.ml ml/*.ml

perform:
/usr/bin/time -f "%E %R" $(COMPILER) --debug times --opt 2 --pretty `which ocamlc.byte` -o $(SCRIPT) 2>&1 | \
env time -f "%E %R" $(COMPILER) --debug times --opt 2 --pretty `which ocamlc.byte` -o $(SCRIPT) 2>&1 | \
tee /dev/stderr | \
ocaml -I +str str.cma ../utils/compilation_metrics.ml $(COMPILER) $(NAME) $(SCRIPT) | \
sh ../utils/aggregate.sh $(KIND)
/usr/bin/time -f '{"compiler": "$(COMPILER)", "time":"%E"}' node $(SCRIPT) -c $(ARGS) 2>&1 | \
env time -f '{"compiler": "$(COMPILER)", "time":"%E"}' node $(SCRIPT) -c $(ARGS) 2>&1 | \
tee /dev/stderr | \
sh ../utils/format_metrics.sh exec | \
sh ../utils/aggregate.sh $(KIND)
10 changes: 5 additions & 5 deletions benchmarks/benchmark-others/bigarrays/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@
export NAME=Others
export SUBNAME=bigarrays

SHELL=/bin/bash -o pipefail
SHELL=/usr/bin/env bash -o pipefail

bench:
@date -u +"%FT%TZ - $(NAME)/$(SUBNAME): starting"
ocamlc bench.ml -o bench
$(MAKE) perform COMPILER=js_of_ocaml SCRIPT=bench.js KIND=js
$(MAKE) perform COMPILER=wasm_of_ocaml SCRIPT=bench.wasm.js KIND=wasm
#$(MAKE) perform COMPILER=js_of_ocaml FLAGS= SCRIPT=bench.js KIND=js
$(MAKE) perform COMPILER=wasm_of_ocaml FLAGS="--enable use-js-string" SCRIPT=bench.wasm.js KIND=wasm
@date -u +"%FT%TZ - $(NAME)/$(SUBNAME): done"

perform:
$(COMPILER) --opt 2 --pretty bench -o $(SCRIPT)
/usr/bin/time -f '{"compiler": "$(COMPILER)", "time":"%E"}' node $(SCRIPT) 2>&1 | \
$(COMPILER) $(FLAGS) --opt 2 --pretty bench -o $(SCRIPT)
env time -f '{"compiler": "$(COMPILER)", "time":"%E"}' node $(SCRIPT) 2>&1 | \
sh ../../utils/format_metrics.sh exec | \
sh ../../utils/aggregate.sh $(KIND)
15 changes: 9 additions & 6 deletions benchmarks/benchmark-others/bin_prot/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,21 @@
export NAME=Others
export SUBNAME=bin_prot

SHELL=/bin/bash -o pipefail
SHELL=/usr/bin/env bash -o pipefail

bench:
@date -u +"%FT%TZ - $(NAME)/$(SUBNAME): starting"
dune build --profile release --root .
node _build/default/bench.bc.js 400000
$(MAKE) perform COMPILER=js_of_ocaml SCRIPT=_build/default/bench.bc.js KIND=js
$(MAKE) perform COMPILER=wasm_of_ocaml SCRIPT=_build/default/bench.bc.wasm.js KIND=wasm
mkdir -p ../../../../janestreet/bench/bin_prot/
cp -f dune bench.ml ../../../../janestreet/bench/bin_prot/
cd ../../../../janestreet/bench/bin_prot && dune build --root ../.. --profile release bench/bin_prot/bench.bc.js bench/bin_prot/bench.bc.wasm.js
cp -rf ../../../../janestreet/_build/default/bench/bin_prot/bench.bc* .
node bench.bc.js 400000
$(MAKE) perform COMPILER=js_of_ocaml SCRIPT=bench.bc.js KIND=js
$(MAKE) perform COMPILER=wasm_of_ocaml SCRIPT=bench.bc.wasm.js KIND=wasm
@date -u +"%FT%TZ - $(NAME)/$(SUBNAME): done"

perform:
/usr/bin/time -f '{"compiler": "$(COMPILER)", "time":"%E"}' node $(SCRIPT) 2>&1 1> /dev/null | \
env time -f '{"compiler": "$(COMPILER)", "time":"%E"}' node $(SCRIPT) 2>&1 1> /dev/null | \
tee /dev/stderr | \
sh ../../utils/format_metrics.sh exec | \
sh ../../utils/aggregate.sh $(KIND)
3 changes: 2 additions & 1 deletion benchmarks/benchmark-others/bin_prot/dune
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
(names bench)
(modes js wasm)
(js_of_ocaml
(enabled_if true)
(flags --opt 2))
(wasm_of_ocaml
(flags --opt 2))
(flags --opt 2 --enable use-js-string))
(preprocess
(pps ppx_bin_prot))
(libraries unix))
4 changes: 2 additions & 2 deletions benchmarks/benchmark-others/lexifi-g2pp/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
export NAME=Others
export SUBNAME=lexifi-g2pp

SHELL=/bin/bash -o pipefail
SHELL=/usr/bin/env bash -o pipefail

bench:
@date -u +"%FT%TZ - $(NAME)/$(SUBNAME): starting"
Expand All @@ -13,6 +13,6 @@ bench:
@date -u +"%FT%TZ - $(NAME)/$(SUBNAME): done"

perform:
/usr/bin/time -f '{"compiler": "$(COMPILER)", "time":"%E"}' node $(SCRIPT) 2>&1 1> /dev/null | \
env time -f '{"compiler": "$(COMPILER)", "time":"%E"}' node $(SCRIPT) 2>&1 1> /dev/null | \
sh ../../utils/format_metrics.sh exec | \
sh ../../utils/aggregate.sh $(KIND)
4 changes: 2 additions & 2 deletions benchmarks/benchmark-partial-render-table/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

export NAME=Partial Render Table

SHELL=/bin/bash -o pipefail
SHELL=/usr/bin/env bash -o pipefail

bench:
@date -u +"%FT%TZ - $(NAME): starting"
Expand All @@ -14,7 +14,7 @@ bench:
@date -u +"%FT%TZ - $(NAME): done"

perform:
/usr/bin/time -f "%E %R" $(COMPILER) --debug times --opt 2 --pretty main.bc-for-jsoo -o out.js 2>&1 | \
env time -f "%E %R" $(COMPILER) --debug times --opt 2 --pretty --enable use-js-string main.bc-for-jsoo -o out.js 2>&1 | \
tee /dev/stderr | \
ocaml -I +str str.cma ../utils/compilation_metrics.ml $(COMPILER) "$(NAME)" out.js | \
sh ../utils/aggregate.sh $(KIND)
Expand Down
21 changes: 14 additions & 7 deletions compiler/bin-wasm_of_ocaml/compile.ml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ let preprocessor_variables () =
| `Disabled | `Jspi -> "jspi"
| `Cps -> "cps"
| `Double_translation -> assert false) )
; "use-js-string", Wat_preprocess.Bool (Config.Flag.use_js_string ())
]

let with_runtime_files ~runtime_wasm_files f =
Expand Down Expand Up @@ -126,6 +127,7 @@ let build_runtime ~runtime_file =
[ "bindings"
; "Math"
; "js"
; "str"
; "wasm:js-string"
; "wasm:text-encoder"
; "wasm:text-decoder"
Expand Down Expand Up @@ -257,25 +259,25 @@ let generate_prelude ~out_file =
Driver.optimize_for_wasm ~profile ~shapes:false code
in
let context = Generate.start () in
let _ =
let _, generated_js =
Generate.f
~context
~unit_name:(Some "prelude")
~unit_name:(Some "wasmoo_prelude")
~live_vars:variable_uses
~in_cps
~deadcode_sentinal
~global_flow_data
program
in
Generate.wasm_output ch ~opt_source_map_file:None ~context;
uinfo.provides
uinfo.provides, generated_js

let build_prelude z =
Fs.with_intermediate_file (Filename.temp_file "prelude" ".wasm")
@@ fun prelude_file ->
let predefined_exceptions = generate_prelude ~out_file:prelude_file in
let info = generate_prelude ~out_file:prelude_file in
Zip.add_file z ~name:"prelude.wasm" ~file:prelude_file;
predefined_exceptions
info

let build_js_runtime ~primitives ?runtime_arguments () =
let always_required_js, primitives =
Expand Down Expand Up @@ -483,12 +485,17 @@ let run
let z = Zip.open_out tmp_output_file in
Zip.add_file z ~name:"runtime.wasm" ~file:tmp_wasm_file;
Zip.add_entry z ~name:"runtime.js" ~contents:js_runtime;
let predefined_exceptions = build_prelude z in
let predefined_exceptions, fragments = build_prelude z in
Link.add_info
z
~predefined_exceptions
~build_info:(Build_info.create `Runtime)
~unit_data:[]
~unit_data:
[ { Link.unit_name = "wasmoo_prelude"
; unit_info = Unit_info.empty
; fragments
}
]
();
Zip.close_out z)
else
Expand Down
7 changes: 6 additions & 1 deletion compiler/bin-wasm_of_ocaml/gen/gen.ml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,12 @@ let check_js_file fname =

let default_flags = []

let interesting_runtimes = [ [ "effects", `S "jspi" ]; [ "effects", `S "cps" ] ]
let interesting_runtimes =
[ [ "effects", `S "jspi"; "use-js-string", `B false ]
; [ "effects", `S "cps"; "use-js-string", `B false ]
; [ "effects", `S "jspi"; "use-js-string", `B true ]
; [ "effects", `S "cps"; "use-js-string", `B true ]
]

let name_runtime standard l =
let flags =
Expand Down
9 changes: 8 additions & 1 deletion compiler/bin-wasm_of_ocaml/link_wasm.ml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,14 @@ let options =
in
let build_t input_modules output_file variables allowed_imports common opt merge =
let allowed_imports =
if List.is_empty allowed_imports then None else Some (List.concat allowed_imports)
match allowed_imports with
| [] -> Some [ "str" ]
| _ :: _ as l ->
let l = List.concat l in
if List.mem ~eq:String.equal "str" l then
Some l
else
Some ("str" :: l)
in
`Ok
{ input_modules
Expand Down
Loading
Loading