Skip to content

Commit 32fb083

Browse files
committed
WASI runtime
1 parent 00f3421 commit 32fb083

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+4466
-227
lines changed

compiler/bin-wasm_of_ocaml/cmd_arg.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ let normalize_effects (effects : [ `Disabled | `Cps | `Jspi ] option) common :
4646
[--effects cps] *)
4747
if List.mem ~eq:String.equal "effects" common.Jsoo_cmdline.Arg.optim.enable
4848
then `Cps
49+
else if List.mem ~eq:String.equal "wasi" common.Jsoo_cmdline.Arg.optim.enable
50+
then `Disabled
4951
else `Jspi
5052
| Some ((`Disabled | `Cps | `Jspi) as e) -> e
5153

compiler/bin-wasm_of_ocaml/compile.ml

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,11 @@ let preprocessor_variables () =
8181
[ ( "effects"
8282
, Wat_preprocess.String
8383
(match Config.effects () with
84-
| `Disabled | `Jspi -> "jspi"
84+
| `Disabled -> "disabled"
85+
| `Jspi -> "jspi"
8586
| `Cps -> "cps"
8687
| `Double_translation -> assert false) )
88+
; "wasi", Wat_preprocess.Bool (Config.Flag.wasi ())
8789
]
8890

8991
let with_runtime_files ~runtime_wasm_files f =
@@ -115,21 +117,26 @@ let build_runtime ~runtime_file =
115117
; file = module_name ^ ".wat"
116118
; source = Contents contents
117119
})
118-
Runtime_files.wat_files
120+
(if Config.Flag.wasi ()
121+
then ("libc", Runtime_files.wasi_libc) :: Runtime_files.wat_files
122+
else Runtime_files.wat_files)
119123
in
120124
Runtime.build
121125
~link_options:[ "-g" ]
122126
~opt_options:[ "-g"; "-O2" ]
123127
~variables
124128
~allowed_imports:
125129
(Some
126-
[ "bindings"
127-
; "Math"
128-
; "js"
129-
; "wasm:js-string"
130-
; "wasm:text-encoder"
131-
; "wasm:text-decoder"
132-
])
130+
(if Config.Flag.wasi ()
131+
then [ "wasi_snapshot_preview1"; "OCaml" ]
132+
else
133+
[ "bindings"
134+
; "Math"
135+
; "js"
136+
; "wasm:js-string"
137+
; "wasm:text-encoder"
138+
; "wasm:text-decoder"
139+
]))
133140
~inputs
134141
~output_file:runtime_file
135142

@@ -185,7 +192,10 @@ let link_and_optimize
185192
let t = Timer.make ~get_time:Unix.time () in
186193
let primitives =
187194
Binaryen.dead_code_elimination
188-
~dependencies:Runtime_files.dependencies
195+
~dependencies:
196+
(if Config.Flag.wasi ()
197+
then Runtime_files.wasi_dependencies
198+
else Runtime_files.dependencies)
189199
~opt_input_sourcemap:opt_temp_sourcemap
190200
~opt_output_sourcemap:opt_temp_sourcemap'
191201
~input_file:temp_file
@@ -302,7 +312,13 @@ let build_js_runtime ~primitives ?runtime_arguments () =
302312
| _ -> assert false
303313
in
304314
let init_fun =
305-
match Parse_js.parse (Parse_js.Lexer.of_string Runtime_files.js_runtime) with
315+
match
316+
Parse_js.parse
317+
(Parse_js.Lexer.of_string
318+
(if Config.Flag.wasi ()
319+
then Runtime_files.js_wasi_launcher
320+
else Runtime_files.js_launcher))
321+
with
306322
| [ (Expression_statement f, _) ] -> f
307323
| _ -> assert false
308324
in
@@ -600,9 +616,12 @@ let run
600616
if binaryen_times ()
601617
then Format.eprintf " link_and_optimize: %a@." Timer.print t2;
602618
let wasm_name =
603-
Printf.sprintf
604-
"code-%s"
605-
(String.sub (Digest.to_hex (Digest.file tmp_wasm_file)) ~pos:0 ~len:20)
619+
if Config.Flag.wasi ()
620+
then "code"
621+
else
622+
Printf.sprintf
623+
"code-%s"
624+
(String.sub (Digest.to_hex (Digest.file tmp_wasm_file)) ~pos:0 ~len:20)
606625
in
607626
let tmp_wasm_file' = Filename.concat tmp_dir (wasm_name ^ ".wasm") in
608627
Sys.rename tmp_wasm_file tmp_wasm_file';

compiler/bin-wasm_of_ocaml/dune

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
gen/gen.exe
2929
../../runtime/wasm/runtime.js
3030
../../runtime/wasm/deps.json
31+
../../runtime/wasm/runtime-wasi.js
32+
../../runtime/wasm/deps-wasi.json
33+
../../runtime/wasm/libc.wasm
3134
(glob_files ../../runtime/wasm/*.wat)
3235
(glob_files ../../runtime/wasm/runtime-*.wasm))
3336
(action

compiler/bin-wasm_of_ocaml/gen/gen.ml

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,26 @@ let check_js_file fname =
7777

7878
let default_flags = []
7979

80-
let interesting_runtimes = [ [ "effects", `S "jspi" ]; [ "effects", `S "cps" ] ]
80+
let interesting_runtimes =
81+
[ [ "effects", `S "jspi"; "wasi", `B false ]
82+
; [ "effects", `S "cps"; "wasi", `B false ]
83+
; [ "effects", `S "disabled"; "wasi", `B true ]
84+
; [ "effects", `S "cps"; "wasi", `B true ]
85+
]
86+
87+
let defaults = [ "effects", "disabled" ]
8188

8289
let name_runtime standard l =
8390
let flags =
8491
List.filter_map l ~f:(fun (k, v) ->
8592
match v with
86-
| `S s -> Some s
93+
| `S s ->
94+
if
95+
List.exists
96+
~f:(fun (k', s') -> String.equal k k' && String.equal s s')
97+
defaults
98+
then None
99+
else Some s
87100
| `B b -> if b then Some k else None)
88101
in
89102
String.concat ~sep:"-" ("runtime" :: (if standard then [ "standard" ] else flags))
@@ -110,25 +123,31 @@ let print_flags f flags =
110123

111124
let () =
112125
let () = set_binary_mode_out stdout true in
113-
let js_runtime, deps, wat_files, runtimes =
126+
let js_launcher, deps, js_wasi_launcher, wasi_deps, wasi_libc, wat_files, runtimes =
114127
match Array.to_list Sys.argv with
115-
| _ :: js_runtime :: deps :: rest ->
116-
assert (Filename.check_suffix js_runtime ".js");
128+
| _ :: js_launcher :: deps :: js_wasi_launcher :: wasi_deps :: wasi_libc :: rest ->
129+
assert (Filename.check_suffix js_launcher ".js");
130+
assert (Filename.check_suffix js_wasi_launcher ".js");
117131
assert (Filename.check_suffix deps ".json");
132+
assert (Filename.check_suffix wasi_deps ".json");
118133
let wat_files, rest =
119134
List.partition rest ~f:(fun f -> Filename.check_suffix f ".wat")
120135
in
121136
let wasm_files, rest =
122137
List.partition rest ~f:(fun f -> Filename.check_suffix f ".wasm")
123138
in
124139
assert (List.is_empty rest);
125-
js_runtime, deps, wat_files, wasm_files
140+
js_launcher, deps, js_wasi_launcher, wasi_deps, wasi_libc, wat_files, wasm_files
126141
| _ -> assert false
127142
in
128-
check_js_file js_runtime;
143+
check_js_file js_launcher;
144+
check_js_file js_wasi_launcher;
129145
Format.printf "open Wasm_of_ocaml_compiler@.";
130-
Format.printf "let js_runtime = {|\n%s\n|}@." (Fs.read_file js_runtime);
146+
Format.printf "let js_launcher = {|\n%s\n|}@." (Fs.read_file js_launcher);
131147
Format.printf "let dependencies = {|\n%s\n|}@." (Fs.read_file deps);
148+
Format.printf "let js_wasi_launcher = {|\n%s\n|}@." (Fs.read_file js_wasi_launcher);
149+
Format.printf "let wasi_dependencies = {|\n%s\n|}@." (Fs.read_file wasi_deps);
150+
Format.printf "let wasi_libc = %S@." (Fs.read_file wasi_libc);
132151
Format.printf
133152
"let wat_files = [%a]@."
134153
(Format.pp_print_list (fun f file ->

compiler/lib-wasm/binaryen.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ let common_options () =
3838
; "--enable-bulk-memory"
3939
; "--enable-nontrapping-float-to-int"
4040
; "--enable-strings"
41+
; "--enable-multimemory" (* To keep wasm-merge happy *)
4142
]
4243
in
4344
let l = if Config.Flag.pretty () then "-g" :: l else l in

compiler/lib-wasm/gc_target.ml

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,7 +1296,12 @@ module Math = struct
12961296
{ W.params = List.init ~len:n ~f:(fun _ : W.value_type -> F64); result = [ F64 ] }
12971297

12981298
let unary name x =
1299-
let* f = register_import ~import_module:"Math" ~name (Fun (float_func_type 1)) in
1299+
let* f =
1300+
register_import
1301+
~import_module:(if Config.Flag.wasi () then "env" else "Math")
1302+
~name
1303+
(Fun (float_func_type 1))
1304+
in
13001305
let* x = x in
13011306
return (W.Call (f, [ x ]))
13021307

@@ -1339,7 +1344,12 @@ module Math = struct
13391344
let log10 f = unary "log10" f
13401345

13411346
let binary name x y =
1342-
let* f = register_import ~import_module:"Math" ~name (Fun (float_func_type 2)) in
1347+
let* f =
1348+
register_import
1349+
~import_module:(if Config.Flag.wasi () then "env" else "Math")
1350+
~name
1351+
(Fun (float_func_type 2))
1352+
in
13431353
let* x = x in
13441354
let* y = y in
13451355
return (W.Call (f, [ x; y ]))
@@ -1682,21 +1692,34 @@ let handle_exceptions ~result_typ ~fall_through ~context body x exn_handler =
16821692
x
16831693
(block_expr
16841694
{ params = []; result = [ Type.value ] }
1685-
(let* exn =
1686-
block_expr
1687-
{ params = []; result = [ externref ] }
1688-
(let* e =
1689-
try_expr
1690-
{ params = []; result = [ externref ] }
1691-
(body
1692-
~result_typ:[ externref ]
1693-
~fall_through:`Skip
1694-
~context:(`Skip :: `Skip :: `Catch :: context))
1695-
[ ocaml_tag, 1, Type.value; js_tag, 0, externref ]
1696-
in
1697-
instr (W.Push e))
1698-
in
1699-
instr (W.CallInstr (f, [ exn ]))))
1695+
(if Config.Flag.wasi ()
1696+
then
1697+
let* e =
1698+
try_expr
1699+
{ params = []; result = [ Type.value ] }
1700+
(body
1701+
~result_typ:[ Type.value ]
1702+
~fall_through:`Skip
1703+
~context:(`Skip :: `Catch :: context))
1704+
[ ocaml_tag, 0, Type.value ]
1705+
in
1706+
instr (W.Push e)
1707+
else
1708+
let* exn =
1709+
block_expr
1710+
{ params = []; result = [ externref ] }
1711+
(let* e =
1712+
try_expr
1713+
{ params = []; result = [ externref ] }
1714+
(body
1715+
~result_typ:[ externref ]
1716+
~fall_through:`Skip
1717+
~context:(`Skip :: `Skip :: `Catch :: context))
1718+
[ ocaml_tag, 1, Type.value; js_tag, 0, externref ]
1719+
in
1720+
instr (W.Push e))
1721+
in
1722+
instr (W.CallInstr (f, [ exn ]))))
17001723
in
17011724
let* () = no_event in
17021725
exn_handler ~result_typ ~fall_through ~context)

compiler/lib-wasm/generate.ml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ module Generate (Target : Target_sig.S) = struct
226226
(if negate then Arith.( <> ) else Arith.( = ))
227227
Arith.(transl_prim_arg ctx ~typ:(Int Unnormalized) x lsl const 1l)
228228
Arith.(transl_prim_arg ctx ~typ:(Int Unnormalized) y lsl const 1l)
229-
| Top, Top ->
229+
| Top, Top when not (Config.Flag.wasi ()) ->
230230
Value.js_eqeqeq
231231
~negate
232232
(transl_prim_arg ctx ~typ:Top x)
@@ -236,7 +236,9 @@ module Generate (Target : Target_sig.S) = struct
236236
(if negate then Value.phys_neq else Value.phys_eq)
237237
(transl_prim_arg ctx ~typ:Top x)
238238
(transl_prim_arg ctx ~typ:Top y)
239-
| (Int _ | Number _ | Tuple _), _ | _, (Int _ | Number _ | Tuple _) ->
239+
| (Int _ | Number _ | Tuple _), _
240+
| _, (Int _ | Number _ | Tuple _)
241+
| Top, Top (* when wasi is enabled *) ->
240242
(* Only Top may contain JavaScript values *)
241243
(if negate then Value.phys_neq else Value.phys_eq)
242244
(transl_prim_arg ctx ~typ:Top x)

compiler/lib/config.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ module Flag = struct
106106
let es6 = o ~name:"es6" ~default:false
107107

108108
let load_shapes_auto = o ~name:"load-shapes-auto" ~default:false
109+
110+
let wasi = o ~name:"wasi" ~default:false
109111
end
110112

111113
module Param = struct

compiler/lib/config.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ module Flag : sig
7676

7777
val load_shapes_auto : unit -> bool
7878

79+
val wasi : unit -> bool
80+
7981
val enable : string -> unit
8082

8183
val disable : string -> unit

compiler/tests-jsoo/dune

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
(enabled_if
1212
(>= %{ocaml_version} 4.14))
1313
(inline_tests
14+
(deps
15+
(sandbox preserve_file_kind))
1416
(modes js wasm best))
1517
(preprocess
1618
(pps ppx_expect)))
@@ -22,6 +24,8 @@
2224
(enabled_if
2325
(>= %{ocaml_version} 5.1.1))
2426
(inline_tests
27+
(deps
28+
(sandbox preserve_file_kind))
2529
(modes js wasm best))
2630
(preprocess
2731
(pps ppx_expect)))
@@ -33,6 +37,22 @@
3337
(enabled_if
3438
(>= %{ocaml_version} 5.1.1))
3539
(inline_tests
40+
(deps
41+
(sandbox preserve_file_kind))
42+
(modes js wasm best))
43+
(preprocess
44+
(pps ppx_expect)))
45+
46+
(library
47+
(name jsoo_testsuite_perms)
48+
(modules test_unix_perms)
49+
(libraries unix)
50+
;; WASI has no notion of file permissions (it uses capabilities instead)
51+
(enabled_if
52+
(<> %{profile} wasi))
53+
(inline_tests
54+
(deps
55+
(sandbox preserve_file_kind))
3656
(modes js wasm best))
3757
(preprocess
3858
(pps ppx_expect)))
@@ -48,13 +68,16 @@
4868
test_bigarray
4969
test_marshal_compressed
5070
test_parsing
71+
test_unix_perms
5172
calc_parser
5273
calc_lexer))
5374
(libraries unix compiler-libs.common js_of_ocaml-compiler)
5475
(foreign_stubs
5576
(language c)
5677
(names bigarray_stubs jsoo_runtime_stubs))
5778
(inline_tests
79+
(deps
80+
(sandbox preserve_file_kind))
5881
(modes js wasm best))
5982
(preprocess
6083
(pps ppx_expect)))

0 commit comments

Comments
 (0)