Skip to content
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

fix: add --output to wat2wasm, wasm2wat and opt cmd #416

Merged
merged 6 commits into from
Aug 27, 2024
Merged
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
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## unreleased

- add `--output` option to `wat2wasm`, `wasm2wat` and `opt` cmd
- add `--emit-file` option to `wasm2wat` to emit .wat files
- adds flags `--fail-on-trap-only` and `fail-on-assertion-only`
- parameterize the `Thread` module on the symbolic memory and the `Choice_monad` module on a Thread
Expand Down
6 changes: 3 additions & 3 deletions example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ COMMANDS
fmt [--inplace] [OPTION]… [ARG]…
Format a .wat or .wast file

opt [--debug] [--unsafe] [OPTION]… [ARG]…
opt [--debug] [--output=FILE] [--unsafe] [OPTION]… ARG
Optimize a module

run [OPTION]… [ARG]…
Expand All @@ -53,11 +53,11 @@ COMMANDS
validate [--debug] [OPTION]… [ARG]…
Validate a module

wasm2wat [--emit-file] [OPTION]… [ARG]…
wasm2wat [--emit-file] [--output=FILE] [OPTION]… ARG
Generate a text format file (.wat) from a binary format file
(.wasm)

wat2wasm [OPTION]… [ARG]…
wat2wasm [OPTION]… ARG
Generate a binary format file (.wasm) from a text format file
(.wat)

Expand Down
5 changes: 4 additions & 1 deletion example/opt/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -371,12 +371,15 @@ NAME
owi-opt - Optimize a module

SYNOPSIS
owi opt [--debug] [--unsafe] [OPTION]… [ARG]…
owi opt [--debug] [--output=FILE] [--unsafe] [OPTION]… ARG

OPTIONS
-d, --debug
debug mode

-o FILE, --output=FILE
Write output to a file.

-u, --unsafe
skip typechecking pass

Expand Down
7 changes: 5 additions & 2 deletions example/wasm2wat/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,14 @@ NAME
file (.wasm)

SYNOPSIS
owi wasm2wat [--emit-file] [OPTION]… [ARG]…
owi wasm2wat [--emit-file] [--output=FILE] [OPTION]… ARG

OPTIONS
--emit-file
emit (.wat) files from corresponding (.wasm) files
Emit (.wat) files from corresponding (.wasm) files.

-o FILE, --output=FILE
Write output to a file.

COMMON OPTIONS
--help[=FMT] (default=auto)
Expand Down
5 changes: 4 additions & 1 deletion example/wat2wasm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,15 @@ NAME
format file (.wat)

SYNOPSIS
owi wat2wasm [OPTION]… [ARG]…
owi wat2wasm [OPTION]… ARG

OPTIONS
-d, --debug
debug mode

-o FILE, --output=FILE
Write output to a file.

--optimize
optimize mode

Expand Down
19 changes: 8 additions & 11 deletions src/ast/binary_encoder.ml
Original file line number Diff line number Diff line change
Expand Up @@ -759,17 +759,14 @@ let encode
encode_section buf '\x0B' encode_datas data;
Buffer.contents buf

let write_file filename content =
let write_file outfile filename content =
let _dir, filename = Fpath.split_base filename in
let filename, _ext = Fpath.split_ext filename in
let filename = Fpath.add_ext ".wasm" filename in
let filename = Fpath.to_string filename in
let oc = Out_channel.open_bin filename in
Out_channel.output_string oc content;
Out_channel.close oc

let convert (filename : Fpath.t) ~unsafe ~optimize m =
let filename = Fpath.set_ext "wasm" filename in
Bos.OS.File.write (Option.value outfile ~default:filename) content

let convert (outfile : Fpath.t option) (filename : Fpath.t) ~unsafe ~optimize m
=
Log.debug0 "bin encoding ...@\n";
let+ m = Compile.Text.until_optimize ~unsafe ~optimize m in
let* m = Compile.Text.until_optimize ~unsafe ~optimize m in
let content = encode m in
write_file filename content
write_file outfile filename content
3 changes: 2 additions & 1 deletion src/ast/binary_encoder.mli
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
(* Written by the Owi programmers *)

val convert :
Fpath.t
Fpath.t option
-> Fpath.t
-> unsafe:bool
-> optimize:bool
-> Text.modul
Expand Down
27 changes: 22 additions & 5 deletions src/bin/owi.ml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,23 @@ let files =
let f = existing_non_dir_file in
Cmdliner.Arg.(value & pos_all f [] (info [] ~doc))

let emit_files =
let doc = "emit (.wat) files from corresponding (.wasm) files" in
let sourcefile =
let doc = "source file" in
let f = existing_non_dir_file in
Cmdliner.Arg.(required & pos 0 (some f) None (info [] ~doc))

let outfile =
let doc = "Write output to a file." in
let string_to_path =
Cmdliner.Arg.conv ~docv:"FILE" (Fpath.of_string, Fpath.pp)
in
Cmdliner.Arg.(
value
& opt (some string_to_path) None
& info [ "o"; "output" ] ~docv:"FILE" ~doc )

let emit_file =
let doc = "Emit (.wat) files from corresponding (.wasm) files." in
Cmdliner.Arg.(value & flag & info [ "emit-file" ] ~doc)

let no_exhaustion =
Expand Down Expand Up @@ -181,7 +196,7 @@ let opt_cmd =
let man = [] @ shared_man in
Cmd.info "opt" ~version ~doc ~sdocs ~man
in
Cmd.v info Term.(const Cmd_opt.cmd $ debug $ unsafe $ files)
Cmd.v info Term.(const Cmd_opt.cmd $ debug $ unsafe $ sourcefile $ outfile)

let run_cmd =
let open Cmdliner in
Expand Down Expand Up @@ -249,7 +264,7 @@ let wasm2wat_cmd =
let man = [] @ shared_man in
Cmd.info "wasm2wat" ~version ~doc ~sdocs ~man
in
Cmd.v info Term.(const Cmd_wasm2wat.cmd $ files $ emit_files)
Cmd.v info Term.(const Cmd_wasm2wat.cmd $ sourcefile $ emit_file $ outfile)

let wat2wasm_cmd =
let open Cmdliner in
Expand All @@ -261,7 +276,9 @@ let wat2wasm_cmd =
Cmd.info "wat2wasm" ~version ~doc ~sdocs ~man
in
Cmd.v info
Term.(const Cmd_wat2wasm.cmd $ profiling $ debug $ unsafe $ optimize $ files)
Term.(
const Cmd_wat2wasm.cmd $ profiling $ debug $ unsafe $ optimize $ outfile
$ sourcefile )

let cli =
let open Cmdliner in
Expand Down
16 changes: 9 additions & 7 deletions src/cmd/cmd_opt.ml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ open Syntax
let optimize_file ~unsafe filename =
Compile.File.until_optimize ~unsafe ~optimize:true filename

let cmd debug unsafe files =
let print_or_emit ~unsafe file outfile =
let* m = optimize_file ~unsafe file in
let m = Binary_to_text.modul m in
match outfile with
| Some name -> Bos.OS.File.writef name "%a@\n" Text.pp_modul m
| None -> Ok (Fmt.pr "%a@\n" Text.pp_modul m)

let cmd debug unsafe file outfile =
if debug then Log.debug_on := true;
list_iter
(fun file ->
let+ m = optimize_file ~unsafe file in
let m = Binary_to_text.modul m in
Fmt.pr "%a@\n" Text.pp_modul m )
files
print_or_emit ~unsafe file outfile
2 changes: 1 addition & 1 deletion src/cmd/cmd_opt.mli
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
(* Copyright © 2021-2024 OCamlPro *)
(* Written by the Owi programmers *)

val cmd : bool -> bool -> Fpath.t list -> unit Result.t
val cmd : bool -> bool -> Fpath.t -> Fpath.t option -> unit Result.t
17 changes: 13 additions & 4 deletions src/cmd/cmd_wasm2wat.ml
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,25 @@
open Syntax

(** Utility function to handle writing to a file or printing to stdout *)
let cmd_one emitfile file =
let cmd_one emitfile outfile file =
let ext = Fpath.get_ext file in
let wat_file = Fpath.set_ext "wat" file in
let _dir, wat_file = Fpath.split_base file in
let wat_file = Fpath.set_ext "wat" wat_file in

match ext with
| ".wasm" ->
let* m = Parse.Binary.Module.from_file file in
let m = Binary_to_text.modul m in
if emitfile then Bos.OS.File.writef wat_file "%a@\n" Text.pp_modul m
let outname, output =
begin
match outfile with
| Some name -> (name, true)
| None -> (wat_file, false)
end
in
if emitfile || output then
Bos.OS.File.writef outname "%a@\n" Text.pp_modul m
else Ok (Fmt.pr "%a@\n" Text.pp_modul m)
| ext -> Error (`Unsupported_file_extension ext)

let cmd files emitfile = list_iter (cmd_one emitfile) files
let cmd file emitfile outfile = cmd_one emitfile outfile file
2 changes: 1 addition & 1 deletion src/cmd/cmd_wasm2wat.mli
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
(* Copyright © 2021-2024 OCamlPro *)
(* Written by the Owi programmers *)

val cmd : Fpath.t list -> bool -> unit Result.t
val cmd : Fpath.t -> bool -> Fpath.t option -> unit Result.t
8 changes: 4 additions & 4 deletions src/cmd/cmd_wat2wasm.ml
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@

open Syntax

let cmd_one ~unsafe ~optimize file =
let cmd_one ~unsafe ~optimize outfile file =
let ext = Fpath.get_ext file in
match ext with
| ".wat" ->
let* modul = Parse.Text.Module.from_file file in
Binary_encoder.convert file ~unsafe ~optimize modul
Binary_encoder.convert outfile file ~unsafe ~optimize modul
| ext -> Error (`Unsupported_file_extension ext)

let cmd profiling debug unsafe optimize files =
let cmd profiling debug unsafe optimize outfile file =
if profiling then Log.profiling_on := true;
if debug then Log.debug_on := true;
list_iter (cmd_one ~unsafe ~optimize) files
cmd_one ~unsafe ~optimize outfile file
2 changes: 1 addition & 1 deletion src/cmd/cmd_wat2wasm.mli
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
(* Copyright © 2021-2024 OCamlPro *)
(* Written by the Owi programmers *)

val cmd : bool -> bool -> bool -> bool -> Fpath.t list -> unit Result.t
val cmd : bool -> bool -> bool -> bool -> Fpath.t option -> Fpath.t -> unit Result.t
6 changes: 3 additions & 3 deletions test/help/help.t
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ no subcommand should print help
fmt [--inplace] [OPTION]… [ARG]…
Format a .wat or .wast file

opt [--debug] [--unsafe] [OPTION]… [ARG]…
opt [--debug] [--output=FILE] [--unsafe] [OPTION]… ARG
Optimize a module

run [OPTION]… [ARG]…
Expand All @@ -31,11 +31,11 @@ no subcommand should print help
validate [--debug] [OPTION]… [ARG]…
Validate a module

wasm2wat [--emit-file] [OPTION]… [ARG]…
wasm2wat [--emit-file] [--output=FILE] [OPTION]… ARG
Generate a text format file (.wat) from a binary format file
(.wasm)

wat2wasm [OPTION]… [ARG]…
wat2wasm [OPTION]… ARG
Generate a binary format file (.wasm) from a text format file
(.wat)

Expand Down
2 changes: 1 addition & 1 deletion test/opt/not_exists.t
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
file doesn't exist:
$ owi opt not_exists.wat --debug
owi: no file 'not_exists.wat'
Usage: owi opt [--debug] [--unsafe] [OPTION]… [ARG]…
Usage: owi opt [--debug] [--output=FILE] [--unsafe] [OPTION]… ARG
Try 'owi opt --help' or 'owi --help' for more information.
[124]
10 changes: 10 additions & 0 deletions test/opt/output.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
$ owi opt fbinop.wat -o bar.wat
$ owi fmt bar.wat
(module

(type (sub final (func)))
(func $start

)
(start 0)
)
2 changes: 1 addition & 1 deletion test/wasm2wat/not_exists.t
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
$ owi wasm2wat idontexist.wat
owi: no file 'idontexist.wat'
Usage: owi wasm2wat [--emit-file] [OPTION]… [ARG]…
Usage: owi wasm2wat [--emit-file] [--output=FILE] [OPTION]… ARG
Try 'owi wasm2wat --help' or 'owi --help' for more information.
[124]
$ owi wasm2wat bad.ext
Expand Down
20 changes: 20 additions & 0 deletions test/wasm2wat/output.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
$ owi wasm2wat done.wasm -o bar.wat
$ owi fmt bar.wat
(module

(type (sub final (func (param i32) (param i32) (result i32))))

(type (sub final (func)))
(func (param i32) (param i32) (result i32)
local.get 0
local.get 1
i32.add
)
(func
i32.const 22
i32.const 20
call 0
drop
)
(start 1)
)
2 changes: 1 addition & 1 deletion test/wat2wasm/not_exists.t
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
$ owi wat2wasm not_exists.wat
owi: no file 'not_exists.wat'
Usage: owi wat2wasm [OPTION]… [ARG]…
Usage: owi wat2wasm [OPTION]… ARG
Try 'owi wat2wasm --help' or 'owi --help' for more information.
[124]
$ owi wat2wasm bad.ext
Expand Down
26 changes: 26 additions & 0 deletions test/wat2wasm/output.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
$ owi wat2wasm func.wat -o bar.wasm
$ owi run bar.wasm --debug
typechecking ...
linking ...
interpreting ...
stack : [ ]
running instr: call 1
calling func : func anonymous
stack : [ ]
running instr: f32.const 40.400_001_525_878_906
stack : [ f32.const 40.400_001_525_878_906 ]
running instr: call 0
calling func : func anonymous
stack : [ ]
running instr: f32.const 2.019_999_980_926_513_7
stack : [ f32.const 2.019_999_980_926_513_7 ]
running instr: local.tee 1
stack : [ f32.const 2.019_999_980_926_513_7 ]
running instr: local.get 0
stack : [ f32.const 40.400_001_525_878_906 ; f32.const 2.019_999_980_926_513_7 ]
running instr: f32.add
stack : [ f32.const 42.420_001_983_642_578 ]
stack : [ f32.const 42.420_001_983_642_578 ]
running instr: drop
stack : [ ]
stack : [ ]
Loading