Skip to content

WASI runtime #1831

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 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
96 changes: 94 additions & 2 deletions .github/workflows/build-wasm_of_ocaml.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ jobs:
matrix:
os:
- ubuntu-latest
os-name:
- Ubuntu
ocaml-compiler:
- "4.14"
- "5.0"
Expand All @@ -27,30 +29,50 @@ jobs:
- false
all_jane_street_tests:
- false
wasi:
- false
include:
- os: macos-latest
os-name: MacOS
ocaml-compiler: "5.3"
separate_compilation: true
jane_street_tests: false
all_jane_street_tests: false
wasi: false
- os: windows-latest
os-name: Windows
ocaml-compiler: "5.2"
separate_compilation: true
jane_street_tests: true
all_jane_street_tests: true
wasi: false
- os: ubuntu-latest
os-name: Ubuntu
ocaml-compiler: "5.2"
separate_compilation: true
jane_street_tests: true
all_jane_street_tests: true
wasi: false
- os: ubuntu-latest
os-name: Ubuntu
ocaml-compiler: "5.2"
separate_compilation: false
jane_street_tests: true
all_jane_street_tests: false
wasi: false
- os: ubuntu-latest
os-name: Ubuntu
ocaml-compiler: "5.3"
separate_compilation: true
jane_street_tests: false
all_jane_street_tests: false
wasi: true

runs-on: ${{ matrix.os }}

name:
${{ matrix.wasi && 'WASI / ' || '' }}${{ (! matrix.separate_compilation) && 'Whole program / ' || ''}}${{ matrix.ocaml-compiler }} / ${{ matrix.os-name }}${{ matrix.all_jane_street_tests && ' / Jane Street tests' || ''}}

steps:
- name: Set git to use LF
if: ${{ matrix.os == 'windows-latest' && matrix.ocaml-compiler < 5.2 }}
Expand All @@ -77,6 +99,54 @@ jobs:
with:
node-version: latest

- name: Set-up Rust toolchain
if: matrix.wasi
uses: actions-rust-lang/setup-rust-toolchain@v1

- name: Checkout Wasmtime
if: matrix.wasi
uses: actions/checkout@v4
with:
repository: bytecodealliance/wasmtime
path: wasmtime
submodules: true

- name: Build Wasmtime
if: matrix.wasi
working-directory: ./wasmtime
run: |
cargo build
echo `pwd`/target/debug >> "$GITHUB_PATH"

- name: Checkout Virgil
if: matrix.wasi
uses: actions/checkout@v4
with:
repository: titzer/virgil
path: virgil

- name: Build Virgil
if: matrix.wasi
working-directory: ./virgil
run: |
export PATH=$PATH:`pwd`/bin
echo `pwd`/bin >> "$GITHUB_PATH"
make

- name: Checkout Wizard engine
if: matrix.wasi
uses: actions/checkout@v4
with:
repository: titzer/wizard-engine
path: wizard-engine

- name: Build Wizard engine
if: matrix.wasi
working-directory: ./wizard-engine
run: |
make -j 4
echo `pwd`/bin >> "$GITHUB_PATH"

- name: Set-up OCaml ${{ matrix.ocaml-compiler }}
uses: ocaml/setup-ocaml@v3
with:
Expand Down Expand Up @@ -129,7 +199,7 @@ jobs:
opam install . -t

- name: Run tests
if: ${{ matrix.separate_compilation }}
if: ${{ matrix.separate_compilation && ! matrix.wasi }}
working-directory: ./wasm_of_ocaml
run: opam exec -- dune build @runtest-wasm

Expand All @@ -138,11 +208,33 @@ jobs:
# See https://github.com/libuv/libuv/issues/3622

- name: Run tests with CPS effects
if: ${{ matrix.ocaml-compiler >= '5.' && matrix.separate_compilation }}
if: ${{ matrix.ocaml-compiler >= '5.' && matrix.separate_compilation && ! matrix.wasi }}
continue-on-error: ${{ matrix.os == 'windows-latest' }}
working-directory: ./wasm_of_ocaml
run: opam exec -- dune build @runtest-wasm --profile with-effects

- name: Run tests (WASI runtime - node)
if: ${{ matrix.wasi }}
working-directory: ./wasm_of_ocaml
run: opam exec -- dune build @runtest-wasm --profile wasi

- name: Run tests (WASI runtime - Wizard engine)
if: ${{ matrix.wasi }}
working-directory: ./wasm_of_ocaml
env:
WASM_ENGINE: wizard-fast
run: opam exec -- dune build @runtest-wasm --profile wasi

- name: Run tests (WASI runtime - wasmtime)
if: ${{ matrix.wasi }}
working-directory: ./wasm_of_ocaml
env:
WASM_ENGINE: wasmtime
WASI_FLAGS: --enable trap-on-exception
RUST_BACKTRACE: 0
continue-on-error: true
run: opam exec -- dune build @runtest-wasm --profile wasi

- name: Run Base tests
if: matrix.all_jane_street_tests
continue-on-error: ${{ matrix.os == 'windows-latest' }}
Expand Down
6 changes: 5 additions & 1 deletion compiler/bin-wasm_of_ocaml/cmd_arg.ml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,11 @@ let normalize_effects (effects : [ `Cps | `Jspi ] option) common : Config.effect
| None ->
(* For backward compatibility, consider that [--enable effects] alone means
[--effects cps] *)
if List.mem "effects" ~set:common.Jsoo_cmdline.Arg.optim.enable then `Cps else `Jspi
if List.mem "effects" ~set:common.Jsoo_cmdline.Arg.optim.enable
then `Cps
else if List.mem "wasi" ~set:common.Jsoo_cmdline.Arg.optim.enable
then `Disabled
else `Jspi
| Some ((`Cps | `Jspi) as e) -> e

type t =
Expand Down
31 changes: 24 additions & 7 deletions compiler/bin-wasm_of_ocaml/compile.ml
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,12 @@ let build_runtime ~runtime_file =
[ ( "effects"
, Wat_preprocess.String
(match Config.effects () with
| `Disabled -> "disabled"
| `Jspi -> "jspi"
| `Cps -> "cps"
| `Disabled | `Double_translation -> assert false) )
| `Double_translation -> assert false) )
; "wasi", Wat_preprocess.Bool (Config.Flag.wasi ())
; "trap-on-exception", Wat_preprocess.Bool (Config.Flag.trap_on_exception ())
]
in
match
Expand All @@ -113,7 +116,9 @@ let build_runtime ~runtime_file =
; file = module_name ^ ".wat"
; source = Contents contents
})
Runtime_files.wat_files
(if Config.Flag.wasi ()
then ("libc", Runtime_files.wasi_libc) :: Runtime_files.wat_files
else Runtime_files.wat_files)
in
Runtime.build
~link_options:[ "-g" ]
Expand Down Expand Up @@ -175,7 +180,10 @@ let link_and_optimize
@@ fun opt_temp_sourcemap' ->
let primitives =
Binaryen.dead_code_elimination
~dependencies:Runtime_files.dependencies
~dependencies:
(if Config.Flag.wasi ()
then Runtime_files.wasi_dependencies
else Runtime_files.dependencies)
~opt_input_sourcemap:opt_temp_sourcemap
~opt_output_sourcemap:opt_temp_sourcemap'
~input_file:temp_file
Expand Down Expand Up @@ -293,7 +301,13 @@ let build_js_runtime ~primitives ?runtime_arguments () =
| _ -> assert false
in
let init_fun =
match Parse_js.parse (Parse_js.Lexer.of_string Runtime_files.js_runtime) with
match
Parse_js.parse
(Parse_js.Lexer.of_string
(if Config.Flag.wasi ()
then Runtime_files.js_wasi_launcher
else Runtime_files.js_launcher))
with
| [ (Expression_statement f, _) ] -> f
| _ -> assert false
in
Expand Down Expand Up @@ -530,9 +544,12 @@ let run
tmp_wasm_file
in
let wasm_name =
Printf.sprintf
"code-%s"
(String.sub (Digest.to_hex (Digest.file tmp_wasm_file)) ~pos:0 ~len:20)
if Config.Flag.wasi ()
then "code"
else
Printf.sprintf
"code-%s"
(String.sub (Digest.to_hex (Digest.file tmp_wasm_file)) ~pos:0 ~len:20)
in
let tmp_wasm_file' = Filename.concat tmp_dir (wasm_name ^ ".wasm") in
Sys.rename tmp_wasm_file tmp_wasm_file';
Expand Down
3 changes: 3 additions & 0 deletions compiler/bin-wasm_of_ocaml/dune
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
gen/gen.exe
../../runtime/wasm/runtime.js
../../runtime/wasm/deps.json
../../runtime/wasm/runtime-wasi.js
../../runtime/wasm/deps-wasi.json
../../runtime/wasm/libc.wasm
(glob_files ../../runtime/wasm/*.wat)
(glob_files ../../runtime/wasm/runtime-*.wasm))
(action
Expand Down
31 changes: 22 additions & 9 deletions compiler/bin-wasm_of_ocaml/gen/gen.ml
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,22 @@ let check_js_file fname =
(* Keep the two variables below in sync with function build_runtime in
../compile.ml *)

let default_flags = []
let default_flags = [ "trap-on-exception", `B false ]

let interesting_runtimes = [ [ "effects", `S "jspi" ]; [ "effects", `S "cps" ] ]
let interesting_runtimes =
[ [ "effects", `S "jspi"; "wasi", `B false ]
; [ "effects", `S "cps"; "wasi", `B false ]
; [ "effects", `S "disabled"; "wasi", `B true ]
; [ "effects", `S "cps"; "wasi", `B true ]
]

let defaults = [ "effects", "disabled" ]

let name_runtime standard l =
let flags =
List.filter_map l ~f:(fun (k, v) ->
match v with
| `S s -> Some s
| `S s -> if List.mem (k, s) ~set:defaults then None else Some s
| `B b -> if b then Some k else None)
in
String.concat ~sep:"-" ("runtime" :: (if standard then [ "standard" ] else flags))
Expand All @@ -67,25 +74,31 @@ let print_flags f flags =

let () =
let () = set_binary_mode_out stdout true in
let js_runtime, deps, wat_files, runtimes =
let js_launcher, deps, js_wasi_launcher, wasi_deps, wasi_libc, wat_files, runtimes =
match Array.to_list Sys.argv with
| _ :: js_runtime :: deps :: rest ->
assert (Filename.check_suffix js_runtime ".js");
| _ :: js_launcher :: deps :: js_wasi_launcher :: wasi_deps :: wasi_libc :: rest ->
assert (Filename.check_suffix js_launcher ".js");
assert (Filename.check_suffix js_wasi_launcher ".js");
assert (Filename.check_suffix deps ".json");
assert (Filename.check_suffix wasi_deps ".json");
let wat_files, rest =
List.partition rest ~f:(fun f -> Filename.check_suffix f ".wat")
in
let wasm_files, rest =
List.partition rest ~f:(fun f -> Filename.check_suffix f ".wasm")
in
assert (List.is_empty rest);
js_runtime, deps, wat_files, wasm_files
js_launcher, deps, js_wasi_launcher, wasi_deps, wasi_libc, wat_files, wasm_files
| _ -> assert false
in
check_js_file js_runtime;
check_js_file js_launcher;
check_js_file js_wasi_launcher;
Format.printf "open Wasm_of_ocaml_compiler@.";
Format.printf "let js_runtime = {|\n%s\n|}@." (Fs.read_file js_runtime);
Format.printf "let js_launcher = {|\n%s\n|}@." (Fs.read_file js_launcher);
Format.printf "let dependencies = {|\n%s\n|}@." (Fs.read_file deps);
Format.printf "let js_wasi_launcher = {|\n%s\n|}@." (Fs.read_file js_wasi_launcher);
Format.printf "let wasi_dependencies = {|\n%s\n|}@." (Fs.read_file wasi_deps);
Format.printf "let wasi_libc = %S@." (String.escaped (Fs.read_file wasi_libc));
Format.printf
"let wat_files = [%a]@."
(Format.pp_print_list (fun f file ->
Expand Down
8 changes: 5 additions & 3 deletions compiler/lib-wasm/binaryen.ml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ let common_options () =
; "--enable-bulk-memory"
; "--enable-nontrapping-float-to-int"
; "--enable-strings"
; "--enable-multimemory" (* To keep wasm-merge happy *)
]
in
if Config.Flag.pretty () then "-g" :: l else l
Expand Down Expand Up @@ -111,9 +112,9 @@ let dead_code_elimination
filter_unused_primitives primitives usage_file

let optimization_options =
[| [ "-O2"; "--skip-pass=inlining-optimizing"; "--traps-never-happen" ]
; [ "-O2"; "--skip-pass=inlining-optimizing"; "--traps-never-happen" ]
; [ "-O3"; "--skip-pass=inlining-optimizing"; "--traps-never-happen" ]
[| [ "-O2"; "--skip-pass=inlining-optimizing" ]
; [ "-O2"; "--skip-pass=inlining-optimizing" ]
; [ "-O3"; "--skip-pass=inlining-optimizing" ]
|]

let optimize
Expand All @@ -133,6 +134,7 @@ let optimize
command
("wasm-opt"
:: (common_options ()
@ (if Config.Flag.trap_on_exception () then [] else [ "--traps-never-happen" ])
@ Option.value ~default:optimization_options.(level - 1) options
@ [ Filename.quote input_file; "-o"; Filename.quote output_file ])
@ opt_flag "--input-source-map" opt_input_sourcemap
Expand Down
Loading
Loading