Skip to content

Commit bf8abcc

Browse files
committed
WASI runtime
1 parent 8921577 commit bf8abcc

File tree

55 files changed

+4366
-193
lines changed

Some content is hidden

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

55 files changed

+4366
-193
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
; "exnref", Wat_preprocess.Bool (Config.Flag.exnref ())
8890
]
8991

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

@@ -186,7 +193,10 @@ let link_and_optimize
186193
let t = Timer.make ~get_time:Unix.time () in
187194
let primitives =
188195
Binaryen.dead_code_elimination
189-
~dependencies:Runtime_files.dependencies
196+
~dependencies:
197+
(if Config.Flag.wasi ()
198+
then Runtime_files.wasi_dependencies
199+
else Runtime_files.dependencies)
190200
~opt_input_sourcemap:opt_temp_sourcemap
191201
~opt_output_sourcemap:opt_temp_sourcemap'
192202
~input_file:temp_file
@@ -303,7 +313,13 @@ let build_js_runtime ~primitives ?runtime_arguments () =
303313
| _ -> assert false
304314
in
305315
let init_fun =
306-
match Parse_js.parse (Parse_js.Lexer.of_string Runtime_files.js_runtime) with
316+
match
317+
Parse_js.parse
318+
(Parse_js.Lexer.of_string
319+
(if Config.Flag.wasi ()
320+
then Runtime_files.js_wasi_launcher
321+
else Runtime_files.js_launcher))
322+
with
307323
| [ (Expression_statement f, _) ] -> f
308324
| _ -> assert false
309325
in
@@ -601,9 +617,12 @@ let run
601617
if binaryen_times ()
602618
then Format.eprintf " link_and_optimize: %a@." Timer.print t2;
603619
let wasm_name =
604-
Printf.sprintf
605-
"code-%s"
606-
(String.sub (Digest.to_hex (Digest.file tmp_wasm_file)) ~pos:0 ~len:20)
620+
if Config.Flag.wasi ()
621+
then "code"
622+
else
623+
Printf.sprintf
624+
"code-%s"
625+
(String.sub (Digest.to_hex (Digest.file tmp_wasm_file)) ~pos:0 ~len:20)
607626
in
608627
let tmp_wasm_file' = Filename.concat tmp_dir (wasm_name ^ ".wasm") in
609628
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 = [ "exnref", `B false ]
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: 56 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,8 +1331,8 @@ module Math = struct
13311331
let unary name x =
13321332
let* f =
13331333
register_import
1334-
~allow_tail_call:false
1335-
~import_module:"Math"
1334+
~allow_tail_call:(Config.Flag.wasi ())
1335+
~import_module:(if Config.Flag.wasi () then "env" else "Math")
13361336
~name
13371337
(Fun (float_func_type 1))
13381338
in
@@ -1380,8 +1380,8 @@ module Math = struct
13801380
let binary name x y =
13811381
let* f =
13821382
register_import
1383-
~allow_tail_call:false
1384-
~import_module:"Math"
1383+
~allow_tail_call:(Config.Flag.wasi ())
1384+
~import_module:(if Config.Flag.wasi () then "env" else "Math")
13851385
~name
13861386
(Fun (float_func_type 2))
13871387
in
@@ -1413,6 +1413,18 @@ module Bigarray = struct
14131413
(Memory.wasm_struct_get ty (Memory.wasm_cast ty a) 3)
14141414
(Arith.const (Int32.of_int n))
14151415

1416+
let little_endian () =
1417+
if Config.Flag.wasi ()
1418+
then Arith.(const 1l)
1419+
else
1420+
let* le =
1421+
register_import
1422+
~import_module:"bindings"
1423+
~name:"littleEndian"
1424+
(Global { mut = false; typ = I32 })
1425+
in
1426+
return (W.GlobalGet le)
1427+
14161428
let get_at_offset ~(kind : Typing.Bigarray.kind) a i =
14171429
let name, (typ : Wasm_ast.value_type), size, box =
14181430
match kind with
@@ -1453,19 +1465,14 @@ module Bigarray = struct
14531465
return (W.F64PromoteF32 x) )
14541466
| Complex64 -> "dv_get_f64", F64, 4, Fun.id
14551467
in
1456-
let* little_endian =
1457-
register_import
1458-
~import_module:"bindings"
1459-
~name:"littleEndian"
1460-
(Global { mut = false; typ = I32 })
1461-
in
1468+
let* little_endian = little_endian () in
14621469
let* f =
14631470
register_import
1464-
~import_module:"bindings"
1471+
~import_module:(if Config.Flag.wasi () then "env" else "bindings")
14651472
~name
14661473
(Fun
14671474
{ W.params =
1468-
Ref { nullable = true; typ = Extern }
1475+
Ref { nullable = not (Config.Flag.wasi ()); typ = Extern }
14691476
:: I32
14701477
:: (if size = 0 then [] else [ I32 ])
14711478
; result = [ typ ]
@@ -1487,14 +1494,12 @@ module Bigarray = struct
14871494
| Nativeint
14881495
| Float16 ->
14891496
box
1490-
(return
1491-
(W.Call
1492-
(f, ta :: ofs :: (if size = 0 then [] else [ W.GlobalGet little_endian ]))))
1497+
(return (W.Call (f, ta :: ofs :: (if size = 0 then [] else [ little_endian ]))))
14931498
| Complex32 | Complex64 ->
14941499
let delta = Int32.shift_left 1l (size - 1) in
14951500
let* ofs' = Arith.(return ofs + const delta) in
1496-
let* x = box (return (W.Call (f, [ ta; ofs; W.GlobalGet little_endian ]))) in
1497-
let* y = box (return (W.Call (f, [ ta; ofs'; W.GlobalGet little_endian ]))) in
1501+
let* x = box (return (W.Call (f, [ ta; ofs; little_endian ]))) in
1502+
let* y = box (return (W.Call (f, [ ta; ofs'; little_endian ]))) in
14981503
let* ty = Type.float_array_type in
14991504
return (W.ArrayNewFixed (ty, [ x; y ]))
15001505

@@ -1539,19 +1544,14 @@ module Bigarray = struct
15391544
let* ty = Type.bigarray_type in
15401545
let* ta = Memory.wasm_struct_get ty (Memory.wasm_cast ty a) 2 in
15411546
let* ofs = Arith.(i lsl const (Int32.of_int size)) in
1542-
let* little_endian =
1543-
register_import
1544-
~import_module:"bindings"
1545-
~name:"littleEndian"
1546-
(Global { mut = false; typ = I32 })
1547-
in
1547+
let* little_endian = little_endian () in
15481548
let* f =
15491549
register_import
1550-
~import_module:"bindings"
1550+
~import_module:(if Config.Flag.wasi () then "env" else "bindings")
15511551
~name
15521552
(Fun
15531553
{ W.params =
1554-
Ref { nullable = true; typ = Extern }
1554+
Ref { nullable = not (Config.Flag.wasi ()); typ = Extern }
15551555
:: I32
15561556
:: typ
15571557
:: (if size = 0 then [] else [ I32 ])
@@ -1572,18 +1572,15 @@ module Bigarray = struct
15721572
| Float16 ->
15731573
let* v = unbox v in
15741574
instr
1575-
(W.CallInstr
1576-
( f
1577-
, ta :: ofs :: v :: (if size = 0 then [] else [ W.GlobalGet little_endian ])
1578-
))
1575+
(W.CallInstr (f, ta :: ofs :: v :: (if size = 0 then [] else [ little_endian ])))
15791576
| Complex32 | Complex64 ->
15801577
let delta = Int32.shift_left 1l (size - 1) in
15811578
let* ofs' = Arith.(return ofs + const delta) in
15821579
let ty = Type.float_array_type in
15831580
let* x = unbox (Memory.wasm_array_get ~ty v (Arith.const 0l)) in
1584-
let* () = instr (W.CallInstr (f, [ ta; ofs; x; W.GlobalGet little_endian ])) in
1581+
let* () = instr (W.CallInstr (f, [ ta; ofs; x; little_endian ])) in
15851582
let* y = unbox (Memory.wasm_array_get ~ty v (Arith.const 1l)) in
1586-
instr (W.CallInstr (f, [ ta; ofs'; y; W.GlobalGet little_endian ]))
1583+
instr (W.CallInstr (f, [ ta; ofs'; y; little_endian ]))
15871584

15881585
let offset ~bound_error_index ~(layout : Typing.Bigarray.layout) ta ~indices =
15891586
let l =
@@ -1956,21 +1953,34 @@ let handle_exceptions ~result_typ ~fall_through ~context body x exn_handler =
19561953
x
19571954
(block_expr
19581955
{ params = []; result = [ Type.value ] }
1959-
(let* exn =
1960-
block_expr
1961-
{ params = []; result = [ externref ] }
1962-
(let* e =
1963-
try_expr
1964-
{ params = []; result = [ externref ] }
1965-
(body
1966-
~result_typ:[ externref ]
1967-
~fall_through:`Skip
1968-
~context:(`Skip :: `Skip :: `Catch :: context))
1969-
[ ocaml_tag, 1, Type.value; js_tag, 0, externref ]
1970-
in
1971-
instr (W.Push e))
1972-
in
1973-
instr (W.CallInstr (f, [ exn ]))))
1956+
(if Config.Flag.wasi ()
1957+
then
1958+
let* e =
1959+
try_expr
1960+
{ params = []; result = [ Type.value ] }
1961+
(body
1962+
~result_typ:[ Type.value ]
1963+
~fall_through:`Skip
1964+
~context:(`Skip :: `Catch :: context))
1965+
[ ocaml_tag, 0, Type.value ]
1966+
in
1967+
instr (W.Push e)
1968+
else
1969+
let* exn =
1970+
block_expr
1971+
{ params = []; result = [ externref ] }
1972+
(let* e =
1973+
try_expr
1974+
{ params = []; result = [ externref ] }
1975+
(body
1976+
~result_typ:[ externref ]
1977+
~fall_through:`Skip
1978+
~context:(`Skip :: `Skip :: `Catch :: context))
1979+
[ ocaml_tag, 1, Type.value; js_tag, 0, externref ]
1980+
in
1981+
instr (W.Push e))
1982+
in
1983+
instr (W.CallInstr (f, [ exn ]))))
19741984
in
19751985
let* () = no_event in
19761986
exn_handler ~result_typ ~fall_through ~context)

compiler/lib-wasm/generate.ml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ module Generate (Target : Target_sig.S) = struct
209209
(if negate then Arith.( <> ) else Arith.( = ))
210210
Arith.(transl_prim_arg ctx ~typ:(Int Unnormalized) x lsl const 1l)
211211
Arith.(transl_prim_arg ctx ~typ:(Int Unnormalized) y lsl const 1l)
212-
| Top, Top ->
212+
| Top, Top when not (Config.Flag.wasi ()) ->
213213
Value.js_eqeqeq
214214
~negate
215215
(transl_prim_arg ctx ~typ:Top x)
@@ -220,7 +220,8 @@ module Generate (Target : Target_sig.S) = struct
220220
(transl_prim_arg ctx ~typ:Top x)
221221
(transl_prim_arg ctx ~typ:Top y)
222222
| (Int _ | Number _ | Tuple _ | Bigarray _), _
223-
| _, (Int _ | Number _ | Tuple _ | Bigarray _) ->
223+
| _, (Int _ | Number _ | Tuple _ | Bigarray _)
224+
| Top, Top (* when wasi is enabled *) ->
224225
(* Only Top may contain JavaScript values *)
225226
(if negate then Value.phys_neq else Value.phys_eq)
226227
(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
@@ -108,6 +108,8 @@ module Flag = struct
108108
let load_shapes_auto = o ~name:"load-shapes-auto" ~default:false
109109

110110
let exnref = o ~name:"exnref" ~default:false
111+
112+
let wasi = o ~name:"wasi" ~default:false
111113
end
112114

113115
module Param = struct

compiler/lib/config.mli

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

7979
val exnref : unit -> bool
8080

81+
val wasi : unit -> bool
82+
8183
val enable : string -> unit
8284

8385
val disable : string -> unit

0 commit comments

Comments
 (0)