Skip to content

Commit

Permalink
Wat file preprocessor
Browse files Browse the repository at this point in the history
  • Loading branch information
vouillon committed Jan 30, 2025
1 parent 28f0ca6 commit 8e47ba1
Show file tree
Hide file tree
Showing 14 changed files with 953 additions and 41 deletions.
30 changes: 22 additions & 8 deletions compiler/bin-wasm_of_ocaml/compile.ml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,21 @@ let output_gen output_file f =
Code.Var.set_stable (Config.Flag.stable_var ());
Filename.gen_file output_file f

let with_runtime_files ~runtime_wasm_files f =
let inputs =
List.map
~f:(fun file ->
{ Wat_preprocess.module_name = "env"
; file
; source =
(if Link.Wasm_binary.check_file ~file
then File
else Contents (Js_of_ocaml_compiler.Fs.read_file file))
})
runtime_wasm_files
in
Wat_preprocess.with_preprocessed_files ~variables:[] ~inputs f

let link_and_optimize
~profile
~sourcemap_root
Expand Down Expand Up @@ -100,15 +115,15 @@ let link_and_optimize
then Some (Filename.temp_file "wasm-merged" ".wasm.map")
else None)
@@ fun opt_temp_sourcemap ->
(with_runtime_files ~runtime_wasm_files
@@ fun runtime_inputs ->
Binaryen.link
~inputs:
(List.map
~f:(fun file -> { Binaryen.module_name = "env"; file })
(runtime_file :: runtime_wasm_files)
(({ Binaryen.module_name = "env"; file = runtime_file } :: runtime_inputs)
@ List.map ~f:(fun file -> { Binaryen.module_name = "OCaml"; file }) wat_files)
~opt_output_sourcemap:opt_temp_sourcemap
~output_file:temp_file
();
());
Fs.with_intermediate_file (Filename.temp_file "wasm-dce" ".wasm")
@@ fun temp_file' ->
opt_with
Expand Down Expand Up @@ -141,12 +156,11 @@ let link_runtime ~profile runtime_wasm_files output_file =
Fs.write_file ~name:runtime_file ~contents:Runtime_files.wasm_runtime;
Fs.with_intermediate_file (Filename.temp_file "wasm-merged" ".wasm")
@@ fun temp_file ->
with_runtime_files ~runtime_wasm_files
@@ fun runtime_inputs ->
Binaryen.link
~opt_output_sourcemap:None
~inputs:
(List.map
~f:(fun file -> { Binaryen.module_name = "env"; file })
(runtime_file :: runtime_wasm_files))
~inputs:({ Binaryen.module_name = "env"; file = runtime_file } :: runtime_inputs)
~output_file:temp_file
();
Binaryen.optimize
Expand Down
181 changes: 181 additions & 0 deletions compiler/bin-wasmoo_util/cmd_arg.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
(* Js_of_ocaml compiler
* http://www.ocsigen.org/js_of_ocaml/
* Copyright (C) 2014 Hugo Heuzard
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, with linking exception;
* either version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*)

open Cmdliner

type variables =
{ enable : string list
; disable : string list
; set : (string * string) list
}

type preprocess_options =
{ input_file : string option
; output_file : string option
; variables : variables
}

let variable_options =
let enable =
let doc = "Set preprocessor variable $(docv) to true." in
let arg =
Arg.(value & opt_all (list string) [] & info [ "enable" ] ~docv:"VAR" ~doc)
in
Term.(const List.flatten $ arg)
in
let disable =
let doc = "Set preprocessor variable $(docv) to false." in
let arg =
Arg.(value & opt_all (list string) [] & info [ "disable" ] ~docv:"VAR" ~doc)
in
Term.(const List.flatten $ arg)
in
let set =
let doc = "Set preprocessor variable $(i,VAR) to value $(i,VALUE)." in
let arg =
Arg.(
value
& opt_all (list (pair ~sep:'=' string string)) []
& info [ "set" ] ~docv:"VAR=VALUE" ~doc)
in
Term.(const List.flatten $ arg)
in
let build_t enable disable set = { enable; disable; set } in
Term.(const build_t $ enable $ disable $ set)

let preprocess_options =
let input_file =
let doc =
"Use the Wasm text file $(docv) as input (default to the standard input)."
in
Arg.(value & pos 0 (some string) None & info [] ~docv:"INPUT_FILE" ~doc)
in
let output_file =
let doc = "Specify the output file $(docv) (default to the standard output)." in
Arg.(value & opt (some string) None & info [ "o" ] ~docv:"OUTPUT_FILE" ~doc)
in
let build_t input_file output_file variables =
`Ok { input_file; output_file; variables }
in
let t = Term.(const build_t $ input_file $ output_file $ variable_options) in
Term.ret t

type binaryen_options =
{ common : string list
; opt : string list
; merge : string list
}

type link_options =
{ input_modules : (string * string) list
; output_file : string
; variables : variables
; binaryen_options : binaryen_options
}

let link_options =
let input_modules =
let doc =
"Specify an input module with name $(i,NAME) in Wasm text file $(i,FILE)."
in
Arg.(
value
& pos_right 0 (pair ~sep:':' string string) []
& info [] ~docv:"NAME:FILE" ~doc)
in
let output_file =
let doc = "Specify the Wasm binary output file $(docv)." in
Arg.(required & pos 0 (some string) None & info [] ~docv:"WASM_FILE" ~doc)
in
let binaryen_options =
let doc = "Pass option $(docv) to binaryen tools" in
Arg.(value & opt_all string [] & info [ "binaryen" ] ~docv:"OPT" ~doc)
in
let opt_options =
let doc = "Pass option $(docv) to $(b,wasm-opt)" in
Arg.(value & opt_all string [] & info [ "binaryen-opt" ] ~docv:"OPT" ~doc)
in
let merge_options =
let doc = "Pass option $(docv) to $(b,wasm-merge)" in
Arg.(value & opt_all string [] & info [ "binaryen-merge" ] ~docv:"OPT" ~doc)
in
let build_t input_modules output_file variables common opt merge =
`Ok
{ input_modules; output_file; variables; binaryen_options = { common; opt; merge } }
in
let t =
Term.(
const build_t
$ input_modules
$ output_file
$ variable_options
$ binaryen_options
$ opt_options
$ merge_options)
in
Term.ret t

let make_info ~name ~doc ~description =
let man =
[ `S "DESCRIPTION"
; `P description
; `S "BUGS"
; `P
"Bugs are tracked on github at \
$(i,https://github.com/ocsigen/js_of_ocaml/issues)."
; `S "SEE ALSO"
; `P "wasm_of_ocaml(1)"
; `S "AUTHORS"
; `P "Jerome Vouillon, Hugo Heuzard."
; `S "LICENSE"
; `P "Copyright (C) 2010-2025."
; `P
"wasmoo_util is free software, you can redistribute it and/or modify it under \
the terms of the GNU Lesser General Public License as published by the Free \
Software Foundation, with linking exception; either version 2.1 of the License, \
or (at your option) any later version."
]
in
let version =
match Js_of_ocaml_compiler.Compiler_version.git_version with
| "" -> Js_of_ocaml_compiler.Compiler_version.s
| v -> Printf.sprintf "%s+%s" Js_of_ocaml_compiler.Compiler_version.s v
in
Cmd.info name ~version ~doc ~man

let preprocess_info =
make_info
~name:"pp"
~doc:"Wasm text file preprocessor"
~description:"$(b,wasmoo_util pp) is a Wasm text file preprocessor."

let link_info =
make_info
~name:"link"
~doc:"Wasm linker"
~description:
"$(b,wasmoo_util link) is a Wasm linker. It takes as input a list of Wasm text \
files, preprocesses them, links them together, and outputs a single Wasm binary \
module"

let info =
make_info
~name:"wasmoo_util"
~doc:"Wasm utilities"
~description:"wasmoo_util is a collection of utilities for $(b,wasm_of_ocaml)"
52 changes: 52 additions & 0 deletions compiler/bin-wasmoo_util/cmd_arg.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
(* Wasm_of_ocaml compiler
* http://www.ocsigen.org/js_of_ocaml/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, with linking exception;
* either version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*)

type variables =
{ enable : string list
; disable : string list
; set : (string * string) list
}

type preprocess_options =
{ input_file : string option
; output_file : string option
; variables : variables
}

val preprocess_options : preprocess_options Cmdliner.Term.t

val preprocess_info : Cmdliner.Cmd.info

type binaryen_options =
{ common : string list
; opt : string list
; merge : string list
}

type link_options =
{ input_modules : (string * string) list
; output_file : string
; variables : variables
; binaryen_options : binaryen_options
}

val link_options : link_options Cmdliner.Term.t

val link_info : Cmdliner.Cmd.info

val info : Cmdliner.Cmd.info
17 changes: 17 additions & 0 deletions compiler/bin-wasmoo_util/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
(executable
(name wasmoo_util)
(public_name wasmoo_util)
(package wasm_of_ocaml-compiler)
(libraries wasm_of_ocaml-compiler jsoo_cmdline cmdliner))

(rule
(targets wasmoo_util.1)
(action
(with-stdout-to
%{targets}
(run %{bin:wasmoo_util} --help=groff))))

(install
(section man)
(package wasm_of_ocaml-compiler)
(files wasmoo_util.1))
Loading

0 comments on commit 8e47ba1

Please sign in to comment.