From f1d0369778d8351559debb4ffad68f0fab6ea9cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Vouillon?= Date: Tue, 4 Jul 2023 15:27:47 +0200 Subject: [PATCH 01/26] Add wasm_files option and wasmoo_runtime META file entry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Vouillon --- doc/reference/dune/executable.rst | 3 +++ src/dune_findlib/meta.ml | 9 +++++++-- src/dune_findlib/package0.ml | 1 + src/dune_findlib/package0.mli | 1 + src/dune_rules/dune_package.ml | 4 ++++ src/dune_rules/findlib.ml | 2 ++ src/dune_rules/gen_meta.ml | 5 +++++ src/dune_rules/inline_tests.ml | 2 +- src/dune_rules/install_rules.ml | 8 +++++++- src/dune_rules/jsoo/js_of_ocaml.ml | 13 ++++++++++++- src/dune_rules/jsoo/js_of_ocaml.mli | 2 ++ src/dune_rules/jsoo/jsoo_rules.ml | 9 ++++++++- src/dune_rules/lib_info.ml | 7 +++++++ src/dune_rules/lib_info.mli | 2 ++ src/dune_rules/stanzas/library.ml | 4 ++++ 15 files changed, 66 insertions(+), 6 deletions(-) diff --git a/doc/reference/dune/executable.rst b/doc/reference/dune/executable.rst index 6521f17a652..c4453f4b155 100644 --- a/doc/reference/dune/executable.rst +++ b/doc/reference/dune/executable.rst @@ -258,6 +258,9 @@ options using ``(js_of_ocaml ())``. - ``(javascript_files ())`` to specify ``js_of_ocaml`` JavaScript runtime files. +- ``(wasm_files ())`` to specify ``wasm_of_ocaml`` + JavaScript and Wasm runtime files. + - ``(compilation_mode )`` where ``>`` is either ``whole_program`` or ``separate``. This is only available inside ``executable`` stanzas. diff --git a/src/dune_findlib/meta.ml b/src/dune_findlib/meta.ml index 34715f2c013..b05db277f81 100644 --- a/src/dune_findlib/meta.ml +++ b/src/dune_findlib/meta.ml @@ -332,8 +332,13 @@ let pp_print_string s = let pp_quoted_value var = match var with - | "archive" | "plugin" | "requires" | "ppx_runtime_deps" | "linkopts" | "jsoo_runtime" - -> pp_print_text + | "archive" + | "plugin" + | "requires" + | "ppx_runtime_deps" + | "linkopts" + | "jsoo_runtime" + | "wasmoo_runtime" -> pp_print_text | _ -> pp_print_string ;; diff --git a/src/dune_findlib/package0.ml b/src/dune_findlib/package0.ml index 8d42b30791c..5e8152c1612 100644 --- a/src/dune_findlib/package0.ml +++ b/src/dune_findlib/package0.ml @@ -25,6 +25,7 @@ let make_archives t var preds = let version t = Vars.get t.vars "version" Ps.empty let description t = Vars.get t.vars "description" Ps.empty let jsoo_runtime t = get_paths t "jsoo_runtime" Ps.empty +let wasmoo_runtime t = get_paths t "wasmoo_runtime" Ps.empty let requires t = Vars.get_words t.vars "requires" preds diff --git a/src/dune_findlib/package0.mli b/src/dune_findlib/package0.mli index 83e8ff5b809..e736926ac5e 100644 --- a/src/dune_findlib/package0.mli +++ b/src/dune_findlib/package0.mli @@ -11,6 +11,7 @@ val meta_fn : Filename.t val version : t -> string option val description : t -> string option val jsoo_runtime : t -> Path.t list +val wasmoo_runtime : t -> Path.t list val requires : t -> Lib_name.t list val exports : t -> Lib_name.t list val ppx_runtime_deps : t -> Lib_name.t list diff --git a/src/dune_rules/dune_package.ml b/src/dune_rules/dune_package.ml index d14728342ba..8aa155f9b65 100644 --- a/src/dune_rules/dune_package.ml +++ b/src/dune_rules/dune_package.ml @@ -104,6 +104,7 @@ module Lib = struct in let melange_runtime_deps = additional_paths (Lib_info.melange_runtime_deps info) in let jsoo_runtime = Lib_info.jsoo_runtime info in + let wasmoo_runtime = Lib_info.wasmoo_runtime info in let virtual_ = Option.is_some (Lib_info.virtual_ info) in let instrumentation_backend = Lib_info.instrumentation_backend info in let native_archives = @@ -137,6 +138,7 @@ module Lib = struct ; paths "foreign_dll_files" foreign_dll_files ; paths "native_archives" native_archives ; paths "jsoo_runtime" jsoo_runtime + ; paths "wasmoo_runtime" wasmoo_runtime ; Lib_dep.L.field_encode requires ~name:"requires" ; libs "ppx_runtime_deps" ppx_runtime_deps ; field_o "implements" (no_loc Lib_name.encode) implements @@ -212,6 +214,7 @@ module Lib = struct and+ foreign_dll_files = paths "foreign_dll_files" and+ native_archives = paths "native_archives" and+ jsoo_runtime = paths "jsoo_runtime" + and+ wasmoo_runtime = paths "wasmoo_runtime" and+ melange_runtime_deps = paths "melange_runtime_deps" and+ requires = field_l "requires" (Lib_dep.decode ~allow_re_export:true) and+ ppx_runtime_deps = libs "ppx_runtime_deps" @@ -281,6 +284,7 @@ module Lib = struct ~native_archives:(Files native_archives) ~foreign_dll_files ~jsoo_runtime + ~wasmoo_runtime ~preprocess ~enabled ~virtual_deps diff --git a/src/dune_rules/findlib.ml b/src/dune_rules/findlib.ml index 4029c5d2b67..73228dde5e4 100644 --- a/src/dune_rules/findlib.ml +++ b/src/dune_rules/findlib.ml @@ -141,6 +141,7 @@ let to_dune_library (t : Findlib.Package.t) ~dir_contents ~ext_lib ~external_loc let public_headers = Lib_info.File_deps.External [] in let plugins = Findlib.Package.plugins t in let jsoo_runtime = Findlib.Package.jsoo_runtime t in + let wasmoo_runtime = Findlib.Package.wasmoo_runtime t in let melange_runtime_deps = Lib_info.File_deps.External [] in let preprocess = Preprocess.Per_module.no_preprocessing () in let virtual_ = None in @@ -237,6 +238,7 @@ let to_dune_library (t : Findlib.Package.t) ~dir_contents ~ext_lib ~external_loc ~native_archives:(Files native_archives) ~foreign_dll_files:[] ~jsoo_runtime + ~wasmoo_runtime ~preprocess ~enabled ~virtual_deps diff --git a/src/dune_rules/gen_meta.ml b/src/dune_rules/gen_meta.ml index b96a1f03b6c..d04fef2f695 100644 --- a/src/dune_rules/gen_meta.ml +++ b/src/dune_rules/gen_meta.ml @@ -158,6 +158,11 @@ let gen_lib pub_name lib ~version = | l -> let l = List.map l ~f:Path.basename in [ rule "jsoo_runtime" [] Set (String.concat l ~sep:" ") ]) + ; (match Lib_info.wasmoo_runtime info with + | [] -> [] + | l -> + let l = List.map l ~f:Path.basename in + [ rule "wasmoo_runtime" [] Set (String.concat l ~sep:" ") ]) ] ;; diff --git a/src/dune_rules/inline_tests.ml b/src/dune_rules/inline_tests.ml index 5d63bfddf7d..491d6cd418e 100644 --- a/src/dune_rules/inline_tests.ml +++ b/src/dune_rules/inline_tests.ml @@ -153,7 +153,7 @@ include Sub_system.Register_end_point (struct let js_of_ocaml = Js_of_ocaml.In_context.make ~dir - { lib.buildable.js_of_ocaml with javascript_files = [] } + { lib.buildable.js_of_ocaml with javascript_files = []; wasm_files = [] } in Compilation_context.create () diff --git a/src/dune_rules/install_rules.ml b/src/dune_rules/install_rules.ml index 28b6f36cb6a..a6c93b4d5b6 100644 --- a/src/dune_rules/install_rules.ml +++ b/src/dune_rules/install_rules.ml @@ -110,11 +110,17 @@ end = struct (List.rev_concat_map ~f:(List.rev_map ~f:(fun f -> Section.Lib, f)) (let { Mode.Dict.byte; native } = Lib_info.archives lib in + let jsoo_files = + (* A same runtime file can be used both for jsoo and wasmoo *) + List.sort_uniq + ~compare:Path.Build.compare + (Lib_info.jsoo_runtime lib @ Lib_info.wasmoo_runtime lib) + in [ byte ; native ; foreign_archives ; Lib_info.eval_native_archives_exn lib ~modules - ; Lib_info.jsoo_runtime lib + ; jsoo_files ])) (List.rev_map ~f:(fun f -> Section.Libexec, f) (Lib_info.plugins lib).native) ;; diff --git a/src/dune_rules/jsoo/js_of_ocaml.ml b/src/dune_rules/jsoo/js_of_ocaml.ml index b8876d01eec..1464a765923 100644 --- a/src/dune_rules/jsoo/js_of_ocaml.ml +++ b/src/dune_rules/jsoo/js_of_ocaml.ml @@ -120,6 +120,7 @@ module In_buildable = struct type t = { flags : Ordered_set_lang.Unexpanded.t Flags.t ; javascript_files : string list + ; wasm_files : string list ; compilation_mode : Compilation_mode.t option ; sourcemap : Sourcemap.t option } @@ -137,6 +138,7 @@ module In_buildable = struct ; link = flags (* we set link as well to preserve the old semantic *) } ; javascript_files + ; wasm_files = [] ; compilation_mode = None ; sourcemap = None }) @@ -144,6 +146,11 @@ module In_buildable = struct fields (let+ flags = Flags.decode and+ javascript_files = field "javascript_files" (repeat string) ~default:[] + and+ wasm_files = + field + "wasm_files" + (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> repeat string) + ~default:[] and+ compilation_mode = if executable then @@ -159,12 +166,13 @@ module In_buildable = struct (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> Sourcemap.decode) else return None in - { flags; javascript_files; compilation_mode; sourcemap }) + { flags; javascript_files; wasm_files; compilation_mode; sourcemap }) ;; let default = { flags = Flags.standard ; javascript_files = [] + ; wasm_files = [] ; compilation_mode = None ; sourcemap = None } @@ -175,6 +183,7 @@ module In_context = struct type t = { flags : Ordered_set_lang.Unexpanded.t Flags.t ; javascript_files : Path.Build.t list + ; wasm_files : Path.Build.t list ; compilation_mode : Compilation_mode.t option ; sourcemap : Sourcemap.t option } @@ -183,6 +192,7 @@ module In_context = struct { flags = x.flags ; javascript_files = List.map ~f:(fun name -> Path.Build.relative dir name) x.javascript_files + ; wasm_files = List.map ~f:(fun name -> Path.Build.relative dir name) x.wasm_files ; compilation_mode = x.compilation_mode ; sourcemap = x.sourcemap } @@ -191,6 +201,7 @@ module In_context = struct let default = { flags = Flags.standard ; javascript_files = [] + ; wasm_files = [] ; compilation_mode = None ; sourcemap = None } diff --git a/src/dune_rules/jsoo/js_of_ocaml.mli b/src/dune_rules/jsoo/js_of_ocaml.mli index 0716f35ebde..d471bdde081 100644 --- a/src/dune_rules/jsoo/js_of_ocaml.mli +++ b/src/dune_rules/jsoo/js_of_ocaml.mli @@ -55,6 +55,7 @@ module In_buildable : sig type t = { flags : Flags.Spec.t ; javascript_files : string list + ; wasm_files : string list ; compilation_mode : Compilation_mode.t option ; sourcemap : Sourcemap.t option } @@ -67,6 +68,7 @@ module In_context : sig type t = { flags : Flags.Spec.t ; javascript_files : Path.Build.t list + ; wasm_files : Path.Build.t list ; compilation_mode : Compilation_mode.t option ; sourcemap : Sourcemap.t option } diff --git a/src/dune_rules/jsoo/jsoo_rules.ml b/src/dune_rules/jsoo/jsoo_rules.ml index 1825efeb7b0..6d02e79c3fc 100644 --- a/src/dune_rules/jsoo/jsoo_rules.ml +++ b/src/dune_rules/jsoo/jsoo_rules.ml @@ -457,6 +457,7 @@ let setup_separate_compilation_rules sctx components = let in_context = { Js_of_ocaml.In_context.flags = Js_of_ocaml.Flags.standard ; javascript_files = [] + ; wasm_files = [] ; compilation_mode = None ; sourcemap = None } @@ -510,7 +511,13 @@ let build_exe = let sctx = Compilation_context.super_context cc in let dir = Compilation_context.dir cc in - let { Js_of_ocaml.In_context.javascript_files; flags; compilation_mode; sourcemap } = + let { Js_of_ocaml.In_context.javascript_files + ; wasm_files = _ + ; flags + ; compilation_mode + ; sourcemap + } + = in_context in let target = Path.Build.set_extension src ~ext:Js_of_ocaml.Ext.exe in diff --git a/src/dune_rules/lib_info.ml b/src/dune_rules/lib_info.ml index 32a89a883f8..ca5d45f6536 100644 --- a/src/dune_rules/lib_info.ml +++ b/src/dune_rules/lib_info.ml @@ -316,6 +316,7 @@ type 'path t = ; native_archives : 'path native_archives ; foreign_dll_files : 'path list ; jsoo_runtime : 'path list + ; wasmoo_runtime : 'path list ; requires : Lib_dep.t list ; ppx_runtime_deps : (Loc.t * Lib_name.t) list ; preprocess : Preprocess.With_instrumentation.t Preprocess.Per_module.t @@ -371,6 +372,7 @@ let synopsis t = t.synopsis let wrapped t = t.wrapped let special_builtin_support t = t.special_builtin_support let jsoo_runtime t = t.jsoo_runtime +let wasmoo_runtime t = t.wasmoo_runtime let main_module_name t = t.main_module_name let orig_src_dir t = t.orig_src_dir let best_src_dir t = Option.value ~default:t.src_dir t.orig_src_dir @@ -414,6 +416,7 @@ let create ~native_archives ~foreign_dll_files ~jsoo_runtime + ~wasmoo_runtime ~preprocess ~enabled ~virtual_deps @@ -451,6 +454,7 @@ let create ; native_archives ; foreign_dll_files ; jsoo_runtime + ; wasmoo_runtime ; preprocess ; enabled ; virtual_deps @@ -495,6 +499,7 @@ let map t ~path_kind ~f_path ~f_obj_dir ~f_public_deps = ; foreign_dll_files = List.map ~f t.foreign_dll_files ; native_archives ; jsoo_runtime = List.map ~f t.jsoo_runtime + ; wasmoo_runtime = List.map ~f t.wasmoo_runtime ; melange_runtime_deps = File_deps.map ~f:f_public_deps t.melange_runtime_deps ; path_kind } @@ -544,6 +549,7 @@ let to_dyn ; native_archives ; foreign_dll_files ; jsoo_runtime + ; wasmoo_runtime ; preprocess = _ ; enabled = _ ; virtual_deps @@ -583,6 +589,7 @@ let to_dyn ; "native_archives", dyn_of_native_archives path native_archives ; "foreign_dll_files", list path foreign_dll_files ; "jsoo_runtime", list path jsoo_runtime + ; "wasmoo_runtime", list path wasmoo_runtime ; "requires", list Lib_dep.to_dyn requires ; "ppx_runtime_deps", list (snd Lib_name.to_dyn) ppx_runtime_deps ; "virtual_deps", list (snd Lib_name.to_dyn) virtual_deps diff --git a/src/dune_rules/lib_info.mli b/src/dune_rules/lib_info.mli index 41ea767962a..0fe1fa5868c 100644 --- a/src/dune_rules/lib_info.mli +++ b/src/dune_rules/lib_info.mli @@ -136,6 +136,7 @@ val default_implementation : _ t -> (Loc.t * Lib_name.t) option val kind : _ t -> Lib_kind.t val synopsis : _ t -> string option val jsoo_runtime : 'path t -> 'path list +val wasmoo_runtime : 'path t -> 'path list val melange_runtime_deps : 'path t -> 'path File_deps.t val obj_dir : 'path t -> 'path Obj_dir.t val virtual_ : _ t -> Modules.t Source.t option @@ -212,6 +213,7 @@ val create -> native_archives:'a native_archives -> foreign_dll_files:'a list -> jsoo_runtime:'a list + -> wasmoo_runtime:'a list -> preprocess:Preprocess.With_instrumentation.t Preprocess.Per_module.t -> enabled:Enabled_status.t Memo.t -> virtual_deps:(Loc.t * Lib_name.t) list diff --git a/src/dune_rules/stanzas/library.ml b/src/dune_rules/stanzas/library.ml index ae64703d300..44c5b9f9200 100644 --- a/src/dune_rules/stanzas/library.ml +++ b/src/dune_rules/stanzas/library.ml @@ -428,6 +428,9 @@ let to_lib_info let jsoo_runtime = List.map conf.buildable.js_of_ocaml.javascript_files ~f:(Path.Build.relative dir) in + let wasmoo_runtime = + List.map conf.buildable.js_of_ocaml.wasm_files ~f:(Path.Build.relative dir) + in let status = match conf.visibility with | Private pkg -> Lib_info.Status.Private (conf.project, pkg) @@ -566,6 +569,7 @@ let to_lib_info ~native_archives ~foreign_dll_files ~jsoo_runtime + ~wasmoo_runtime ~preprocess ~enabled ~virtual_deps From 774d877efd74511777d560dd41b6d58582d5fb1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Vouillon?= Date: Tue, 13 Jun 2023 14:47:20 +0200 Subject: [PATCH 02/26] Compilation to Wasm using Wasm_of_ocaml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Vouillon --- src/dune_rules/dir_status.ml | 122 +++++++++-- src/dune_rules/dir_status.mli | 9 +- src/dune_rules/exe.ml | 4 +- src/dune_rules/gen_rules.ml | 12 +- src/dune_rules/inline_tests.ml | 124 ++++++----- src/dune_rules/jsoo/js_of_ocaml.ml | 91 ++++++-- src/dune_rules/jsoo/js_of_ocaml.mli | 39 +++- src/dune_rules/jsoo/jsoo_rules.ml | 305 ++++++++++++++++++-------- src/dune_rules/jsoo/jsoo_rules.mli | 8 + src/dune_rules/lib_rules.ml | 28 +-- src/dune_rules/module_compilation.ml | 24 +- src/dune_rules/stanzas/executables.ml | 2 +- src/dune_rules/test_rules.ml | 40 ++-- 13 files changed, 572 insertions(+), 236 deletions(-) diff --git a/src/dune_rules/dir_status.ml b/src/dune_rules/dir_status.ml index 9047ae71529..b9ac1be90e2 100644 --- a/src/dune_rules/dir_status.ml +++ b/src/dune_rules/dir_status.ml @@ -85,6 +85,23 @@ let error_no_module_consumer ~loc (qualification : Include_subdirs.qualification ] ;; +let when_enabled ~dir ~enabled_if directory_targets = + if Path.Build.Map.is_empty directory_targets + then Memo.return directory_targets + else + (match enabled_if with + | Blang.Const const -> Memo.return const + | _ -> + (* Only evaluate the expander if the enabled_if field is + non-trivial to avoid memo cycles. If the enabled_if field is absent + from the "rule" stanza then its value will be [Const true]. *) + let* expander = Expander0.get ~dir in + Expander0.eval_blang expander enabled_if) + >>| function + | false -> Path.Build.Map.empty + | true -> directory_targets +;; + let directory_targets_of_rule ~dir { Rule_conf.targets; loc = rule_loc; enabled_if; _ } = match targets with | Infer -> @@ -114,26 +131,94 @@ let directory_targets_of_rule ~dir { Rule_conf.targets; loc = rule_loc; enabled_ completely, so just ignore this rule for now. *) acc)) in - if Path.Build.Map.is_empty directory_targets - then Memo.return directory_targets - else - (match enabled_if with - | Blang.Const const -> Memo.return const - | _ -> - (* Only evaluate the expander if the enabled_if field is - non-trivial to avoid memo cycles. If the enabled_if field is absent - from the "rule" stanza then its value will be [Const true]. *) - let* expander = Expander0.get ~dir in - Expander0.eval_blang expander enabled_if) - >>| (function - | false -> Path.Build.Map.empty - | true -> directory_targets) + when_enabled ~dir ~enabled_if directory_targets +;; + +let jsoo_wasm_enabled + ~(jsoo_submodes : + dir:Import.Path.Build.t + -> submodes:Js_of_ocaml.Submode.Set.t option + -> Js_of_ocaml.Submode.t list Memo.t) + ~dir + ~submodes + = + let+ submodes = jsoo_submodes ~dir ~submodes in + List.mem ~equal:Poly.equal submodes Wasm +;; + +let directory_targets_of_executables + ~jsoo_submodes + ~dir + { Executables.names; modes; enabled_if; buildable; _ } + = + let* directory_targets = + let* wasm_enabled = + jsoo_wasm_enabled ~jsoo_submodes ~dir ~submodes:buildable.js_of_ocaml.submodes + in + let* explicit_js_mode = + let+ scope = Scope.DB.find_by_dir dir in + let project = Scope.project scope in + Dune_project.explicit_js_mode project + in + if Executables.Link_mode.( + Map.mem modes js || ((not explicit_js_mode) && Map.mem modes byte)) + && wasm_enabled + then + Memo.List.fold_left + (Nonempty_list.to_list names) + ~init:Path.Build.Map.empty + ~f:(fun acc (_, name) -> + let dir_target = Path.Build.relative dir (name ^ Js_of_ocaml.Ext.wasm_dir) in + Path.Build.Map.set acc dir_target buildable.loc |> Memo.return) + else Memo.return Path.Build.Map.empty + in + when_enabled ~dir ~enabled_if directory_targets +;; + +let directory_targets_of_library + ~jsoo_submodes + ~dir + { Library.sub_systems; name; enabled_if; buildable; _ } + = + let* directory_targets = + match Sub_system_name.Map.find sub_systems Inline_tests_info.Tests.name with + | Some (Inline_tests_info.Tests.T { modes; loc; enabled_if; _ }) + when Inline_tests_info.Mode_conf.Set.mem modes Javascript -> + let* directory_targets = + let+ wasm_enabled = + jsoo_wasm_enabled ~jsoo_submodes ~dir ~submodes:buildable.js_of_ocaml.submodes + in + if wasm_enabled + then ( + let lib_name = snd name in + let inline_test_dir = + let inline_test_name = + sprintf "%s.inline-tests" (Lib_name.Local.to_string lib_name) + in + Path.Build.relative dir ("." ^ inline_test_name) + in + let name = + sprintf "inline_test_runner_%s" (Lib_name.Local.to_string lib_name) + in + let dir_target = + Path.Build.relative inline_test_dir (name ^ Js_of_ocaml.Ext.wasm_dir) + in + Path.Build.Map.singleton dir_target loc) + else Path.Build.Map.empty + in + when_enabled ~dir ~enabled_if directory_targets + | _ -> Memo.return Path.Build.Map.empty + in + when_enabled ~dir ~enabled_if directory_targets ;; -let extract_directory_targets ~dir stanzas = +let extract_directory_targets ~jsoo_submodes ~dir stanzas = Memo.parallel_map stanzas ~f:(fun stanza -> match Stanza.repr stanza with | Rule_conf.T rule -> directory_targets_of_rule ~dir rule + | Executables.T exes | Tests.T { exes; _ } -> + directory_targets_of_executables ~jsoo_submodes ~dir exes + | Library.T lib -> directory_targets_of_library ~jsoo_submodes ~dir lib | Coq_stanza.Theory.T m -> (* It's unfortunate that we need to pull in the coq rules here. But we don't have a generic mechanism for this yet. *) @@ -280,15 +365,16 @@ end = struct ;; end -let directory_targets t ~dir = +let directory_targets t ~jsoo_submodes ~dir = match t with | Lock_dir | Generated | Source_only _ | Is_component_of_a_group_but_not_the_root _ -> Memo.return Path.Build.Map.empty | Standalone (_, dune_file) -> - Dune_file.stanzas dune_file >>= extract_directory_targets ~dir + Dune_file.stanzas dune_file >>= extract_directory_targets ~jsoo_submodes ~dir | Group_root { components; dune_file; _ } -> let f ~dir stanzas acc = - extract_directory_targets ~dir stanzas >>| Path.Build.Map.superpose acc + extract_directory_targets ~jsoo_submodes ~dir stanzas + >>| Path.Build.Map.superpose acc in let* init = let* stanzas = Dune_file.stanzas dune_file in diff --git a/src/dune_rules/dir_status.mli b/src/dune_rules/dir_status.mli index 0980d46911d..c42a0d592ff 100644 --- a/src/dune_rules/dir_status.mli +++ b/src/dune_rules/dir_status.mli @@ -42,4 +42,11 @@ module DB : sig val get : dir:Path.Build.t -> t Memo.t end -val directory_targets : t -> dir:Path.Build.t -> Loc.t Path.Build.Map.t Memo.t +val directory_targets + : t + -> jsoo_submodes: + (dir:Import.Path.Build.t + -> submodes:Js_of_ocaml.Submode.Set.t option + -> Js_of_ocaml.Submode.t list Memo.t) + -> dir:Path.Build.t + -> Loc.t Path.Build.Map.t Memo.t diff --git a/src/dune_rules/exe.ml b/src/dune_rules/exe.ml index 906ba06739a..23941e5e22f 100644 --- a/src/dune_rules/exe.ml +++ b/src/dune_rules/exe.ml @@ -27,7 +27,7 @@ module Linkage = struct let native = { mode = Native; ext = ".exe"; flags = [] } let is_native x = x.mode = Native - let is_js x = x.mode = Byte && x.ext = Js_of_ocaml.Ext.exe + let is_js x = x.mode = Byte && x.ext = Js_of_ocaml.Ext.exe ~submode:JS let is_byte x = x.mode = Byte && not (is_js x) let custom_with_ext ~ext ocaml_version = @@ -45,7 +45,7 @@ module Linkage = struct | Ok _ -> native ;; - let js = { mode = Byte; ext = Js_of_ocaml.Ext.exe; flags = [] } + let js = { mode = Byte; ext = Js_of_ocaml.Ext.exe ~submode:JS; flags = [] } let is_plugin t = List.mem (List.map ~f:Mode.plugin_ext Mode.all) t.ext ~equal:String.equal diff --git a/src/dune_rules/gen_rules.ml b/src/dune_rules/gen_rules.ml index c752c5d9566..9e23ac38706 100644 --- a/src/dune_rules/gen_rules.ml +++ b/src/dune_rules/gen_rules.ml @@ -137,7 +137,10 @@ end = struct js = Some (List.map (Nonempty_list.to_list exes.names) ~f:(fun (_, exe) -> - Path.Build.relative dir (exe ^ Js_of_ocaml.Ext.exe))) + [ Path.Build.relative dir (exe ^ Js_of_ocaml.Ext.exe ~submode:JS) + ; Path.Build.relative dir (exe ^ Js_of_ocaml.Ext.exe ~submode:Wasm) + ]) + |> List.flatten) }) | Alias_conf.T alias -> let+ () = Simple_rules.alias sctx alias ~dir ~expander in @@ -520,7 +523,12 @@ let gen_rules_regular_directory sctx ~src_dir ~components ~dir = in let+ rules = let+ make_rules = - let+ directory_targets = Dir_status.directory_targets dir_status ~dir in + let+ directory_targets = + Dir_status.directory_targets + dir_status + ~jsoo_submodes:Jsoo_rules.jsoo_submodes + ~dir + in let allowed_subdirs = let automatic = Automatic_subdir.subdirs components in let toplevel = diff --git a/src/dune_rules/inline_tests.ml b/src/dune_rules/inline_tests.ml index 491d6cd418e..b0373fae180 100644 --- a/src/dune_rules/inline_tests.ml +++ b/src/dune_rules/inline_tests.ml @@ -68,6 +68,18 @@ include Sub_system.Register_end_point (struct module Mode_conf = Inline_tests_info.Mode_conf module Info = Inline_tests_info.Tests + let configurations ~dir modes submodes = + let open Memo.O in + Memo.sequential_map (Mode_conf.Set.to_list modes) ~f:(fun (mode : Mode_conf.t) -> + match mode with + | Native | Best -> Memo.return [ mode, ".exe" ] + | Byte -> Memo.return [ mode, ".bc" ] + | Javascript -> + let+ submodes = Jsoo_rules.jsoo_submodes ~dir ~submodes in + List.map submodes ~f:(fun submode -> mode, Js_of_ocaml.Ext.exe ~submode)) + >>| List.flatten + ;; + let gen_rules c ~expander ~(info : Info.t) ~backends = let { Sub_system.Library_compilation_context.super_context = sctx ; dir @@ -237,17 +249,14 @@ include Sub_system.Register_end_point (struct else Sandbox_config.needs_sandboxing in let deps, sandbox = Dep_conf_eval.unnamed ~sandbox info.deps ~expander in - let action (mode : Mode_conf.t) (flags : string list Action_builder.t) + let action + (mode : Mode_conf.t) + (ext : string) + (flags : string list Action_builder.t) : Action.t Action_builder.t = (* [action] needs to run from [dir] as we use [dir] to resolve the exe path in case of a custom [runner] *) - let ext = - match mode with - | Native | Best -> ".exe" - | Javascript -> Js_of_ocaml.Ext.exe - | Byte -> ".bc" - in let custom_runner = match mode with | Native | Best | Byte -> None @@ -308,58 +317,55 @@ include Sub_system.Register_end_point (struct List.concat l in let source_files = List.concat_map source_modules ~f:Module.sources in - Memo.parallel_iter_seq - (Mode_conf.Set.to_seq info.modes) - ~f:(fun (mode : Mode_conf.t) -> - let partition_file = - Path.Build.relative inline_test_dir ("partitions-" ^ Mode_conf.to_string mode) - in - let* () = - match partitions_flags with - | None -> Memo.return () - | Some partitions_flags -> - let open Action_builder.O in - action mode partitions_flags - >>| Action.Full.make ~sandbox - |> Action_builder.with_stdout_to partition_file - |> Super_context.add_rule sctx ~dir ~loc - in - let* runtest_alias = - match mode with - | Native | Best | Byte -> Memo.return Alias0.runtest - | Javascript -> Jsoo_rules.js_of_ocaml_runtest_alias ~dir - in - Super_context.add_alias_action - sctx - ~dir - ~loc:info.loc - (Alias.make ~dir runtest_alias) - (let open Action_builder.O in - let+ actions = - let* partitions_flags = - match partitions_flags with - | None -> Action_builder.return [ None ] - | Some _ -> - let+ partitions = - Action_builder.lines_of (Path.build partition_file) - in - List.map ~f:(fun x -> Some x) partitions - in - List.map partitions_flags ~f:(fun p -> action mode (flags p)) - |> Action_builder.all - and+ () = Action_builder.paths source_files in - match actions with - | [] -> Action.Full.empty - | _ :: _ -> - let run_tests = Action.concurrent actions in - let diffs = - List.map source_files ~f:(fun fn -> - Path.as_in_build_dir_exn fn - |> Path.Build.extend_basename ~suffix:".corrected" - |> Promote.Diff_action.diff ~optional:true fn) - |> Action.concurrent - in - Action.Full.make ~sandbox @@ Action.progn [ run_tests; diffs ])) + let* confs = configurations ~dir info.modes lib.buildable.js_of_ocaml.submodes in + Memo.parallel_iter confs ~f:(fun ((mode : Mode_conf.t), ext) -> + let partition_file = + Path.Build.relative inline_test_dir ("partitions-" ^ Mode_conf.to_string mode) + in + let* () = + match partitions_flags with + | None -> Memo.return () + | Some partitions_flags -> + let open Action_builder.O in + action mode ext partitions_flags + >>| Action.Full.make ~sandbox + |> Action_builder.with_stdout_to partition_file + |> Super_context.add_rule sctx ~dir ~loc + in + let* runtest_alias = + match mode with + | Native | Best | Byte -> Memo.return Alias0.runtest + | Javascript -> Jsoo_rules.js_of_ocaml_runtest_alias ~dir + in + Super_context.add_alias_action + sctx + ~dir + ~loc:info.loc + (Alias.make ~dir runtest_alias) + (let open Action_builder.O in + let+ actions = + let* partitions_flags = + match partitions_flags with + | None -> Action_builder.return [ None ] + | Some _ -> + let+ partitions = Action_builder.lines_of (Path.build partition_file) in + List.map ~f:(fun x -> Some x) partitions + in + List.map partitions_flags ~f:(fun p -> action mode ext (flags p)) + |> Action_builder.all + and+ () = Action_builder.paths source_files in + match actions with + | [] -> Action.Full.empty + | _ :: _ -> + let run_tests = Action.concurrent actions in + let diffs = + List.map source_files ~f:(fun fn -> + Path.as_in_build_dir_exn fn + |> Path.Build.extend_basename ~suffix:".corrected" + |> Promote.Diff_action.diff ~optional:true fn) + |> Action.concurrent + in + Action.Full.make ~sandbox @@ Action.progn [ run_tests; diffs ])) ;; let gen_rules c ~(info : Info.t) ~backends = diff --git a/src/dune_rules/jsoo/js_of_ocaml.ml b/src/dune_rules/jsoo/js_of_ocaml.ml index 1464a765923..9cdbd1801dd 100644 --- a/src/dune_rules/jsoo/js_of_ocaml.ml +++ b/src/dune_rules/jsoo/js_of_ocaml.ml @@ -1,14 +1,9 @@ open Import open Dune_lang.Decoder -module Ext = struct - type t = string - - let exe = ".bc.js" - let cmo = ".cmo.js" - let cma = ".cma.js" - let runtime = ".bc.runtime.js" -end +(* (js_of_ocaml ...) options are also used when producing Wasm code + with wasm_of_ocaml, since the compilation process is similar and + generates a JavaScript file with basically the same behavior. *) let field_oslu name = Ordered_set_lang.Unexpanded.field name @@ -100,6 +95,39 @@ module Flags = struct ;; end +module Submode = struct + type t = + | JS + | Wasm + + module Set = struct + type t = + { js : bool + ; wasm : bool + } + + let decode = + map + (repeat1 (enum [ "js", JS; "wasm", Wasm ])) + ~f:(fun l -> + List.fold_left + ~f:(fun t submode -> + match submode with + | JS -> { t with js = true } + | Wasm -> { t with wasm = true }) + ~init:{ js = false; wasm = false } + l) + ;; + + let equal x y = x.js = y.js && x.wasm = y.wasm + + let to_list x = + let l = if x.wasm then [ Wasm ] else [] in + if x.js then JS :: l else l + ;; + end +end + module Compilation_mode = struct type t = | Whole_program @@ -119,6 +147,7 @@ end module In_buildable = struct type t = { flags : Ordered_set_lang.Unexpanded.t Flags.t + ; submodes : Submode.Set.t option ; javascript_files : string list ; wasm_files : string list ; compilation_mode : Compilation_mode.t option @@ -137,6 +166,7 @@ module In_buildable = struct ; compile = flags ; link = flags (* we set link as well to preserve the old semantic *) } + ; submodes = None ; javascript_files ; wasm_files = [] ; compilation_mode = None @@ -145,6 +175,10 @@ module In_buildable = struct else fields (let+ flags = Flags.decode + and+ submodes = + field_o + "submodes" + (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> Submode.Set.decode) and+ javascript_files = field "javascript_files" (repeat string) ~default:[] and+ wasm_files = field @@ -166,11 +200,12 @@ module In_buildable = struct (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> Sourcemap.decode) else return None in - { flags; javascript_files; wasm_files; compilation_mode; sourcemap }) + { flags; submodes; javascript_files; wasm_files; compilation_mode; sourcemap }) ;; let default = { flags = Flags.standard + ; submodes = None ; javascript_files = [] ; wasm_files = [] ; compilation_mode = None @@ -182,6 +217,7 @@ end module In_context = struct type t = { flags : Ordered_set_lang.Unexpanded.t Flags.t + ; submodes : Submode.Set.t option ; javascript_files : Path.Build.t list ; wasm_files : Path.Build.t list ; compilation_mode : Compilation_mode.t option @@ -190,6 +226,7 @@ module In_context = struct let make ~(dir : Path.Build.t) (x : In_buildable.t) = { flags = x.flags + ; submodes = x.submodes ; javascript_files = List.map ~f:(fun name -> Path.Build.relative dir name) x.javascript_files ; wasm_files = List.map ~f:(fun name -> Path.Build.relative dir name) x.wasm_files @@ -200,6 +237,7 @@ module In_context = struct let default = { flags = Flags.standard + ; submodes = None ; javascript_files = [] ; wasm_files = [] ; compilation_mode = None @@ -208,12 +246,29 @@ module In_context = struct ;; end +module Ext = struct + type t = string + + let select ~submode js wasm = + match submode with + | Submode.JS -> js + | Wasm -> wasm + ;; + + let exe ~submode = select ~submode ".bc.js" ".bc.wasm.js" + let cmo ~submode = select ~submode ".cmo.js" ".wasmo" + let cma ~submode = select ~submode ".cma.js" ".wasma" + let runtime ~submode = select ~submode ".bc.runtime.js" ".bc.runtime.wasma" + let wasm_dir = ".bc.wasm.assets" +end + module Env = struct type 'a t = { compilation_mode : Compilation_mode.t option ; sourcemap : Sourcemap.t option ; runtest_alias : Alias.Name.t option ; flags : 'a Flags.t + ; submodes : Submode.Set.t option } let decode = @@ -224,20 +279,26 @@ module Env = struct "sourcemap" (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> Sourcemap.decode) and+ runtest_alias = field_o "runtest_alias" Dune_lang.Alias.decode - and+ flags = Flags.decode in + and+ flags = Flags.decode + and+ submodes = + field_o + "submodes" + (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> Submode.Set.decode) + in Option.iter ~f:Alias0.register_as_standard runtest_alias; - { compilation_mode; sourcemap; runtest_alias; flags } + { compilation_mode; sourcemap; runtest_alias; flags; submodes } ;; - let equal { compilation_mode; sourcemap; runtest_alias; flags } t = + let equal { compilation_mode; sourcemap; submodes; runtest_alias; flags } t = Option.equal Compilation_mode.equal compilation_mode t.compilation_mode && Option.equal Sourcemap.equal sourcemap t.sourcemap && Option.equal Alias.Name.equal runtest_alias t.runtest_alias && Flags.equal Ordered_set_lang.Unexpanded.equal flags t.flags + && Option.equal Submode.Set.equal submodes t.submodes ;; - let map ~f { compilation_mode; sourcemap; runtest_alias; flags } = - { compilation_mode; sourcemap; runtest_alias; flags = Flags.map ~f flags } + let map ~f { compilation_mode; sourcemap; runtest_alias; flags; submodes } = + { compilation_mode; sourcemap; runtest_alias; flags = Flags.map ~f flags; submodes } ;; let empty = @@ -245,6 +306,7 @@ module Env = struct ; sourcemap = None ; runtest_alias = None ; flags = Flags.standard + ; submodes = None } ;; @@ -253,6 +315,7 @@ module Env = struct ; sourcemap = None ; runtest_alias = None ; flags = Flags.default ~profile + ; submodes = None } ;; end diff --git a/src/dune_rules/jsoo/js_of_ocaml.mli b/src/dune_rules/jsoo/js_of_ocaml.mli index d471bdde081..e0f83341c97 100644 --- a/src/dune_rules/jsoo/js_of_ocaml.mli +++ b/src/dune_rules/jsoo/js_of_ocaml.mli @@ -1,14 +1,5 @@ open Import -module Ext : sig - type t = string - - val exe : t - val cmo : t - val cma : t - val runtime : t -end - module Flags : sig type 'flags t = { build_runtime : 'flags @@ -45,6 +36,23 @@ module Sourcemap : sig | File end +module Submode : sig + type t = + | JS + | Wasm + + type submode := t + + module Set : sig + type t = + { js : bool + ; wasm : bool + } + + val to_list : t -> submode list + end +end + module Compilation_mode : sig type t = | Whole_program @@ -54,6 +62,7 @@ end module In_buildable : sig type t = { flags : Flags.Spec.t + ; submodes : Submode.Set.t option ; javascript_files : string list ; wasm_files : string list ; compilation_mode : Compilation_mode.t option @@ -67,6 +76,7 @@ end module In_context : sig type t = { flags : Flags.Spec.t + ; submodes : Submode.Set.t option ; javascript_files : Path.Build.t list ; wasm_files : Path.Build.t list ; compilation_mode : Compilation_mode.t option @@ -77,12 +87,23 @@ module In_context : sig val default : t end +module Ext : sig + type t = string + + val exe : submode:Submode.t -> t + val cmo : submode:Submode.t -> t + val cma : submode:Submode.t -> t + val runtime : submode:Submode.t -> t + val wasm_dir : t +end + module Env : sig type 'a t = { compilation_mode : Compilation_mode.t option ; sourcemap : Sourcemap.t option ; runtest_alias : Alias.Name.t option ; flags : 'a Flags.t + ; submodes : Submode.Set.t option } val map : f:('a -> 'b) -> 'a t -> 'b t diff --git a/src/dune_rules/jsoo/jsoo_rules.ml b/src/dune_rules/jsoo/jsoo_rules.ml index 6d02e79c3fc..216ae45cb18 100644 --- a/src/dune_rules/jsoo/jsoo_rules.ml +++ b/src/dune_rules/jsoo/jsoo_rules.ml @@ -14,6 +14,7 @@ let jsoo_env = { Js_of_ocaml.Env.compilation_mode = Option.first_some local.compilation_mode parent.compilation_mode ; sourcemap = Option.first_some local.sourcemap parent.sourcemap + ; submodes = Option.first_some local.submodes parent.submodes ; runtest_alias = Option.first_some local.runtest_alias parent.runtest_alias ; flags = Js_of_ocaml.Flags.make @@ -194,6 +195,11 @@ let jsoo ~dir sctx = "js_of_ocaml" ;; +let wasmoo ~dir sctx = + (* TODO add a hint when wasm_of_ocaml released on opam *) + Super_context.resolve_program sctx ~dir ~loc:None "wasm_of_ocaml" +;; + type sub_command = | Compile | Link @@ -212,6 +218,7 @@ let js_of_ocaml_flags t ~dir (spec : Js_of_ocaml.Flags.Spec.t) = let js_of_ocaml_rule sctx + ~(submode : Js_of_ocaml.Submode.t) ~sub_command ~dir ~(flags : _ Js_of_ocaml.Flags.t) @@ -219,9 +226,14 @@ let js_of_ocaml_rule ~spec ~target ~sourcemap + ~directory_targets = let open Action_builder.O in - let jsoo = jsoo ~dir sctx in + let jsoo = + match submode with + | JS -> jsoo ~dir sctx + | Wasm -> wasmoo ~dir sctx + in let flags = let* flags = js_of_ocaml_flags sctx ~dir flags in match sub_command with @@ -236,10 +248,12 @@ let js_of_ocaml_rule | Compile -> S [] | Link -> A "link" | Build_runtime -> A "build-runtime") - ; (match (sourcemap : Js_of_ocaml.Sourcemap.t) with - | No -> A "--no-source-map" - | Inline -> A "--source-map-inline" - | File -> + ; (match (sourcemap : Js_of_ocaml.Sourcemap.t), submode with + | No, _ -> A "--no-source-map" + | Inline, _ | File, Wasm -> + (* With wasm_of_ocaml, source maps are always inline *) + A "--source-map-inline" + | File, JS -> S [ A "--source-map" ; Hidden_targets [ Path.Build.set_extension target ~ext:".map" ] @@ -256,11 +270,20 @@ let js_of_ocaml_rule ; Target target ; spec ] + |> Action_builder.With_targets.add_directories ~directory_targets ;; -let jsoo_runtime_files = List.concat_map ~f:(fun t -> Lib_info.jsoo_runtime (Lib.info t)) +let jsoo_runtime_files ~(submode : Js_of_ocaml.Submode.t) libs = + List.concat_map + ~f:(fun t -> + (match submode with + | JS -> Lib_info.jsoo_runtime + | Wasm -> Lib_info.wasmoo_runtime) + (Lib.info t)) + libs +;; -let standalone_runtime_rule cc ~javascript_files ~target ~flags = +let standalone_runtime_rule ~submode cc ~runtime_files ~target ~flags = let dir = Compilation_context.dir cc in let sctx = Compilation_context.super_context cc in let config = @@ -274,22 +297,24 @@ let standalone_runtime_rule cc ~javascript_files ~target ~flags = [ Resolve.Memo.args (let open Resolve.Memo.O in let+ libs = libs in - Command.Args.Deps (jsoo_runtime_files libs)) - ; Deps (List.map ~f:Path.build javascript_files) + Command.Args.Deps (jsoo_runtime_files ~submode libs)) + ; Deps (List.map ~f:Path.build runtime_files) ] in let dir = Compilation_context.dir cc in js_of_ocaml_rule (Compilation_context.super_context cc) + ~submode ~sub_command:Build_runtime ~dir ~flags ~target + ~directory_targets:[] ~spec ~config:(Some config) ;; -let exe_rule cc ~linkall ~javascript_files ~src ~target ~flags = +let exe_rule ~submode cc ~linkall ~runtime_files ~src ~target ~directory_targets ~flags = let dir = Compilation_context.dir cc in let sctx = Compilation_context.super_context cc in let libs = Compilation_context.requires_link cc in @@ -313,44 +338,71 @@ let exe_rule cc ~linkall ~javascript_files ~src ~target ~flags = [ Resolve.Memo.args (let open Resolve.Memo.O in let+ libs = libs in - Command.Args.Deps (jsoo_runtime_files libs)) - ; Deps (List.map ~f:Path.build javascript_files) + Command.Args.Deps (jsoo_runtime_files ~submode libs)) + ; Deps (List.map ~f:Path.build runtime_files) ; Dep (Path.build src) ; Dyn linkall ] in - js_of_ocaml_rule sctx ~sub_command:Compile ~dir ~spec ~target ~flags ~config:None + js_of_ocaml_rule + sctx + ~submode + ~sub_command:Compile + ~dir + ~spec + ~target + ~directory_targets + ~flags + ~config:None ;; -let with_js_ext s = +let with_js_ext ~submode s = match Filename.split_extension s with - | name, ".cma" -> name ^ Js_of_ocaml.Ext.cma - | name, ".cmo" -> name ^ Js_of_ocaml.Ext.cmo + | name, ".cma" -> name ^ Js_of_ocaml.Ext.cma ~submode + | name, ".cmo" -> name ^ Js_of_ocaml.Ext.cmo ~submode | _ -> assert false ;; -let jsoo_archives ctx config lib = +let jsoo_archives ~submode ctx config lib = let info = Lib.info lib in let archives = Lib_info.archives info in match Lib.is_local lib with | true -> let obj_dir = Lib_info.obj_dir info in List.map archives.byte ~f:(fun archive -> - in_obj_dir' ~obj_dir ~config:(Some config) [ with_js_ext (Path.basename archive) ]) + in_obj_dir' + ~obj_dir + ~config:(Some config) + [ with_js_ext ~submode (Path.basename archive) ]) | false -> List.map archives.byte ~f:(fun archive -> Path.build (in_build_dir ctx ~config - [ Lib_name.to_string (Lib.name lib); with_js_ext (Path.basename archive) ])) + [ Lib_name.to_string (Lib.name lib) + ; with_js_ext ~submode (Path.basename archive) + ])) ;; -let link_rule cc ~runtime ~target ~obj_dir cm ~flags ~linkall ~link_time_code_gen = +let link_rule + ~submode + cc + ~runtime + ~target + ~directory_targets + ~obj_dir + cm + ~flags + ~linkall + ~link_time_code_gen + = let sctx = Compilation_context.super_context cc in let dir = Compilation_context.dir cc in let mod_name m = - Module_name.Unique.artifact_filename (Module.obj_name m) ~ext:Js_of_ocaml.Ext.cmo + Module_name.Unique.artifact_filename + (Module.obj_name m) + ~ext:(Js_of_ocaml.Ext.cmo ~submode) in let ctx = Super_context.context sctx |> Context.build_context in let get_all = @@ -371,20 +423,22 @@ let link_rule cc ~runtime ~target ~obj_dir cm ~flags ~linkall ~link_time_code_ge (* Special case for the stdlib because it is not referenced in the META *) let stdlib = - Path.build (in_build_dir ctx ~config [ "stdlib"; "stdlib" ^ Js_of_ocaml.Ext.cma ]) + Path.build + (in_build_dir ctx ~config [ "stdlib"; "stdlib" ^ Js_of_ocaml.Ext.cma ~submode ]) in let special_units = List.concat_map to_link ~f:(function | Lib_flags.Lib_and_module.Lib _lib -> [] | Module (obj_dir, m) -> [ in_obj_dir' ~obj_dir ~config:None [ mod_name m ] ]) in - let all_libs = List.concat_map libs ~f:(jsoo_archives ctx config) in + let all_libs = List.concat_map libs ~f:(jsoo_archives ~submode ctx config) in let all_other_modules = List.map cm ~f:(fun m -> Path.build (in_obj_dir ~obj_dir ~config:None [ mod_name m ])) in let std_exit = - Path.build (in_build_dir ctx ~config [ "stdlib"; "std_exit" ^ Js_of_ocaml.Ext.cmo ]) + Path.build + (in_build_dir ctx ~config [ "stdlib"; "std_exit" ^ Js_of_ocaml.Ext.cmo ~submode ]) in let linkall = force_linkall || linkall in Command.Args.S @@ -401,22 +455,44 @@ let link_rule cc ~runtime ~target ~obj_dir cm ~flags ~linkall ~link_time_code_ge ] in let spec = Command.Args.S [ Dep (Path.build runtime); Dyn get_all ] in - js_of_ocaml_rule sctx ~sub_command:Link ~dir ~spec ~target ~flags ~config:None + js_of_ocaml_rule + sctx + ~submode + ~sub_command:Link + ~dir + ~spec + ~target + ~directory_targets + ~flags + ~config:None ;; -let build_cm' sctx ~dir ~in_context ~src ~target ~config ~sourcemap = +let build_cm' sctx ~dir ~in_context ~submode ~src ~target ~config ~sourcemap = let spec = Command.Args.Dep src in let flags = in_context.Js_of_ocaml.In_context.flags in - js_of_ocaml_rule sctx ~sub_command:Compile ~dir ~flags ~spec ~target ~config ~sourcemap + js_of_ocaml_rule + sctx + ~submode + ~sub_command:Compile + ~dir + ~flags + ~spec + ~target + ~directory_targets:[] + ~config + ~sourcemap ;; -let build_cm sctx ~dir ~in_context ~src ~obj_dir ~config = - let name = with_js_ext (Path.basename src) in +let iter_submodes ~f = Memo.parallel_iter [ Js_of_ocaml.Submode.JS; Wasm ] ~f + +let build_cm sctx ~dir ~in_context ~submode ~src ~obj_dir ~config = + let name = with_js_ext ~submode (Path.basename src) in let target = in_obj_dir ~obj_dir ~config [ name ] in build_cm' sctx ~dir ~in_context + ~submode ~src ~target ~config:(Option.map config ~f:Action_builder.return) @@ -450,32 +526,37 @@ let setup_separate_compilation_rules sctx components = archive "stdlib.cma" :: archive "std_exit.cmo" :: archives | _ -> archives in - Memo.parallel_iter archives ~f:(fun fn -> - let build_context = Context.build_context ctx in - let name = Path.basename fn in - let dir = in_build_dir build_context ~config [ lib_name ] in - let in_context = - { Js_of_ocaml.In_context.flags = Js_of_ocaml.Flags.standard - ; javascript_files = [] - ; wasm_files = [] - ; compilation_mode = None - ; sourcemap = None - } - in - let src = - let src_dir = Lib_info.src_dir info in - Path.relative src_dir name - in - let target = in_build_dir build_context ~config [ lib_name; with_js_ext name ] in - build_cm' - sctx - ~dir - ~in_context - ~src - ~target - ~config:(Some (Action_builder.return config)) - ~sourcemap:Js_of_ocaml.Sourcemap.Inline - |> Super_context.add_rule sctx ~dir)) + iter_submodes ~f:(fun submode -> + Memo.parallel_iter archives ~f:(fun fn -> + let build_context = Context.build_context ctx in + let name = Path.basename fn in + let dir = in_build_dir build_context ~config [ lib_name ] in + let in_context = + { Js_of_ocaml.In_context.flags = Js_of_ocaml.Flags.standard + ; submodes = None + ; javascript_files = [] + ; wasm_files = [] + ; compilation_mode = None + ; sourcemap = None + } + in + let src = + let src_dir = Lib_info.src_dir info in + Path.relative src_dir name + in + let target = + in_build_dir build_context ~config [ lib_name; with_js_ext ~submode name ] + in + build_cm' + sctx + ~dir + ~in_context + ~submode + ~src + ~target + ~config:(Some (Action_builder.return config)) + ~sourcemap:Js_of_ocaml.Sourcemap.Inline + |> Super_context.add_rule sctx ~dir))) ;; let js_of_ocaml_compilation_mode t ~dir = @@ -498,6 +579,19 @@ let js_of_ocaml_sourcemap t ~dir = else No ;; +let jsoo_submodes ~dir ~submodes = + let+ submodes = + match submodes with + | Some _ -> Memo.return submodes + | None -> + let+ js_of_ocaml = jsoo_env ~dir in + js_of_ocaml.submodes + in + match submodes with + | Some m -> Js_of_ocaml.Submode.Set.to_list m + | None -> [ JS ] +;; + let build_exe cc ~loc @@ -512,21 +606,15 @@ let build_exe let sctx = Compilation_context.super_context cc in let dir = Compilation_context.dir cc in let { Js_of_ocaml.In_context.javascript_files - ; wasm_files = _ + ; wasm_files ; flags + ; submodes ; compilation_mode ; sourcemap } = in_context in - let target = Path.Build.set_extension src ~ext:Js_of_ocaml.Ext.exe in - let standalone_runtime = - in_obj_dir - ~obj_dir - ~config:None - [ Path.Build.basename (Path.Build.set_extension src ~ext:Js_of_ocaml.Ext.runtime) ] - in let mode : Rule.Mode.t = match promote with | None -> Standard @@ -540,34 +628,79 @@ let build_exe match sourcemap with | None -> js_of_ocaml_sourcemap sctx ~dir | Some x -> Memo.return x + and* submodes = jsoo_submodes ~dir ~submodes in + let* () = + if not (List.mem ~equal:Poly.equal submodes JS) + then ( + let dst = Path.Build.set_extension src ~ext:(Js_of_ocaml.Ext.exe ~submode:JS) in + let src = + Path.build (Path.Build.set_extension src ~ext:(Js_of_ocaml.Ext.exe ~submode:Wasm)) + in + Super_context.add_rule ~loc ~dir ~mode sctx (Action_builder.copy ~src ~dst)) + else Memo.return () in - match (cmode : Js_of_ocaml.Compilation_mode.t) with - | Separate_compilation -> - let+ () = - standalone_runtime_rule - cc - ~javascript_files - ~target:standalone_runtime - ~flags - ~sourcemap:Js_of_ocaml.Sourcemap.Inline - |> Super_context.add_rule ~loc sctx ~dir - and+ () = - link_rule + Memo.parallel_iter submodes ~f:(fun submode -> + let standalone_runtime = + in_obj_dir + ~obj_dir + ~config:None + [ Path.Build.basename + (Path.Build.set_extension src ~ext:(Js_of_ocaml.Ext.runtime ~submode)) + ] + in + let target = + let ext = Js_of_ocaml.Ext.exe ~submode in + Path.Build.set_extension src ~ext + in + let runtime_files = + match submode with + | JS -> javascript_files + | Wasm -> wasm_files + in + let directory_targets = + match submode with + | JS -> [] + | Wasm -> [ Path.Build.set_extension src ~ext:Js_of_ocaml.Ext.wasm_dir ] + in + match (cmode : Js_of_ocaml.Compilation_mode.t) with + | Separate_compilation -> + let+ () = + standalone_runtime_rule + ~submode + cc + ~runtime_files + ~target:standalone_runtime + ~flags + ~sourcemap:Js_of_ocaml.Sourcemap.Inline + |> Super_context.add_rule ~loc sctx ~dir + and+ () = + link_rule + ~submode + cc + ~runtime:standalone_runtime + ~target + ~directory_targets + ~obj_dir + top_sorted_modules + ~flags + ~linkall + ~link_time_code_gen + ~sourcemap + |> Super_context.add_rule sctx ~loc ~dir ~mode + in + () + | Whole_program -> + exe_rule + ~submode cc - ~runtime:standalone_runtime + ~linkall + ~runtime_files + ~src ~target - ~obj_dir - top_sorted_modules + ~directory_targets ~flags - ~linkall - ~link_time_code_gen ~sourcemap - |> Super_context.add_rule sctx ~loc ~dir ~mode - in - () - | Whole_program -> - exe_rule cc ~linkall ~javascript_files ~src ~target ~flags ~sourcemap - |> Super_context.add_rule sctx ~loc ~dir ~mode + |> Super_context.add_rule sctx ~loc ~dir ~mode) ;; let runner = "node" diff --git a/src/dune_rules/jsoo/jsoo_rules.mli b/src/dune_rules/jsoo/jsoo_rules.mli index e5643e1b4c7..f0a3b2190dc 100644 --- a/src/dune_rules/jsoo/jsoo_rules.mli +++ b/src/dune_rules/jsoo/jsoo_rules.mli @@ -19,6 +19,7 @@ val build_cm : Super_context.t -> dir:Path.Build.t -> in_context:Js_of_ocaml.In_context.t + -> submode:Js_of_ocaml.Submode.t -> src:Path.t -> obj_dir:Path.Build.t Obj_dir.t -> config:Config.t option @@ -41,6 +42,13 @@ val runner : string val js_of_ocaml_runtest_alias : dir:Path.Build.t -> Alias.Name.t Memo.t val jsoo_env : dir:Path.Build.t -> string list Action_builder.t Js_of_ocaml.Env.t Memo.t +val jsoo_submodes + : dir:Import.Path.Build.t + -> submodes:Js_of_ocaml.Submode.Set.t option + -> Js_of_ocaml.Submode.t list Memo.t + +val iter_submodes : f:(Js_of_ocaml.Submode.t -> unit Memo.t) -> unit Memo.t + val js_of_ocaml_compilation_mode : Super_context.t -> dir:Path.Build.t diff --git a/src/dune_rules/lib_rules.ml b/src/dune_rules/lib_rules.ml index 8fbb9b2d2de..1e0d90cbeca 100644 --- a/src/dune_rules/lib_rules.ml +++ b/src/dune_rules/lib_rules.ml @@ -471,21 +471,23 @@ let setup_build_archives (lib : Library.t) ~top_sorted_modules ~cctx ~expander ~ iter_modes_concurrently modes.ocaml ~f:(fun mode -> build_lib lib ~native_archives ~dir ~sctx ~expander ~flags ~mode ~cm_files) and* () = - (* Build *.cma.js *) + (* Build *.cma.js / *.wasma *) Memo.when_ modes.ocaml.byte (fun () -> let src = Library.archive lib ~dir ~ext:(Mode.compiled_lib_ext Mode.Byte) in - let action_with_targets = - List.map Jsoo_rules.Config.all ~f:(fun config -> - Jsoo_rules.build_cm - sctx - ~dir - ~in_context:js_of_ocaml - ~config:(Some config) - ~src:(Path.build src) - ~obj_dir) - in - Memo.parallel_iter action_with_targets ~f:(fun rule -> - Super_context.add_rule sctx ~dir ~loc:lib.buildable.loc rule)) + Jsoo_rules.iter_submodes ~f:(fun submode -> + let action_with_targets = + List.map Jsoo_rules.Config.all ~f:(fun config -> + Jsoo_rules.build_cm + sctx + ~dir + ~in_context:js_of_ocaml + ~submode + ~config:(Some config) + ~src:(Path.build src) + ~obj_dir) + in + Memo.parallel_iter action_with_targets ~f:(fun rule -> + Super_context.add_rule sctx ~dir ~loc:lib.buildable.loc rule))) in Memo.when_ (Dynlink_supported.By_the_os.get natdynlink_supported && modes.ocaml.native) diff --git a/src/dune_rules/module_compilation.ml b/src/dune_rules/module_compilation.ml index 57e3bd62aaf..d6d4be15973 100644 --- a/src/dune_rules/module_compilation.ml +++ b/src/dune_rules/module_compilation.ml @@ -313,19 +313,21 @@ let build_module ?(force_write_cmi = false) ?(precompiled_cmi = false) cctx m = | Some src -> Compilation_context.js_of_ocaml cctx |> Memo.Option.iter ~f:(fun in_context -> - (* Build *.cmo.js *) + (* Build *.cmo.js / *.wasmo *) let sctx = Compilation_context.super_context cctx in let dir = Compilation_context.dir cctx in - let action_with_targets = - Jsoo_rules.build_cm - sctx - ~dir - ~in_context - ~src:(Path.build src) - ~obj_dir - ~config:None - in - Super_context.add_rule sctx ~dir action_with_targets)) + Jsoo_rules.iter_submodes ~f:(fun submode -> + let action_with_targets = + Jsoo_rules.build_cm + sctx + ~dir + ~in_context + ~submode + ~src:(Path.build src) + ~obj_dir + ~config:None + in + Super_context.add_rule sctx ~dir action_with_targets))) in Memo.when_ melange (fun () -> let* () = build_cm ~cm_kind:(Melange Cmj) ~phase:None in diff --git a/src/dune_rules/stanzas/executables.ml b/src/dune_rules/stanzas/executables.ml index 875b8f61cdf..b8f728cf8db 100644 --- a/src/dune_rules/stanzas/executables.ml +++ b/src/dune_rules/stanzas/executables.ml @@ -307,7 +307,7 @@ module Link_mode = struct | Byte, Shared_object -> ".bc" ^ ext_dll | Native, Shared_object -> ext_dll | mode, Plugin -> Mode.plugin_ext mode - | Byte, Js -> Js_of_ocaml.Ext.exe + | Byte, Js -> Js_of_ocaml.Ext.exe ~submode:JS | Native, Js -> User_error.raise ~loc [ Pp.text "Javascript generation only supports bytecode!" ]) ;; diff --git a/src/dune_rules/test_rules.ml b/src/dune_rules/test_rules.ml index 33a3dc4b393..66125a7a10f 100644 --- a/src/dune_rules/test_rules.ml +++ b/src/dune_rules/test_rules.ml @@ -21,52 +21,52 @@ let test_kind dir_contents (loc, name, ext) = else `Regular ;; -let ext_of_mode runtest_mode = - match runtest_mode with - | `js -> Js_of_ocaml.Ext.exe - | `bc -> ".bc" - | `exe -> ".exe" -;; - let custom_runner runtest_mode = match runtest_mode with | `js -> Some Jsoo_rules.runner | `bc | `exe -> None ;; -let runtest_modes modes project = +let runtest_modes modes submodes project = if Dune_project.dune_version project < (3, 0) - then [ `exe ] + then Memo.return [ `exe, ".exe" ] else Executables.Link_mode.Map.to_list modes - |> List.filter_map ~f:(fun ((mode : Executables.Link_mode.t), _) -> + |> Memo.sequential_map ~f:(fun ((mode : Executables.Link_mode.t), _) -> match mode with - | Byte_complete -> Some `exe - | Other { kind = Exe; mode = Native | Best } -> Some `exe - | Other { kind = Exe; mode = Byte } -> Some `bc - | Other { kind = Js; _ } -> Some `js + | Byte_complete | Other { kind = Exe; mode = Native | Best } -> + Memo.return [ `exe, ".exe" ] + | Other { kind = Exe; mode = Byte } -> Memo.return [ `bc, ".bc" ] + | Other { kind = Js; _ } -> + Memo.return + (List.map submodes ~f:(fun submode -> `js, Js_of_ocaml.Ext.exe ~submode)) | Other { kind = C | Object | Shared_object | Plugin; _ } -> (* We don't know how to run tests in these cases *) - None) - |> List.sort_uniq ~compare:Poly.compare + Memo.return []) + >>| List.flatten + >>| List.sort_uniq ~compare:Poly.compare ;; let rules (t : Tests.t) ~sctx ~dir ~scope ~expander ~dir_contents = let* () = - let runtest_modes = runtest_modes t.exes.modes (Scope.project scope) in + let* runtest_modes = + let* submodes = + Jsoo_rules.jsoo_submodes ~dir ~submodes:t.exes.buildable.js_of_ocaml.submodes + in + runtest_modes t.exes.modes submodes (Scope.project scope) + in Expander.eval_blang expander t.enabled_if >>= function | false -> let loc = Nonempty_list.hd t.exes.names |> fst in - Memo.parallel_iter runtest_modes ~f:(fun mode -> + Memo.parallel_iter runtest_modes ~f:(fun (mode, _) -> let* alias_name = alias mode ~dir in let alias = Alias.make alias_name ~dir in Simple_rules.Alias_rules.add_empty sctx ~loc ~alias) | true -> Nonempty_list.to_list t.exes.names |> Memo.parallel_iter ~f:(fun (loc, s) -> - Memo.parallel_iter runtest_modes ~f:(fun runtest_mode -> - let ext = ext_of_mode runtest_mode in + Memo.parallel_iter runtest_modes ~f:(fun (runtest_mode, ext) -> let custom_runner = custom_runner runtest_mode in let test_pform = Pform.Var Test in let run_action = From 5da9c12a74c6942c4d6d891d9f745623a13f1886 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Vouillon?= Date: Fri, 28 Jun 2024 10:49:30 +0200 Subject: [PATCH 03/26] Update documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Vouillon --- doc/howto/index.rst | 1 + doc/reference/dune/env.rst | 4 +++ doc/reference/dune/executable.rst | 22 +++++++++++---- doc/wasmoo.rst | 46 +++++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 doc/wasmoo.rst diff --git a/doc/howto/index.rst b/doc/howto/index.rst index 91362367a07..ca3fb49843f 100644 --- a/doc/howto/index.rst +++ b/doc/howto/index.rst @@ -15,6 +15,7 @@ These guides will help you use Dune's features in your project. ../sites ../instrumentation ../jsoo + ../wasmoo ../melange ../virtual-libraries ../tests diff --git a/doc/reference/dune/env.rst b/doc/reference/dune/env.rst index cb44d06e17d..485a1bc396b 100644 --- a/doc/reference/dune/env.rst +++ b/doc/reference/dune/env.rst @@ -51,6 +51,10 @@ Fields supported in ```` are: - ``(js_of_ocaml (runtest_alias ))`` specifies the alias under which :ref:`inline_tests` and tests (:ref:`tests-stanza`) run for the `js` mode. +- ``(js_of_ocaml (submodes ))`` controls whether to generate + JavaScript, Wasm code, or both. Each submode is either ``js`` or ``wasm``. + The default is to generate JavaScript code. + - ``(binaries )``, where ```` is a list of entries of the form ``( as )``. ``( as )`` makes the binary ```` available in the command search as just ````. For diff --git a/doc/reference/dune/executable.rst b/doc/reference/dune/executable.rst index c4453f4b155..deb0e3f1ba0 100644 --- a/doc/reference/dune/executable.rst +++ b/doc/reference/dune/executable.rst @@ -14,12 +14,15 @@ executable stanzas is as follows: There can be additional modules in the current directory; you only need to specify the entry point. Given an ``executable`` stanza with ``(name )``, Dune will know how to build ``.exe``. If requested, it will also know how -to build ``.bc`` and ``.bc.js`` (Dune 2.0 and up also need specific -configuration (see the ``modes`` optional field below)). +to build ``.bc``, ``.bc.js`` and ``.bc.wasm.js`` (Dune 2.0 +and up also need specific configuration (see the ``modes`` optional field +below)). ``.exe`` is a native code executable, ``.bc`` is a bytecode -executable which requires ``ocamlrun`` to run, and ``.bc.js`` is a -JavaScript generated using ``js_of_ocaml``. +executable which requires ``ocamlrun`` to run, ``.bc.js`` is a +JavaScript generated using ``js_of_ocaml``, and ``.bc.wasm.js`` is a +Wasm loader generated using ``wasm_of_ocaml`` (the Wasm modules are included in +directory ``.bc.wasm.assets``). Please note: in case native compilation is not available, ``.exe`` will be a custom bytecode executable, in the sense of ``ocamlc -custom``. This means @@ -215,7 +218,8 @@ The extensions for the various linking modes are chosen as follows: .. (byte shared_object) .bc%{ext_dll} .. (native/best shared_object) %{ext_dll} .. c .bc.c -.. js .bc.js +.. js .bc.js (JavaScript) +.. js .bc.wasm.js (Wasm) .. (best plugin) %{ext_plugin} .. (byte plugin) .cma .. (native plugin) .cmxs @@ -233,6 +237,10 @@ linking mode that's the same as ``byte_complete``, but it uses the extension currently tracked by Dune, so they don't run ``.bc`` files during the build. Run the ``.bc.exe`` or ``.exe`` ones instead, as these are self-contained. +When compiling to Wasm but not to JavaScript, a ``.bc.js`` file can +also be produced for compatibility. It is just a copy of the +``bc.wasm.js`` file. + Lastly, note that ``.bc`` executables cannot contain C stubs. If your executable contains C stubs you may want to use ``(modes exe)``. @@ -267,6 +275,10 @@ options using ``(js_of_ocaml ())``. - ``(sourcemap )`` where ``>`` is one of ``no``, ``file`` or ``inline``. This is only available inside ``executable`` stanzas. +- ``(submodes )`` controls whether to generate + JavaScript or Wasm code. Each submode is either ``js`` or ``wasm``. + The default is taken from the environment. + ```` is specified in the :doc:`/reference/ordered-set-language`. The default values for ``flags``, ``compilation_mode`` and ``sourcemap`` depend on the selected build profile. The diff --git a/doc/wasmoo.rst b/doc/wasmoo.rst new file mode 100644 index 00000000000..e5548df05ec --- /dev/null +++ b/doc/wasmoo.rst @@ -0,0 +1,46 @@ +.. _wasmoo: + +*************************************** +Wasm Compilation With Wasm_of_ocaml +*************************************** + +.. TODO(diataxis) + + This is an how-to guide. + +Wasm_of_ocaml_ is a compiler from OCaml to WebAssembly (Wasm for +short). The compiler works by translating OCaml bytecode to Wasm code. + +Compiling to Wasm is very similar to compiling to JavaScript. See +:doc:`jsoo` for more information. + + +Compiling to Wasm +================= + +Dune has full support building Wasm_of_ocaml libraries and executables transparently. +There's no need to customize or enable anything to compile OCaml +libraries/executables to Wasm. + +To build a Wasm executable, just define an executable as you would normally. +Consider this example: + +.. code:: console + + $ echo 'print_endline "hello from wasm"' > foo.ml + +With the following ``dune`` file: + +.. code:: dune + + (executable (name foo) (modes js) (js_of_ocaml (submodes wasm))) + +And then request the ``.wasm.js`` target: + +.. code:: console + + $ dune build ./foo.bc.wasm.js + $ node _build/default/foo.bc.wasm.js + hello from wasm + +.. _wasm_of_ocaml: https://github.com/ocaml-wasm/wasm_of_ocaml From fae1f0cac9e0b7f3a6b640b9ad6917c082e2186a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Vouillon?= Date: Sat, 6 Jul 2024 14:07:50 +0200 Subject: [PATCH 04/26] Add tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Vouillon --- Makefile | 3 + .../gen-opam-install-file/stubs.t/dune | 12 +- .../stubs.t/dune-project | 2 +- .../gen-opam-install-file/stubs.t/foo.wat | 1 + .../gen-opam-install-file/stubs.t/run.t | 1 + .../blackbox-tests/test-cases/meta-gen.t/dune | 7 +- .../test-cases/meta-gen.t/dune-project | 2 +- .../test-cases/meta-gen.t/run.t | 1 + .../test-cases/wasmoo/build-info.t/main.opam | 0 .../test-cases/wasmoo/build-info.t/run.t | 292 ++++++++++++++++++ .../test-cases/wasmoo/build-info.t/src/dune | 13 + .../wasmoo/build-info.t/src/main.ml | 9 + test/blackbox-tests/test-cases/wasmoo/dune | 16 + .../test-cases/wasmoo/github3622.t | 28 ++ .../wasmoo/inline-tests.t/byte/byte.ml | 2 + .../wasmoo/inline-tests.t/byte/dune | 3 + .../test-cases/wasmoo/inline-tests.t/dune | 8 + .../wasmoo/inline-tests.t/native/dune | 3 + .../wasmoo/inline-tests.t/native/native.ml | 2 + .../test-cases/wasmoo/inline-tests.t/run.t | 24 ++ .../wasmoo/inline-tests.t/wasm/dune | 6 + .../wasmoo/inline-tests.t/wasm/wasm.ml | 5 + .../wasmoo/inline-tests.t/wasm/wasm.wat | 4 + .../wasmoo/jsoo-config.t/bin/bin1.ml | 6 + .../wasmoo/jsoo-config.t/bin/bin2.ml | 6 + .../wasmoo/jsoo-config.t/bin/bin3.ml | 6 + .../test-cases/wasmoo/jsoo-config.t/bin/dune | 24 ++ .../test-cases/wasmoo/jsoo-config.t/dune | 7 + .../wasmoo/jsoo-config.t/dune-project | 1 + .../test-cases/wasmoo/jsoo-config.t/lib/dune | 1 + .../wasmoo/jsoo-config.t/lib/library1.ml | 3 + .../test-cases/wasmoo/jsoo-config.t/run.t | 12 + .../wasmoo/no-check-prim.t/bin/dune | 8 + .../wasmoo/no-check-prim.t/bin/runtime.js | 3 + .../wasmoo/no-check-prim.t/bin/technologic.ml | 13 + .../wasmoo/no-check-prim.t/bin/z.ml | 1 + .../wasmoo/no-check-prim.t/dune-project | 1 + .../wasmoo/no-check-prim.t/lib/dune | 7 + .../wasmoo/no-check-prim.t/lib/runtime.js | 6 + .../wasmoo/no-check-prim.t/lib/runtime.wat | 7 + .../wasmoo/no-check-prim.t/lib/x.ml | 5 + .../wasmoo/no-check-prim.t/lib/y.ml | 1 + .../test-cases/wasmoo/no-check-prim.t/run.t | 50 +++ .../test-cases/wasmoo/no-check-prim.t/x.opam | 0 .../test-cases/wasmoo/public-libs.t/a/a.ml | 1 + .../test-cases/wasmoo/public-libs.t/a/dune | 3 + .../test-cases/wasmoo/public-libs.t/b/dune | 5 + .../test-cases/wasmoo/public-libs.t/b/main.ml | 1 + .../wasmoo/public-libs.t/dune-project | 3 + .../test-cases/wasmoo/public-libs.t/run.t | 3 + .../test-cases/wasmoo/simple.t/bin/dune | 8 + .../test-cases/wasmoo/simple.t/bin/runtime.js | 3 + .../wasmoo/simple.t/bin/technologic.ml | 13 + .../test-cases/wasmoo/simple.t/bin/z.ml | 1 + .../test-cases/wasmoo/simple.t/dune-project | 1 + .../test-cases/wasmoo/simple.t/lib/dune | 7 + .../test-cases/wasmoo/simple.t/lib/runtime.js | 6 + .../wasmoo/simple.t/lib/runtime.wat | 7 + .../test-cases/wasmoo/simple.t/lib/stubs.c | 3 + .../test-cases/wasmoo/simple.t/lib/x.ml | 5 + .../test-cases/wasmoo/simple.t/lib/y.ml | 1 + .../test-cases/wasmoo/simple.t/run.t | 32 ++ .../test-cases/wasmoo/simple.t/x.opam | 0 .../test-cases/wasmoo/submodes.t/dune | 8 + .../test-cases/wasmoo/submodes.t/dune-project | 1 + .../test-cases/wasmoo/submodes.t/main.ml | 4 + .../test-cases/wasmoo/submodes.t/run.t | 27 ++ .../test-cases/wasmoo/tests.t/a.ml | 1 + .../test-cases/wasmoo/tests.t/b.expected | 1 + .../test-cases/wasmoo/tests.t/b.ml | 1 + .../test-cases/wasmoo/tests.t/dune | 5 + .../test-cases/wasmoo/tests.t/dune-project | 1 + .../test-cases/wasmoo/tests.t/run.t | 4 + 73 files changed, 757 insertions(+), 11 deletions(-) create mode 100644 test/blackbox-tests/test-cases/gen-opam-install-file/stubs.t/foo.wat create mode 100644 test/blackbox-tests/test-cases/wasmoo/build-info.t/main.opam create mode 100644 test/blackbox-tests/test-cases/wasmoo/build-info.t/run.t create mode 100644 test/blackbox-tests/test-cases/wasmoo/build-info.t/src/dune create mode 100644 test/blackbox-tests/test-cases/wasmoo/build-info.t/src/main.ml create mode 100644 test/blackbox-tests/test-cases/wasmoo/dune create mode 100644 test/blackbox-tests/test-cases/wasmoo/github3622.t create mode 100644 test/blackbox-tests/test-cases/wasmoo/inline-tests.t/byte/byte.ml create mode 100644 test/blackbox-tests/test-cases/wasmoo/inline-tests.t/byte/dune create mode 100644 test/blackbox-tests/test-cases/wasmoo/inline-tests.t/dune create mode 100644 test/blackbox-tests/test-cases/wasmoo/inline-tests.t/native/dune create mode 100644 test/blackbox-tests/test-cases/wasmoo/inline-tests.t/native/native.ml create mode 100644 test/blackbox-tests/test-cases/wasmoo/inline-tests.t/run.t create mode 100644 test/blackbox-tests/test-cases/wasmoo/inline-tests.t/wasm/dune create mode 100644 test/blackbox-tests/test-cases/wasmoo/inline-tests.t/wasm/wasm.ml create mode 100644 test/blackbox-tests/test-cases/wasmoo/inline-tests.t/wasm/wasm.wat create mode 100644 test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/bin/bin1.ml create mode 100644 test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/bin/bin2.ml create mode 100644 test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/bin/bin3.ml create mode 100644 test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/bin/dune create mode 100644 test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/dune create mode 100644 test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/dune-project create mode 100644 test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/lib/dune create mode 100644 test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/lib/library1.ml create mode 100644 test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/run.t create mode 100644 test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/bin/dune create mode 100644 test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/bin/runtime.js create mode 100644 test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/bin/technologic.ml create mode 100644 test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/bin/z.ml create mode 100644 test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/dune-project create mode 100644 test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/lib/dune create mode 100644 test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/lib/runtime.js create mode 100644 test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/lib/runtime.wat create mode 100644 test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/lib/x.ml create mode 100644 test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/lib/y.ml create mode 100644 test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/run.t create mode 100644 test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/x.opam create mode 100644 test/blackbox-tests/test-cases/wasmoo/public-libs.t/a/a.ml create mode 100644 test/blackbox-tests/test-cases/wasmoo/public-libs.t/a/dune create mode 100644 test/blackbox-tests/test-cases/wasmoo/public-libs.t/b/dune create mode 100644 test/blackbox-tests/test-cases/wasmoo/public-libs.t/b/main.ml create mode 100644 test/blackbox-tests/test-cases/wasmoo/public-libs.t/dune-project create mode 100644 test/blackbox-tests/test-cases/wasmoo/public-libs.t/run.t create mode 100644 test/blackbox-tests/test-cases/wasmoo/simple.t/bin/dune create mode 100644 test/blackbox-tests/test-cases/wasmoo/simple.t/bin/runtime.js create mode 100644 test/blackbox-tests/test-cases/wasmoo/simple.t/bin/technologic.ml create mode 100644 test/blackbox-tests/test-cases/wasmoo/simple.t/bin/z.ml create mode 100644 test/blackbox-tests/test-cases/wasmoo/simple.t/dune-project create mode 100644 test/blackbox-tests/test-cases/wasmoo/simple.t/lib/dune create mode 100644 test/blackbox-tests/test-cases/wasmoo/simple.t/lib/runtime.js create mode 100644 test/blackbox-tests/test-cases/wasmoo/simple.t/lib/runtime.wat create mode 100644 test/blackbox-tests/test-cases/wasmoo/simple.t/lib/stubs.c create mode 100644 test/blackbox-tests/test-cases/wasmoo/simple.t/lib/x.ml create mode 100644 test/blackbox-tests/test-cases/wasmoo/simple.t/lib/y.ml create mode 100644 test/blackbox-tests/test-cases/wasmoo/simple.t/run.t create mode 100644 test/blackbox-tests/test-cases/wasmoo/simple.t/x.opam create mode 100644 test/blackbox-tests/test-cases/wasmoo/submodes.t/dune create mode 100644 test/blackbox-tests/test-cases/wasmoo/submodes.t/dune-project create mode 100644 test/blackbox-tests/test-cases/wasmoo/submodes.t/main.ml create mode 100644 test/blackbox-tests/test-cases/wasmoo/submodes.t/run.t create mode 100644 test/blackbox-tests/test-cases/wasmoo/tests.t/a.ml create mode 100644 test/blackbox-tests/test-cases/wasmoo/tests.t/b.expected create mode 100644 test/blackbox-tests/test-cases/wasmoo/tests.t/b.ml create mode 100644 test/blackbox-tests/test-cases/wasmoo/tests.t/dune create mode 100644 test/blackbox-tests/test-cases/wasmoo/tests.t/dune-project create mode 100644 test/blackbox-tests/test-cases/wasmoo/tests.t/run.t diff --git a/Makefile b/Makefile index 65d9b208827..728b2234370 100644 --- a/Makefile +++ b/Makefile @@ -89,6 +89,9 @@ test-windows: $(BIN) test-js: $(BIN) $(BIN) build @runtest-js +test-wasm: $(BIN) + DUNE_WASM_TEST=enable $(BIN) build @runtest-wasm + test-coq: $(BIN) DUNE_COQ_TEST=enable $(BIN) build @runtest-coq diff --git a/test/blackbox-tests/test-cases/gen-opam-install-file/stubs.t/dune b/test/blackbox-tests/test-cases/gen-opam-install-file/stubs.t/dune index f6f742a6fc9..af74ed3b5df 100644 --- a/test/blackbox-tests/test-cases/gen-opam-install-file/stubs.t/dune +++ b/test/blackbox-tests/test-cases/gen-opam-install-file/stubs.t/dune @@ -1,11 +1,11 @@ (library (name foo) (install_c_headers cfoo) - (js_of_ocaml (javascript_files foo.js)) - (c_names c) - (cxx_names cpp) + (js_of_ocaml (javascript_files foo.js) (wasm_files foo.js foo.wat)) + (foreign_stubs (language c) (names c)) + (foreign_stubs (language cxx) (names cpp)) (public_name foo)) -(alias - (name default) - (action (echo "%{read:foo.install}"))) \ No newline at end of file +(rule + (alias default) + (action (echo "%{read:foo.install}"))) diff --git a/test/blackbox-tests/test-cases/gen-opam-install-file/stubs.t/dune-project b/test/blackbox-tests/test-cases/gen-opam-install-file/stubs.t/dune-project index de4fc209200..3e2a6150dda 100644 --- a/test/blackbox-tests/test-cases/gen-opam-install-file/stubs.t/dune-project +++ b/test/blackbox-tests/test-cases/gen-opam-install-file/stubs.t/dune-project @@ -1 +1 @@ -(lang dune 1.0) +(lang dune 3.17) diff --git a/test/blackbox-tests/test-cases/gen-opam-install-file/stubs.t/foo.wat b/test/blackbox-tests/test-cases/gen-opam-install-file/stubs.t/foo.wat new file mode 100644 index 00000000000..3af8f254547 --- /dev/null +++ b/test/blackbox-tests/test-cases/gen-opam-install-file/stubs.t/foo.wat @@ -0,0 +1 @@ +(module) diff --git a/test/blackbox-tests/test-cases/gen-opam-install-file/stubs.t/run.t b/test/blackbox-tests/test-cases/gen-opam-install-file/stubs.t/run.t index 6a8b999201e..25fedb24d65 100644 --- a/test/blackbox-tests/test-cases/gen-opam-install-file/stubs.t/run.t +++ b/test/blackbox-tests/test-cases/gen-opam-install-file/stubs.t/run.t @@ -13,6 +13,7 @@ stubs and js files installed "_build/install/default/lib/foo/foo.cmxa" "_build/install/default/lib/foo/foo.js" "_build/install/default/lib/foo/foo.ml" + "_build/install/default/lib/foo/foo.wat" "_build/install/default/lib/foo/libfoo_stubs$ext_lib" "_build/install/default/lib/foo/opam" ] diff --git a/test/blackbox-tests/test-cases/meta-gen.t/dune b/test/blackbox-tests/test-cases/meta-gen.t/dune index 91925536c33..8fb1d5c797c 100644 --- a/test/blackbox-tests/test-cases/meta-gen.t/dune +++ b/test/blackbox-tests/test-cases/meta-gen.t/dune @@ -13,7 +13,9 @@ (library (name foobar_runtime_lib2) - (js_of_ocaml (javascript_files foobar_runtime.js foobar_runtime2.js)) + (js_of_ocaml + (javascript_files foobar_runtime.js foobar_runtime2.js) + (wasm_files foobar_runtime.wat foobar_runtime2.wat)) (public_name foobar.runtime-lib2) (synopsis "runtime library for foobar.rewriter2")) @@ -41,6 +43,5 @@ (libraries foobar) (preprocess (pps foobar_rewriter))) -(alias - (name runtest) +(rule (alias runtest) (action (echo "%{read:META.foobar}"))) diff --git a/test/blackbox-tests/test-cases/meta-gen.t/dune-project b/test/blackbox-tests/test-cases/meta-gen.t/dune-project index 6aae99ad17a..3e2a6150dda 100644 --- a/test/blackbox-tests/test-cases/meta-gen.t/dune-project +++ b/test/blackbox-tests/test-cases/meta-gen.t/dune-project @@ -1 +1 @@ -(lang dune 1.9) +(lang dune 3.17) diff --git a/test/blackbox-tests/test-cases/meta-gen.t/run.t b/test/blackbox-tests/test-cases/meta-gen.t/run.t index 8a939042406..7716e35b6fd 100644 --- a/test/blackbox-tests/test-cases/meta-gen.t/run.t +++ b/test/blackbox-tests/test-cases/meta-gen.t/run.t @@ -61,6 +61,7 @@ plugin(byte) = "foobar_runtime_lib2.cma" plugin(native) = "foobar_runtime_lib2.cmxs" jsoo_runtime = "foobar_runtime.js foobar_runtime2.js" + wasmoo_runtime = "foobar_runtime.wat foobar_runtime2.wat" ) package "sub" ( directory = "sub" diff --git a/test/blackbox-tests/test-cases/wasmoo/build-info.t/main.opam b/test/blackbox-tests/test-cases/wasmoo/build-info.t/main.opam new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/blackbox-tests/test-cases/wasmoo/build-info.t/run.t b/test/blackbox-tests/test-cases/wasmoo/build-info.t/run.t new file mode 100644 index 00000000000..04aa5e6195e --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/build-info.t/run.t @@ -0,0 +1,292 @@ +Jsoo and build-info + + $ echo "(lang dune 3.17)" > dune-project + $ dune build + Warning: '--source-map' is enabled but the bytecode program was compiled with no debugging information. + Warning: Consider passing '-g' option to ocamlc. + $ node _build/default/src/main.bc.wasm.js + unknown + $ dune install --prefix _install --display short 2>&1 | sed 's/-[a-f0-9]*[.]wasm/.wasm/' + Installing _install/lib/main/META + Installing _install/lib/main/dune-package + Installing _install/lib/main/opam + Installing _install/bin/main + Installing _install/bin/main.bc.wasm.assets/Build_info.wasm + Installing _install/bin/main.bc.wasm.assets/Build_info.wasm.map + Installing _install/bin/main.bc.wasm.assets/Build_info__Build_info_data.wasm + Installing _install/bin/main.bc.wasm.assets/Build_info__Build_info_data.wasm.map + Installing _install/bin/main.bc.wasm.assets/CamlinternalAtomic.wasm + Installing _install/bin/main.bc.wasm.assets/CamlinternalAtomic.wasm.map + Installing _install/bin/main.bc.wasm.assets/CamlinternalFormat.wasm + Installing _install/bin/main.bc.wasm.assets/CamlinternalFormat.wasm.map + Installing _install/bin/main.bc.wasm.assets/CamlinternalFormatBasics.wasm + Installing _install/bin/main.bc.wasm.assets/CamlinternalFormatBasics.wasm.map + Installing _install/bin/main.bc.wasm.assets/CamlinternalLazy.wasm + Installing _install/bin/main.bc.wasm.assets/CamlinternalLazy.wasm.map + Installing _install/bin/main.bc.wasm.assets/Dune__exe__Main.wasm + Installing _install/bin/main.bc.wasm.assets/Dune__exe__Main.wasm.map + Installing _install/bin/main.bc.wasm.assets/Std_exit.wasm + Installing _install/bin/main.bc.wasm.assets/Std_exit.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__Buffer.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__Buffer.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__Bytes.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__Bytes.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__Char.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__Char.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__Int.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__Int.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__Lazy.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__Lazy.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__List.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__List.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__Obj.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__Obj.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__Printf.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__Printf.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__Seq.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__Seq.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__String.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__String.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__Sys.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__Sys.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__Uchar.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__Uchar.wasm.map + Installing _install/bin/main.bc.wasm.assets/prelude.wasm + Installing _install/bin/main.bc.wasm.assets/runtime.wasm + Installing _install/bin/main.bc.wasm.assets/start.wasm + Installing _install/bin/main.bc.wasm.assets/start-291802e1.wat + Installing _install/bin/main.bc.wasm.js + $ node _install/bin/main.bc.wasm.js + unknown + $ git init -q + $ touch README + $ git add README + $ git commit -m "initial" -q + $ git tag v1 -am "V1" + $ git commit -m "empty2" --allow-empty -q + $ echo "HELLO" > README + $ dune build + Warning: '--source-map' is enabled but the bytecode program was compiled with no debugging information. + Warning: Consider passing '-g' option to ocamlc. + $ node _build/default/src/main.bc.wasm.js + unknown + $ dune install --prefix _install --display short 2>&1 | sed 's/-[a-f0-9]*[.]wasm/.wasm/' + Deleting _install/lib/main/META + Installing _install/lib/main/META + Deleting _install/lib/main/dune-package + Installing _install/lib/main/dune-package + Deleting _install/lib/main/opam + Installing _install/lib/main/opam + Deleting _install/bin/main + Installing _install/bin/main + Deleting _install/bin/main.bc.wasm.assets/Build_info.wasm + Installing _install/bin/main.bc.wasm.assets/Build_info.wasm + Deleting _install/bin/main.bc.wasm.assets/Build_info.wasm.map + Installing _install/bin/main.bc.wasm.assets/Build_info.wasm.map + Installing _install/bin/main.bc.wasm.assets/Build_info__Build_info_data.wasm + Deleting _install/bin/main.bc.wasm.assets/Build_info__Build_info_data.wasm.map + Installing _install/bin/main.bc.wasm.assets/Build_info__Build_info_data.wasm.map + Deleting _install/bin/main.bc.wasm.assets/CamlinternalAtomic.wasm + Installing _install/bin/main.bc.wasm.assets/CamlinternalAtomic.wasm + Deleting _install/bin/main.bc.wasm.assets/CamlinternalAtomic.wasm.map + Installing _install/bin/main.bc.wasm.assets/CamlinternalAtomic.wasm.map + Deleting _install/bin/main.bc.wasm.assets/CamlinternalFormat.wasm + Installing _install/bin/main.bc.wasm.assets/CamlinternalFormat.wasm + Deleting _install/bin/main.bc.wasm.assets/CamlinternalFormat.wasm.map + Installing _install/bin/main.bc.wasm.assets/CamlinternalFormat.wasm.map + Deleting _install/bin/main.bc.wasm.assets/CamlinternalFormatBasics.wasm + Installing _install/bin/main.bc.wasm.assets/CamlinternalFormatBasics.wasm + Deleting _install/bin/main.bc.wasm.assets/CamlinternalFormatBasics.wasm.map + Installing _install/bin/main.bc.wasm.assets/CamlinternalFormatBasics.wasm.map + Deleting _install/bin/main.bc.wasm.assets/CamlinternalLazy.wasm + Installing _install/bin/main.bc.wasm.assets/CamlinternalLazy.wasm + Deleting _install/bin/main.bc.wasm.assets/CamlinternalLazy.wasm.map + Installing _install/bin/main.bc.wasm.assets/CamlinternalLazy.wasm.map + Deleting _install/bin/main.bc.wasm.assets/Dune__exe__Main.wasm + Installing _install/bin/main.bc.wasm.assets/Dune__exe__Main.wasm + Deleting _install/bin/main.bc.wasm.assets/Dune__exe__Main.wasm.map + Installing _install/bin/main.bc.wasm.assets/Dune__exe__Main.wasm.map + Deleting _install/bin/main.bc.wasm.assets/Std_exit.wasm + Installing _install/bin/main.bc.wasm.assets/Std_exit.wasm + Deleting _install/bin/main.bc.wasm.assets/Std_exit.wasm.map + Installing _install/bin/main.bc.wasm.assets/Std_exit.wasm.map + Deleting _install/bin/main.bc.wasm.assets/Stdlib.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib.wasm + Deleting _install/bin/main.bc.wasm.assets/Stdlib.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib.wasm.map + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Buffer.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__Buffer.wasm + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Buffer.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__Buffer.wasm.map + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Bytes.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__Bytes.wasm + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Bytes.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__Bytes.wasm.map + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Char.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__Char.wasm + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Char.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__Char.wasm.map + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Int.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__Int.wasm + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Int.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__Int.wasm.map + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Lazy.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__Lazy.wasm + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Lazy.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__Lazy.wasm.map + Deleting _install/bin/main.bc.wasm.assets/Stdlib__List.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__List.wasm + Deleting _install/bin/main.bc.wasm.assets/Stdlib__List.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__List.wasm.map + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Obj.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__Obj.wasm + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Obj.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__Obj.wasm.map + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Printf.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__Printf.wasm + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Printf.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__Printf.wasm.map + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Seq.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__Seq.wasm + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Seq.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__Seq.wasm.map + Deleting _install/bin/main.bc.wasm.assets/Stdlib__String.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__String.wasm + Deleting _install/bin/main.bc.wasm.assets/Stdlib__String.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__String.wasm.map + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Sys.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__Sys.wasm + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Sys.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__Sys.wasm.map + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Uchar.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__Uchar.wasm + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Uchar.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__Uchar.wasm.map + Deleting _install/bin/main.bc.wasm.assets/prelude.wasm + Installing _install/bin/main.bc.wasm.assets/prelude.wasm + Deleting _install/bin/main.bc.wasm.assets/runtime.wasm + Installing _install/bin/main.bc.wasm.assets/runtime.wasm + Deleting _install/bin/main.bc.wasm.assets/start.wasm + Installing _install/bin/main.bc.wasm.assets/start.wasm + Deleting _install/bin/main.bc.wasm.assets/start-291802e1.wat + Installing _install/bin/main.bc.wasm.assets/start-291802e1.wat + Deleting _install/bin/main.bc.wasm.js + Installing _install/bin/main.bc.wasm.js + Installing _install/doc/main/README + $ node _install/bin/main.bc.wasm.js + v1-1-xxxxx-dirty + $ echo "(name main)" >> dune-project + $ echo "(version 0.2.0)" >> dune-project + $ dune build + Warning: '--source-map' is enabled but the bytecode program was compiled with no debugging information. + Warning: Consider passing '-g' option to ocamlc. + $ node _build/default/src/main.bc.wasm.js + 0.2.0 + $ dune install --prefix _install --display short 2>&1 | sed 's/-[a-f0-9]*[.]wasm/.wasm/' + Deleting _install/lib/main/META + Installing _install/lib/main/META + Deleting _install/lib/main/dune-package + Installing _install/lib/main/dune-package + Deleting _install/lib/main/opam + Installing _install/lib/main/opam + Deleting _install/bin/main + Installing _install/bin/main + Deleting _install/bin/main.bc.wasm.assets/Build_info.wasm + Installing _install/bin/main.bc.wasm.assets/Build_info.wasm + Deleting _install/bin/main.bc.wasm.assets/Build_info.wasm.map + Installing _install/bin/main.bc.wasm.assets/Build_info.wasm.map + Installing _install/bin/main.bc.wasm.assets/Build_info__Build_info_data.wasm + Deleting _install/bin/main.bc.wasm.assets/Build_info__Build_info_data.wasm.map + Installing _install/bin/main.bc.wasm.assets/Build_info__Build_info_data.wasm.map + Deleting _install/bin/main.bc.wasm.assets/CamlinternalAtomic.wasm + Installing _install/bin/main.bc.wasm.assets/CamlinternalAtomic.wasm + Deleting _install/bin/main.bc.wasm.assets/CamlinternalAtomic.wasm.map + Installing _install/bin/main.bc.wasm.assets/CamlinternalAtomic.wasm.map + Deleting _install/bin/main.bc.wasm.assets/CamlinternalFormat.wasm + Installing _install/bin/main.bc.wasm.assets/CamlinternalFormat.wasm + Deleting _install/bin/main.bc.wasm.assets/CamlinternalFormat.wasm.map + Installing _install/bin/main.bc.wasm.assets/CamlinternalFormat.wasm.map + Deleting _install/bin/main.bc.wasm.assets/CamlinternalFormatBasics.wasm + Installing _install/bin/main.bc.wasm.assets/CamlinternalFormatBasics.wasm + Deleting _install/bin/main.bc.wasm.assets/CamlinternalFormatBasics.wasm.map + Installing _install/bin/main.bc.wasm.assets/CamlinternalFormatBasics.wasm.map + Deleting _install/bin/main.bc.wasm.assets/CamlinternalLazy.wasm + Installing _install/bin/main.bc.wasm.assets/CamlinternalLazy.wasm + Deleting _install/bin/main.bc.wasm.assets/CamlinternalLazy.wasm.map + Installing _install/bin/main.bc.wasm.assets/CamlinternalLazy.wasm.map + Deleting _install/bin/main.bc.wasm.assets/Dune__exe__Main.wasm + Installing _install/bin/main.bc.wasm.assets/Dune__exe__Main.wasm + Deleting _install/bin/main.bc.wasm.assets/Dune__exe__Main.wasm.map + Installing _install/bin/main.bc.wasm.assets/Dune__exe__Main.wasm.map + Deleting _install/bin/main.bc.wasm.assets/Std_exit.wasm + Installing _install/bin/main.bc.wasm.assets/Std_exit.wasm + Deleting _install/bin/main.bc.wasm.assets/Std_exit.wasm.map + Installing _install/bin/main.bc.wasm.assets/Std_exit.wasm.map + Deleting _install/bin/main.bc.wasm.assets/Stdlib.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib.wasm + Deleting _install/bin/main.bc.wasm.assets/Stdlib.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib.wasm.map + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Buffer.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__Buffer.wasm + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Buffer.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__Buffer.wasm.map + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Bytes.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__Bytes.wasm + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Bytes.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__Bytes.wasm.map + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Char.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__Char.wasm + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Char.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__Char.wasm.map + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Int.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__Int.wasm + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Int.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__Int.wasm.map + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Lazy.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__Lazy.wasm + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Lazy.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__Lazy.wasm.map + Deleting _install/bin/main.bc.wasm.assets/Stdlib__List.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__List.wasm + Deleting _install/bin/main.bc.wasm.assets/Stdlib__List.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__List.wasm.map + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Obj.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__Obj.wasm + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Obj.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__Obj.wasm.map + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Printf.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__Printf.wasm + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Printf.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__Printf.wasm.map + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Seq.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__Seq.wasm + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Seq.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__Seq.wasm.map + Deleting _install/bin/main.bc.wasm.assets/Stdlib__String.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__String.wasm + Deleting _install/bin/main.bc.wasm.assets/Stdlib__String.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__String.wasm.map + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Sys.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__Sys.wasm + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Sys.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__Sys.wasm.map + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Uchar.wasm + Installing _install/bin/main.bc.wasm.assets/Stdlib__Uchar.wasm + Deleting _install/bin/main.bc.wasm.assets/Stdlib__Uchar.wasm.map + Installing _install/bin/main.bc.wasm.assets/Stdlib__Uchar.wasm.map + Deleting _install/bin/main.bc.wasm.assets/prelude.wasm + Installing _install/bin/main.bc.wasm.assets/prelude.wasm + Deleting _install/bin/main.bc.wasm.assets/runtime.wasm + Installing _install/bin/main.bc.wasm.assets/runtime.wasm + Deleting _install/bin/main.bc.wasm.assets/start.wasm + Installing _install/bin/main.bc.wasm.assets/start.wasm + Deleting _install/bin/main.bc.wasm.assets/start-291802e1.wat + Installing _install/bin/main.bc.wasm.assets/start-291802e1.wat + Deleting _install/bin/main.bc.wasm.js + Installing _install/bin/main.bc.wasm.js + Deleting _install/doc/main/README + Installing _install/doc/main/README + $ node _build/default/src/main.bc.wasm.js + 0.2.0 diff --git a/test/blackbox-tests/test-cases/wasmoo/build-info.t/src/dune b/test/blackbox-tests/test-cases/wasmoo/build-info.t/src/dune new file mode 100644 index 00000000000..9f1d7f4c7b4 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/build-info.t/src/dune @@ -0,0 +1,13 @@ +(executable + (name main) + (public_name main) + (modes js byte) + (js_of_ocaml (submodes wasm)) + (modules main) + (package main) + (libraries dune-build-info)) + +(install + (section bin) + (files main.bc.wasm.js) + (dirs main.bc.wasm.assets)) diff --git a/test/blackbox-tests/test-cases/wasmoo/build-info.t/src/main.ml b/test/blackbox-tests/test-cases/wasmoo/build-info.t/src/main.ml new file mode 100644 index 00000000000..c526da6abf4 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/build-info.t/src/main.ml @@ -0,0 +1,9 @@ +let version = + match Build_info.V1.version () with + | None -> "unknown" + | Some v -> Build_info.V1.Version.to_string v + +let () = match String.split_on_char '-' version with + | [tag; plus; _commit; dirty] -> Printf.printf "%s-%s-%s-%s" tag plus "xxxxx" dirty + | [ x ] -> print_endline x + | _ -> print_endline "unexpected" diff --git a/test/blackbox-tests/test-cases/wasmoo/dune b/test/blackbox-tests/test-cases/wasmoo/dune new file mode 100644 index 00000000000..5a26ce4c4bf --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/dune @@ -0,0 +1,16 @@ +(cram + (applies_to :whole_subtree) + (deps %{bin:node} %{bin:js_of_ocaml} %{bin:wasm_of_ocaml}) + (alias runtest-wasm) + (enabled_if + (= %{env:DUNE_WASM_TEST=disable} enable))) + +(cram + (applies_to inline-tests) + (deps + (package ppx_expect))) + +(cram + (applies_to build-info) + (deps + (package dune-build-info))) diff --git a/test/blackbox-tests/test-cases/wasmoo/github3622.t b/test/blackbox-tests/test-cases/wasmoo/github3622.t new file mode 100644 index 00000000000..f4103f2d768 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/github3622.t @@ -0,0 +1,28 @@ +This test demonstrates a bug in dune's separation compilation of jsoo. +std_exit.cmo wasn't being linked in the end, which was causing at_exit hooks not +being ran and channels not being flushed. + +Setup fixtures: + + $ echo "(lang dune 3.17)" > dune-project + $ echo 'let () = print_string "bla"' > main.ml + $ cat >dune < (executable + > (name main) + > (modes js) + > (js_of_ocaml (submodes wasm))) + > EOF + +Test without separate compilation: + + $ dune build --profile=release ./main.bc.wasm.js + $ node _build/default/main.bc.wasm.js + bla + +Test with separate compilation: + + $ dune build --profile=dev ./main.bc.wasm.js + $ node _build/default/main.bc.wasm.js + bla + +The result should be the same diff --git a/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/byte/byte.ml b/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/byte/byte.ml new file mode 100644 index 00000000000..23b5d38322a --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/byte/byte.ml @@ -0,0 +1,2 @@ +let _ = assert (Sys.backend_type = Bytecode) +let _ = print_endline "inline tests (Byte)" diff --git a/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/byte/dune b/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/byte/dune new file mode 100644 index 00000000000..aaf265b6a85 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/byte/dune @@ -0,0 +1,3 @@ +(library + (name inline_tests_byte) + (inline_tests (modes byte) (backend fake_backend))) diff --git a/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/dune b/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/dune new file mode 100644 index 00000000000..418c95e453a --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/dune @@ -0,0 +1,8 @@ +(library + (name fake_backend) + (modules ()) + (inline_tests.backend + (generate_runner + (progn + (echo "[@@@warning \"-40\"]\n") + (cat %{impl-files}))))) diff --git a/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/native/dune b/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/native/dune new file mode 100644 index 00000000000..44373b41fb1 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/native/dune @@ -0,0 +1,3 @@ +(library + (name inline_tests_native) + (inline_tests (modes native) (backend fake_backend))) diff --git a/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/native/native.ml b/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/native/native.ml new file mode 100644 index 00000000000..f28bab40046 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/native/native.ml @@ -0,0 +1,2 @@ +let _ = assert (Sys.backend_type = Native) +let _ = print_endline "inline tests (Native)" diff --git a/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/run.t b/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/run.t new file mode 100644 index 00000000000..f4ccb7dbe36 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/run.t @@ -0,0 +1,24 @@ +Run inline tests using node js + + $ cat >dune-project < (lang dune 3.17) + > EOF + + $ dune runtest + inline tests (Byte) + inline tests (Byte) + inline tests (Native) + inline tests (Native) + inline tests (Wasm) + inline tests (Wasm) + + $ dune runtest --profile release + inline tests (Native) + inline tests (Native) + inline tests (Wasm) + inline tests (Wasm) + + $ dune build wasm/.inline_tests_wasm.inline-tests/inline_test_runner_inline_tests_wasm.bc --display short + Error: Don't know how to build + wasm/.inline_tests_wasm.inline-tests/inline_test_runner_inline_tests_wasm.bc + [1] diff --git a/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/wasm/dune b/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/wasm/dune new file mode 100644 index 00000000000..7fa81740628 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/wasm/dune @@ -0,0 +1,6 @@ +(library + (name inline_tests_wasm) + (js_of_ocaml (wasm_files wasm.wat) (submodes wasm)) + (inline_tests + (modes js) + (backend fake_backend))) diff --git a/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/wasm/wasm.ml b/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/wasm/wasm.ml new file mode 100644 index 00000000000..2db226905c3 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/wasm/wasm.ml @@ -0,0 +1,5 @@ +external prim : unit -> bool = "wasmoo_stubs" + +let _ = assert (Sys.int_size = 31) +let _ = assert (prim ()) +let _ = print_endline "inline tests (Wasm)" diff --git a/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/wasm/wasm.wat b/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/wasm/wasm.wat new file mode 100644 index 00000000000..810e81aa67e --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/wasm/wasm.wat @@ -0,0 +1,4 @@ +(module + (func (export "wasmoo_stubs") (param (ref eq)) (result (ref eq)) + (ref.i31 (i32.const 1))) +) diff --git a/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/bin/bin1.ml b/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/bin/bin1.ml new file mode 100644 index 00000000000..bf7f3d4d481 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/bin/bin1.ml @@ -0,0 +1,6 @@ +let name = "bin1" +let hello name = print_endline ("Hi " ^ name) + +let () = Library1.hello name + +let () = hello Library1.name diff --git a/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/bin/bin2.ml b/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/bin/bin2.ml new file mode 100644 index 00000000000..87c52bec613 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/bin/bin2.ml @@ -0,0 +1,6 @@ +let name = "bin2" +let hello name = print_endline ("Hi " ^ name) + +let () = Library1.hello name + +let () = hello Library1.name diff --git a/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/bin/bin3.ml b/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/bin/bin3.ml new file mode 100644 index 00000000000..d94b8d12e3a --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/bin/bin3.ml @@ -0,0 +1,6 @@ +let name = "bin3" +let hello name = print_endline ("Hi " ^ name) + +let () = Library1.hello name + +let () = hello Library1.name diff --git a/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/bin/dune b/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/bin/dune new file mode 100644 index 00000000000..6dc09bed0e5 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/bin/dune @@ -0,0 +1,24 @@ +(executable + (name bin1) + (modules bin1) + (modes js) + (libraries library1) + (js_of_ocaml + (flags (:standard --enable use-js-string))) +) + +(executable + (name bin2) + (modules bin2) + (modes js) + (libraries library1) + (js_of_ocaml + (flags (:standard --disable use-js-string))) +) + +(executable + (name bin3) + (modules bin3) + (modes js) + (libraries library1) +) diff --git a/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/dune b/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/dune new file mode 100644 index 00000000000..7f70cce913f --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/dune @@ -0,0 +1,7 @@ +(env + (_ + (js_of_ocaml + (submodes wasm) + (flags (:standard --quiet)) + (compilation_mode separate) +))) diff --git a/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/dune-project b/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/dune-project new file mode 100644 index 00000000000..3e2a6150dda --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/dune-project @@ -0,0 +1 @@ +(lang dune 3.17) diff --git a/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/lib/dune b/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/lib/dune new file mode 100644 index 00000000000..22f5ea64365 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/lib/dune @@ -0,0 +1 @@ +(library (name library1)) \ No newline at end of file diff --git a/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/lib/library1.ml b/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/lib/library1.ml new file mode 100644 index 00000000000..70ad25d7d71 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/lib/library1.ml @@ -0,0 +1,3 @@ +let name = "library1" + +let hello name = print_endline ("Hello " ^ name) diff --git a/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/run.t b/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/run.t new file mode 100644 index 00000000000..656ea0da897 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/run.t @@ -0,0 +1,12 @@ +tests js_of_ocaml configs + + $ dune build bin/bin1.bc.wasm.js bin/bin2.bc.wasm.js bin/bin3.bc.wasm.js + $ node _build/default/bin/bin1.bc.wasm.js + Hello bin1 + Hi library1 + $ node _build/default/bin/bin2.bc.wasm.js + Hello bin2 + Hi library1 + $ node _build/default/bin/bin3.bc.wasm.js + Hello bin3 + Hi library1 diff --git a/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/bin/dune b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/bin/dune new file mode 100644 index 00000000000..de172d2b9a3 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/bin/dune @@ -0,0 +1,8 @@ +(executables + (names technologic) + (libraries js_of_ocaml x) + (modes js) + (js_of_ocaml + (submodes wasm) + (flags (:standard)) + (wasm_files runtime.js))) diff --git a/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/bin/runtime.js b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/bin/runtime.js new file mode 100644 index 00000000000..c8210c33522 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/bin/runtime.js @@ -0,0 +1,3 @@ +global.globalPrintFunction = function(x){ + console.log(x); +} diff --git a/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/bin/technologic.ml b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/bin/technologic.ml new file mode 100644 index 00000000000..06e79a164ec --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/bin/technologic.ml @@ -0,0 +1,13 @@ +module Js = Js_of_ocaml.Js + +let _ = + print_endline X.buy_it; + let obj = Js.Unsafe.obj [|"name", Js.Unsafe.inject (Js.string Z.use_it)|] in + Printf.printf "%s\n%!" (X.print obj); + X.external_print (Js.string "break it"); + (fun x -> + let global = Js.Unsafe.get Js.Unsafe.global "global" in + let globalPrintFunction : Js.js_string Js.t -> unit = + Js.Unsafe.get global "globalPrintFunction" in + Js.Unsafe.fun_call globalPrintFunction [|Js.Unsafe.inject x|] + ) (Js.string "fix it") diff --git a/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/bin/z.ml b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/bin/z.ml new file mode 100644 index 00000000000..30bb9cee296 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/bin/z.ml @@ -0,0 +1 @@ +let use_it = "use it" diff --git a/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/dune-project b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/dune-project new file mode 100644 index 00000000000..3e2a6150dda --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/dune-project @@ -0,0 +1 @@ +(lang dune 3.17) diff --git a/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/lib/dune b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/lib/dune new file mode 100644 index 00000000000..a68edc1c0f7 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/lib/dune @@ -0,0 +1,7 @@ +(library + (name x) + (libraries js_of_ocaml) + (public_name x) + (js_of_ocaml + (flags (--pretty)) (wasm_files runtime.js runtime.wat)) + ) diff --git a/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/lib/runtime.js b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/lib/runtime.js new file mode 100644 index 00000000000..f2398f02647 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/lib/runtime.js @@ -0,0 +1,6 @@ + + +//Provides: jsPrint +function jsPrint(x){ + joo_global_object.console.log(x); +} diff --git a/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/lib/runtime.wat b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/lib/runtime.wat new file mode 100644 index 00000000000..d88b8003704 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/lib/runtime.wat @@ -0,0 +1,7 @@ +(module + (import "env" "unwrap" (func $unwrap (param (ref eq)) (result anyref))) + (import "js" "jsPrint" (func $jsPrint (param anyref))) + (func (export "jsPrint") (param $x (ref eq)) (result (ref eq)) + (call $jsPrint (call $unwrap (local.get $x))) + (ref.i31 (i32.const 0))) +) diff --git a/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/lib/x.ml b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/lib/x.ml new file mode 100644 index 00000000000..37ff0eaa243 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/lib/x.ml @@ -0,0 +1,5 @@ +module Js = Js_of_ocaml.Js + +let buy_it = "buy " ^ Y.it +let print x = Js.to_string (Js.Unsafe.get x "name") +external external_print : Js.js_string Js.t -> unit = "jsPrint" diff --git a/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/lib/y.ml b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/lib/y.ml new file mode 100644 index 00000000000..d11948ee573 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/lib/y.ml @@ -0,0 +1 @@ +let it = "it" diff --git a/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/run.t b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/run.t new file mode 100644 index 00000000000..1b42947088d --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/run.t @@ -0,0 +1,50 @@ +Compilation using jsoo + + $ dune build --display short bin/technologic.bc.js @install 2>&1 | \ + > sed s,^\ *$(ocamlc -config-var c_compiler),\ \ C_COMPILER,g + wasm_of_ocaml bin/.technologic.eobjs/jsoo/technologic.bc.runtime.wasma + ocamldep bin/.technologic.eobjs/dune__exe__Technologic.impl.d + ocamldep lib/.x.objs/x.impl.d + ocamlc lib/.x.objs/byte/x__.{cmi,cmo,cmt} + ocamldep lib/.x.objs/x__Y.impl.d + ocamldep bin/.technologic.eobjs/dune__exe__Z.impl.d + ocamlopt lib/.x.objs/native/x__.{cmx,o} + ocamlc lib/.x.objs/byte/x__Y.{cmi,cmo,cmt} + wasm_of_ocaml .js/default/js_of_ocaml-compiler.runtime/jsoo_runtime.wasma + wasm_of_ocaml .js/default/js_of_ocaml/js_of_ocaml.wasma + wasm_of_ocaml .js/default/stdlib/std_exit.wasmo + wasm_of_ocaml .js/default/stdlib/stdlib.wasma + ocamlc bin/.technologic.eobjs/byte/dune__exe.{cmi,cmo,cmt} + ocamldep bin/.technologic.eobjs/dune__exe__Technologic.intf.d + ocamlopt lib/.x.objs/native/x__Y.{cmx,o} + ocamlc lib/.x.objs/byte/x.{cmi,cmo,cmt} + wasm_of_ocaml bin/.technologic.eobjs/jsoo/dune__exe.wasmo + ocamlopt lib/.x.objs/native/x.{cmx,o} + ocamlc bin/.technologic.eobjs/byte/dune__exe__Technologic.{cmi,cmti} + ocamlc lib/x.cma + ocamlc bin/.technologic.eobjs/byte/dune__exe__Z.{cmi,cmo,cmt} + ocamlopt lib/x.{a,cmxa} + wasm_of_ocaml lib/.x.objs/jsoo/default/x.wasma + ocamlc bin/.technologic.eobjs/byte/dune__exe__Technologic.{cmo,cmt} + wasm_of_ocaml bin/.technologic.eobjs/jsoo/dune__exe__Z.wasmo + ocamlopt lib/x.cmxs + wasm_of_ocaml bin/.technologic.eobjs/jsoo/dune__exe__Technologic.wasmo + wasm_of_ocaml bin/technologic.bc.wasm.{js,assets} + $ node ./_build/default/bin/technologic.bc.wasm.js + buy it + use it + break it + fix it + $ dune build bin/technologic.bc.wasm.js @install --profile release + $ node ./_build/default/bin/technologic.bc.wasm.js + buy it + use it + break it + fix it + $ cat >dune-workspace < (lang dune 3.17) + > (context + > (default (disable_dynamically_linked_foreign_archives true))) + > EOF + $ dune build bin/technologic.bc.wasm.js @install --profile dev + $ dune build bin/technologic.bc.wasm.js @install --profile release diff --git a/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/x.opam b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/x.opam new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/blackbox-tests/test-cases/wasmoo/public-libs.t/a/a.ml b/test/blackbox-tests/test-cases/wasmoo/public-libs.t/a/a.ml new file mode 100644 index 00000000000..df5e542079b --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/public-libs.t/a/a.ml @@ -0,0 +1 @@ +let x = 12 diff --git a/test/blackbox-tests/test-cases/wasmoo/public-libs.t/a/dune b/test/blackbox-tests/test-cases/wasmoo/public-libs.t/a/dune new file mode 100644 index 00000000000..9222db1e318 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/public-libs.t/a/dune @@ -0,0 +1,3 @@ +(library + (public_name foo.a) + (name a)) diff --git a/test/blackbox-tests/test-cases/wasmoo/public-libs.t/b/dune b/test/blackbox-tests/test-cases/wasmoo/public-libs.t/b/dune new file mode 100644 index 00000000000..18b69c13178 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/public-libs.t/b/dune @@ -0,0 +1,5 @@ +(executable + (name main) + (libraries a) + (modes js) + (js_of_ocaml (submodes wasm))) diff --git a/test/blackbox-tests/test-cases/wasmoo/public-libs.t/b/main.ml b/test/blackbox-tests/test-cases/wasmoo/public-libs.t/b/main.ml new file mode 100644 index 00000000000..e9273e98aa0 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/public-libs.t/b/main.ml @@ -0,0 +1 @@ +let _ = A.x diff --git a/test/blackbox-tests/test-cases/wasmoo/public-libs.t/dune-project b/test/blackbox-tests/test-cases/wasmoo/public-libs.t/dune-project new file mode 100644 index 00000000000..a8110e485a8 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/public-libs.t/dune-project @@ -0,0 +1,3 @@ +(lang dune 3.17) + +(package (name foo)) diff --git a/test/blackbox-tests/test-cases/wasmoo/public-libs.t/run.t b/test/blackbox-tests/test-cases/wasmoo/public-libs.t/run.t new file mode 100644 index 00000000000..68a3c636a8a --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/public-libs.t/run.t @@ -0,0 +1,3 @@ +Compilation of libraries with public-names + + $ dune build diff --git a/test/blackbox-tests/test-cases/wasmoo/simple.t/bin/dune b/test/blackbox-tests/test-cases/wasmoo/simple.t/bin/dune new file mode 100644 index 00000000000..de172d2b9a3 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/simple.t/bin/dune @@ -0,0 +1,8 @@ +(executables + (names technologic) + (libraries js_of_ocaml x) + (modes js) + (js_of_ocaml + (submodes wasm) + (flags (:standard)) + (wasm_files runtime.js))) diff --git a/test/blackbox-tests/test-cases/wasmoo/simple.t/bin/runtime.js b/test/blackbox-tests/test-cases/wasmoo/simple.t/bin/runtime.js new file mode 100644 index 00000000000..c8210c33522 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/simple.t/bin/runtime.js @@ -0,0 +1,3 @@ +global.globalPrintFunction = function(x){ + console.log(x); +} diff --git a/test/blackbox-tests/test-cases/wasmoo/simple.t/bin/technologic.ml b/test/blackbox-tests/test-cases/wasmoo/simple.t/bin/technologic.ml new file mode 100644 index 00000000000..06e79a164ec --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/simple.t/bin/technologic.ml @@ -0,0 +1,13 @@ +module Js = Js_of_ocaml.Js + +let _ = + print_endline X.buy_it; + let obj = Js.Unsafe.obj [|"name", Js.Unsafe.inject (Js.string Z.use_it)|] in + Printf.printf "%s\n%!" (X.print obj); + X.external_print (Js.string "break it"); + (fun x -> + let global = Js.Unsafe.get Js.Unsafe.global "global" in + let globalPrintFunction : Js.js_string Js.t -> unit = + Js.Unsafe.get global "globalPrintFunction" in + Js.Unsafe.fun_call globalPrintFunction [|Js.Unsafe.inject x|] + ) (Js.string "fix it") diff --git a/test/blackbox-tests/test-cases/wasmoo/simple.t/bin/z.ml b/test/blackbox-tests/test-cases/wasmoo/simple.t/bin/z.ml new file mode 100644 index 00000000000..30bb9cee296 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/simple.t/bin/z.ml @@ -0,0 +1 @@ +let use_it = "use it" diff --git a/test/blackbox-tests/test-cases/wasmoo/simple.t/dune-project b/test/blackbox-tests/test-cases/wasmoo/simple.t/dune-project new file mode 100644 index 00000000000..3e2a6150dda --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/simple.t/dune-project @@ -0,0 +1 @@ +(lang dune 3.17) diff --git a/test/blackbox-tests/test-cases/wasmoo/simple.t/lib/dune b/test/blackbox-tests/test-cases/wasmoo/simple.t/lib/dune new file mode 100644 index 00000000000..d1633abbadb --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/simple.t/lib/dune @@ -0,0 +1,7 @@ +(library + (name x) + (libraries js_of_ocaml) + (public_name x) + (js_of_ocaml + (flags (--pretty)) (wasm_files runtime.js runtime.wat)) + (foreign_stubs (language c) (names stubs))) diff --git a/test/blackbox-tests/test-cases/wasmoo/simple.t/lib/runtime.js b/test/blackbox-tests/test-cases/wasmoo/simple.t/lib/runtime.js new file mode 100644 index 00000000000..f2398f02647 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/simple.t/lib/runtime.js @@ -0,0 +1,6 @@ + + +//Provides: jsPrint +function jsPrint(x){ + joo_global_object.console.log(x); +} diff --git a/test/blackbox-tests/test-cases/wasmoo/simple.t/lib/runtime.wat b/test/blackbox-tests/test-cases/wasmoo/simple.t/lib/runtime.wat new file mode 100644 index 00000000000..d88b8003704 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/simple.t/lib/runtime.wat @@ -0,0 +1,7 @@ +(module + (import "env" "unwrap" (func $unwrap (param (ref eq)) (result anyref))) + (import "js" "jsPrint" (func $jsPrint (param anyref))) + (func (export "jsPrint") (param $x (ref eq)) (result (ref eq)) + (call $jsPrint (call $unwrap (local.get $x))) + (ref.i31 (i32.const 0))) +) diff --git a/test/blackbox-tests/test-cases/wasmoo/simple.t/lib/stubs.c b/test/blackbox-tests/test-cases/wasmoo/simple.t/lib/stubs.c new file mode 100644 index 00000000000..9d98a815a89 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/simple.t/lib/stubs.c @@ -0,0 +1,3 @@ +#include +#include +void jsPrint () { fprintf(stderr, "Unimplemented Javascript primitive myPrint!\n"); exit(1); } diff --git a/test/blackbox-tests/test-cases/wasmoo/simple.t/lib/x.ml b/test/blackbox-tests/test-cases/wasmoo/simple.t/lib/x.ml new file mode 100644 index 00000000000..37ff0eaa243 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/simple.t/lib/x.ml @@ -0,0 +1,5 @@ +module Js = Js_of_ocaml.Js + +let buy_it = "buy " ^ Y.it +let print x = Js.to_string (Js.Unsafe.get x "name") +external external_print : Js.js_string Js.t -> unit = "jsPrint" diff --git a/test/blackbox-tests/test-cases/wasmoo/simple.t/lib/y.ml b/test/blackbox-tests/test-cases/wasmoo/simple.t/lib/y.ml new file mode 100644 index 00000000000..d11948ee573 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/simple.t/lib/y.ml @@ -0,0 +1 @@ +let it = "it" diff --git a/test/blackbox-tests/test-cases/wasmoo/simple.t/run.t b/test/blackbox-tests/test-cases/wasmoo/simple.t/run.t new file mode 100644 index 00000000000..1dad7602308 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/simple.t/run.t @@ -0,0 +1,32 @@ +Compilation using wasmoo + $ dune build bin/technologic.bc.wasm.js @install --profile dev + $ node ./_build/default/bin/technologic.bc.wasm.js + buy it + use it + break it + fix it + $ dune build @install --profile release + $ node ./_build/default/bin/technologic.bc.wasm.js + buy it + use it + break it + fix it + +Compilation using wasmoo with disable_dynamically_linked_foreign_archives = true + + $ cat >dune-workspace < (lang dune 3.17) + > (context + > (default (disable_dynamically_linked_foreign_archives true))) + > EOF + $ dune clean + $ dune build bin/technologic.bc.wasm.js @install --profile dev + +Js_of_ocaml whole program compilation works with +disable_dynamically_linked_foreign_archives = true: + + $ dune build bin/technologic.bc.wasm.js @install --profile release + +We expect a runtime error when running this bc-for-jsoo file. + + $ ! if dune exe bin/technologic.bc-for-jsoo ; then true ; else false ; fi 2> /dev/null diff --git a/test/blackbox-tests/test-cases/wasmoo/simple.t/x.opam b/test/blackbox-tests/test-cases/wasmoo/simple.t/x.opam new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/blackbox-tests/test-cases/wasmoo/submodes.t/dune b/test/blackbox-tests/test-cases/wasmoo/submodes.t/dune new file mode 100644 index 00000000000..9ebfc9795b2 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/submodes.t/dune @@ -0,0 +1,8 @@ + +(executable + (name main) + (modes js)) + +(env + (wasm (js_of_ocaml (submodes wasm))) + (both (js_of_ocaml (submodes js wasm)))) diff --git a/test/blackbox-tests/test-cases/wasmoo/submodes.t/dune-project b/test/blackbox-tests/test-cases/wasmoo/submodes.t/dune-project new file mode 100644 index 00000000000..3e2a6150dda --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/submodes.t/dune-project @@ -0,0 +1 @@ +(lang dune 3.17) diff --git a/test/blackbox-tests/test-cases/wasmoo/submodes.t/main.ml b/test/blackbox-tests/test-cases/wasmoo/submodes.t/main.ml new file mode 100644 index 00000000000..caaffbbaa9d --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/submodes.t/main.ml @@ -0,0 +1,4 @@ +let () = + match Sys.backend_type with + Other typ -> print_endline typ + | _ -> assert false diff --git a/test/blackbox-tests/test-cases/wasmoo/submodes.t/run.t b/test/blackbox-tests/test-cases/wasmoo/submodes.t/run.t new file mode 100644 index 00000000000..7183468bb7b --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/submodes.t/run.t @@ -0,0 +1,27 @@ +Building with different combinations of submodes + +The default is to only compile to JavaScript + + $ dune build --profile js + $ node _build/default/main.bc.js + js_of_ocaml + $ dune build --profile js main.bc.wasm.js + Error: Don't know how to build main.bc.wasm.js + [1] + +Compiling to Wasm. One can still use the .bc.js binary but it runs +the Wasm code. + + $ dune build --profile wasm + $ node _build/default/main.bc.js + wasm_of_ocaml + $ node _build/default/main.bc.wasm.js + wasm_of_ocaml + +Compiling to both JS and Wasm. + + $ dune build --profile both + $ node _build/default/main.bc.js + js_of_ocaml + $ node _build/default/main.bc.wasm.js + wasm_of_ocaml diff --git a/test/blackbox-tests/test-cases/wasmoo/tests.t/a.ml b/test/blackbox-tests/test-cases/wasmoo/tests.t/a.ml new file mode 100644 index 00000000000..351293c912d --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/tests.t/a.ml @@ -0,0 +1 @@ +let () = print_endline "a: ok" diff --git a/test/blackbox-tests/test-cases/wasmoo/tests.t/b.expected b/test/blackbox-tests/test-cases/wasmoo/tests.t/b.expected new file mode 100644 index 00000000000..3aca7c21f74 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/tests.t/b.expected @@ -0,0 +1 @@ +b: ok diff --git a/test/blackbox-tests/test-cases/wasmoo/tests.t/b.ml b/test/blackbox-tests/test-cases/wasmoo/tests.t/b.ml new file mode 100644 index 00000000000..9b1f9b5f9f2 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/tests.t/b.ml @@ -0,0 +1 @@ +let () = print_endline "b: ok" diff --git a/test/blackbox-tests/test-cases/wasmoo/tests.t/dune b/test/blackbox-tests/test-cases/wasmoo/tests.t/dune new file mode 100644 index 00000000000..c91a047df42 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/tests.t/dune @@ -0,0 +1,5 @@ +(tests + (names a b) + (modes js)) + +(env (_ (js_of_ocaml (runtest_alias runtest-js) (submodes wasm) (compilation_mode whole_program)))) diff --git a/test/blackbox-tests/test-cases/wasmoo/tests.t/dune-project b/test/blackbox-tests/test-cases/wasmoo/tests.t/dune-project new file mode 100644 index 00000000000..3e2a6150dda --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/tests.t/dune-project @@ -0,0 +1 @@ +(lang dune 3.17) diff --git a/test/blackbox-tests/test-cases/wasmoo/tests.t/run.t b/test/blackbox-tests/test-cases/wasmoo/tests.t/run.t new file mode 100644 index 00000000000..60d459816d0 --- /dev/null +++ b/test/blackbox-tests/test-cases/wasmoo/tests.t/run.t @@ -0,0 +1,4 @@ +tests stanza with wasmoo + + $ dune build @default @runtest-js + a: ok From 7ba44dd1fcead58d9a8b961725c5bd1403e7291c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Vouillon?= Date: Thu, 4 Jul 2024 15:54:03 +0200 Subject: [PATCH 05/26] Changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Vouillon --- doc/changes/11093.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 doc/changes/11093.md diff --git a/doc/changes/11093.md b/doc/changes/11093.md new file mode 100644 index 00000000000..54000c8c106 --- /dev/null +++ b/doc/changes/11093.md @@ -0,0 +1 @@ +- Wasm_of_ocaml support (#11093, @vouillon) From a1cbe1f4525eec56e48e6dc167df796b3812606f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Vouillon?= Date: Sat, 6 Jul 2024 15:46:44 +0200 Subject: [PATCH 06/26] ci: enable wasm_of_ocaml tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Vouillon --- .github/workflows/workflow.yml | 88 ++++++++++++++++++++++ test/blackbox-tests/test-cases/wasmoo/dune | 5 -- 2 files changed, 88 insertions(+), 5 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 9f24ccc46b5..230c61015ef 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -190,6 +190,94 @@ jobs: # We disable the Dune cache when running the tests DUNE_CACHE: disabled + wasm: + name: Wasm_of_ocaml + runs-on: ubuntu-latest + steps: + - name: Install node + uses: actions/setup-node@v4 + with: + node-version: latest + + - name: Restore cached binaryen + id: cache-binaryen + uses: actions/cache/restore@v4 + with: + path: binaryen + key: ${{ runner.os }}-binaryen-version_119 + + - name: Checkout binaryen + if: steps.cache-binaryen.outputs.cache-hit != 'true' + uses: actions/checkout@v4 + with: + repository: WebAssembly/binaryen + path: binaryen + submodules: true + ref: version_119 + + - name: Install ninja + if: steps.cache-binaryen.outputs.cache-hit != 'true' + run: sudo apt-get install ninja-build + + - name: Build binaryen + if: steps.cache-binaryen.outputs.cache-hit != 'true' + working-directory: ./binaryen + run: | + cmake -G Ninja . + ninja + + - name: Cache binaryen + if: steps.cache-binaryen.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 + with: + path: binaryen + key: ${{ runner.os }}-binaryen-version_119 + + - name: Set binaryen's path + run: | + echo "$GITHUB_WORKSPACE/binaryen/bin" >> $GITHUB_PATH + + - name: Checkout code + uses: actions/checkout@v4 + with: + path: dune + + - name: Use OCaml 4.14.x + uses: ocaml/setup-ocaml@v3 + with: + ocaml-compiler: 4.14.x + opam-pin: false + opam-depext: false + dune-cache: true + + - name: Update dune + working-directory: ./dune + run: opam pin add -n dune . --with-version 3.17.0 + + - name: Checkout wasm_of_ocaml + uses: actions/checkout@v4 + with: + repository: ocaml-wasm/wasm_of_ocaml + ref: target-dir + path: wasm_of_ocaml + + - name: Install wasm_of_ocaml + working-directory: ./wasm_of_ocaml + run: | + opam pin add -n . --with-version `< VERSION` + opam install wasm_of_ocaml-compiler + + - name: Set git user + run: | + git config --global user.name github-actions[bot] + git config --global user.email github-actions[bot]@users.noreply.github.com + - name: Run tests + working-directory: ./dune + run: opam exec -- make test-wasm + env: + # We disable the Dune cache when running the tests + DUNE_CACHE: disabled + monorepo_benchmark_test: name: Build monorepo benchmark docker image runs-on: ubuntu-latest diff --git a/test/blackbox-tests/test-cases/wasmoo/dune b/test/blackbox-tests/test-cases/wasmoo/dune index 5a26ce4c4bf..c5e142618c0 100644 --- a/test/blackbox-tests/test-cases/wasmoo/dune +++ b/test/blackbox-tests/test-cases/wasmoo/dune @@ -5,11 +5,6 @@ (enabled_if (= %{env:DUNE_WASM_TEST=disable} enable))) -(cram - (applies_to inline-tests) - (deps - (package ppx_expect))) - (cram (applies_to build-info) (deps From 5c1c3395283e9db3ef361e370cf096ba31a270b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Vouillon?= Date: Thu, 26 Sep 2024 15:33:24 +0200 Subject: [PATCH 07/26] Wording changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Vouillon --- .github/workflows/workflow.yml | 26 +++++++++---------- doc/wasmoo.rst | 4 +-- .../test-cases/wasmoo/github3622.t | 6 ++--- .../test-cases/wasmoo/inline-tests.t/run.t | 2 +- .../test-cases/wasmoo/no-check-prim.t/run.t | 2 +- .../test-cases/wasmoo/public-libs.t/run.t | 2 +- .../test-cases/wasmoo/simple.t/run.t | 10 +++---- .../test-cases/wasmoo/submodes.t/run.t | 2 +- 8 files changed, 27 insertions(+), 27 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 230c61015ef..527695f6f92 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -194,19 +194,19 @@ jobs: name: Wasm_of_ocaml runs-on: ubuntu-latest steps: - - name: Install node + - name: Install Node uses: actions/setup-node@v4 with: node-version: latest - - name: Restore cached binaryen + - name: Restore Cached Binaryen id: cache-binaryen uses: actions/cache/restore@v4 with: path: binaryen key: ${{ runner.os }}-binaryen-version_119 - - name: Checkout binaryen + - name: Checkout Binaryen if: steps.cache-binaryen.outputs.cache-hit != 'true' uses: actions/checkout@v4 with: @@ -215,29 +215,29 @@ jobs: submodules: true ref: version_119 - - name: Install ninja + - name: Install Ninja if: steps.cache-binaryen.outputs.cache-hit != 'true' run: sudo apt-get install ninja-build - - name: Build binaryen + - name: Build Binaryen if: steps.cache-binaryen.outputs.cache-hit != 'true' working-directory: ./binaryen run: | cmake -G Ninja . ninja - - name: Cache binaryen + - name: Cache Binaryen if: steps.cache-binaryen.outputs.cache-hit != 'true' uses: actions/cache/save@v4 with: path: binaryen key: ${{ runner.os }}-binaryen-version_119 - - name: Set binaryen's path + - name: Set Binaryen's Path run: | echo "$GITHUB_WORKSPACE/binaryen/bin" >> $GITHUB_PATH - - name: Checkout code + - name: Checkout Code uses: actions/checkout@v4 with: path: dune @@ -250,28 +250,28 @@ jobs: opam-depext: false dune-cache: true - - name: Update dune + - name: Update Dune working-directory: ./dune run: opam pin add -n dune . --with-version 3.17.0 - - name: Checkout wasm_of_ocaml + - name: Checkout Wasm_of_ocaml uses: actions/checkout@v4 with: repository: ocaml-wasm/wasm_of_ocaml ref: target-dir path: wasm_of_ocaml - - name: Install wasm_of_ocaml + - name: Install Wasm_of_ocaml working-directory: ./wasm_of_ocaml run: | opam pin add -n . --with-version `< VERSION` opam install wasm_of_ocaml-compiler - - name: Set git user + - name: Set Git User run: | git config --global user.name github-actions[bot] git config --global user.email github-actions[bot]@users.noreply.github.com - - name: Run tests + - name: Run Tests working-directory: ./dune run: opam exec -- make test-wasm env: diff --git a/doc/wasmoo.rst b/doc/wasmoo.rst index e5548df05ec..2a088b6d6db 100644 --- a/doc/wasmoo.rst +++ b/doc/wasmoo.rst @@ -18,8 +18,8 @@ Compiling to Wasm is very similar to compiling to JavaScript. See Compiling to Wasm ================= -Dune has full support building Wasm_of_ocaml libraries and executables transparently. -There's no need to customize or enable anything to compile OCaml +Dune has full support for building wasm_of_ocaml libraries and executables transparently. +There's no need to customise or enable anything to compile OCaml libraries/executables to Wasm. To build a Wasm executable, just define an executable as you would normally. diff --git a/test/blackbox-tests/test-cases/wasmoo/github3622.t b/test/blackbox-tests/test-cases/wasmoo/github3622.t index f4103f2d768..5b83eb58c01 100644 --- a/test/blackbox-tests/test-cases/wasmoo/github3622.t +++ b/test/blackbox-tests/test-cases/wasmoo/github3622.t @@ -1,6 +1,6 @@ -This test demonstrates a bug in dune's separation compilation of jsoo. -std_exit.cmo wasn't being linked in the end, which was causing at_exit hooks not -being ran and channels not being flushed. +This test demonstrates a bug in Dune's separation compilation of JSOO. +`std_exit.cmo` wasn't being linked in the end, so the `at_exit` +hooks didn't run and the channels weren't flushed. Setup fixtures: diff --git a/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/run.t b/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/run.t index f4ccb7dbe36..ea39b6b928c 100644 --- a/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/run.t +++ b/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/run.t @@ -1,4 +1,4 @@ -Run inline tests using node js +Run inline tests using Node.js $ cat >dune-project < (lang dune 3.17) diff --git a/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/run.t b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/run.t index 1b42947088d..fec9ab2e6a9 100644 --- a/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/run.t +++ b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/run.t @@ -1,4 +1,4 @@ -Compilation using jsoo +Compilation using WasmOO $ dune build --display short bin/technologic.bc.js @install 2>&1 | \ > sed s,^\ *$(ocamlc -config-var c_compiler),\ \ C_COMPILER,g diff --git a/test/blackbox-tests/test-cases/wasmoo/public-libs.t/run.t b/test/blackbox-tests/test-cases/wasmoo/public-libs.t/run.t index 68a3c636a8a..2a5b7fbfd7b 100644 --- a/test/blackbox-tests/test-cases/wasmoo/public-libs.t/run.t +++ b/test/blackbox-tests/test-cases/wasmoo/public-libs.t/run.t @@ -1,3 +1,3 @@ -Compilation of libraries with public-names +Compilation of libraries with `public-names` $ dune build diff --git a/test/blackbox-tests/test-cases/wasmoo/simple.t/run.t b/test/blackbox-tests/test-cases/wasmoo/simple.t/run.t index 1dad7602308..f8194c95599 100644 --- a/test/blackbox-tests/test-cases/wasmoo/simple.t/run.t +++ b/test/blackbox-tests/test-cases/wasmoo/simple.t/run.t @@ -1,4 +1,4 @@ -Compilation using wasmoo +Compilation using WasmOO $ dune build bin/technologic.bc.wasm.js @install --profile dev $ node ./_build/default/bin/technologic.bc.wasm.js buy it @@ -12,7 +12,7 @@ Compilation using wasmoo break it fix it -Compilation using wasmoo with disable_dynamically_linked_foreign_archives = true +Compilation using WasmOO with `disable_dynamically_linked_foreign_archives = true` $ cat >dune-workspace < (lang dune 3.17) @@ -22,11 +22,11 @@ Compilation using wasmoo with disable_dynamically_linked_foreign_archives = true $ dune clean $ dune build bin/technologic.bc.wasm.js @install --profile dev -Js_of_ocaml whole program compilation works with -disable_dynamically_linked_foreign_archives = true: +Wasm_of_ocaml whole program compilation works with +`disable_dynamically_linked_foreign_archives = true`: $ dune build bin/technologic.bc.wasm.js @install --profile release -We expect a runtime error when running this bc-for-jsoo file. +We expect a runtime error when running this `bc-for-jsoo` file. $ ! if dune exe bin/technologic.bc-for-jsoo ; then true ; else false ; fi 2> /dev/null diff --git a/test/blackbox-tests/test-cases/wasmoo/submodes.t/run.t b/test/blackbox-tests/test-cases/wasmoo/submodes.t/run.t index 7183468bb7b..2995e7e95e0 100644 --- a/test/blackbox-tests/test-cases/wasmoo/submodes.t/run.t +++ b/test/blackbox-tests/test-cases/wasmoo/submodes.t/run.t @@ -9,7 +9,7 @@ The default is to only compile to JavaScript Error: Don't know how to build main.bc.wasm.js [1] -Compiling to Wasm. One can still use the .bc.js binary but it runs +Compiling to Wasm. One can still use the `.bc.js` binary but it runs the Wasm code. $ dune build --profile wasm From 4ae8cc4f9e174995c10f17b9efabd3c01fad26e1 Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Sun, 20 Oct 2024 15:19:36 +0100 Subject: [PATCH 08/26] _ Signed-off-by: Rudi Grinberg --- src/dune_rules/dir_status.ml | 44 +++++++++++++---------------- src/dune_rules/jsoo/js_of_ocaml.ml | 18 ++++++------ src/dune_rules/jsoo/js_of_ocaml.mli | 2 ++ src/dune_rules/jsoo/jsoo_rules.ml | 36 +++++++++++------------ 4 files changed, 48 insertions(+), 52 deletions(-) diff --git a/src/dune_rules/dir_status.ml b/src/dune_rules/dir_status.ml index b9ac1be90e2..b088fde58ae 100644 --- a/src/dune_rules/dir_status.ml +++ b/src/dune_rules/dir_status.ml @@ -143,7 +143,7 @@ let jsoo_wasm_enabled ~submodes = let+ submodes = jsoo_submodes ~dir ~submodes in - List.mem ~equal:Poly.equal submodes Wasm + List.mem ~equal:Js_of_ocaml.Submode.equal submodes Wasm ;; let directory_targets_of_executables @@ -184,29 +184,25 @@ let directory_targets_of_library match Sub_system_name.Map.find sub_systems Inline_tests_info.Tests.name with | Some (Inline_tests_info.Tests.T { modes; loc; enabled_if; _ }) when Inline_tests_info.Mode_conf.Set.mem modes Javascript -> - let* directory_targets = - let+ wasm_enabled = - jsoo_wasm_enabled ~jsoo_submodes ~dir ~submodes:buildable.js_of_ocaml.submodes - in - if wasm_enabled - then ( - let lib_name = snd name in - let inline_test_dir = - let inline_test_name = - sprintf "%s.inline-tests" (Lib_name.Local.to_string lib_name) - in - Path.Build.relative dir ("." ^ inline_test_name) - in - let name = - sprintf "inline_test_runner_%s" (Lib_name.Local.to_string lib_name) - in - let dir_target = - Path.Build.relative inline_test_dir (name ^ Js_of_ocaml.Ext.wasm_dir) - in - Path.Build.Map.singleton dir_target loc) - else Path.Build.Map.empty - in - when_enabled ~dir ~enabled_if directory_targets + jsoo_wasm_enabled ~jsoo_submodes ~dir ~submodes:buildable.js_of_ocaml.submodes + >>| (function + | false -> Path.Build.Map.empty + | true -> + let dir_target = + let lib_name = snd name in + let name = + sprintf "inline_test_runner_%s" (Lib_name.Local.to_string lib_name) + in + let inline_test_dir = + let inline_test_name = + sprintf "%s.inline-tests" (Lib_name.Local.to_string lib_name) + in + Path.Build.relative dir ("." ^ inline_test_name) + in + Path.Build.relative inline_test_dir (name ^ Js_of_ocaml.Ext.wasm_dir) + in + Path.Build.Map.singleton dir_target loc) + >>= when_enabled ~dir ~enabled_if | _ -> Memo.return Path.Build.Map.empty in when_enabled ~dir ~enabled_if directory_targets diff --git a/src/dune_rules/jsoo/js_of_ocaml.ml b/src/dune_rules/jsoo/js_of_ocaml.ml index 9cdbd1801dd..d351dbd163e 100644 --- a/src/dune_rules/jsoo/js_of_ocaml.ml +++ b/src/dune_rules/jsoo/js_of_ocaml.ml @@ -100,23 +100,25 @@ module Submode = struct | JS | Wasm + let equal = Poly.equal + module Set = struct type t = { js : bool ; wasm : bool } + let empty = { js = false; wasm = false } + + let add t = function + | JS -> { t with js = true } + | Wasm -> { t with wasm = true } + ;; + let decode = map (repeat1 (enum [ "js", JS; "wasm", Wasm ])) - ~f:(fun l -> - List.fold_left - ~f:(fun t submode -> - match submode with - | JS -> { t with js = true } - | Wasm -> { t with wasm = true }) - ~init:{ js = false; wasm = false } - l) + ~f:(List.fold_left ~init:empty ~f:add) ;; let equal x y = x.js = y.js && x.wasm = y.wasm diff --git a/src/dune_rules/jsoo/js_of_ocaml.mli b/src/dune_rules/jsoo/js_of_ocaml.mli index e0f83341c97..2294e9e8051 100644 --- a/src/dune_rules/jsoo/js_of_ocaml.mli +++ b/src/dune_rules/jsoo/js_of_ocaml.mli @@ -43,6 +43,8 @@ module Submode : sig type submode := t + val equal : t -> t -> bool + module Set : sig type t = { js : bool diff --git a/src/dune_rules/jsoo/jsoo_rules.ml b/src/dune_rules/jsoo/jsoo_rules.ml index 216ae45cb18..adc91fdeb0f 100644 --- a/src/dune_rules/jsoo/jsoo_rules.ml +++ b/src/dune_rules/jsoo/jsoo_rules.ml @@ -274,13 +274,11 @@ let js_of_ocaml_rule ;; let jsoo_runtime_files ~(submode : Js_of_ocaml.Submode.t) libs = - List.concat_map - ~f:(fun t -> - (match submode with - | JS -> Lib_info.jsoo_runtime - | Wasm -> Lib_info.wasmoo_runtime) - (Lib.info t)) - libs + List.concat_map libs ~f:(fun t -> + (match submode with + | JS -> Lib_info.jsoo_runtime + | Wasm -> Lib_info.wasmoo_runtime) + (Lib.info t)) ;; let standalone_runtime_rule ~submode cc ~runtime_files ~target ~flags = @@ -580,16 +578,14 @@ let js_of_ocaml_sourcemap t ~dir = ;; let jsoo_submodes ~dir ~submodes = - let+ submodes = - match submodes with - | Some _ -> Memo.return submodes - | None -> - let+ js_of_ocaml = jsoo_env ~dir in - js_of_ocaml.submodes - in - match submodes with + (match submodes with + | Some _ -> Memo.return submodes + | None -> + let+ js_of_ocaml = jsoo_env ~dir in + js_of_ocaml.submodes) + >>| function + | None -> [ Js_of_ocaml.Submode.JS ] | Some m -> Js_of_ocaml.Submode.Set.to_list m - | None -> [ JS ] ;; let build_exe @@ -630,14 +626,14 @@ let build_exe | Some x -> Memo.return x and* submodes = jsoo_submodes ~dir ~submodes in let* () = - if not (List.mem ~equal:Poly.equal submodes JS) - then ( + match List.mem ~equal:Poly.equal submodes JS with + | false -> Memo.return () + | true -> let dst = Path.Build.set_extension src ~ext:(Js_of_ocaml.Ext.exe ~submode:JS) in let src = Path.build (Path.Build.set_extension src ~ext:(Js_of_ocaml.Ext.exe ~submode:Wasm)) in - Super_context.add_rule ~loc ~dir ~mode sctx (Action_builder.copy ~src ~dst)) - else Memo.return () + Super_context.add_rule ~loc ~dir ~mode sctx (Action_builder.copy ~src ~dst) in Memo.parallel_iter submodes ~f:(fun submode -> let standalone_runtime = From e26ece414adbc639497712bb27a5f2dc2bdb6e6d Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Sun, 20 Oct 2024 15:22:58 +0100 Subject: [PATCH 09/26] _ Signed-off-by: Rudi Grinberg --- src/dune_rules/jsoo/js_of_ocaml.ml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dune_rules/jsoo/js_of_ocaml.ml b/src/dune_rules/jsoo/js_of_ocaml.ml index d351dbd163e..3ee467e80bd 100644 --- a/src/dune_rules/jsoo/js_of_ocaml.ml +++ b/src/dune_rules/jsoo/js_of_ocaml.ml @@ -116,9 +116,9 @@ module Submode = struct ;; let decode = - map - (repeat1 (enum [ "js", JS; "wasm", Wasm ])) - ~f:(List.fold_left ~init:empty ~f:add) + enum [ "js", JS; "wasm", Wasm ] + |> repeat1 + |> map ~f:(List.fold_left ~init:empty ~f:add) ;; let equal x y = x.js = y.js && x.wasm = y.wasm From 21ca0cae1880fff44382838b360492e61a49a700 Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Sun, 20 Oct 2024 15:24:57 +0100 Subject: [PATCH 10/26] _ Signed-off-by: Rudi Grinberg --- src/dune_rules/dir_status.mli | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dune_rules/dir_status.mli b/src/dune_rules/dir_status.mli index c42a0d592ff..3c5497e7a45 100644 --- a/src/dune_rules/dir_status.mli +++ b/src/dune_rules/dir_status.mli @@ -45,7 +45,7 @@ end val directory_targets : t -> jsoo_submodes: - (dir:Import.Path.Build.t + (dir:Path.Build.t -> submodes:Js_of_ocaml.Submode.Set.t option -> Js_of_ocaml.Submode.t list Memo.t) -> dir:Path.Build.t From 3fb25415941bd307a45af0588a2afac0cb63ec26 Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Sun, 20 Oct 2024 16:22:08 +0100 Subject: [PATCH 11/26] _ Signed-off-by: Rudi Grinberg --- src/dune_rules/dir_status.ml | 35 ++++++++++++++++----------------- src/dune_rules/install_rules.ml | 6 +++--- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/dune_rules/dir_status.ml b/src/dune_rules/dir_status.ml index b088fde58ae..337a955aebd 100644 --- a/src/dune_rules/dir_status.ml +++ b/src/dune_rules/dir_status.ml @@ -136,7 +136,7 @@ let directory_targets_of_rule ~dir { Rule_conf.targets; loc = rule_loc; enabled_ let jsoo_wasm_enabled ~(jsoo_submodes : - dir:Import.Path.Build.t + dir:Path.Build.t -> submodes:Js_of_ocaml.Submode.Set.t option -> Js_of_ocaml.Submode.t list Memo.t) ~dir @@ -152,25 +152,24 @@ let directory_targets_of_executables { Executables.names; modes; enabled_if; buildable; _ } = let* directory_targets = - let* wasm_enabled = + (* CR-someday rgrinberg: we don't necessarily need to evalute + [explicit_js_mode] or [wasm_enabled] here *) + let+ wasm_enabled = jsoo_wasm_enabled ~jsoo_submodes ~dir ~submodes:buildable.js_of_ocaml.submodes + and+ explicit_js_mode = + Scope.DB.find_by_dir dir >>| Scope.project >>| Dune_project.explicit_js_mode in - let* explicit_js_mode = - let+ scope = Scope.DB.find_by_dir dir in - let project = Scope.project scope in - Dune_project.explicit_js_mode project - in - if Executables.Link_mode.( - Map.mem modes js || ((not explicit_js_mode) && Map.mem modes byte)) - && wasm_enabled - then - Memo.List.fold_left - (Nonempty_list.to_list names) - ~init:Path.Build.Map.empty - ~f:(fun acc (_, name) -> - let dir_target = Path.Build.relative dir (name ^ Js_of_ocaml.Ext.wasm_dir) in - Path.Build.Map.set acc dir_target buildable.loc |> Memo.return) - else Memo.return Path.Build.Map.empty + match + Executables.Link_mode.( + Map.mem modes js || ((not explicit_js_mode) && Map.mem modes byte)) + && wasm_enabled + with + | false -> Path.Build.Map.empty + | true -> + Nonempty_list.to_list names + |> List.fold_left ~init:Path.Build.Map.empty ~f:(fun acc (_, name) -> + let dir_target = Path.Build.relative dir (name ^ Js_of_ocaml.Ext.wasm_dir) in + Path.Build.Map.set acc dir_target buildable.loc) in when_enabled ~dir ~enabled_if directory_targets ;; diff --git a/src/dune_rules/install_rules.ml b/src/dune_rules/install_rules.ml index a6c93b4d5b6..d53e6b32b07 100644 --- a/src/dune_rules/install_rules.ml +++ b/src/dune_rules/install_rules.ml @@ -112,9 +112,9 @@ end = struct (let { Mode.Dict.byte; native } = Lib_info.archives lib in let jsoo_files = (* A same runtime file can be used both for jsoo and wasmoo *) - List.sort_uniq - ~compare:Path.Build.compare - (Lib_info.jsoo_runtime lib @ Lib_info.wasmoo_runtime lib) + Lib_info.jsoo_runtime lib + |> List.rev_append (Lib_info.wasmoo_runtime lib) + |> List.sort_uniq ~compare:Path.Build.compare in [ byte ; native From 583ba09ecc81b822b6fbf2955b4ac517fc260339 Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Sun, 20 Oct 2024 16:32:14 +0100 Subject: [PATCH 12/26] _ Signed-off-by: Rudi Grinberg --- .../test-cases/wasmoo/simple.t/bin/dune | 6 +++--- test/blackbox-tests/test-cases/wasmoo/submodes.t/dune | 9 ++++----- test/blackbox-tests/test-cases/wasmoo/tests.t/dune | 11 ++++++++--- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/test/blackbox-tests/test-cases/wasmoo/simple.t/bin/dune b/test/blackbox-tests/test-cases/wasmoo/simple.t/bin/dune index de172d2b9a3..1f0939d8c4c 100644 --- a/test/blackbox-tests/test-cases/wasmoo/simple.t/bin/dune +++ b/test/blackbox-tests/test-cases/wasmoo/simple.t/bin/dune @@ -3,6 +3,6 @@ (libraries js_of_ocaml x) (modes js) (js_of_ocaml - (submodes wasm) - (flags (:standard)) - (wasm_files runtime.js))) + (submodes wasm) + (flags (:standard)) + (wasm_files runtime.js))) diff --git a/test/blackbox-tests/test-cases/wasmoo/submodes.t/dune b/test/blackbox-tests/test-cases/wasmoo/submodes.t/dune index 9ebfc9795b2..c8dcdb3f898 100644 --- a/test/blackbox-tests/test-cases/wasmoo/submodes.t/dune +++ b/test/blackbox-tests/test-cases/wasmoo/submodes.t/dune @@ -1,8 +1,7 @@ - (executable - (name main) - (modes js)) + (name main) + (modes js)) (env - (wasm (js_of_ocaml (submodes wasm))) - (both (js_of_ocaml (submodes js wasm)))) + (wasm (js_of_ocaml (submodes wasm))) + (both (js_of_ocaml (submodes js wasm)))) diff --git a/test/blackbox-tests/test-cases/wasmoo/tests.t/dune b/test/blackbox-tests/test-cases/wasmoo/tests.t/dune index c91a047df42..c5e43ef8ad3 100644 --- a/test/blackbox-tests/test-cases/wasmoo/tests.t/dune +++ b/test/blackbox-tests/test-cases/wasmoo/tests.t/dune @@ -1,5 +1,10 @@ (tests - (names a b) - (modes js)) + (names a b) + (modes js)) -(env (_ (js_of_ocaml (runtest_alias runtest-js) (submodes wasm) (compilation_mode whole_program)))) +(env + (_ + (js_of_ocaml + (runtest_alias runtest-js) + (submodes wasm) + (compilation_mode whole_program)))) From 0e10ececaffe4235ac2de9d9907c640d0f9632c7 Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Sun, 20 Oct 2024 16:46:03 +0100 Subject: [PATCH 13/26] _ Signed-off-by: Rudi Grinberg --- src/dune_rules/jsoo/jsoo_rules.ml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dune_rules/jsoo/jsoo_rules.ml b/src/dune_rules/jsoo/jsoo_rules.ml index adc91fdeb0f..0b5e2b7ba4f 100644 --- a/src/dune_rules/jsoo/jsoo_rules.ml +++ b/src/dune_rules/jsoo/jsoo_rules.ml @@ -626,14 +626,14 @@ let build_exe | Some x -> Memo.return x and* submodes = jsoo_submodes ~dir ~submodes in let* () = - match List.mem ~equal:Poly.equal submodes JS with - | false -> Memo.return () - | true -> + if List.mem ~equal:Poly.equal submodes JS + then Memo.return () + else ( let dst = Path.Build.set_extension src ~ext:(Js_of_ocaml.Ext.exe ~submode:JS) in let src = Path.build (Path.Build.set_extension src ~ext:(Js_of_ocaml.Ext.exe ~submode:Wasm)) in - Super_context.add_rule ~loc ~dir ~mode sctx (Action_builder.copy ~src ~dst) + Super_context.add_rule ~loc ~dir ~mode sctx (Action_builder.copy ~src ~dst)) in Memo.parallel_iter submodes ~f:(fun submode -> let standalone_runtime = From f4e3c593657be0fe7ac189f9d10f85753f245e9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Vouillon?= Date: Mon, 21 Oct 2024 20:13:15 +0200 Subject: [PATCH 14/26] Wasm_of_ocaml support: alternative design MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Vouillon --- .github/workflows/workflow.yml | 2 +- bin/printenv.ml | 20 +- src/dune_lang/binary_kind.ml | 8 +- src/dune_lang/binary_kind.mli | 1 - src/dune_rules/cinaps.ml | 2 +- src/dune_rules/compilation_context.ml | 2 +- src/dune_rules/compilation_context.mli | 4 +- src/dune_rules/dir_status.ml | 51 ++-- src/dune_rules/dir_status.mli | 10 +- src/dune_rules/dune_env.ml | 13 + src/dune_rules/dune_env.mli | 1 + src/dune_rules/exe.ml | 66 +++-- src/dune_rules/exe.mli | 5 +- src/dune_rules/exe_rules.ml | 51 +++- src/dune_rules/gen_rules.ml | 6 +- src/dune_rules/inline_tests.ml | 75 ++--- src/dune_rules/inline_tests_info.ml | 16 +- src/dune_rules/inline_tests_info.mli | 2 +- src/dune_rules/jsoo/js_of_ocaml.ml | 197 ++++++++----- src/dune_rules/jsoo/js_of_ocaml.mli | 79 +++-- src/dune_rules/jsoo/jsoo_rules.ml | 272 ++++++++++-------- src/dune_rules/jsoo/jsoo_rules.mli | 39 ++- src/dune_rules/lib_rules.ml | 8 +- src/dune_rules/mdx.ml | 2 +- src/dune_rules/melange/melange_rules.ml | 2 +- src/dune_rules/module_compilation.ml | 15 +- src/dune_rules/ppx_driver.ml | 2 +- src/dune_rules/stanzas/buildable.ml | 17 +- src/dune_rules/stanzas/buildable.mli | 2 +- src/dune_rules/stanzas/executables.ml | 42 ++- src/dune_rules/stanzas/executables.mli | 3 + src/dune_rules/stanzas/library.ml | 7 +- src/dune_rules/test_rules.ml | 49 ++-- src/dune_rules/toplevel.ml | 2 +- src/dune_rules/utop.ml | 2 +- .../gen-opam-install-file/stubs.t/dune | 3 +- .../blackbox-tests/test-cases/meta-gen.t/dune | 2 + .../test-cases/meta-gen.t/run.t | 6 +- .../test-cases/wasmoo/build-info.t/run.t | 259 +++-------------- .../test-cases/wasmoo/build-info.t/src/dune | 3 +- .../test-cases/wasmoo/github3622.t | 3 +- .../wasmoo/inline-tests.t/wasm/dune | 4 +- .../test-cases/wasmoo/jsoo-config.t/bin/dune | 10 +- .../test-cases/wasmoo/jsoo-config.t/dune | 3 +- .../wasmoo/no-check-prim.t/bin/dune | 8 +- .../wasmoo/no-check-prim.t/lib/dune | 4 +- .../wasmoo/no-check-prim.t/lib/runtime.js | 2 +- .../test-cases/wasmoo/no-check-prim.t/run.t | 2 +- .../test-cases/wasmoo/public-libs.t/b/dune | 3 +- .../test-cases/wasmoo/simple.t/bin/dune | 8 +- .../test-cases/wasmoo/simple.t/lib/dune | 2 +- .../test-cases/wasmoo/simple.t/lib/runtime.js | 2 +- .../test-cases/wasmoo/submodes.t/dune | 6 +- .../test-cases/wasmoo/submodes.t/run.t | 10 +- .../test-cases/wasmoo/tests.t/dune | 5 +- .../workspaces/workspace-env.t/run.t | 3 + 56 files changed, 742 insertions(+), 681 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 527695f6f92..b1e1ef0be24 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -258,7 +258,7 @@ jobs: uses: actions/checkout@v4 with: repository: ocaml-wasm/wasm_of_ocaml - ref: target-dir + ref: wasm-dune path: wasm_of_ocaml - name: Install Wasm_of_ocaml diff --git a/bin/printenv.ml b/bin/printenv.ml index 2489149d649..709bf53c9b2 100644 --- a/bin/printenv.ml +++ b/bin/printenv.ml @@ -27,13 +27,25 @@ let dump sctx ~dir = |> Action_builder.of_memo >>= Dune_rules.Menhir_env.dump and+ coq_dump = Dune_rules.Coq.Coq_rules.coq_env ~dir >>| Dune_rules.Coq.Coq_flags.dump - and+ jsoo_dump = + and+ jsoo_js_dump = let module Js_of_ocaml = Dune_rules.Js_of_ocaml in - let* jsoo = Action_builder.of_memo (Dune_rules.Jsoo_rules.jsoo_env ~dir) in - Js_of_ocaml.Flags.dump jsoo.flags + let* jsoo = Action_builder.of_memo (Dune_rules.Jsoo_rules.jsoo_env ~dir ~mode:JS) in + Js_of_ocaml.Flags.dump ~mode:JS jsoo.flags + and+ jsoo_wasm_dump = + let module Js_of_ocaml = Dune_rules.Js_of_ocaml in + let* jsoo = Action_builder.of_memo (Dune_rules.Jsoo_rules.jsoo_env ~dir ~mode:Wasm) in + Js_of_ocaml.Flags.dump ~mode:Wasm jsoo.flags in let env = - List.concat [ o_dump; c_dump; link_flags_dump; menhir_dump; coq_dump; jsoo_dump ] + List.concat + [ o_dump + ; c_dump + ; link_flags_dump + ; menhir_dump + ; coq_dump + ; jsoo_js_dump + ; jsoo_wasm_dump + ] in Super_context.context sctx |> Context.name, env ;; diff --git a/src/dune_lang/binary_kind.ml b/src/dune_lang/binary_kind.ml index ea635dd8f61..781ee7b88ce 100644 --- a/src/dune_lang/binary_kind.ml +++ b/src/dune_lang/binary_kind.ml @@ -6,7 +6,6 @@ type t = | Object | Shared_object | Plugin - | Js let compare x y = match x, y with @@ -23,9 +22,6 @@ let compare x y = | Shared_object, _ -> Lt | _, Shared_object -> Gt | Plugin, Plugin -> Eq - | Plugin, _ -> Lt - | _, Plugin -> Gt - | Js, Js -> Eq ;; let decode = @@ -37,7 +33,6 @@ let decode = ; "object", return Object ; "shared_object", return Shared_object ; "plugin", Syntax.since Stanza.syntax (2, 4) >>> return Plugin - ; "js", Syntax.since Stanza.syntax (1, 11) >>> return Js ] ;; @@ -47,9 +42,8 @@ let to_string = function | Object -> "object" | Shared_object -> "shared_object" | Plugin -> "plugin" - | Js -> "js" ;; let to_dyn t = Dyn.variant (to_string t) [] let encode t = Dune_sexp.atom (to_string t) -let all = [ C; Exe; Object; Shared_object; Plugin; Js ] +let all = [ C; Exe; Object; Shared_object; Plugin ] diff --git a/src/dune_lang/binary_kind.mli b/src/dune_lang/binary_kind.mli index 8a06def5b42..019fd74f72e 100644 --- a/src/dune_lang/binary_kind.mli +++ b/src/dune_lang/binary_kind.mli @@ -6,7 +6,6 @@ type t = | Object | Shared_object | Plugin - | Js val compare : t -> t -> Ordering.t diff --git a/src/dune_rules/cinaps.ml b/src/dune_rules/cinaps.ml index 4029e480457..5d6ad7223ab 100644 --- a/src/dune_rules/cinaps.ml +++ b/src/dune_rules/cinaps.ml @@ -179,7 +179,7 @@ let gen_rules sctx t ~dir ~scope = ~requires_compile ~requires_link ~flags:(Ocaml_flags.of_list [ "-w"; "-24" ]) - ~js_of_ocaml:None + ~js_of_ocaml:(Js_of_ocaml.Mode.Pair.make None) ~melange_package_name:None ~package:None in diff --git a/src/dune_rules/compilation_context.ml b/src/dune_rules/compilation_context.ml index 9e9e9e25db9..4b3c64fde40 100644 --- a/src/dune_rules/compilation_context.ml +++ b/src/dune_rules/compilation_context.ml @@ -87,7 +87,7 @@ type t = ; preprocessing : Pp_spec.t ; opaque : bool ; stdlib : Ocaml_stdlib.t option - ; js_of_ocaml : Js_of_ocaml.In_context.t option + ; js_of_ocaml : Js_of_ocaml.In_context.t option Js_of_ocaml.Mode.Pair.t ; sandbox : Sandbox_config.t ; package : Package.t option ; vimpl : Vimpl.t option diff --git a/src/dune_rules/compilation_context.mli b/src/dune_rules/compilation_context.mli index 9924ea719a6..c6352430c82 100644 --- a/src/dune_rules/compilation_context.mli +++ b/src/dune_rules/compilation_context.mli @@ -30,7 +30,7 @@ val create -> ?preprocessing:Pp_spec.t -> opaque:opaque -> ?stdlib:Ocaml_stdlib.t - -> js_of_ocaml:Js_of_ocaml.In_context.t option + -> js_of_ocaml:Js_of_ocaml.In_context.t option Js_of_ocaml.Mode.Pair.t -> package:Package.t option -> melange_package_name:Lib_name.t option -> ?vimpl:Vimpl.t @@ -61,7 +61,7 @@ val includes : t -> Command.Args.without_targets Command.Args.t Lib_mode.Cm_kind val preprocessing : t -> Pp_spec.t val opaque : t -> bool val stdlib : t -> Ocaml_stdlib.t option -val js_of_ocaml : t -> Js_of_ocaml.In_context.t option +val js_of_ocaml : t -> Js_of_ocaml.In_context.t option Js_of_ocaml.Mode.Pair.t val sandbox : t -> Sandbox_config.t val set_sandbox : t -> Sandbox_config.t -> t val package : t -> Package.t option diff --git a/src/dune_rules/dir_status.ml b/src/dune_rules/dir_status.ml index 337a955aebd..eaa1136042c 100644 --- a/src/dune_rules/dir_status.ml +++ b/src/dune_rules/dir_status.ml @@ -134,36 +134,25 @@ let directory_targets_of_rule ~dir { Rule_conf.targets; loc = rule_loc; enabled_ when_enabled ~dir ~enabled_if directory_targets ;; -let jsoo_wasm_enabled - ~(jsoo_submodes : - dir:Path.Build.t - -> submodes:Js_of_ocaml.Submode.Set.t option - -> Js_of_ocaml.Submode.t list Memo.t) - ~dir - ~submodes - = - let+ submodes = jsoo_submodes ~dir ~submodes in - List.mem ~equal:Js_of_ocaml.Submode.equal submodes Wasm +let jsoo_wasm_enabled ~jsoo_enabled ~dir ~(buildable : Buildable.t) = + let* expander = Expander0.get ~dir in + jsoo_enabled + ~eval:(Expander0.eval_blang expander) + ~dir + ~in_context:(Js_of_ocaml.In_context.make ~dir buildable.js_of_ocaml) + ~mode:Js_of_ocaml.Mode.Wasm ;; let directory_targets_of_executables - ~jsoo_submodes + ~jsoo_enabled ~dir { Executables.names; modes; enabled_if; buildable; _ } = let* directory_targets = (* CR-someday rgrinberg: we don't necessarily need to evalute - [explicit_js_mode] or [wasm_enabled] here *) - let+ wasm_enabled = - jsoo_wasm_enabled ~jsoo_submodes ~dir ~submodes:buildable.js_of_ocaml.submodes - and+ explicit_js_mode = - Scope.DB.find_by_dir dir >>| Scope.project >>| Dune_project.explicit_js_mode - in - match - Executables.Link_mode.( - Map.mem modes js || ((not explicit_js_mode) && Map.mem modes byte)) - && wasm_enabled - with + [wasm_enabled] here *) + let+ wasm_enabled = jsoo_wasm_enabled ~jsoo_enabled ~dir ~buildable in + match Executables.Link_mode.(Map.mem modes wasm) && wasm_enabled with | false -> Path.Build.Map.empty | true -> Nonempty_list.to_list names @@ -175,15 +164,15 @@ let directory_targets_of_executables ;; let directory_targets_of_library - ~jsoo_submodes + ~jsoo_enabled ~dir { Library.sub_systems; name; enabled_if; buildable; _ } = let* directory_targets = match Sub_system_name.Map.find sub_systems Inline_tests_info.Tests.name with | Some (Inline_tests_info.Tests.T { modes; loc; enabled_if; _ }) - when Inline_tests_info.Mode_conf.Set.mem modes Javascript -> - jsoo_wasm_enabled ~jsoo_submodes ~dir ~submodes:buildable.js_of_ocaml.submodes + when Inline_tests_info.Mode_conf.Set.mem modes (Jsoo Wasm) -> + jsoo_wasm_enabled ~jsoo_enabled ~dir ~buildable >>| (function | false -> Path.Build.Map.empty | true -> @@ -207,13 +196,13 @@ let directory_targets_of_library when_enabled ~dir ~enabled_if directory_targets ;; -let extract_directory_targets ~jsoo_submodes ~dir stanzas = +let extract_directory_targets ~jsoo_enabled ~dir stanzas = Memo.parallel_map stanzas ~f:(fun stanza -> match Stanza.repr stanza with | Rule_conf.T rule -> directory_targets_of_rule ~dir rule | Executables.T exes | Tests.T { exes; _ } -> - directory_targets_of_executables ~jsoo_submodes ~dir exes - | Library.T lib -> directory_targets_of_library ~jsoo_submodes ~dir lib + directory_targets_of_executables ~jsoo_enabled ~dir exes + | Library.T lib -> directory_targets_of_library ~jsoo_enabled ~dir lib | Coq_stanza.Theory.T m -> (* It's unfortunate that we need to pull in the coq rules here. But we don't have a generic mechanism for this yet. *) @@ -360,15 +349,15 @@ end = struct ;; end -let directory_targets t ~jsoo_submodes ~dir = +let directory_targets t ~jsoo_enabled ~dir = match t with | Lock_dir | Generated | Source_only _ | Is_component_of_a_group_but_not_the_root _ -> Memo.return Path.Build.Map.empty | Standalone (_, dune_file) -> - Dune_file.stanzas dune_file >>= extract_directory_targets ~jsoo_submodes ~dir + Dune_file.stanzas dune_file >>= extract_directory_targets ~jsoo_enabled ~dir | Group_root { components; dune_file; _ } -> let f ~dir stanzas acc = - extract_directory_targets ~jsoo_submodes ~dir stanzas + extract_directory_targets ~jsoo_enabled ~dir stanzas >>| Path.Build.Map.superpose acc in let* init = diff --git a/src/dune_rules/dir_status.mli b/src/dune_rules/dir_status.mli index 3c5497e7a45..f1b70b2b2c8 100644 --- a/src/dune_rules/dir_status.mli +++ b/src/dune_rules/dir_status.mli @@ -44,9 +44,11 @@ end val directory_targets : t - -> jsoo_submodes: - (dir:Path.Build.t - -> submodes:Js_of_ocaml.Submode.Set.t option - -> Js_of_ocaml.Submode.t list Memo.t) + -> jsoo_enabled: + (eval:(Blang.t -> bool Memo.t) + -> dir:Path.Build.t + -> in_context:Js_of_ocaml.In_context.t Js_of_ocaml.Mode.Pair.t + -> mode:Js_of_ocaml.Mode.t + -> bool Memo.t) -> dir:Path.Build.t -> Loc.t Path.Build.Map.t Memo.t diff --git a/src/dune_rules/dune_env.ml b/src/dune_rules/dune_env.ml index 8b3a018b08a..7411f9b2d68 100644 --- a/src/dune_rules/dune_env.ml +++ b/src/dune_rules/dune_env.ml @@ -80,6 +80,7 @@ type config = ; menhir : Ordered_set_lang.Unexpanded.t Menhir_env.t ; odoc : Odoc.t ; js_of_ocaml : Ordered_set_lang.Unexpanded.t Js_of_ocaml.Env.t + ; wasm_of_ocaml : Ordered_set_lang.Unexpanded.t Js_of_ocaml.Env.t ; coq : Coq_env.t ; format_config : Format_config.t option ; error_on_use : User_message.t option @@ -102,6 +103,7 @@ let equal_config ; menhir ; odoc ; js_of_ocaml + ; wasm_of_ocaml ; coq ; format_config ; error_on_use @@ -124,6 +126,7 @@ let equal_config && Coq_env.equal coq t.coq && Option.equal Format_config.equal format_config t.format_config && Js_of_ocaml.Env.equal js_of_ocaml t.js_of_ocaml + && Js_of_ocaml.Env.equal wasm_of_ocaml t.wasm_of_ocaml && Option.equal User_message.equal error_on_use t.error_on_use && Option.equal User_message.equal warn_on_load t.warn_on_load && Option.equal Bool.equal bin_annot t.bin_annot @@ -141,6 +144,7 @@ let empty_config = ; menhir = Menhir_env.empty ; odoc = Odoc.empty ; js_of_ocaml = Js_of_ocaml.Env.empty + ; wasm_of_ocaml = Js_of_ocaml.Env.empty ; coq = Coq_env.default ; format_config = None ; error_on_use = None @@ -224,6 +228,13 @@ let js_of_ocaml_field = (Dune_lang.Syntax.since Stanza.syntax (3, 0) >>> Js_of_ocaml.Env.decode) ;; +let wasm_of_ocaml_field = + field + "wasm_of_ocaml" + ~default:Js_of_ocaml.Env.empty + (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> Js_of_ocaml.Env.decode) +;; + let bin_annot = field_o "bin_annot" (Dune_lang.Syntax.since Stanza.syntax (3, 8) >>> bool) let config = @@ -241,6 +252,7 @@ let config = and+ menhir_flags = menhir_flags ~since:(2, 1) ~deleted_in:Menhir_stanza.explain_since and+ odoc = odoc_field and+ js_of_ocaml = js_of_ocaml_field + and+ wasm_of_ocaml = wasm_of_ocaml_field and+ coq = Coq_env.decode and+ format_config = Format_config.field ~since:(2, 8) and+ bin_annot = bin_annot in @@ -261,6 +273,7 @@ let config = ; menhir ; odoc ; js_of_ocaml + ; wasm_of_ocaml ; coq ; format_config ; error_on_use = None diff --git a/src/dune_rules/dune_env.mli b/src/dune_rules/dune_env.mli index a1d46d8c330..d904e237f7f 100644 --- a/src/dune_rules/dune_env.mli +++ b/src/dune_rules/dune_env.mli @@ -30,6 +30,7 @@ type config = ; menhir : Ordered_set_lang.Unexpanded.t Menhir_env.t ; odoc : Odoc.t ; js_of_ocaml : Ordered_set_lang.Unexpanded.t Js_of_ocaml.Env.t + ; wasm_of_ocaml : Ordered_set_lang.Unexpanded.t Js_of_ocaml.Env.t ; coq : Coq_env.t ; format_config : Format_config.t option ; error_on_use : User_message.t option diff --git a/src/dune_rules/exe.ml b/src/dune_rules/exe.ml index 23941e5e22f..3eaa16f1adf 100644 --- a/src/dune_rules/exe.ml +++ b/src/dune_rules/exe.ml @@ -10,28 +10,47 @@ module Program = struct end module Linkage = struct + type mode = + | Ocaml of Link_mode.t + | Jsoo of Js_of_ocaml.Mode.t + type t = - { mode : Link_mode.t + { mode : mode ; ext : string ; flags : string list } - let byte = { mode = Byte; ext = ".bc"; flags = [] } + let byte = { mode = Ocaml Byte; ext = ".bc"; flags = [] } let byte_for_jsoo = - { mode = Byte_for_jsoo + { mode = Ocaml Byte_for_jsoo ; ext = ".bc-for-jsoo" ; flags = [ "-no-check-prims"; "-noautolink" ] } ;; - let native = { mode = Native; ext = ".exe"; flags = [] } - let is_native x = x.mode = Native - let is_js x = x.mode = Byte && x.ext = Js_of_ocaml.Ext.exe ~submode:JS - let is_byte x = x.mode = Byte && not (is_js x) + let native = { mode = Ocaml Native; ext = ".exe"; flags = [] } + + let is_native x = + match x.mode with + | Ocaml Native -> true + | _ -> false + ;; + + let is_jsoo ~mode x = + match x.mode with + | Jsoo m -> Js_of_ocaml.Mode.equal mode m + | _ -> false + ;; + + let is_byte x = + match x.mode with + | Ocaml Byte -> true + | _ -> false + ;; let custom_with_ext ~ext ocaml_version = - { mode = Byte_with_stubs_statically_linked_in + { mode = Ocaml Byte_with_stubs_statically_linked_in ; ext ; flags = [ Ocaml.Version.custom_or_output_complete_exe ocaml_version ] } @@ -45,7 +64,8 @@ module Linkage = struct | Ok _ -> native ;; - let js = { mode = Byte; ext = Js_of_ocaml.Ext.exe ~submode:JS; flags = [] } + let js = { mode = Jsoo JS; ext = Js_of_ocaml.Ext.exe ~mode:JS; flags = [] } + let wasm = { mode = Jsoo Wasm; ext = Js_of_ocaml.Ext.exe ~mode:Wasm; flags = [] } let is_plugin t = List.mem (List.map ~f:Mode.plugin_ext Mode.all) t.ext ~equal:String.equal @@ -65,7 +85,8 @@ module Linkage = struct (m : Executables.Link_mode.t) = match m with - | Other { mode = Byte; kind = Js } -> js + | Jsoo JS -> js + | Jsoo Wasm -> wasm | _ -> let link_mode : Link_mode.t = match m with @@ -85,6 +106,7 @@ module Linkage = struct if Result.is_ok ocaml.ocamlopt then Native else Byte_with_stubs_statically_linked_in) + | Jsoo _ -> assert false (* Handled above *) in let ext = let lib_config = ocaml.lib_config in @@ -100,7 +122,6 @@ module Linkage = struct | Other { kind; _ } -> (match kind with | C -> c_flags - | Js -> [] | Exe -> (match link_mode with | Byte_with_stubs_statically_linked_in -> @@ -126,8 +147,9 @@ module Linkage = struct List.concat_map native_c_libraries ~f:(fun flag -> [ "-cclib"; flag ]) @ so_flags | Byte | Byte_for_jsoo | Byte_with_stubs_statically_linked_in -> so_flags)) + | Jsoo _ -> assert false (* Handled above *) in - { ext; mode = link_mode; flags } + { ext; mode = Ocaml link_mode; flags } ;; end @@ -139,6 +161,7 @@ let link_exe ~loc ~name ~(linkage : Linkage.t) + ~linkage_mode ~cm_files ~link_time_code_gen ~promote @@ -150,7 +173,7 @@ let link_exe let sctx = Compilation_context.super_context cctx in let ctx = Super_context.context sctx in let dir = Compilation_context.dir cctx in - let mode = Link_mode.mode linkage.mode in + let mode = Link_mode.mode linkage_mode in let exe = exe_path_from_name cctx ~name ~linkage in let top_sorted_cms = Cm_files.top_sorted_cms cm_files ~mode in let fdo_linker_script = Fdo.Linker_script.create cctx (Path.build exe) in @@ -199,7 +222,7 @@ let link_exe sctx to_link ~lib_config:ocaml.lib_config - ~mode:linkage.mode + ~mode:linkage_mode ]) ; Deps o_files ; Dyn (Action_builder.map top_sorted_cms ~f:(fun x -> Command.Args.Deps x)) @@ -227,10 +250,12 @@ let link_js ~link_args ~promote ~link_time_code_gen + ~jsoo_mode cctx = let in_context = Compilation_context.js_of_ocaml cctx + |> Js_of_ocaml.Mode.Pair.select ~mode:jsoo_mode |> Option.value ~default:Js_of_ocaml.In_context.default in let src = exe_path_from_name cctx ~name ~linkage:Linkage.byte_for_jsoo in @@ -252,6 +277,7 @@ let link_js ~promote ~link_time_code_gen ~linkall + ~jsoo_mode ;; type dep_graphs = { for_exes : Module.t list Action_builder.t list } @@ -302,8 +328,8 @@ let link_many in let+ () = Memo.parallel_iter linkages ~f:(fun linkage -> - if Linkage.is_js linkage - then ( + match linkage.Linkage.mode with + | Jsoo jsoo_mode -> let obj_dir = Compilation_context.obj_dir cctx in link_js ~loc @@ -313,8 +339,9 @@ let link_many ~promote ~link_args cctx - ~link_time_code_gen) - else + ~link_time_code_gen + ~jsoo_mode + | Ocaml linkage_mode -> let* link_time_code_gen = match Linkage.is_plugin linkage with | false -> Memo.return link_time_code_gen @@ -328,7 +355,7 @@ let link_many in let link_args, o_files = let select_o_files = Mode.Map.Multi.for_only ~and_all:true o_files in - match linkage.mode with + match linkage_mode with | Native -> link_args, select_o_files Mode.Native | Byte | Byte_for_jsoo | Byte_with_stubs_statically_linked_in -> link_args, select_o_files Mode.Byte @@ -338,6 +365,7 @@ let link_many ~loc ~name ~linkage + ~linkage_mode ~cm_files ~link_time_code_gen ~promote diff --git a/src/dune_rules/exe.mli b/src/dune_rules/exe.mli index 0fdc14db1ed..a1e2fd6338e 100644 --- a/src/dune_rules/exe.mli +++ b/src/dune_rules/exe.mli @@ -33,8 +33,11 @@ module Linkage : sig (** Javascript compilation, extension [.bc.js] *) val js : t + (** Wasm compilation, extension [.bc.wasm.js] *) + val wasm : t + val is_native : t -> bool - val is_js : t -> bool + val is_jsoo : mode:Js_of_ocaml.Mode.t -> t -> bool val is_byte : t -> bool val of_user_config diff --git a/src/dune_rules/exe_rules.ml b/src/dune_rules/exe_rules.ml index 528c2fb768b..6040869a2ad 100644 --- a/src/dune_rules/exe_rules.ml +++ b/src/dune_rules/exe_rules.ml @@ -8,13 +8,19 @@ let linkages (ocaml : Ocaml_toolchain.t) ~(exes : Executables.t) ~explicit_js_mode - ~(jsoo_compilation_mode : Js_of_ocaml.Compilation_mode.t) + ~jsoo_enabled_modes + ~jsoo_is_whole_program = let module L = Executables.Link_mode in let l = let has_native = Result.is_ok ocaml.ocamlopt in let modes = L.Map.to_list exes.modes + |> List.filter ~f:(fun (mode, _) -> + match mode with + | Executables.Link_mode.Jsoo mode -> + Js_of_ocaml.Mode.Pair.select ~mode jsoo_enabled_modes + | Byte_complete | Other _ -> true) |> List.map ~f:(fun (mode, loc) -> Exe.Linkage.of_user_config ocaml ~dynamically_linked_foreign_archives ~loc mode) in @@ -24,20 +30,31 @@ let linkages else List.filter modes ~f:(fun x -> not (Exe.Linkage.is_native x)) in let modes = - if L.Map.mem exes.modes L.js + if L.Map.existsi ~f:(fun m _ -> L.is_jsoo m) exes.modes then ( - match jsoo_compilation_mode with - | Whole_program -> Exe.Linkage.byte_for_jsoo :: modes - | Separate_compilation -> modes) + let jsoo_bytecode_exe_needed = + Js_of_ocaml.Mode.Set.inter jsoo_enabled_modes jsoo_is_whole_program + in + let bytecode_exe_needed = + L.Map.foldi + ~f:(fun m _ p -> + match m with + | Executables.Link_mode.Jsoo mode -> + Js_of_ocaml.Mode.Pair.select ~mode jsoo_bytecode_exe_needed || p + | Byte_complete | Other _ -> p) + ~init:false + exes.modes + in + if bytecode_exe_needed then Exe.Linkage.byte_for_jsoo :: modes else modes) else if explicit_js_mode then modes else if L.Map.mem exes.modes L.byte then Exe.Linkage.js :: - (match jsoo_compilation_mode with - | Whole_program -> Exe.Linkage.byte_for_jsoo :: modes - | Separate_compilation -> modes) + (if Js_of_ocaml.Mode.Pair.select ~mode:JS jsoo_is_whole_program + then Exe.Linkage.byte_for_jsoo :: modes + else modes) else modes in modes @@ -143,8 +160,11 @@ let executables_rules let* ocaml = Context.ocaml ctx in let project = Scope.project scope in let explicit_js_mode = Dune_project.explicit_js_mode project in + let js_of_ocaml = Js_of_ocaml.In_context.make ~dir exes.buildable.js_of_ocaml in let* linkages = - let* jsoo_compilation_mode = Jsoo_rules.js_of_ocaml_compilation_mode sctx ~dir in + let* jsoo_enabled_modes = + Jsoo_rules.jsoo_enabled_modes ~expander ~dir ~in_context:js_of_ocaml + and* jsoo_is_whole_program = Jsoo_rules.jsoo_is_whole_program sctx ~dir in let+ dynamically_linked_foreign_archives = Context.dynamically_linked_foreign_archives ctx in @@ -153,7 +173,8 @@ let executables_rules ~dynamically_linked_foreign_archives ~exes ~explicit_js_mode - ~jsoo_compilation_mode + ~jsoo_enabled_modes + ~jsoo_is_whole_program in let* flags = Buildable_rules.ocaml_flags sctx ~dir exes.buildable.flags in let* modules, pp = @@ -173,10 +194,12 @@ let executables_rules let requires_compile = Lib.Compile.direct_requires compile_info in let requires_link = Lib.Compile.requires_link compile_info in let js_of_ocaml = - let js_of_ocaml = Js_of_ocaml.In_context.make ~dir exes.buildable.js_of_ocaml in - if explicit_js_mode - then Option.some_if (List.exists linkages ~f:Exe.Linkage.is_js) js_of_ocaml - else Some js_of_ocaml + Js_of_ocaml.Mode.Pair.mapi + ~f:(fun mode x -> + Option.some_if + ((not explicit_js_mode) || List.exists linkages ~f:(Exe.Linkage.is_jsoo ~mode)) + x) + js_of_ocaml in Compilation_context.create () diff --git a/src/dune_rules/gen_rules.ml b/src/dune_rules/gen_rules.ml index 9e23ac38706..47bc054b2c7 100644 --- a/src/dune_rules/gen_rules.ml +++ b/src/dune_rules/gen_rules.ml @@ -137,8 +137,8 @@ end = struct js = Some (List.map (Nonempty_list.to_list exes.names) ~f:(fun (_, exe) -> - [ Path.Build.relative dir (exe ^ Js_of_ocaml.Ext.exe ~submode:JS) - ; Path.Build.relative dir (exe ^ Js_of_ocaml.Ext.exe ~submode:Wasm) + [ Path.Build.relative dir (exe ^ Js_of_ocaml.Ext.exe ~mode:JS) + ; Path.Build.relative dir (exe ^ Js_of_ocaml.Ext.exe ~mode:Wasm) ]) |> List.flatten) }) @@ -526,7 +526,7 @@ let gen_rules_regular_directory sctx ~src_dir ~components ~dir = let+ directory_targets = Dir_status.directory_targets dir_status - ~jsoo_submodes:Jsoo_rules.jsoo_submodes + ~jsoo_enabled:Jsoo_rules.jsoo_enabled ~dir in let allowed_subdirs = diff --git a/src/dune_rules/inline_tests.ml b/src/dune_rules/inline_tests.ml index b0373fae180..6bd1406d518 100644 --- a/src/dune_rules/inline_tests.ml +++ b/src/dune_rules/inline_tests.ml @@ -68,18 +68,6 @@ include Sub_system.Register_end_point (struct module Mode_conf = Inline_tests_info.Mode_conf module Info = Inline_tests_info.Tests - let configurations ~dir modes submodes = - let open Memo.O in - Memo.sequential_map (Mode_conf.Set.to_list modes) ~f:(fun (mode : Mode_conf.t) -> - match mode with - | Native | Best -> Memo.return [ mode, ".exe" ] - | Byte -> Memo.return [ mode, ".bc" ] - | Javascript -> - let+ submodes = Jsoo_rules.jsoo_submodes ~dir ~submodes in - List.map submodes ~f:(fun submode -> mode, Js_of_ocaml.Ext.exe ~submode)) - >>| List.flatten - ;; - let gen_rules c ~expander ~(info : Info.t) ~backends = let { Sub_system.Library_compilation_context.super_context = sctx ; dir @@ -119,6 +107,12 @@ include Sub_system.Register_end_point (struct Lib.closure ~linking:true ((lib :: libs) @ more_libs) in (* Generate the runner file *) + let js_of_ocaml = + Js_of_ocaml.Mode.Pair.map + ~f:(fun (x : Js_of_ocaml.In_context.t) -> + { x with javascript_files = []; wasm_files = [] }) + (Js_of_ocaml.In_context.make ~dir lib.buildable.js_of_ocaml) + in let* () = Super_context.add_rule sctx @@ -162,11 +156,6 @@ include Sub_system.Register_end_point (struct Buildable_rules.ocaml_flags sctx ~dir info.executable_ocaml_flags in let flags = Ocaml_flags.append_common ocaml_flags [ "-w"; "-24"; "-g" ] in - let js_of_ocaml = - Js_of_ocaml.In_context.make - ~dir - { lib.buildable.js_of_ocaml with javascript_files = []; wasm_files = [] } - in Compilation_context.create () ~super_context:sctx @@ -177,23 +166,37 @@ include Sub_system.Register_end_point (struct ~requires_compile:runner_libs ~requires_link:(Memo.lazy_ (fun () -> runner_libs)) ~flags - ~js_of_ocaml:(Some js_of_ocaml) + ~js_of_ocaml:(Js_of_ocaml.Mode.Pair.map ~f:Option.some js_of_ocaml) ~melange_package_name:None ~package in + let* modes = + let+ jsoo_enabled_modes = + Jsoo_rules.jsoo_enabled_modes ~expander ~dir ~in_context:js_of_ocaml + in + Mode_conf.Set.to_list info.modes + |> List.filter ~f:(fun (mode : Mode_conf.t) -> + match mode with + | Native | Best | Byte -> true + | Jsoo mode -> Js_of_ocaml.Mode.Pair.select ~mode jsoo_enabled_modes) + in let* linkages = - let+ jsoo_compilation_mode = Jsoo_rules.js_of_ocaml_compilation_mode sctx ~dir in + let+ jsoo_is_whole_program = Jsoo_rules.jsoo_is_whole_program sctx ~dir in let ocaml = Compilation_context.ocaml cctx in - List.concat_map (Mode_conf.Set.to_list info.modes) ~f:(fun (mode : Mode_conf.t) -> + List.concat_map modes ~f:(fun (mode : Mode_conf.t) -> match mode with | Native -> [ Exe.Linkage.native ] | Best -> [ Exe.Linkage.native_or_custom ocaml ] | Byte -> [ Exe.Linkage.custom_with_ext ~ext:".bc" ocaml.version ] - | Javascript -> - (match jsoo_compilation_mode with - | Js_of_ocaml.Compilation_mode.Whole_program -> - [ Exe.Linkage.js; Exe.Linkage.byte_for_jsoo ] - | Separate_compilation -> [ Exe.Linkage.js ])) + | Jsoo jsoo_mode -> + let linkage = + match jsoo_mode with + | JS -> Exe.Linkage.js + | Wasm -> Exe.Linkage.wasm + in + if Js_of_ocaml.Mode.Pair.select ~mode:jsoo_mode jsoo_is_whole_program + then [ Exe.Linkage.byte_for_jsoo; linkage ] + else [ linkage ]) in let* (_ : Exe.dep_graphs) = let link_args = @@ -249,18 +252,21 @@ include Sub_system.Register_end_point (struct else Sandbox_config.needs_sandboxing in let deps, sandbox = Dep_conf_eval.unnamed ~sandbox info.deps ~expander in - let action - (mode : Mode_conf.t) - (ext : string) - (flags : string list Action_builder.t) + let action (mode : Mode_conf.t) (flags : string list Action_builder.t) : Action.t Action_builder.t = (* [action] needs to run from [dir] as we use [dir] to resolve the exe path in case of a custom [runner] *) + let ext = + match mode with + | Native | Best -> ".exe" + | Jsoo mode -> Js_of_ocaml.Ext.exe ~mode + | Byte -> ".bc" + in let custom_runner = match mode with | Native | Best | Byte -> None - | Javascript -> Some Jsoo_rules.runner + | Jsoo _ -> Some Jsoo_rules.runner in let exe = Path.build (Path.Build.relative inline_test_dir (name ^ ext)) in let open Action_builder.O in @@ -317,8 +323,7 @@ include Sub_system.Register_end_point (struct List.concat l in let source_files = List.concat_map source_modules ~f:Module.sources in - let* confs = configurations ~dir info.modes lib.buildable.js_of_ocaml.submodes in - Memo.parallel_iter confs ~f:(fun ((mode : Mode_conf.t), ext) -> + Memo.parallel_iter modes ~f:(fun (mode : Mode_conf.t) -> let partition_file = Path.Build.relative inline_test_dir ("partitions-" ^ Mode_conf.to_string mode) in @@ -327,7 +332,7 @@ include Sub_system.Register_end_point (struct | None -> Memo.return () | Some partitions_flags -> let open Action_builder.O in - action mode ext partitions_flags + action mode partitions_flags >>| Action.Full.make ~sandbox |> Action_builder.with_stdout_to partition_file |> Super_context.add_rule sctx ~dir ~loc @@ -335,7 +340,7 @@ include Sub_system.Register_end_point (struct let* runtest_alias = match mode with | Native | Best | Byte -> Memo.return Alias0.runtest - | Javascript -> Jsoo_rules.js_of_ocaml_runtest_alias ~dir + | Jsoo mode -> Jsoo_rules.js_of_ocaml_runtest_alias ~dir ~mode in Super_context.add_alias_action sctx @@ -351,7 +356,7 @@ include Sub_system.Register_end_point (struct let+ partitions = Action_builder.lines_of (Path.build partition_file) in List.map ~f:(fun x -> Some x) partitions in - List.map partitions_flags ~f:(fun p -> action mode ext (flags p)) + List.map partitions_flags ~f:(fun p -> action mode (flags p)) |> Action_builder.all and+ () = Action_builder.paths source_files in match actions with diff --git a/src/dune_rules/inline_tests_info.ml b/src/dune_rules/inline_tests_info.ml index 44772b2977f..47e247aa7ba 100644 --- a/src/dune_rules/inline_tests_info.ml +++ b/src/dune_rules/inline_tests_info.ml @@ -68,7 +68,7 @@ module Mode_conf = struct module T = struct type t = | Byte - | Javascript + | Jsoo of Js_of_ocaml.Mode.t | Native | Best @@ -77,9 +77,9 @@ module Mode_conf = struct | Byte, Byte -> Eq | Byte, _ -> Lt | _, Byte -> Gt - | Javascript, Javascript -> Eq - | Javascript, _ -> Lt - | _, Javascript -> Gt + | Jsoo m, Jsoo m' -> Js_of_ocaml.Mode.compare m m' + | Jsoo _, _ -> Lt + | _, Jsoo _ -> Gt | Native, Native -> Eq | Native, _ -> Lt | _, Native -> Gt @@ -94,12 +94,16 @@ module Mode_conf = struct let to_string = function | Byte -> "byte" - | Javascript -> "js" + | Jsoo JS -> "js" + | Jsoo Wasm -> "wasm" | Native -> "native" | Best -> "best" ;; - let decode = enum [ "byte", Byte; "js", Javascript; "native", Native; "best", Best ] + let decode = + enum [ "byte", Byte; "js", Jsoo JS; "native", Native; "best", Best ] + <|> sum [ "wasm", Syntax.since Stanza.syntax (3, 17) >>> return (Jsoo Wasm) ] + ;; module O = Comparable.Make (T) module Map = O.Map diff --git a/src/dune_rules/inline_tests_info.mli b/src/dune_rules/inline_tests_info.mli index af486d63786..2135df4aa88 100644 --- a/src/dune_rules/inline_tests_info.mli +++ b/src/dune_rules/inline_tests_info.mli @@ -16,7 +16,7 @@ end module Mode_conf : sig type t = | Byte - | Javascript + | Jsoo of Js_of_ocaml.Mode.t | Native | Best diff --git a/src/dune_rules/jsoo/js_of_ocaml.ml b/src/dune_rules/jsoo/js_of_ocaml.ml index 3ee467e80bd..883c19437be 100644 --- a/src/dune_rules/jsoo/js_of_ocaml.ml +++ b/src/dune_rules/jsoo/js_of_ocaml.ml @@ -1,8 +1,8 @@ open Import open Dune_lang.Decoder -(* (js_of_ocaml ...) options are also used when producing Wasm code - with wasm_of_ocaml, since the compilation process is similar and +(* We use the same set of options when producing Wasm code with + wasm_of_ocaml, since the compilation process is similar and generates a JavaScript file with basically the same behavior. *) let field_oslu name = Ordered_set_lang.Unexpanded.field name @@ -24,6 +24,78 @@ module Sourcemap = struct ;; end +module Mode = struct + type t = + | JS + | Wasm + + let equal = Poly.equal + + let select ~mode js wasm = + match mode with + | JS -> js + | Wasm -> wasm + ;; + + let compare m m' = + match m, m' with + | JS, JS -> Eq + | JS, _ -> Lt + | _, JS -> Gt + | Wasm, Wasm -> Eq + ;; + + let decode = + let open Dune_sexp in + let open Decoder in + sum [ "js", return JS; "wasm", return Wasm ] + ;; + + let to_string s = + match s with + | JS -> "js" + | Wasm -> "wasm" + ;; + + let to_dyn t = Dyn.variant (to_string t) [] + let encode t = Dune_sexp.atom (to_string t) + + module Pair = struct + type 'a t = + { js : 'a + ; wasm : 'a + } + + let select ~mode { js; wasm } = + match mode with + | JS -> js + | Wasm -> wasm + ;; + + let make v = { js = v; wasm = v } + let init ~f = { js = f JS; wasm = f Wasm } + let map ~f { js; wasm } = { js = f js; wasm = f wasm } + let mapi ~f { js; wasm } = { js = f JS js; wasm = f Wasm wasm } + + let map2 ~f { js; wasm } { js = js'; wasm = wasm' } = + { js = f js js'; wasm = f wasm wasm' } + ;; + end + + module Set = struct + type t = bool Pair.t + + let inter = Pair.map2 ~f:( && ) + let union = Pair.map2 ~f:( || ) + let is_empty (x : t) = not (x.js || x.wasm) + + let to_list (x : t) = + let l = if x.wasm then [ Wasm ] else [] in + if x.js then JS :: l else l + ;; + end +end + module Flags = struct type 'flags t = { build_runtime : 'flags @@ -81,55 +153,25 @@ module Flags = struct { build_runtime; compile; link } ;; - let dump t = + let dump ~mode t = let open Action_builder.O in let+ build_runtime = t.build_runtime and+ compile = t.compile and+ link = t.link in + let prefix = + match mode with + | Mode.JS -> "js" + | Wasm -> "wasm" + in List.map ~f:Dune_lang.Encoder.(pair string (list string)) - [ "js_of_ocaml_flags", compile - ; "js_of_ocaml_build_runtime_flags", build_runtime - ; "js_of_ocaml_link_flags", link + [ prefix ^ "_of_ocaml_flags", compile + ; prefix ^ "_of_ocaml_build_runtime_flags", build_runtime + ; prefix ^ "_of_ocaml_link_flags", link ] ;; end -module Submode = struct - type t = - | JS - | Wasm - - let equal = Poly.equal - - module Set = struct - type t = - { js : bool - ; wasm : bool - } - - let empty = { js = false; wasm = false } - - let add t = function - | JS -> { t with js = true } - | Wasm -> { t with wasm = true } - ;; - - let decode = - enum [ "js", JS; "wasm", Wasm ] - |> repeat1 - |> map ~f:(List.fold_left ~init:empty ~f:add) - ;; - - let equal x y = x.js = y.js && x.wasm = y.wasm - - let to_list x = - let l = if x.wasm then [ Wasm ] else [] in - if x.js then JS :: l else l - ;; - end -end - module Compilation_mode = struct type t = | Whole_program @@ -149,14 +191,14 @@ end module In_buildable = struct type t = { flags : Ordered_set_lang.Unexpanded.t Flags.t - ; submodes : Submode.Set.t option + ; enabled_if : Blang.t option ; javascript_files : string list ; wasm_files : string list ; compilation_mode : Compilation_mode.t option ; sourcemap : Sourcemap.t option } - let decode ~executable = + let decode ~executable ~mode = let* syntax_version = Dune_lang.Syntax.get_exn Stanza.syntax in if syntax_version < (3, 0) then @@ -168,7 +210,7 @@ module In_buildable = struct ; compile = flags ; link = flags (* we set link as well to preserve the old semantic *) } - ; submodes = None + ; enabled_if = Some Blang.true_ ; javascript_files ; wasm_files = [] ; compilation_mode = None @@ -177,16 +219,19 @@ module In_buildable = struct else fields (let+ flags = Flags.decode - and+ submodes = + and+ enabled_if = field_o - "submodes" - (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> Submode.Set.decode) + "enabled_if" + (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> Blang.decode) and+ javascript_files = field "javascript_files" (repeat string) ~default:[] and+ wasm_files = - field - "wasm_files" - (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> repeat string) - ~default:[] + match mode with + | Mode.JS -> return [] + | Wasm -> + field + "wasm_files" + (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> repeat string) + ~default:[] and+ compilation_mode = if executable then @@ -202,12 +247,12 @@ module In_buildable = struct (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> Sourcemap.decode) else return None in - { flags; submodes; javascript_files; wasm_files; compilation_mode; sourcemap }) + { flags; enabled_if; javascript_files; wasm_files; compilation_mode; sourcemap }) ;; let default = { flags = Flags.standard - ; submodes = None + ; enabled_if = None ; javascript_files = [] ; wasm_files = [] ; compilation_mode = None @@ -219,16 +264,16 @@ end module In_context = struct type t = { flags : Ordered_set_lang.Unexpanded.t Flags.t - ; submodes : Submode.Set.t option + ; enabled_if : Blang.t option ; javascript_files : Path.Build.t list ; wasm_files : Path.Build.t list ; compilation_mode : Compilation_mode.t option ; sourcemap : Sourcemap.t option } - let make ~(dir : Path.Build.t) (x : In_buildable.t) = + let make_one ~(dir : Path.Build.t) (x : In_buildable.t) = { flags = x.flags - ; submodes = x.submodes + ; enabled_if = x.enabled_if ; javascript_files = List.map ~f:(fun name -> Path.Build.relative dir name) x.javascript_files ; wasm_files = List.map ~f:(fun name -> Path.Build.relative dir name) x.wasm_files @@ -237,9 +282,11 @@ module In_context = struct } ;; + let make ~dir x = Mode.Pair.map ~f:(fun x -> make_one ~dir x) x + let default = { flags = Flags.standard - ; submodes = None + ; enabled_if = None ; javascript_files = [] ; wasm_files = [] ; compilation_mode = None @@ -251,16 +298,10 @@ end module Ext = struct type t = string - let select ~submode js wasm = - match submode with - | Submode.JS -> js - | Wasm -> wasm - ;; - - let exe ~submode = select ~submode ".bc.js" ".bc.wasm.js" - let cmo ~submode = select ~submode ".cmo.js" ".wasmo" - let cma ~submode = select ~submode ".cma.js" ".wasma" - let runtime ~submode = select ~submode ".bc.runtime.js" ".bc.runtime.wasma" + let exe ~mode = Mode.select ~mode ".bc.js" ".bc.wasm.js" + let cmo ~mode = Mode.select ~mode ".cmo.js" ".wasmo" + let cma ~mode = Mode.select ~mode ".cma.js" ".wasma" + let runtime ~mode = Mode.select ~mode ".bc.runtime.js" ".bc.runtime.wasma" let wasm_dir = ".bc.wasm.assets" end @@ -270,7 +311,7 @@ module Env = struct ; sourcemap : Sourcemap.t option ; runtest_alias : Alias.Name.t option ; flags : 'a Flags.t - ; submodes : Submode.Set.t option + ; enabled_if : Blang.t option } let decode = @@ -282,25 +323,25 @@ module Env = struct (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> Sourcemap.decode) and+ runtest_alias = field_o "runtest_alias" Dune_lang.Alias.decode and+ flags = Flags.decode - and+ submodes = + and+ enabled_if = field_o - "submodes" - (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> Submode.Set.decode) + "enabled_if" + (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> Blang.decode) in Option.iter ~f:Alias0.register_as_standard runtest_alias; - { compilation_mode; sourcemap; runtest_alias; flags; submodes } + { compilation_mode; sourcemap; runtest_alias; flags; enabled_if } ;; - let equal { compilation_mode; sourcemap; submodes; runtest_alias; flags } t = + let equal { compilation_mode; sourcemap; enabled_if; runtest_alias; flags } t = Option.equal Compilation_mode.equal compilation_mode t.compilation_mode && Option.equal Sourcemap.equal sourcemap t.sourcemap && Option.equal Alias.Name.equal runtest_alias t.runtest_alias && Flags.equal Ordered_set_lang.Unexpanded.equal flags t.flags - && Option.equal Submode.Set.equal submodes t.submodes + && Option.equal Blang.equal enabled_if t.enabled_if ;; - let map ~f { compilation_mode; sourcemap; runtest_alias; flags; submodes } = - { compilation_mode; sourcemap; runtest_alias; flags = Flags.map ~f flags; submodes } + let map ~f { compilation_mode; sourcemap; runtest_alias; flags; enabled_if } = + { compilation_mode; sourcemap; runtest_alias; flags = Flags.map ~f flags; enabled_if } ;; let empty = @@ -308,7 +349,7 @@ module Env = struct ; sourcemap = None ; runtest_alias = None ; flags = Flags.standard - ; submodes = None + ; enabled_if = None } ;; @@ -317,7 +358,7 @@ module Env = struct ; sourcemap = None ; runtest_alias = None ; flags = Flags.default ~profile - ; submodes = None + ; enabled_if = Some Blang.true_ } ;; end diff --git a/src/dune_rules/jsoo/js_of_ocaml.mli b/src/dune_rules/jsoo/js_of_ocaml.mli index 2294e9e8051..429155fef4e 100644 --- a/src/dune_rules/jsoo/js_of_ocaml.mli +++ b/src/dune_rules/jsoo/js_of_ocaml.mli @@ -1,5 +1,42 @@ open Import +module Mode : sig + type t = + | JS + | Wasm + + type mode := t + + val select : mode:t -> 'a -> 'a -> 'a + val equal : t -> t -> bool + val compare : t -> t -> Ordering.t + val decode : t Dune_lang.Decoder.t + val encode : t Dune_lang.Encoder.t + val to_dyn : t -> Dyn.t + + module Pair : sig + type 'a t = + { js : 'a + ; wasm : 'a + } + + val select : mode:mode -> 'a t -> 'a + val make : 'a -> 'a t + val init : f:(mode -> 'a) -> 'a t + val map : f:('a -> 'b) -> 'a t -> 'b t + val mapi : f:(mode -> 'a -> 'b) -> 'a t -> 'b t + end + + module Set : sig + type t = bool Pair.t + + val inter : t -> t -> t + val union : t -> t -> t + val to_list : t -> mode list + val is_empty : t -> bool + end +end + module Flags : sig type 'flags t = { build_runtime : 'flags @@ -26,7 +63,10 @@ module Flags : sig -> string list Action_builder.t) -> string list Action_builder.t t - val dump : string list Action_builder.t t -> Dune_lang.t list Action_builder.t + val dump + : mode:Mode.t + -> string list Action_builder.t t + -> Dune_lang.t list Action_builder.t end module Sourcemap : sig @@ -36,25 +76,6 @@ module Sourcemap : sig | File end -module Submode : sig - type t = - | JS - | Wasm - - type submode := t - - val equal : t -> t -> bool - - module Set : sig - type t = - { js : bool - ; wasm : bool - } - - val to_list : t -> submode list - end -end - module Compilation_mode : sig type t = | Whole_program @@ -64,38 +85,38 @@ end module In_buildable : sig type t = { flags : Flags.Spec.t - ; submodes : Submode.Set.t option + ; enabled_if : Blang.t option ; javascript_files : string list ; wasm_files : string list ; compilation_mode : Compilation_mode.t option ; sourcemap : Sourcemap.t option } - val decode : executable:bool -> t Dune_lang.Decoder.t + val decode : executable:bool -> mode:Mode.t -> t Dune_lang.Decoder.t val default : t end module In_context : sig type t = { flags : Flags.Spec.t - ; submodes : Submode.Set.t option + ; enabled_if : Blang.t option ; javascript_files : Path.Build.t list ; wasm_files : Path.Build.t list ; compilation_mode : Compilation_mode.t option ; sourcemap : Sourcemap.t option } - val make : dir:Path.Build.t -> In_buildable.t -> t + val make : dir:Path.Build.t -> In_buildable.t Mode.Pair.t -> t Mode.Pair.t val default : t end module Ext : sig type t = string - val exe : submode:Submode.t -> t - val cmo : submode:Submode.t -> t - val cma : submode:Submode.t -> t - val runtime : submode:Submode.t -> t + val exe : mode:Mode.t -> t + val cmo : mode:Mode.t -> t + val cma : mode:Mode.t -> t + val runtime : mode:Mode.t -> t val wasm_dir : t end @@ -105,7 +126,7 @@ module Env : sig ; sourcemap : Sourcemap.t option ; runtest_alias : Alias.Name.t option ; flags : 'a Flags.t - ; submodes : Submode.Set.t option + ; enabled_if : Blang.t option } val map : f:('a -> 'b) -> 'a t -> 'b t diff --git a/src/dune_rules/jsoo/jsoo_rules.ml b/src/dune_rules/jsoo/jsoo_rules.ml index 0b5e2b7ba4f..aed29b64429 100644 --- a/src/dune_rules/jsoo/jsoo_rules.ml +++ b/src/dune_rules/jsoo/jsoo_rules.ml @@ -1,7 +1,7 @@ open Import open Memo.O -let jsoo_env = +let compute_env ~mode = let f = Env_stanza_db_flags.flags ~name:"jsoo-env" @@ -9,12 +9,21 @@ let jsoo_env = let+ profile = Per_context.profile ctx in Js_of_ocaml.Env.(map ~f:Action_builder.return (default ~profile))) ~f:(fun ~parent expander (local : Dune_env.config) -> - let local = local.js_of_ocaml in - let+ parent = parent in + let local = Js_of_ocaml.Mode.select ~mode local.js_of_ocaml local.wasm_of_ocaml in + let* parent = parent in + let+ enabled_if = + match local.enabled_if with + | None -> + Memo.return + (match parent.enabled_if with + | Some (Const default) -> default + | _ -> assert false) + | Some enabled_if -> Expander.eval_blang expander enabled_if + in { Js_of_ocaml.Env.compilation_mode = Option.first_some local.compilation_mode parent.compilation_mode ; sourcemap = Option.first_some local.sourcemap parent.sourcemap - ; submodes = Option.first_some local.submodes parent.submodes + ; enabled_if = Some (Const enabled_if) ; runtest_alias = Option.first_some local.runtest_alias parent.runtest_alias ; flags = Js_of_ocaml.Flags.make @@ -28,6 +37,10 @@ let jsoo_env = (Staged.unstage f) dir ;; +let js_env = compute_env ~mode:JS +let wasm_env = compute_env ~mode:Wasm +let jsoo_env ~dir ~mode = (Js_of_ocaml.Mode.select ~mode js_env wasm_env) ~dir + module Config : sig type t @@ -205,11 +218,11 @@ type sub_command = | Link | Build_runtime -let js_of_ocaml_flags t ~dir (spec : Js_of_ocaml.Flags.Spec.t) = +let js_of_ocaml_flags t ~dir ~mode (spec : Js_of_ocaml.Flags.Spec.t) = Action_builder.of_memo @@ let+ expander = Super_context.expander t ~dir - and+ js_of_ocaml = jsoo_env ~dir in + and+ js_of_ocaml = jsoo_env ~dir ~mode in Js_of_ocaml.Flags.make ~spec ~default:js_of_ocaml.flags @@ -218,7 +231,7 @@ let js_of_ocaml_flags t ~dir (spec : Js_of_ocaml.Flags.Spec.t) = let js_of_ocaml_rule sctx - ~(submode : Js_of_ocaml.Submode.t) + ~(mode : Js_of_ocaml.Mode.t) ~sub_command ~dir ~(flags : _ Js_of_ocaml.Flags.t) @@ -230,12 +243,12 @@ let js_of_ocaml_rule = let open Action_builder.O in let jsoo = - match submode with + match mode with | JS -> jsoo ~dir sctx | Wasm -> wasmoo ~dir sctx in let flags = - let* flags = js_of_ocaml_flags sctx ~dir flags in + let* flags = js_of_ocaml_flags sctx ~dir ~mode flags in match sub_command with | Compile -> flags.compile | Link -> flags.link @@ -248,7 +261,7 @@ let js_of_ocaml_rule | Compile -> S [] | Link -> A "link" | Build_runtime -> A "build-runtime") - ; (match (sourcemap : Js_of_ocaml.Sourcemap.t), submode with + ; (match (sourcemap : Js_of_ocaml.Sourcemap.t), mode with | No, _ -> A "--no-source-map" | Inline, _ | File, Wasm -> (* With wasm_of_ocaml, source maps are always inline *) @@ -273,19 +286,19 @@ let js_of_ocaml_rule |> Action_builder.With_targets.add_directories ~directory_targets ;; -let jsoo_runtime_files ~(submode : Js_of_ocaml.Submode.t) libs = +let jsoo_runtime_files ~(mode : Js_of_ocaml.Mode.t) libs = List.concat_map libs ~f:(fun t -> - (match submode with + (match mode with | JS -> Lib_info.jsoo_runtime | Wasm -> Lib_info.wasmoo_runtime) (Lib.info t)) ;; -let standalone_runtime_rule ~submode cc ~runtime_files ~target ~flags = +let standalone_runtime_rule ~mode cc ~runtime_files ~target ~flags = let dir = Compilation_context.dir cc in let sctx = Compilation_context.super_context cc in let config = - js_of_ocaml_flags sctx ~dir flags + js_of_ocaml_flags sctx ~dir ~mode flags |> Action_builder.bind ~f:(fun (x : _ Js_of_ocaml.Flags.t) -> x.compile) |> Action_builder.map ~f:Config.of_flags in @@ -295,14 +308,14 @@ let standalone_runtime_rule ~submode cc ~runtime_files ~target ~flags = [ Resolve.Memo.args (let open Resolve.Memo.O in let+ libs = libs in - Command.Args.Deps (jsoo_runtime_files ~submode libs)) + Command.Args.Deps (jsoo_runtime_files ~mode libs)) ; Deps (List.map ~f:Path.build runtime_files) ] in let dir = Compilation_context.dir cc in js_of_ocaml_rule (Compilation_context.super_context cc) - ~submode + ~mode ~sub_command:Build_runtime ~dir ~flags @@ -312,7 +325,7 @@ let standalone_runtime_rule ~submode cc ~runtime_files ~target ~flags = ~config:(Some config) ;; -let exe_rule ~submode cc ~linkall ~runtime_files ~src ~target ~directory_targets ~flags = +let exe_rule ~mode cc ~linkall ~runtime_files ~src ~target ~directory_targets ~flags = let dir = Compilation_context.dir cc in let sctx = Compilation_context.super_context cc in let libs = Compilation_context.requires_link cc in @@ -336,7 +349,7 @@ let exe_rule ~submode cc ~linkall ~runtime_files ~src ~target ~directory_targets [ Resolve.Memo.args (let open Resolve.Memo.O in let+ libs = libs in - Command.Args.Deps (jsoo_runtime_files ~submode libs)) + Command.Args.Deps (jsoo_runtime_files ~mode libs)) ; Deps (List.map ~f:Path.build runtime_files) ; Dep (Path.build src) ; Dyn linkall @@ -344,7 +357,7 @@ let exe_rule ~submode cc ~linkall ~runtime_files ~src ~target ~directory_targets in js_of_ocaml_rule sctx - ~submode + ~mode ~sub_command:Compile ~dir ~spec @@ -354,14 +367,14 @@ let exe_rule ~submode cc ~linkall ~runtime_files ~src ~target ~directory_targets ~config:None ;; -let with_js_ext ~submode s = +let with_js_ext ~mode s = match Filename.split_extension s with - | name, ".cma" -> name ^ Js_of_ocaml.Ext.cma ~submode - | name, ".cmo" -> name ^ Js_of_ocaml.Ext.cmo ~submode + | name, ".cma" -> name ^ Js_of_ocaml.Ext.cma ~mode + | name, ".cmo" -> name ^ Js_of_ocaml.Ext.cmo ~mode | _ -> assert false ;; -let jsoo_archives ~submode ctx config lib = +let jsoo_archives ~mode ctx config lib = let info = Lib.info lib in let archives = Lib_info.archives info in match Lib.is_local lib with @@ -371,7 +384,7 @@ let jsoo_archives ~submode ctx config lib = in_obj_dir' ~obj_dir ~config:(Some config) - [ with_js_ext ~submode (Path.basename archive) ]) + [ with_js_ext ~mode (Path.basename archive) ]) | false -> List.map archives.byte ~f:(fun archive -> Path.build @@ -379,12 +392,12 @@ let jsoo_archives ~submode ctx config lib = ctx ~config [ Lib_name.to_string (Lib.name lib) - ; with_js_ext ~submode (Path.basename archive) + ; with_js_ext ~mode (Path.basename archive) ])) ;; let link_rule - ~submode + ~mode cc ~runtime ~target @@ -400,13 +413,13 @@ let link_rule let mod_name m = Module_name.Unique.artifact_filename (Module.obj_name m) - ~ext:(Js_of_ocaml.Ext.cmo ~submode) + ~ext:(Js_of_ocaml.Ext.cmo ~mode) in let ctx = Super_context.context sctx |> Context.build_context in let get_all = let open Action_builder.O in let+ config = - js_of_ocaml_flags sctx ~dir flags + js_of_ocaml_flags sctx ~dir ~mode flags |> Action_builder.bind ~f:(fun (x : _ Js_of_ocaml.Flags.t) -> x.compile) |> Action_builder.map ~f:Config.of_flags and+ cm = cm @@ -422,21 +435,21 @@ let link_rule META *) let stdlib = Path.build - (in_build_dir ctx ~config [ "stdlib"; "stdlib" ^ Js_of_ocaml.Ext.cma ~submode ]) + (in_build_dir ctx ~config [ "stdlib"; "stdlib" ^ Js_of_ocaml.Ext.cma ~mode ]) in let special_units = List.concat_map to_link ~f:(function | Lib_flags.Lib_and_module.Lib _lib -> [] | Module (obj_dir, m) -> [ in_obj_dir' ~obj_dir ~config:None [ mod_name m ] ]) in - let all_libs = List.concat_map libs ~f:(jsoo_archives ~submode ctx config) in + let all_libs = List.concat_map libs ~f:(jsoo_archives ~mode ctx config) in let all_other_modules = List.map cm ~f:(fun m -> Path.build (in_obj_dir ~obj_dir ~config:None [ mod_name m ])) in let std_exit = Path.build - (in_build_dir ctx ~config [ "stdlib"; "std_exit" ^ Js_of_ocaml.Ext.cmo ~submode ]) + (in_build_dir ctx ~config [ "stdlib"; "std_exit" ^ Js_of_ocaml.Ext.cmo ~mode ]) in let linkall = force_linkall || linkall in Command.Args.S @@ -455,7 +468,7 @@ let link_rule let spec = Command.Args.S [ Dep (Path.build runtime); Dyn get_all ] in js_of_ocaml_rule sctx - ~submode + ~mode ~sub_command:Link ~dir ~spec @@ -465,12 +478,12 @@ let link_rule ~config:None ;; -let build_cm' sctx ~dir ~in_context ~submode ~src ~target ~config ~sourcemap = +let build_cm' sctx ~dir ~in_context ~mode ~src ~target ~config ~sourcemap = let spec = Command.Args.Dep src in let flags = in_context.Js_of_ocaml.In_context.flags in js_of_ocaml_rule sctx - ~submode + ~mode ~sub_command:Compile ~dir ~flags @@ -481,16 +494,16 @@ let build_cm' sctx ~dir ~in_context ~submode ~src ~target ~config ~sourcemap = ~sourcemap ;; -let iter_submodes ~f = Memo.parallel_iter [ Js_of_ocaml.Submode.JS; Wasm ] ~f +let iter_jsoo_modes ~f = Memo.parallel_iter [ Js_of_ocaml.Mode.JS; Wasm ] ~f -let build_cm sctx ~dir ~in_context ~submode ~src ~obj_dir ~config = - let name = with_js_ext ~submode (Path.basename src) in +let build_cm sctx ~dir ~in_context ~mode ~src ~obj_dir ~config = + let name = with_js_ext ~mode (Path.basename src) in let target = in_obj_dir ~obj_dir ~config [ name ] in build_cm' sctx ~dir ~in_context - ~submode + ~mode ~src ~target ~config:(Option.map config ~f:Action_builder.return) @@ -524,14 +537,14 @@ let setup_separate_compilation_rules sctx components = archive "stdlib.cma" :: archive "std_exit.cmo" :: archives | _ -> archives in - iter_submodes ~f:(fun submode -> + iter_jsoo_modes ~f:(fun mode -> Memo.parallel_iter archives ~f:(fun fn -> let build_context = Context.build_context ctx in let name = Path.basename fn in let dir = in_build_dir build_context ~config [ lib_name ] in let in_context = { Js_of_ocaml.In_context.flags = Js_of_ocaml.Flags.standard - ; submodes = None + ; enabled_if = Some Blang.true_ ; javascript_files = [] ; wasm_files = [] ; compilation_mode = None @@ -543,13 +556,13 @@ let setup_separate_compilation_rules sctx components = Path.relative src_dir name in let target = - in_build_dir build_context ~config [ lib_name; with_js_ext ~submode name ] + in_build_dir build_context ~config [ lib_name; with_js_ext ~mode name ] in build_cm' sctx ~dir ~in_context - ~submode + ~mode ~src ~target ~config:(Some (Action_builder.return config)) @@ -557,8 +570,8 @@ let setup_separate_compilation_rules sctx components = |> Super_context.add_rule sctx ~dir))) ;; -let js_of_ocaml_compilation_mode t ~dir = - let+ js_of_ocaml = jsoo_env ~dir in +let js_of_ocaml_compilation_mode t ~dir ~mode = + let+ js_of_ocaml = jsoo_env ~dir ~mode in match js_of_ocaml.compilation_mode with | Some m -> m | None -> @@ -567,8 +580,8 @@ let js_of_ocaml_compilation_mode t ~dir = else Whole_program ;; -let js_of_ocaml_sourcemap t ~dir = - let+ js_of_ocaml = jsoo_env ~dir in +let js_of_ocaml_sourcemap t ~dir ~mode = + let+ js_of_ocaml = jsoo_env ~dir ~mode in match js_of_ocaml.sourcemap with | Some sm -> sm | None -> @@ -577,15 +590,37 @@ let js_of_ocaml_sourcemap t ~dir = else No ;; -let jsoo_submodes ~dir ~submodes = - (match submodes with - | Some _ -> Memo.return submodes - | None -> - let+ js_of_ocaml = jsoo_env ~dir in - js_of_ocaml.submodes) - >>| function - | None -> [ Js_of_ocaml.Submode.JS ] - | Some m -> Js_of_ocaml.Submode.Set.to_list m +let jsoo_enabled + ~eval + ~dir + ~(in_context : Js_of_ocaml.In_context.t Js_of_ocaml.Mode.Pair.t) + ~mode + = + match (Js_of_ocaml.Mode.Pair.select ~mode in_context).enabled_if with + | Some enabled_if -> eval enabled_if + | None -> + let* js_of_ocaml = jsoo_env ~dir ~mode in + (match js_of_ocaml.enabled_if with + | Some (Const default) -> Memo.return default + | _ -> assert false) +;; + +let jsoo_enabled_modes ~expander ~dir ~in_context = + let eval = Expander.eval_blang expander in + let+ js = jsoo_enabled ~eval ~dir ~in_context ~mode:JS + and+ wasm = jsoo_enabled ~eval ~dir ~in_context ~mode:Wasm in + { Js_of_ocaml.Mode.Pair.js; wasm } +;; + +let jsoo_is_whole_program t ~dir = + let is_whole_program (mode : Js_of_ocaml.Compilation_mode.t) = + match mode with + | Whole_program -> true + | Separate_compilation -> false + in + let+ js = js_of_ocaml_compilation_mode t ~dir ~mode:JS + and+ wasm = js_of_ocaml_compilation_mode t ~dir ~mode:Wasm in + { Js_of_ocaml.Mode.Pair.js = is_whole_program js; wasm = is_whole_program wasm } ;; let build_exe @@ -598,111 +633,94 @@ let build_exe ~promote ~linkall ~link_time_code_gen + ~jsoo_mode:mode = let sctx = Compilation_context.super_context cc in let dir = Compilation_context.dir cc in let { Js_of_ocaml.In_context.javascript_files ; wasm_files ; flags - ; submodes ; compilation_mode ; sourcemap + ; _ } = in_context in - let mode : Rule.Mode.t = + let target = Path.Build.set_extension src ~ext:(Js_of_ocaml.Ext.exe ~mode) in + let standalone_runtime = + in_obj_dir + ~obj_dir + ~config:None + [ Path.Build.basename + (Path.Build.set_extension src ~ext:(Js_of_ocaml.Ext.runtime ~mode)) + ] + in + let rule_mode : Rule.Mode.t = match promote with | None -> Standard | Some p -> Promote p in let* cmode = match compilation_mode with - | None -> js_of_ocaml_compilation_mode sctx ~dir + | None -> js_of_ocaml_compilation_mode sctx ~dir ~mode | Some x -> Memo.return x and* sourcemap = match sourcemap with - | None -> js_of_ocaml_sourcemap sctx ~dir + | None -> js_of_ocaml_sourcemap sctx ~dir ~mode | Some x -> Memo.return x - and* submodes = jsoo_submodes ~dir ~submodes in - let* () = - if List.mem ~equal:Poly.equal submodes JS - then Memo.return () - else ( - let dst = Path.Build.set_extension src ~ext:(Js_of_ocaml.Ext.exe ~submode:JS) in - let src = - Path.build (Path.Build.set_extension src ~ext:(Js_of_ocaml.Ext.exe ~submode:Wasm)) - in - Super_context.add_rule ~loc ~dir ~mode sctx (Action_builder.copy ~src ~dst)) in - Memo.parallel_iter submodes ~f:(fun submode -> - let standalone_runtime = - in_obj_dir - ~obj_dir - ~config:None - [ Path.Build.basename - (Path.Build.set_extension src ~ext:(Js_of_ocaml.Ext.runtime ~submode)) - ] - in - let target = - let ext = Js_of_ocaml.Ext.exe ~submode in - Path.Build.set_extension src ~ext - in - let runtime_files = - match submode with - | JS -> javascript_files - | Wasm -> wasm_files - in - let directory_targets = - match submode with - | JS -> [] - | Wasm -> [ Path.Build.set_extension src ~ext:Js_of_ocaml.Ext.wasm_dir ] - in - match (cmode : Js_of_ocaml.Compilation_mode.t) with - | Separate_compilation -> - let+ () = - standalone_runtime_rule - ~submode - cc - ~runtime_files - ~target:standalone_runtime - ~flags - ~sourcemap:Js_of_ocaml.Sourcemap.Inline - |> Super_context.add_rule ~loc sctx ~dir - and+ () = - link_rule - ~submode - cc - ~runtime:standalone_runtime - ~target - ~directory_targets - ~obj_dir - top_sorted_modules - ~flags - ~linkall - ~link_time_code_gen - ~sourcemap - |> Super_context.add_rule sctx ~loc ~dir ~mode - in - () - | Whole_program -> - exe_rule - ~submode + let runtime_files = javascript_files @ wasm_files in + let directory_targets = + match mode with + | JS -> [] + | Wasm -> [ Path.Build.set_extension src ~ext:Js_of_ocaml.Ext.wasm_dir ] + in + match (cmode : Js_of_ocaml.Compilation_mode.t) with + | Separate_compilation -> + let+ () = + standalone_runtime_rule + ~mode cc - ~linkall ~runtime_files - ~src + ~target:standalone_runtime + ~flags + ~sourcemap:Js_of_ocaml.Sourcemap.Inline + |> Super_context.add_rule ~loc sctx ~dir + and+ () = + link_rule + ~mode + cc + ~runtime:standalone_runtime ~target ~directory_targets + ~obj_dir + top_sorted_modules ~flags + ~linkall + ~link_time_code_gen ~sourcemap - |> Super_context.add_rule sctx ~loc ~dir ~mode) + |> Super_context.add_rule sctx ~loc ~dir ~mode:rule_mode + in + () + | Whole_program -> + exe_rule + ~mode + cc + ~linkall + ~runtime_files + ~src + ~target + ~directory_targets + ~flags + ~sourcemap + |> Super_context.add_rule sctx ~loc ~dir ~mode:rule_mode ;; let runner = "node" -let js_of_ocaml_runtest_alias ~dir = - let+ js_of_ocaml = jsoo_env ~dir in +let js_of_ocaml_runtest_alias ~dir ~mode = + let+ js_of_ocaml = jsoo_env ~dir ~mode in match js_of_ocaml.runtest_alias with | Some a -> a | None -> Alias0.runtest diff --git a/src/dune_rules/jsoo/jsoo_rules.mli b/src/dune_rules/jsoo/jsoo_rules.mli index f0a3b2190dc..ec9a0365525 100644 --- a/src/dune_rules/jsoo/jsoo_rules.mli +++ b/src/dune_rules/jsoo/jsoo_rules.mli @@ -19,7 +19,7 @@ val build_cm : Super_context.t -> dir:Path.Build.t -> in_context:Js_of_ocaml.In_context.t - -> submode:Js_of_ocaml.Submode.t + -> mode:Js_of_ocaml.Mode.t -> src:Path.t -> obj_dir:Path.Build.t Obj_dir.t -> config:Config.t option @@ -35,21 +35,44 @@ val build_exe -> promote:Rule.Promote.t option -> linkall:bool Action_builder.t -> link_time_code_gen:Link_time_code_gen_type.t Resolve.t + -> jsoo_mode:Js_of_ocaml.Mode.t -> unit Memo.t val setup_separate_compilation_rules : Super_context.t -> string list -> unit Memo.t val runner : string -val js_of_ocaml_runtest_alias : dir:Path.Build.t -> Alias.Name.t Memo.t -val jsoo_env : dir:Path.Build.t -> string list Action_builder.t Js_of_ocaml.Env.t Memo.t -val jsoo_submodes - : dir:Import.Path.Build.t - -> submodes:Js_of_ocaml.Submode.Set.t option - -> Js_of_ocaml.Submode.t list Memo.t +val js_of_ocaml_runtest_alias + : dir:Path.Build.t + -> mode:Js_of_ocaml.Mode.t + -> Alias.Name.t Memo.t -val iter_submodes : f:(Js_of_ocaml.Submode.t -> unit Memo.t) -> unit Memo.t +val jsoo_env + : dir:Path.Build.t + -> mode:Js_of_ocaml.Mode.t + -> string list Action_builder.t Js_of_ocaml.Env.t Memo.t + +val jsoo_enabled + : eval:(Blang.t -> bool Memo.t) + -> dir:Path.Build.t + -> in_context:Js_of_ocaml.In_context.t Js_of_ocaml.Mode.Pair.t + -> mode:Js_of_ocaml.Mode.t + -> bool Memo.t + +val jsoo_enabled_modes + : expander:Expander.t + -> dir:Path.Build.t + -> in_context:Js_of_ocaml.In_context.t Js_of_ocaml.Mode.Pair.t + -> Js_of_ocaml.Mode.Set.t Memo.t + +val jsoo_is_whole_program + : Super_context.t + -> dir:Path.Build.t + -> Js_of_ocaml.Mode.Set.t Memo.t + +val iter_jsoo_modes : f:(Js_of_ocaml.Mode.t -> unit Memo.t) -> unit Memo.t val js_of_ocaml_compilation_mode : Super_context.t -> dir:Path.Build.t + -> mode:Js_of_ocaml.Mode.t -> Js_of_ocaml.Compilation_mode.t Memo.t diff --git a/src/dune_rules/lib_rules.ml b/src/dune_rules/lib_rules.ml index 1e0d90cbeca..140e40359e7 100644 --- a/src/dune_rules/lib_rules.ml +++ b/src/dune_rules/lib_rules.ml @@ -474,14 +474,14 @@ let setup_build_archives (lib : Library.t) ~top_sorted_modules ~cctx ~expander ~ (* Build *.cma.js / *.wasma *) Memo.when_ modes.ocaml.byte (fun () -> let src = Library.archive lib ~dir ~ext:(Mode.compiled_lib_ext Mode.Byte) in - Jsoo_rules.iter_submodes ~f:(fun submode -> + Jsoo_rules.iter_jsoo_modes ~f:(fun mode -> let action_with_targets = List.map Jsoo_rules.Config.all ~f:(fun config -> Jsoo_rules.build_cm sctx ~dir - ~in_context:js_of_ocaml - ~submode + ~in_context:(Js_of_ocaml.Mode.Pair.select ~mode js_of_ocaml) + ~mode ~config:(Some config) ~src:(Path.build src) ~obj_dir) @@ -542,7 +542,7 @@ let cctx (lib : Library.t) ~sctx ~source_modules ~dir ~expander ~scope ~compile_ ~requires_link ~preprocessing:pp ~opaque:Inherit_from_settings - ~js_of_ocaml:(Some js_of_ocaml) + ~js_of_ocaml:(Js_of_ocaml.Mode.Pair.map ~f:(fun x -> Some x) js_of_ocaml) ?stdlib:lib.stdlib ~package ?vimpl diff --git a/src/dune_rules/mdx.ml b/src/dune_rules/mdx.ml index 891a6df0bfa..03df5c205aa 100644 --- a/src/dune_rules/mdx.ml +++ b/src/dune_rules/mdx.ml @@ -476,7 +476,7 @@ let mdx_prog_gen t ~sctx ~dir ~scope ~mdx_prog = ~requires_compile ~requires_link ~opaque:(Explicit false) - ~js_of_ocaml:None + ~js_of_ocaml:(Js_of_ocaml.Mode.Pair.make None) ~melange_package_name:None ~package:None () diff --git a/src/dune_rules/melange/melange_rules.ml b/src/dune_rules/melange/melange_rules.ml index 146cd46aef8..6bf099324c1 100644 --- a/src/dune_rules/melange/melange_rules.ml +++ b/src/dune_rules/melange/melange_rules.ml @@ -316,7 +316,7 @@ let setup_emit_cmj_rules ~requires_link ~requires_compile:direct_requires ~preprocessing:pp - ~js_of_ocaml:None + ~js_of_ocaml:(Js_of_ocaml.Mode.Pair.make None) ~opaque:Inherit_from_settings ~melange_package_name:None ~package:mel.package diff --git a/src/dune_rules/module_compilation.ml b/src/dune_rules/module_compilation.ml index d6d4be15973..f9a1fa26e40 100644 --- a/src/dune_rules/module_compilation.ml +++ b/src/dune_rules/module_compilation.ml @@ -311,18 +311,19 @@ let build_module ?(force_write_cmi = false) ?(precompiled_cmi = false) cctx m = match Obj_dir.Module.cm_file obj_dir m ~kind:(Ocaml Cmo) with | None -> Memo.return () | Some src -> - Compilation_context.js_of_ocaml cctx - |> Memo.Option.iter ~f:(fun in_context -> - (* Build *.cmo.js / *.wasmo *) - let sctx = Compilation_context.super_context cctx in - let dir = Compilation_context.dir cctx in - Jsoo_rules.iter_submodes ~f:(fun submode -> + Jsoo_rules.iter_jsoo_modes ~f:(fun mode -> + Compilation_context.js_of_ocaml cctx + |> Js_of_ocaml.Mode.Pair.select ~mode + |> Memo.Option.iter ~f:(fun in_context -> + (* Build *.cmo.js / *.wasmo *) + let sctx = Compilation_context.super_context cctx in + let dir = Compilation_context.dir cctx in let action_with_targets = Jsoo_rules.build_cm sctx ~dir ~in_context - ~submode + ~mode ~src:(Path.build src) ~obj_dir ~config:None diff --git a/src/dune_rules/ppx_driver.ml b/src/dune_rules/ppx_driver.ml index ab2e78b5b49..cb42f95a9d1 100644 --- a/src/dune_rules/ppx_driver.ml +++ b/src/dune_rules/ppx_driver.ml @@ -323,7 +323,7 @@ let build_ppx_driver sctx ~scope ~target ~pps ~pp_names = ~requires_compile:(Memo.return requires_compile) ~requires_link ~opaque - ~js_of_ocaml:None + ~js_of_ocaml:(Js_of_ocaml.Mode.Pair.make None) ~melange_package_name:None ~package:None ~bin_annot:false diff --git a/src/dune_rules/stanzas/buildable.ml b/src/dune_rules/stanzas/buildable.ml index d4768cc49a4..a874578fed7 100644 --- a/src/dune_rules/stanzas/buildable.ml +++ b/src/dune_rules/stanzas/buildable.ml @@ -17,7 +17,7 @@ type t = ; preprocessor_deps : Dep_conf.t list ; lint : Preprocess.Without_instrumentation.t Preprocess.Per_module.t ; flags : Ocaml_flags.Spec.t - ; js_of_ocaml : Js_of_ocaml.In_buildable.t + ; js_of_ocaml : Js_of_ocaml.In_buildable.t Js_of_ocaml.Mode.Pair.t ; allow_overlapping_dependencies : bool ; ctypes : Ctypes_field.t option } @@ -99,7 +99,18 @@ let decode (for_ : for_) = in field "js_of_ocaml" - (Js_of_ocaml.In_buildable.decode ~executable) + (Js_of_ocaml.In_buildable.decode ~executable ~mode:JS) + ~default:Js_of_ocaml.In_buildable.default + and+ wasm_of_ocaml = + let executable = + match for_ with + | Executable -> true + | Library _ -> false + in + field + "wasm_of_ocaml" + (Dune_lang.Syntax.since Stanza.syntax (3, 17) + >>> Js_of_ocaml.In_buildable.decode ~executable ~mode:Wasm) ~default:Js_of_ocaml.In_buildable.default and+ allow_overlapping_dependencies = field_b "allow_overlapping_dependencies" and+ version = Dune_lang.Syntax.get_exn Stanza.syntax @@ -171,7 +182,7 @@ let decode (for_ : for_) = ; extra_objects ; libraries ; flags - ; js_of_ocaml + ; js_of_ocaml = { Js_of_ocaml.Mode.Pair.js = js_of_ocaml; wasm = wasm_of_ocaml } ; allow_overlapping_dependencies ; ctypes } diff --git a/src/dune_rules/stanzas/buildable.mli b/src/dune_rules/stanzas/buildable.mli index a4490318911..ec96635d088 100644 --- a/src/dune_rules/stanzas/buildable.mli +++ b/src/dune_rules/stanzas/buildable.mli @@ -16,7 +16,7 @@ type t = ; preprocessor_deps : Dep_conf.t list ; lint : Lint.t ; flags : Ocaml_flags.Spec.t - ; js_of_ocaml : Js_of_ocaml.In_buildable.t + ; js_of_ocaml : Js_of_ocaml.In_buildable.t Js_of_ocaml.Mode.Pair.t ; allow_overlapping_dependencies : bool ; ctypes : Ctypes_field.t option } diff --git a/src/dune_rules/stanzas/executables.ml b/src/dune_rules/stanzas/executables.ml index b8f728cf8db..7426073735f 100644 --- a/src/dune_rules/stanzas/executables.ml +++ b/src/dune_rules/stanzas/executables.ml @@ -206,6 +206,7 @@ module Link_mode = struct module T = struct type t = | Byte_complete + | Jsoo of Js_of_ocaml.Mode.t | Other of { mode : Mode_conf.t ; kind : Binary_kind.t @@ -220,6 +221,9 @@ module Link_mode = struct let open Ordering.O in let= () = Mode_conf.compare mode t.mode in Binary_kind.compare kind t.kind + | Other _, _ -> Lt + | _, Other _ -> Gt + | Jsoo m, Jsoo m' -> Js_of_ocaml.Mode.compare m m' ;; let to_dyn = Dyn.opaque @@ -233,8 +237,15 @@ module Link_mode = struct let shared_object = make Best Shared_object let byte = make Byte Exe let native = make Native Exe - let js = make Byte Js let plugin = make Best Plugin + let js = Jsoo JS + let wasm = Jsoo Wasm + + let is_jsoo m = + match m with + | Jsoo _ -> true + | Byte_complete | Other _ -> false + ;; let simple_representations = [ "exe", exe @@ -248,7 +259,12 @@ module Link_mode = struct ] ;; - let simple = Dune_lang.Decoder.enum simple_representations + let simple_representations_including_wasm = ("wasm", wasm) :: simple_representations + + let simple = + Dune_lang.Decoder.enum simple_representations + <|> sum [ "wasm", Syntax.since Stanza.syntax (3, 17) >>> return wasm ] + ;; let decode = enter @@ -256,11 +272,17 @@ module Link_mode = struct and+ kind = Binary_kind.decode in make mode kind) <|> simple + <|> enter + (keyword "byte" + >>> sum + [ "js", Syntax.since Stanza.syntax (1, 11) >>> return js + ; "wasm", Syntax.since Stanza.syntax (3, 17) >>> return wasm + ]) ;; let simple_encode link_mode = let is_ok (_, candidate) = compare candidate link_mode = Eq in - List.find ~f:is_ok simple_representations + List.find ~f:is_ok simple_representations_including_wasm |> Option.map ~f:(fun (s, _) -> Dune_lang.atom s) ;; @@ -269,7 +291,7 @@ module Link_mode = struct | Some s -> s | None -> (match link_mode with - | Byte_complete -> assert false + | Byte_complete | Jsoo _ -> assert false | Other { mode; kind } -> Dune_lang.Encoder.pair Mode_conf.encode Binary_kind.encode (mode, kind)) ;; @@ -282,6 +304,7 @@ module Link_mode = struct Variant ( "Other" , [ record [ "mode", Mode_conf.to_dyn mode; "kind", Binary_kind.to_dyn kind ] ] ) + | Jsoo mode -> Dyn.Variant ("Jsoo", [ Js_of_ocaml.Mode.to_dyn mode ]) ;; let extension t ~loc ~ext_obj ~ext_dll = @@ -306,10 +329,11 @@ module Link_mode = struct | Native, Object -> ".exe" ^ ext_obj | Byte, Shared_object -> ".bc" ^ ext_dll | Native, Shared_object -> ext_dll - | mode, Plugin -> Mode.plugin_ext mode - | Byte, Js -> Js_of_ocaml.Ext.exe ~submode:JS - | Native, Js -> - User_error.raise ~loc [ Pp.text "Javascript generation only supports bytecode!" ]) + | mode, Plugin -> Mode.plugin_ext mode) + | Jsoo kind -> + (match kind with + | JS -> Js_of_ocaml.Ext.exe ~mode:JS + | Wasm -> Js_of_ocaml.Ext.exe ~mode:Wasm) ;; module O = Comparable.Make (T) @@ -496,6 +520,8 @@ let common = | Byte_complete -> ".bc.exe" | Other { mode = Byte; _ } -> ".bc" | Other { mode = Native | Best; _ } -> ".exe" + | Jsoo JS -> Js_of_ocaml.Ext.exe ~mode:JS + | Jsoo Wasm -> Js_of_ocaml.Ext.exe ~mode:Wasm in Names.install_conf names ~ext ~enabled_if ~dir:project_root in diff --git a/src/dune_rules/stanzas/executables.mli b/src/dune_rules/stanzas/executables.mli index 245112db886..8c5375cf37e 100644 --- a/src/dune_rules/stanzas/executables.mli +++ b/src/dune_rules/stanzas/executables.mli @@ -3,6 +3,7 @@ open Import module Link_mode : sig type t = | Byte_complete + | Jsoo of Js_of_ocaml.Mode.t | Other of { mode : Mode_conf.t ; kind : Binary_kind.t @@ -16,6 +17,8 @@ module Link_mode : sig val byte : t val native : t val js : t + val wasm : t + val is_jsoo : t -> bool val compare : t -> t -> Ordering.t val to_dyn : t -> Dyn.t diff --git a/src/dune_rules/stanzas/library.ml b/src/dune_rules/stanzas/library.ml index 44c5b9f9200..c0a4f42c6d2 100644 --- a/src/dune_rules/stanzas/library.ml +++ b/src/dune_rules/stanzas/library.ml @@ -426,10 +426,13 @@ let to_lib_info Mode.Dict.of_func (fun ~mode -> archive_for_mode ~f_ext ~mode |> Option.to_list) in let jsoo_runtime = - List.map conf.buildable.js_of_ocaml.javascript_files ~f:(Path.Build.relative dir) + let in_buildable = conf.buildable.js_of_ocaml.js in + List.map in_buildable.javascript_files ~f:(Path.Build.relative dir) in let wasmoo_runtime = - List.map conf.buildable.js_of_ocaml.wasm_files ~f:(Path.Build.relative dir) + let in_buildable = conf.buildable.js_of_ocaml.wasm in + List.map in_buildable.javascript_files ~f:(Path.Build.relative dir) + @ List.map in_buildable.wasm_files ~f:(Path.Build.relative dir) in let status = match conf.visibility with diff --git a/src/dune_rules/test_rules.ml b/src/dune_rules/test_rules.ml index 66125a7a10f..909ccb2a9d7 100644 --- a/src/dune_rules/test_rules.ml +++ b/src/dune_rules/test_rules.ml @@ -3,7 +3,7 @@ open Memo.O let alias mode ~dir = match mode with - | `js -> Jsoo_rules.js_of_ocaml_runtest_alias ~dir + | `js mode -> Jsoo_rules.js_of_ocaml_runtest_alias ~dir ~mode | `exe | `bc -> Memo.return Alias0.runtest ;; @@ -21,52 +21,63 @@ let test_kind dir_contents (loc, name, ext) = else `Regular ;; +let ext_of_mode runtest_mode = + match runtest_mode with + | `js mode -> Js_of_ocaml.Ext.exe ~mode + | `bc -> ".bc" + | `exe -> ".exe" +;; + let custom_runner runtest_mode = match runtest_mode with - | `js -> Some Jsoo_rules.runner + | `js _ -> Some Jsoo_rules.runner | `bc | `exe -> None ;; -let runtest_modes modes submodes project = +let runtest_modes modes jsoo_enabled_modes project = if Dune_project.dune_version project < (3, 0) - then Memo.return [ `exe, ".exe" ] + then [ `exe ] else Executables.Link_mode.Map.to_list modes - |> Memo.sequential_map ~f:(fun ((mode : Executables.Link_mode.t), _) -> + |> List.filter_map ~f:(fun ((mode : Executables.Link_mode.t), _) -> match mode with - | Byte_complete | Other { kind = Exe; mode = Native | Best } -> - Memo.return [ `exe, ".exe" ] - | Other { kind = Exe; mode = Byte } -> Memo.return [ `bc, ".bc" ] - | Other { kind = Js; _ } -> - Memo.return - (List.map submodes ~f:(fun submode -> `js, Js_of_ocaml.Ext.exe ~submode)) + | Byte_complete -> Some `exe + | Other { kind = Exe; mode = Native | Best } -> Some `exe + | Other { kind = Exe; mode = Byte } -> Some `bc | Other { kind = C | Object | Shared_object | Plugin; _ } -> (* We don't know how to run tests in these cases *) - Memo.return []) - >>| List.flatten - >>| List.sort_uniq ~compare:Poly.compare + None + | Jsoo mode -> + if Js_of_ocaml.Mode.Pair.select ~mode jsoo_enabled_modes + then Some (`js mode) + else None) + |> List.sort_uniq ~compare:Poly.compare ;; let rules (t : Tests.t) ~sctx ~dir ~scope ~expander ~dir_contents = let* () = let* runtest_modes = - let* submodes = - Jsoo_rules.jsoo_submodes ~dir ~submodes:t.exes.buildable.js_of_ocaml.submodes + let+ jsoo_enabled_modes = + Jsoo_rules.jsoo_enabled_modes + ~expander + ~dir + ~in_context:(Js_of_ocaml.In_context.make ~dir t.exes.buildable.js_of_ocaml) in - runtest_modes t.exes.modes submodes (Scope.project scope) + runtest_modes t.exes.modes jsoo_enabled_modes (Scope.project scope) in Expander.eval_blang expander t.enabled_if >>= function | false -> let loc = Nonempty_list.hd t.exes.names |> fst in - Memo.parallel_iter runtest_modes ~f:(fun (mode, _) -> + Memo.parallel_iter runtest_modes ~f:(fun mode -> let* alias_name = alias mode ~dir in let alias = Alias.make alias_name ~dir in Simple_rules.Alias_rules.add_empty sctx ~loc ~alias) | true -> Nonempty_list.to_list t.exes.names |> Memo.parallel_iter ~f:(fun (loc, s) -> - Memo.parallel_iter runtest_modes ~f:(fun (runtest_mode, ext) -> + Memo.parallel_iter runtest_modes ~f:(fun runtest_mode -> + let ext = ext_of_mode runtest_mode in let custom_runner = custom_runner runtest_mode in let test_pform = Pform.Var Test in let run_action = diff --git a/src/dune_rules/toplevel.ml b/src/dune_rules/toplevel.ml index e80bad4b3b0..dd131b4e12c 100644 --- a/src/dune_rules/toplevel.ml +++ b/src/dune_rules/toplevel.ml @@ -233,7 +233,7 @@ module Stanza = struct ~requires_compile ~requires_link ~flags - ~js_of_ocaml:None + ~js_of_ocaml:(Js_of_ocaml.Mode.Pair.make None) ~melange_package_name:None ~package:None ~preprocessing diff --git a/src/dune_rules/utop.ml b/src/dune_rules/utop.ml index 42369be6f5a..85c53b2b17e 100644 --- a/src/dune_rules/utop.ml +++ b/src/dune_rules/utop.ml @@ -186,7 +186,7 @@ let setup sctx ~dir = ~requires_link ~requires_compile:requires ~flags - ~js_of_ocaml:None + ~js_of_ocaml:(Js_of_ocaml.Mode.Pair.make None) ~melange_package_name:None ~package:None ~preprocessing diff --git a/test/blackbox-tests/test-cases/gen-opam-install-file/stubs.t/dune b/test/blackbox-tests/test-cases/gen-opam-install-file/stubs.t/dune index af74ed3b5df..3c4373c19b2 100644 --- a/test/blackbox-tests/test-cases/gen-opam-install-file/stubs.t/dune +++ b/test/blackbox-tests/test-cases/gen-opam-install-file/stubs.t/dune @@ -1,7 +1,8 @@ (library (name foo) (install_c_headers cfoo) - (js_of_ocaml (javascript_files foo.js) (wasm_files foo.js foo.wat)) + (js_of_ocaml (javascript_files foo.js)) + (wasm_of_ocaml (javascript_files foo.js) (wasm_files foo.wat)) (foreign_stubs (language c) (names c)) (foreign_stubs (language cxx) (names cpp)) (public_name foo)) diff --git a/test/blackbox-tests/test-cases/meta-gen.t/dune b/test/blackbox-tests/test-cases/meta-gen.t/dune index 8fb1d5c797c..6310c17a1d3 100644 --- a/test/blackbox-tests/test-cases/meta-gen.t/dune +++ b/test/blackbox-tests/test-cases/meta-gen.t/dune @@ -14,6 +14,8 @@ (library (name foobar_runtime_lib2) (js_of_ocaml + (javascript_files foobar_runtime.js foobar_runtime2.js)) + (wasm_of_ocaml (javascript_files foobar_runtime.js foobar_runtime2.js) (wasm_files foobar_runtime.wat foobar_runtime2.wat)) (public_name foobar.runtime-lib2) diff --git a/test/blackbox-tests/test-cases/meta-gen.t/run.t b/test/blackbox-tests/test-cases/meta-gen.t/run.t index 7716e35b6fd..5d3c4cb8a2a 100644 --- a/test/blackbox-tests/test-cases/meta-gen.t/run.t +++ b/test/blackbox-tests/test-cases/meta-gen.t/run.t @@ -61,7 +61,11 @@ plugin(byte) = "foobar_runtime_lib2.cma" plugin(native) = "foobar_runtime_lib2.cmxs" jsoo_runtime = "foobar_runtime.js foobar_runtime2.js" - wasmoo_runtime = "foobar_runtime.wat foobar_runtime2.wat" + wasmoo_runtime = + "foobar_runtime.js + foobar_runtime2.js + foobar_runtime.wat + foobar_runtime2.wat" ) package "sub" ( directory = "sub" diff --git a/test/blackbox-tests/test-cases/wasmoo/build-info.t/run.t b/test/blackbox-tests/test-cases/wasmoo/build-info.t/run.t index 04aa5e6195e..429a5cca1be 100644 --- a/test/blackbox-tests/test-cases/wasmoo/build-info.t/run.t +++ b/test/blackbox-tests/test-cases/wasmoo/build-info.t/run.t @@ -11,52 +11,19 @@ Jsoo and build-info Installing _install/lib/main/dune-package Installing _install/lib/main/opam Installing _install/bin/main - Installing _install/bin/main.bc.wasm.assets/Build_info.wasm - Installing _install/bin/main.bc.wasm.assets/Build_info.wasm.map - Installing _install/bin/main.bc.wasm.assets/Build_info__Build_info_data.wasm - Installing _install/bin/main.bc.wasm.assets/Build_info__Build_info_data.wasm.map - Installing _install/bin/main.bc.wasm.assets/CamlinternalAtomic.wasm - Installing _install/bin/main.bc.wasm.assets/CamlinternalAtomic.wasm.map - Installing _install/bin/main.bc.wasm.assets/CamlinternalFormat.wasm - Installing _install/bin/main.bc.wasm.assets/CamlinternalFormat.wasm.map - Installing _install/bin/main.bc.wasm.assets/CamlinternalFormatBasics.wasm - Installing _install/bin/main.bc.wasm.assets/CamlinternalFormatBasics.wasm.map - Installing _install/bin/main.bc.wasm.assets/CamlinternalLazy.wasm - Installing _install/bin/main.bc.wasm.assets/CamlinternalLazy.wasm.map - Installing _install/bin/main.bc.wasm.assets/Dune__exe__Main.wasm - Installing _install/bin/main.bc.wasm.assets/Dune__exe__Main.wasm.map - Installing _install/bin/main.bc.wasm.assets/Std_exit.wasm - Installing _install/bin/main.bc.wasm.assets/Std_exit.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__Buffer.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__Buffer.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__Bytes.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__Bytes.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__Char.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__Char.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__Int.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__Int.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__Lazy.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__Lazy.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__List.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__List.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__Obj.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__Obj.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__Printf.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__Printf.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__Seq.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__Seq.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__String.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__String.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__Sys.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__Sys.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__Uchar.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__Uchar.wasm.map + Installing _install/bin/main.bc.wasm.assets/build_info.wasm + Installing _install/bin/main.bc.wasm.assets/build_info.wasm.map + Installing _install/bin/main.bc.wasm.assets/build_info__Build_info_data.wasm + Installing _install/bin/main.bc.wasm.assets/build_info__Build_info_data.wasm.map + Installing _install/bin/main.bc.wasm.assets/dune__exe__Main.wasm + Installing _install/bin/main.bc.wasm.assets/dune__exe__Main.wasm.map Installing _install/bin/main.bc.wasm.assets/prelude.wasm Installing _install/bin/main.bc.wasm.assets/runtime.wasm Installing _install/bin/main.bc.wasm.assets/start.wasm - Installing _install/bin/main.bc.wasm.assets/start-291802e1.wat + Installing _install/bin/main.bc.wasm.assets/std_exit.wasm + Installing _install/bin/main.bc.wasm.assets/std_exit.wasm.map + Installing _install/bin/main.bc.wasm.assets/stdlib.wasm + Installing _install/bin/main.bc.wasm.assets/stdlib.wasm.map Installing _install/bin/main.bc.wasm.js $ node _install/bin/main.bc.wasm.js unknown @@ -81,97 +48,30 @@ Jsoo and build-info Installing _install/lib/main/opam Deleting _install/bin/main Installing _install/bin/main - Deleting _install/bin/main.bc.wasm.assets/Build_info.wasm - Installing _install/bin/main.bc.wasm.assets/Build_info.wasm - Deleting _install/bin/main.bc.wasm.assets/Build_info.wasm.map - Installing _install/bin/main.bc.wasm.assets/Build_info.wasm.map - Installing _install/bin/main.bc.wasm.assets/Build_info__Build_info_data.wasm - Deleting _install/bin/main.bc.wasm.assets/Build_info__Build_info_data.wasm.map - Installing _install/bin/main.bc.wasm.assets/Build_info__Build_info_data.wasm.map - Deleting _install/bin/main.bc.wasm.assets/CamlinternalAtomic.wasm - Installing _install/bin/main.bc.wasm.assets/CamlinternalAtomic.wasm - Deleting _install/bin/main.bc.wasm.assets/CamlinternalAtomic.wasm.map - Installing _install/bin/main.bc.wasm.assets/CamlinternalAtomic.wasm.map - Deleting _install/bin/main.bc.wasm.assets/CamlinternalFormat.wasm - Installing _install/bin/main.bc.wasm.assets/CamlinternalFormat.wasm - Deleting _install/bin/main.bc.wasm.assets/CamlinternalFormat.wasm.map - Installing _install/bin/main.bc.wasm.assets/CamlinternalFormat.wasm.map - Deleting _install/bin/main.bc.wasm.assets/CamlinternalFormatBasics.wasm - Installing _install/bin/main.bc.wasm.assets/CamlinternalFormatBasics.wasm - Deleting _install/bin/main.bc.wasm.assets/CamlinternalFormatBasics.wasm.map - Installing _install/bin/main.bc.wasm.assets/CamlinternalFormatBasics.wasm.map - Deleting _install/bin/main.bc.wasm.assets/CamlinternalLazy.wasm - Installing _install/bin/main.bc.wasm.assets/CamlinternalLazy.wasm - Deleting _install/bin/main.bc.wasm.assets/CamlinternalLazy.wasm.map - Installing _install/bin/main.bc.wasm.assets/CamlinternalLazy.wasm.map - Deleting _install/bin/main.bc.wasm.assets/Dune__exe__Main.wasm - Installing _install/bin/main.bc.wasm.assets/Dune__exe__Main.wasm - Deleting _install/bin/main.bc.wasm.assets/Dune__exe__Main.wasm.map - Installing _install/bin/main.bc.wasm.assets/Dune__exe__Main.wasm.map - Deleting _install/bin/main.bc.wasm.assets/Std_exit.wasm - Installing _install/bin/main.bc.wasm.assets/Std_exit.wasm - Deleting _install/bin/main.bc.wasm.assets/Std_exit.wasm.map - Installing _install/bin/main.bc.wasm.assets/Std_exit.wasm.map - Deleting _install/bin/main.bc.wasm.assets/Stdlib.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib.wasm - Deleting _install/bin/main.bc.wasm.assets/Stdlib.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib.wasm.map - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Buffer.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__Buffer.wasm - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Buffer.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__Buffer.wasm.map - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Bytes.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__Bytes.wasm - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Bytes.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__Bytes.wasm.map - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Char.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__Char.wasm - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Char.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__Char.wasm.map - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Int.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__Int.wasm - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Int.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__Int.wasm.map - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Lazy.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__Lazy.wasm - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Lazy.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__Lazy.wasm.map - Deleting _install/bin/main.bc.wasm.assets/Stdlib__List.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__List.wasm - Deleting _install/bin/main.bc.wasm.assets/Stdlib__List.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__List.wasm.map - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Obj.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__Obj.wasm - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Obj.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__Obj.wasm.map - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Printf.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__Printf.wasm - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Printf.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__Printf.wasm.map - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Seq.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__Seq.wasm - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Seq.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__Seq.wasm.map - Deleting _install/bin/main.bc.wasm.assets/Stdlib__String.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__String.wasm - Deleting _install/bin/main.bc.wasm.assets/Stdlib__String.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__String.wasm.map - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Sys.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__Sys.wasm - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Sys.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__Sys.wasm.map - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Uchar.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__Uchar.wasm - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Uchar.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__Uchar.wasm.map + Deleting _install/bin/main.bc.wasm.assets/build_info.wasm + Installing _install/bin/main.bc.wasm.assets/build_info.wasm + Deleting _install/bin/main.bc.wasm.assets/build_info.wasm.map + Installing _install/bin/main.bc.wasm.assets/build_info.wasm.map + Installing _install/bin/main.bc.wasm.assets/build_info__Build_info_data.wasm + Installing _install/bin/main.bc.wasm.assets/build_info__Build_info_data.wasm.map + Deleting _install/bin/main.bc.wasm.assets/dune__exe__Main.wasm + Installing _install/bin/main.bc.wasm.assets/dune__exe__Main.wasm + Deleting _install/bin/main.bc.wasm.assets/dune__exe__Main.wasm.map + Installing _install/bin/main.bc.wasm.assets/dune__exe__Main.wasm.map Deleting _install/bin/main.bc.wasm.assets/prelude.wasm Installing _install/bin/main.bc.wasm.assets/prelude.wasm Deleting _install/bin/main.bc.wasm.assets/runtime.wasm Installing _install/bin/main.bc.wasm.assets/runtime.wasm Deleting _install/bin/main.bc.wasm.assets/start.wasm Installing _install/bin/main.bc.wasm.assets/start.wasm - Deleting _install/bin/main.bc.wasm.assets/start-291802e1.wat - Installing _install/bin/main.bc.wasm.assets/start-291802e1.wat + Deleting _install/bin/main.bc.wasm.assets/std_exit.wasm + Installing _install/bin/main.bc.wasm.assets/std_exit.wasm + Deleting _install/bin/main.bc.wasm.assets/std_exit.wasm.map + Installing _install/bin/main.bc.wasm.assets/std_exit.wasm.map + Deleting _install/bin/main.bc.wasm.assets/stdlib.wasm + Installing _install/bin/main.bc.wasm.assets/stdlib.wasm + Deleting _install/bin/main.bc.wasm.assets/stdlib.wasm.map + Installing _install/bin/main.bc.wasm.assets/stdlib.wasm.map Deleting _install/bin/main.bc.wasm.js Installing _install/bin/main.bc.wasm.js Installing _install/doc/main/README @@ -193,97 +93,30 @@ Jsoo and build-info Installing _install/lib/main/opam Deleting _install/bin/main Installing _install/bin/main - Deleting _install/bin/main.bc.wasm.assets/Build_info.wasm - Installing _install/bin/main.bc.wasm.assets/Build_info.wasm - Deleting _install/bin/main.bc.wasm.assets/Build_info.wasm.map - Installing _install/bin/main.bc.wasm.assets/Build_info.wasm.map - Installing _install/bin/main.bc.wasm.assets/Build_info__Build_info_data.wasm - Deleting _install/bin/main.bc.wasm.assets/Build_info__Build_info_data.wasm.map - Installing _install/bin/main.bc.wasm.assets/Build_info__Build_info_data.wasm.map - Deleting _install/bin/main.bc.wasm.assets/CamlinternalAtomic.wasm - Installing _install/bin/main.bc.wasm.assets/CamlinternalAtomic.wasm - Deleting _install/bin/main.bc.wasm.assets/CamlinternalAtomic.wasm.map - Installing _install/bin/main.bc.wasm.assets/CamlinternalAtomic.wasm.map - Deleting _install/bin/main.bc.wasm.assets/CamlinternalFormat.wasm - Installing _install/bin/main.bc.wasm.assets/CamlinternalFormat.wasm - Deleting _install/bin/main.bc.wasm.assets/CamlinternalFormat.wasm.map - Installing _install/bin/main.bc.wasm.assets/CamlinternalFormat.wasm.map - Deleting _install/bin/main.bc.wasm.assets/CamlinternalFormatBasics.wasm - Installing _install/bin/main.bc.wasm.assets/CamlinternalFormatBasics.wasm - Deleting _install/bin/main.bc.wasm.assets/CamlinternalFormatBasics.wasm.map - Installing _install/bin/main.bc.wasm.assets/CamlinternalFormatBasics.wasm.map - Deleting _install/bin/main.bc.wasm.assets/CamlinternalLazy.wasm - Installing _install/bin/main.bc.wasm.assets/CamlinternalLazy.wasm - Deleting _install/bin/main.bc.wasm.assets/CamlinternalLazy.wasm.map - Installing _install/bin/main.bc.wasm.assets/CamlinternalLazy.wasm.map - Deleting _install/bin/main.bc.wasm.assets/Dune__exe__Main.wasm - Installing _install/bin/main.bc.wasm.assets/Dune__exe__Main.wasm - Deleting _install/bin/main.bc.wasm.assets/Dune__exe__Main.wasm.map - Installing _install/bin/main.bc.wasm.assets/Dune__exe__Main.wasm.map - Deleting _install/bin/main.bc.wasm.assets/Std_exit.wasm - Installing _install/bin/main.bc.wasm.assets/Std_exit.wasm - Deleting _install/bin/main.bc.wasm.assets/Std_exit.wasm.map - Installing _install/bin/main.bc.wasm.assets/Std_exit.wasm.map - Deleting _install/bin/main.bc.wasm.assets/Stdlib.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib.wasm - Deleting _install/bin/main.bc.wasm.assets/Stdlib.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib.wasm.map - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Buffer.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__Buffer.wasm - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Buffer.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__Buffer.wasm.map - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Bytes.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__Bytes.wasm - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Bytes.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__Bytes.wasm.map - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Char.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__Char.wasm - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Char.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__Char.wasm.map - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Int.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__Int.wasm - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Int.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__Int.wasm.map - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Lazy.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__Lazy.wasm - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Lazy.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__Lazy.wasm.map - Deleting _install/bin/main.bc.wasm.assets/Stdlib__List.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__List.wasm - Deleting _install/bin/main.bc.wasm.assets/Stdlib__List.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__List.wasm.map - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Obj.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__Obj.wasm - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Obj.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__Obj.wasm.map - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Printf.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__Printf.wasm - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Printf.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__Printf.wasm.map - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Seq.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__Seq.wasm - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Seq.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__Seq.wasm.map - Deleting _install/bin/main.bc.wasm.assets/Stdlib__String.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__String.wasm - Deleting _install/bin/main.bc.wasm.assets/Stdlib__String.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__String.wasm.map - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Sys.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__Sys.wasm - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Sys.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__Sys.wasm.map - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Uchar.wasm - Installing _install/bin/main.bc.wasm.assets/Stdlib__Uchar.wasm - Deleting _install/bin/main.bc.wasm.assets/Stdlib__Uchar.wasm.map - Installing _install/bin/main.bc.wasm.assets/Stdlib__Uchar.wasm.map + Deleting _install/bin/main.bc.wasm.assets/build_info.wasm + Installing _install/bin/main.bc.wasm.assets/build_info.wasm + Deleting _install/bin/main.bc.wasm.assets/build_info.wasm.map + Installing _install/bin/main.bc.wasm.assets/build_info.wasm.map + Installing _install/bin/main.bc.wasm.assets/build_info__Build_info_data.wasm + Installing _install/bin/main.bc.wasm.assets/build_info__Build_info_data.wasm.map + Deleting _install/bin/main.bc.wasm.assets/dune__exe__Main.wasm + Installing _install/bin/main.bc.wasm.assets/dune__exe__Main.wasm + Deleting _install/bin/main.bc.wasm.assets/dune__exe__Main.wasm.map + Installing _install/bin/main.bc.wasm.assets/dune__exe__Main.wasm.map Deleting _install/bin/main.bc.wasm.assets/prelude.wasm Installing _install/bin/main.bc.wasm.assets/prelude.wasm Deleting _install/bin/main.bc.wasm.assets/runtime.wasm Installing _install/bin/main.bc.wasm.assets/runtime.wasm Deleting _install/bin/main.bc.wasm.assets/start.wasm Installing _install/bin/main.bc.wasm.assets/start.wasm - Deleting _install/bin/main.bc.wasm.assets/start-291802e1.wat - Installing _install/bin/main.bc.wasm.assets/start-291802e1.wat + Deleting _install/bin/main.bc.wasm.assets/std_exit.wasm + Installing _install/bin/main.bc.wasm.assets/std_exit.wasm + Deleting _install/bin/main.bc.wasm.assets/std_exit.wasm.map + Installing _install/bin/main.bc.wasm.assets/std_exit.wasm.map + Deleting _install/bin/main.bc.wasm.assets/stdlib.wasm + Installing _install/bin/main.bc.wasm.assets/stdlib.wasm + Deleting _install/bin/main.bc.wasm.assets/stdlib.wasm.map + Installing _install/bin/main.bc.wasm.assets/stdlib.wasm.map Deleting _install/bin/main.bc.wasm.js Installing _install/bin/main.bc.wasm.js Deleting _install/doc/main/README diff --git a/test/blackbox-tests/test-cases/wasmoo/build-info.t/src/dune b/test/blackbox-tests/test-cases/wasmoo/build-info.t/src/dune index 9f1d7f4c7b4..b3391eec43c 100644 --- a/test/blackbox-tests/test-cases/wasmoo/build-info.t/src/dune +++ b/test/blackbox-tests/test-cases/wasmoo/build-info.t/src/dune @@ -1,8 +1,7 @@ (executable (name main) (public_name main) - (modes js byte) - (js_of_ocaml (submodes wasm)) + (modes wasm byte) (modules main) (package main) (libraries dune-build-info)) diff --git a/test/blackbox-tests/test-cases/wasmoo/github3622.t b/test/blackbox-tests/test-cases/wasmoo/github3622.t index 5b83eb58c01..b4a79f8b5a5 100644 --- a/test/blackbox-tests/test-cases/wasmoo/github3622.t +++ b/test/blackbox-tests/test-cases/wasmoo/github3622.t @@ -9,8 +9,7 @@ Setup fixtures: $ cat >dune < (executable > (name main) - > (modes js) - > (js_of_ocaml (submodes wasm))) + > (modes wasm)) > EOF Test without separate compilation: diff --git a/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/wasm/dune b/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/wasm/dune index 7fa81740628..de925d0bb79 100644 --- a/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/wasm/dune +++ b/test/blackbox-tests/test-cases/wasmoo/inline-tests.t/wasm/dune @@ -1,6 +1,6 @@ (library (name inline_tests_wasm) - (js_of_ocaml (wasm_files wasm.wat) (submodes wasm)) + (wasm_of_ocaml (wasm_files wasm.wat)) (inline_tests - (modes js) + (modes wasm) (backend fake_backend))) diff --git a/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/bin/dune b/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/bin/dune index 6dc09bed0e5..996bef7f4a0 100644 --- a/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/bin/dune +++ b/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/bin/dune @@ -1,24 +1,20 @@ (executable (name bin1) (modules bin1) - (modes js) + (modes wasm) (libraries library1) - (js_of_ocaml - (flags (:standard --enable use-js-string))) ) (executable (name bin2) (modules bin2) - (modes js) + (modes wasm) (libraries library1) - (js_of_ocaml - (flags (:standard --disable use-js-string))) ) (executable (name bin3) (modules bin3) - (modes js) + (modes wasm) (libraries library1) ) diff --git a/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/dune b/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/dune index 7f70cce913f..4c6f3c67cf6 100644 --- a/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/dune +++ b/test/blackbox-tests/test-cases/wasmoo/jsoo-config.t/dune @@ -1,7 +1,6 @@ (env (_ - (js_of_ocaml - (submodes wasm) + (wasm_of_ocaml (flags (:standard --quiet)) (compilation_mode separate) ))) diff --git a/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/bin/dune b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/bin/dune index de172d2b9a3..11fce31221b 100644 --- a/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/bin/dune +++ b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/bin/dune @@ -1,8 +1,6 @@ (executables (names technologic) (libraries js_of_ocaml x) - (modes js) - (js_of_ocaml - (submodes wasm) - (flags (:standard)) - (wasm_files runtime.js))) + (modes wasm) + (wasm_of_ocaml + (javascript_files runtime.js))) diff --git a/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/lib/dune b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/lib/dune index a68edc1c0f7..b75532802b2 100644 --- a/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/lib/dune +++ b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/lib/dune @@ -2,6 +2,6 @@ (name x) (libraries js_of_ocaml) (public_name x) - (js_of_ocaml - (flags (--pretty)) (wasm_files runtime.js runtime.wat)) + (wasm_of_ocaml + (flags (--pretty)) (javascript_files runtime.js) (wasm_files runtime.wat)) ) diff --git a/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/lib/runtime.js b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/lib/runtime.js index f2398f02647..30ad61bc948 100644 --- a/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/lib/runtime.js +++ b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/lib/runtime.js @@ -2,5 +2,5 @@ //Provides: jsPrint function jsPrint(x){ - joo_global_object.console.log(x); + globalThis.console.log(x); } diff --git a/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/run.t b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/run.t index fec9ab2e6a9..79999cde7db 100644 --- a/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/run.t +++ b/test/blackbox-tests/test-cases/wasmoo/no-check-prim.t/run.t @@ -1,6 +1,6 @@ Compilation using WasmOO - $ dune build --display short bin/technologic.bc.js @install 2>&1 | \ + $ dune build --display short bin/technologic.bc.wasm.js @install 2>&1 | \ > sed s,^\ *$(ocamlc -config-var c_compiler),\ \ C_COMPILER,g wasm_of_ocaml bin/.technologic.eobjs/jsoo/technologic.bc.runtime.wasma ocamldep bin/.technologic.eobjs/dune__exe__Technologic.impl.d diff --git a/test/blackbox-tests/test-cases/wasmoo/public-libs.t/b/dune b/test/blackbox-tests/test-cases/wasmoo/public-libs.t/b/dune index 18b69c13178..2d2e43adf78 100644 --- a/test/blackbox-tests/test-cases/wasmoo/public-libs.t/b/dune +++ b/test/blackbox-tests/test-cases/wasmoo/public-libs.t/b/dune @@ -1,5 +1,4 @@ (executable (name main) (libraries a) - (modes js) - (js_of_ocaml (submodes wasm))) + (modes wasm)) diff --git a/test/blackbox-tests/test-cases/wasmoo/simple.t/bin/dune b/test/blackbox-tests/test-cases/wasmoo/simple.t/bin/dune index 1f0939d8c4c..08ca6a4ce9f 100644 --- a/test/blackbox-tests/test-cases/wasmoo/simple.t/bin/dune +++ b/test/blackbox-tests/test-cases/wasmoo/simple.t/bin/dune @@ -1,8 +1,6 @@ (executables (names technologic) (libraries js_of_ocaml x) - (modes js) - (js_of_ocaml - (submodes wasm) - (flags (:standard)) - (wasm_files runtime.js))) + (modes wasm) + (wasm_of_ocaml + (javascript_files runtime.js))) diff --git a/test/blackbox-tests/test-cases/wasmoo/simple.t/lib/dune b/test/blackbox-tests/test-cases/wasmoo/simple.t/lib/dune index d1633abbadb..6bd6eaa51b6 100644 --- a/test/blackbox-tests/test-cases/wasmoo/simple.t/lib/dune +++ b/test/blackbox-tests/test-cases/wasmoo/simple.t/lib/dune @@ -2,6 +2,6 @@ (name x) (libraries js_of_ocaml) (public_name x) - (js_of_ocaml + (wasm_of_ocaml (flags (--pretty)) (wasm_files runtime.js runtime.wat)) (foreign_stubs (language c) (names stubs))) diff --git a/test/blackbox-tests/test-cases/wasmoo/simple.t/lib/runtime.js b/test/blackbox-tests/test-cases/wasmoo/simple.t/lib/runtime.js index f2398f02647..30ad61bc948 100644 --- a/test/blackbox-tests/test-cases/wasmoo/simple.t/lib/runtime.js +++ b/test/blackbox-tests/test-cases/wasmoo/simple.t/lib/runtime.js @@ -2,5 +2,5 @@ //Provides: jsPrint function jsPrint(x){ - joo_global_object.console.log(x); + globalThis.console.log(x); } diff --git a/test/blackbox-tests/test-cases/wasmoo/submodes.t/dune b/test/blackbox-tests/test-cases/wasmoo/submodes.t/dune index c8dcdb3f898..def8e78b42f 100644 --- a/test/blackbox-tests/test-cases/wasmoo/submodes.t/dune +++ b/test/blackbox-tests/test-cases/wasmoo/submodes.t/dune @@ -1,7 +1,7 @@ (executable (name main) - (modes js)) + (modes js wasm)) (env - (wasm (js_of_ocaml (submodes wasm))) - (both (js_of_ocaml (submodes js wasm)))) + (js (wasm_of_ocaml (enabled_if false))) + (wasm (js_of_ocaml (enabled_if false)))) diff --git a/test/blackbox-tests/test-cases/wasmoo/submodes.t/run.t b/test/blackbox-tests/test-cases/wasmoo/submodes.t/run.t index 2995e7e95e0..0bf84390a67 100644 --- a/test/blackbox-tests/test-cases/wasmoo/submodes.t/run.t +++ b/test/blackbox-tests/test-cases/wasmoo/submodes.t/run.t @@ -1,6 +1,6 @@ Building with different combinations of submodes -The default is to only compile to JavaScript +Compiling to JavaScript $ dune build --profile js $ node _build/default/main.bc.js @@ -9,14 +9,14 @@ The default is to only compile to JavaScript Error: Don't know how to build main.bc.wasm.js [1] -Compiling to Wasm. One can still use the `.bc.js` binary but it runs -the Wasm code. +Compiling to Wasm. $ dune build --profile wasm - $ node _build/default/main.bc.js - wasm_of_ocaml $ node _build/default/main.bc.wasm.js wasm_of_ocaml + $ dune build --profile wasm main.bc.js + Error: Don't know how to build main.bc.js + [1] Compiling to both JS and Wasm. diff --git a/test/blackbox-tests/test-cases/wasmoo/tests.t/dune b/test/blackbox-tests/test-cases/wasmoo/tests.t/dune index c5e43ef8ad3..fe703fcd7dd 100644 --- a/test/blackbox-tests/test-cases/wasmoo/tests.t/dune +++ b/test/blackbox-tests/test-cases/wasmoo/tests.t/dune @@ -1,10 +1,9 @@ (tests (names a b) - (modes js)) + (modes wasm)) (env (_ - (js_of_ocaml + (wasm_of_ocaml (runtest_alias runtest-js) - (submodes wasm) (compilation_mode whole_program)))) diff --git a/test/blackbox-tests/test-cases/workspaces/workspace-env.t/run.t b/test/blackbox-tests/test-cases/workspaces/workspace-env.t/run.t index bd7c0a3cf09..094d6d20d76 100644 --- a/test/blackbox-tests/test-cases/workspaces/workspace-env.t/run.t +++ b/test/blackbox-tests/test-cases/workspaces/workspace-env.t/run.t @@ -17,3 +17,6 @@ Workspaces also allow you to set the env for a context: (js_of_ocaml_flags ()) (js_of_ocaml_build_runtime_flags ()) (js_of_ocaml_link_flags ()) + (wasm_of_ocaml_flags ()) + (wasm_of_ocaml_build_runtime_flags ()) + (wasm_of_ocaml_link_flags ()) From 409a0f808bee5cc11c92c5bf566a8885105383ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Vouillon?= Date: Mon, 4 Nov 2024 16:37:00 +0100 Subject: [PATCH 15/26] CR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Vouillon --- src/dune_rules/exe_rules.ml | 17 +++++++--------- src/dune_rules/inline_tests.ml | 31 +++++++++++++++--------------- src/dune_rules/jsoo/js_of_ocaml.ml | 16 +++++++-------- 3 files changed, 31 insertions(+), 33 deletions(-) diff --git a/src/dune_rules/exe_rules.ml b/src/dune_rules/exe_rules.ml index 6040869a2ad..f61ee3789c7 100644 --- a/src/dune_rules/exe_rules.ml +++ b/src/dune_rules/exe_rules.ml @@ -17,9 +17,8 @@ let linkages let modes = L.Map.to_list exes.modes |> List.filter ~f:(fun (mode, _) -> - match mode with - | Executables.Link_mode.Jsoo mode -> - Js_of_ocaml.Mode.Pair.select ~mode jsoo_enabled_modes + match (mode : Executables.Link_mode.t) with + | Jsoo mode -> Js_of_ocaml.Mode.Pair.select ~mode jsoo_enabled_modes | Byte_complete | Other _ -> true) |> List.map ~f:(fun (mode, loc) -> Exe.Linkage.of_user_config ocaml ~dynamically_linked_foreign_archives ~loc mode) @@ -36,13 +35,11 @@ let linkages Js_of_ocaml.Mode.Set.inter jsoo_enabled_modes jsoo_is_whole_program in let bytecode_exe_needed = - L.Map.foldi - ~f:(fun m _ p -> - match m with - | Executables.Link_mode.Jsoo mode -> - Js_of_ocaml.Mode.Pair.select ~mode jsoo_bytecode_exe_needed || p - | Byte_complete | Other _ -> p) - ~init:false + L.Map.existsi + ~f:(fun mode _ -> + match (mode : Executables.Link_mode.t) with + | Jsoo mode -> Js_of_ocaml.Mode.Pair.select ~mode jsoo_bytecode_exe_needed + | Byte_complete | Other _ -> false) exes.modes in if bytecode_exe_needed then Exe.Linkage.byte_for_jsoo :: modes else modes) diff --git a/src/dune_rules/inline_tests.ml b/src/dune_rules/inline_tests.ml index 6bd1406d518..8e6e69b4a79 100644 --- a/src/dune_rules/inline_tests.ml +++ b/src/dune_rules/inline_tests.ml @@ -181,22 +181,23 @@ include Sub_system.Register_end_point (struct | Jsoo mode -> Js_of_ocaml.Mode.Pair.select ~mode jsoo_enabled_modes) in let* linkages = - let+ jsoo_is_whole_program = Jsoo_rules.jsoo_is_whole_program sctx ~dir in let ocaml = Compilation_context.ocaml cctx in - List.concat_map modes ~f:(fun (mode : Mode_conf.t) -> - match mode with - | Native -> [ Exe.Linkage.native ] - | Best -> [ Exe.Linkage.native_or_custom ocaml ] - | Byte -> [ Exe.Linkage.custom_with_ext ~ext:".bc" ocaml.version ] - | Jsoo jsoo_mode -> - let linkage = - match jsoo_mode with - | JS -> Exe.Linkage.js - | Wasm -> Exe.Linkage.wasm - in - if Js_of_ocaml.Mode.Pair.select ~mode:jsoo_mode jsoo_is_whole_program - then [ Exe.Linkage.byte_for_jsoo; linkage ] - else [ linkage ]) + let l = + List.map modes ~f:(fun (mode : Mode_conf.t) -> + match mode with + | Native -> Exe.Linkage.native + | Best -> Exe.Linkage.native_or_custom ocaml + | Byte -> Exe.Linkage.custom_with_ext ~ext:".bc" ocaml.version + | Jsoo JS -> Exe.Linkage.js + | Jsoo Wasm -> Exe.Linkage.wasm) + in + let+ jsoo_is_whole_program = Jsoo_rules.jsoo_is_whole_program sctx ~dir in + if List.exists modes ~f:(fun mode -> + match (mode : Mode_conf.t) with + | Jsoo mode -> Js_of_ocaml.Mode.Pair.select ~mode jsoo_is_whole_program + | Native | Best | Byte -> false) + then Exe.Linkage.byte_for_jsoo :: l + else l in let* (_ : Exe.dep_graphs) = let link_args = diff --git a/src/dune_rules/jsoo/js_of_ocaml.ml b/src/dune_rules/jsoo/js_of_ocaml.ml index 883c19437be..dc2fad30ab6 100644 --- a/src/dune_rules/jsoo/js_of_ocaml.ml +++ b/src/dune_rules/jsoo/js_of_ocaml.ml @@ -29,7 +29,7 @@ module Mode = struct | JS | Wasm - let equal = Poly.equal + let equal (a : t) b = Poly.equal a b let select ~mode js wasm = match mode with @@ -89,9 +89,9 @@ module Mode = struct let union = Pair.map2 ~f:( || ) let is_empty (x : t) = not (x.js || x.wasm) - let to_list (x : t) = - let l = if x.wasm then [ Wasm ] else [] in - if x.js then JS :: l else l + let to_list ({ js; wasm } : t) = + let l = if wasm then [ Wasm ] else [] in + if js then JS :: l else l ;; end end @@ -159,8 +159,8 @@ module Flags = struct and+ compile = t.compile and+ link = t.link in let prefix = - match mode with - | Mode.JS -> "js" + match (mode : Mode.t) with + | JS -> "js" | Wasm -> "wasm" in List.map @@ -225,8 +225,8 @@ module In_buildable = struct (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> Blang.decode) and+ javascript_files = field "javascript_files" (repeat string) ~default:[] and+ wasm_files = - match mode with - | Mode.JS -> return [] + match (mode : Mode.t) with + | JS -> return [] | Wasm -> field "wasm_files" From 7b034e6e4f8991c49b1940f236f1436ebda7ab3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Vouillon?= Date: Mon, 4 Nov 2024 17:47:50 +0100 Subject: [PATCH 16/26] CR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Vouillon --- src/dune_rules/jsoo/jsoo_rules.ml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/dune_rules/jsoo/jsoo_rules.ml b/src/dune_rules/jsoo/jsoo_rules.ml index aed29b64429..b10ac8f27b9 100644 --- a/src/dune_rules/jsoo/jsoo_rules.ml +++ b/src/dune_rules/jsoo/jsoo_rules.ml @@ -670,6 +670,10 @@ let build_exe | None -> js_of_ocaml_sourcemap sctx ~dir ~mode | Some x -> Memo.return x in + assert ( + match mode with + | JS -> wasm_files = [] + | Wasm -> true); let runtime_files = javascript_files @ wasm_files in let directory_targets = match mode with From cb89db668d757d784f8d6d13c8cfd88a438e8181 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Vouillon?= Date: Tue, 5 Nov 2024 11:52:08 +0100 Subject: [PATCH 17/26] CR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Vouillon --- src/dune_rules/jsoo/js_of_ocaml.ml | 2 +- src/dune_rules/jsoo/jsoo_rules.ml | 18 ++++++++---------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/dune_rules/jsoo/js_of_ocaml.ml b/src/dune_rules/jsoo/js_of_ocaml.ml index dc2fad30ab6..2c8c8e185f2 100644 --- a/src/dune_rules/jsoo/js_of_ocaml.ml +++ b/src/dune_rules/jsoo/js_of_ocaml.ml @@ -358,7 +358,7 @@ module Env = struct ; sourcemap = None ; runtest_alias = None ; flags = Flags.default ~profile - ; enabled_if = Some Blang.true_ + ; enabled_if = None } ;; end diff --git a/src/dune_rules/jsoo/jsoo_rules.ml b/src/dune_rules/jsoo/jsoo_rules.ml index b10ac8f27b9..c50b47edcc8 100644 --- a/src/dune_rules/jsoo/jsoo_rules.ml +++ b/src/dune_rules/jsoo/jsoo_rules.ml @@ -12,18 +12,16 @@ let compute_env ~mode = let local = Js_of_ocaml.Mode.select ~mode local.js_of_ocaml local.wasm_of_ocaml in let* parent = parent in let+ enabled_if = - match local.enabled_if with - | None -> - Memo.return - (match parent.enabled_if with - | Some (Const default) -> default - | _ -> assert false) - | Some enabled_if -> Expander.eval_blang expander enabled_if + match Option.first_some local.enabled_if parent.enabled_if with + | None -> Memo.return None + | Some enabled_if -> + let+ v = Expander.eval_blang expander enabled_if in + Some (Blang.Const v) in { Js_of_ocaml.Env.compilation_mode = Option.first_some local.compilation_mode parent.compilation_mode ; sourcemap = Option.first_some local.sourcemap parent.sourcemap - ; enabled_if = Some (Const enabled_if) + ; enabled_if ; runtest_alias = Option.first_some local.runtest_alias parent.runtest_alias ; flags = Js_of_ocaml.Flags.make @@ -601,8 +599,8 @@ let jsoo_enabled | None -> let* js_of_ocaml = jsoo_env ~dir ~mode in (match js_of_ocaml.enabled_if with - | Some (Const default) -> Memo.return default - | _ -> assert false) + | Some enabled_if -> eval enabled_if + | None -> Memo.return true) ;; let jsoo_enabled_modes ~expander ~dir ~in_context = From fd5acfc8d1f299cf90883d07c68046fa4ea81581 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Vouillon?= Date: Tue, 5 Nov 2024 12:44:02 +0100 Subject: [PATCH 18/26] Updated documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Vouillon --- doc/reference/dune/env.rst | 21 +++++++-- doc/reference/dune/executable.rst | 45 +++++++++++++------ doc/reference/dune/library.rst | 4 ++ doc/tests.rst | 3 +- doc/wasmoo.rst | 72 ++++++++++++++++++++++++++++--- 5 files changed, 119 insertions(+), 26 deletions(-) diff --git a/doc/reference/dune/env.rst b/doc/reference/dune/env.rst index 485a1bc396b..b05ff751d82 100644 --- a/doc/reference/dune/env.rst +++ b/doc/reference/dune/env.rst @@ -49,11 +49,24 @@ Fields supported in ```` are: or not where ```` is either ``no``, ``file`` (to generate sourcemap in a ``.map`` file next the the generated javascript file) or ``inline`` (to inline the sourcemap at the end of the generated JavaScript file). - ``(js_of_ocaml (runtest_alias ))`` specifies the alias under which - :ref:`inline_tests` and tests (:ref:`tests-stanza`) run for the `js` mode. + :ref:`inline_tests` and tests (:ref:`tests-stanza`) run for the ``js`` mode. -- ``(js_of_ocaml (submodes ))`` controls whether to generate - JavaScript, Wasm code, or both. Each submode is either ``js`` or ``wasm``. - The default is to generate JavaScript code. +- ``(js_of_ocaml (enabled_if ))`` specifies whether the ``js`` mode is enabled. It is enabled by default. + +- ``(wasm_of_ocaml (flags )(build_runtime )(link_flags ))`` + specifies ``wasm_of_ocaml`` flags. See :ref:`wasmoo-field` for more details. + +- ``(wasm_of_ocaml (compilation_mode ))`` controls whether to use separate + compilation or not where ```` is either ``whole_program`` or + ``separate``. + +- ``(wasm_of_ocaml (sourcemap ))`` controls whether to generate sourcemap + or not where ```` is either ``no``, ``file`` (to generate sourcemap in a ``.map`` file next the the generated javascript file) or ``inline`` (to inline the sourcemap at the end of the generated JavaScript file). + +- ``(wasm_of_ocaml (runtest_alias ))`` specifies the alias under which + :ref:`inline_tests` and tests (:ref:`tests-stanza`) run for the ``wasm`` mode. + +- ``(wasm_of_ocaml (enabled_if ))`` specifies whether the ``wasm`` mode is enabled. It is enabled by default. - ``(binaries )``, where ```` is a list of entries of the form ``( as )``. ``( as )`` makes the binary diff --git a/doc/reference/dune/executable.rst b/doc/reference/dune/executable.rst index deb0e3f1ba0..39111b27429 100644 --- a/doc/reference/dune/executable.rst +++ b/doc/reference/dune/executable.rst @@ -15,13 +15,13 @@ There can be additional modules in the current directory; you only need to specify the entry point. Given an ``executable`` stanza with ``(name )``, Dune will know how to build ``.exe``. If requested, it will also know how to build ``.bc``, ``.bc.js`` and ``.bc.wasm.js`` (Dune 2.0 -and up also need specific configuration (see the ``modes`` optional field +and up also needs specific configuration (see the ``modes`` optional field below)). ``.exe`` is a native code executable, ``.bc`` is a bytecode executable which requires ``ocamlrun`` to run, ``.bc.js`` is a JavaScript generated using ``js_of_ocaml``, and ``.bc.wasm.js`` is a -Wasm loader generated using ``wasm_of_ocaml`` (the Wasm modules are included in +Wasm loader script generated using ``wasm_of_ocaml`` (the Wasm modules are included in directory ``.bc.wasm.assets``). Please note: in case native compilation is not available, ``.exe`` will be @@ -94,6 +94,8 @@ files for executables. See - ``js_of_ocaml``: See the section about :ref:`jsoo-field` +- ``wasm_of_ocaml``: See the section about :ref:`wasmoo-field` + - ``flags``, ``ocamlc_flags``, and ``ocamlopt_flags``: See :doc:`/concepts/ocaml-flags`. @@ -168,6 +170,7 @@ available. non-OCaml application. - ``js`` for producing JavaScript from bytecode executables, see :doc:`/reference/dune-project/explicit_js_mode`. +- ``wasm`` for producing JavaScript from bytecode executables. - ``plugin`` for producing a plugin (``.cmxs`` if native or ``.cma`` if bytecode). @@ -189,6 +192,7 @@ Additionally, you can use the following shorthands: - ``byte`` for ``(byte exe)`` - ``native`` for ``(native exe)`` - ``js`` for ``(byte js)`` +- ``wasm`` for ``(byte wasm)`` - ``plugin`` for ``(best plugin)`` For instance, the following ``modes`` fields are all equivalent: @@ -218,8 +222,8 @@ The extensions for the various linking modes are chosen as follows: .. (byte shared_object) .bc%{ext_dll} .. (native/best shared_object) %{ext_dll} .. c .bc.c -.. js .bc.js (JavaScript) -.. js .bc.wasm.js (Wasm) +.. js .bc.js +.. wasm .bc.wasm.js .. (best plugin) %{ext_plugin} .. (byte plugin) .cma .. (native plugin) .cmxs @@ -237,10 +241,6 @@ linking mode that's the same as ``byte_complete``, but it uses the extension currently tracked by Dune, so they don't run ``.bc`` files during the build. Run the ``.bc.exe`` or ``.exe`` ones instead, as these are self-contained. -When compiling to Wasm but not to JavaScript, a ``.bc.js`` file can -also be produced for compatibility. It is just a copy of the -``bc.wasm.js`` file. - Lastly, note that ``.bc`` executables cannot contain C stubs. If your executable contains C stubs you may want to use ``(modes exe)``. @@ -266,20 +266,17 @@ options using ``(js_of_ocaml ())``. - ``(javascript_files ())`` to specify ``js_of_ocaml`` JavaScript runtime files. -- ``(wasm_files ())`` to specify ``wasm_of_ocaml`` - JavaScript and Wasm runtime files. - - ``(compilation_mode )`` where ``>`` is either ``whole_program`` or ``separate``. This is only available inside ``executable`` stanzas. - ``(sourcemap )`` where ``>`` is one of ``no``, ``file`` or ``inline``. This is only available inside ``executable`` stanzas. -- ``(submodes )`` controls whether to generate - JavaScript or Wasm code. Each submode is either ``js`` or ``wasm``. - The default is taken from the environment. +- ``(enabled_if )`` to specify whether the ``js`` mode is enabled. It is enabled by default. + This is only available inside ``executable`` stanzas. ```` is specified in the :doc:`/reference/ordered-set-language`. +```` is specified using the :doc:`/reference/boolean-language`, The default values for ``flags``, ``compilation_mode`` and ``sourcemap`` depend on the selected build profile. The build profile ``dev`` (the default) will enable inline sourcemap, separate compilation and pretty @@ -287,6 +284,26 @@ JavaScript output. See :ref:`jsoo` for more information. +.. _wasmoo-field: + +wasm_of_ocaml +~~~~~~~~~~~~~ + +In ``library`` and ``executable`` stanzas, you can specify ``wasm_of_ocaml`` +options using ``(wasm_of_ocaml ())``. + +```` are all optional. They are the same as the ```` above plus: + +- ``(wasm_files ())`` to specify ``wasm_of_ocaml`` + Wasm runtime files. + +For the ``(sourcemap )`` option, source maps are generated when ``>`` is either ``file`` or ``inline``. They are put within the ``.bc.wasm.assets`` directory in both cases. + +The default values for ``flags``, ``compilation_mode`` and ``sourcemap`` depend on the selected build profile. The +build profile ``dev`` (the default) will enable sourcemaps, separate compilation and pretty Wasm output. + +See :ref:`wasmoo` for more information. + executables ----------- diff --git a/doc/reference/dune/library.rst b/doc/reference/dune/library.rst index 8237e6d8f86..667ab5acaa4 100644 --- a/doc/reference/dune/library.rst +++ b/doc/reference/dune/library.rst @@ -213,6 +213,10 @@ order to declare a multi-directory library, you need to use the Sets options for JavaScript compilation, see :ref:`jsoo-field`. +.. describe:: (wasm_of_ocaml ...) + + Sets options for JavaScript compilation, see :ref:`wasmoo-field`. + .. describe:: (flags ...) See :doc:`/concepts/ocaml-flags`. diff --git a/doc/tests.rst b/doc/tests.rst index a26960658b1..9e9a9f9267f 100644 --- a/doc/tests.rst +++ b/doc/tests.rst @@ -258,6 +258,7 @@ field. Available modes are: - ``best`` for running tests in native mode with fallback to byte code, if native compilation is not available - ``js`` for running tests in JavaScript using Node.js +- ``wasm`` for running tests in Wasm using Node.js For instance: @@ -265,7 +266,7 @@ For instance: (library (name foo) - (inline_tests (modes byte best js)) + (inline_tests (modes byte best js wasm)) (preprocess (pps ppx_expect))) diff --git a/doc/wasmoo.rst b/doc/wasmoo.rst index 2a088b6d6db..3be8a4fe8cd 100644 --- a/doc/wasmoo.rst +++ b/doc/wasmoo.rst @@ -11,9 +11,6 @@ Wasm Compilation With Wasm_of_ocaml Wasm_of_ocaml_ is a compiler from OCaml to WebAssembly (Wasm for short). The compiler works by translating OCaml bytecode to Wasm code. -Compiling to Wasm is very similar to compiling to JavaScript. See -:doc:`jsoo` for more information. - Compiling to Wasm ================= @@ -33,14 +30,75 @@ With the following ``dune`` file: .. code:: dune - (executable (name foo) (modes js) (js_of_ocaml (submodes wasm))) + (executable (name foo) (modes wasm)) And then request the ``.wasm.js`` target: .. code:: console - $ dune build ./foo.bc.wasm.js - $ node _build/default/foo.bc.wasm.js - hello from wasm + $ dune build ./foo.bc.wasm.js + $ node _build/default/foo.bc.wasm.js + hello from wasm + +If you're using the js_of_ocaml syntax extension, you must remember to add the +appropriate PPX in the ``preprocess`` field: + +.. code:: dune + + (executable + (name foo) + (modes wasm) + (preprocess (pps js_of_ocaml-ppx))) + +Selective Compilation +===================== + +The ``js`` and ``wasm`` modes can be selectively disabled using the ``(js_of_ocaml (enabled_if ...))`` and ``(wasm_of_ocaml (enabled_if ...))`` options. This allows for instance to generate one, or the other dependings on a profile: + +.. code:: dune + + (env + (js-only + (wasm_of_ocaml + (enabled_if false))) + (wasm-only + (js_of_ocaml + (enabled_if false)))) + +To be able to invoke the generated code using the same JavaScript script name in all cases, you can add a rule to copy the Wasm launcher script when the js_of_ocaml compilation is disabled. + +.. code:: dune + + (rule + (action + (copy foo.bc.wasm.js foo.bc.js)) + (enabled_if + (= %{profile} wasm-only))) + +Separate Compilation +==================== + +Dune supports two modes of compilation: + +- Direct compilation of a bytecode program to Wasm. This mode allows + wasm_of_ocaml to perform whole-program deadcode elimination and whole-program + inlining. + +- Separate compilation, where compilation units are compiled to Wasm + separately and then linked together. This mode is useful during development as + it builds more quickly. + +The separate compilation mode will be selected when the build profile +is ``dev``, which is the default. It can also be explicitly specified +in an ``env`` stanza (see :doc:`/reference/dune/env`) or per executable +inside ``(wasm_of_ocaml (compilation_mode ...))`` (see :doc:`/reference/dune/executable`) + +Sourcemap +========= + +Wasm_of_ocaml can generate sourcemaps for the generated Wasm code. +By default, they are generated when using the ``dev`` build profile and are not generated otherwise. +The behavior can explicitly be specified in an ``env`` stanza (see :doc:`/reference/dune/env`) +or per executable inside ``(wasm_of_ocaml (sourcemap ...))`` (see :doc:`/reference/dune/executable`) .. _wasm_of_ocaml: https://github.com/ocaml-wasm/wasm_of_ocaml From d31295f8b473469b10e212711144d0aea8e40ecf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Vouillon?= Date: Tue, 5 Nov 2024 13:53:42 +0100 Subject: [PATCH 19/26] Some clean-up MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Vouillon --- src/dune_rules/jsoo/js_of_ocaml.ml | 52 +++++++++++----------------- src/dune_rules/jsoo/js_of_ocaml.mli | 6 +--- src/dune_rules/jsoo/jsoo_rules.ml | 13 ++----- src/dune_rules/jsoo/jsoo_rules.mli | 2 -- src/dune_rules/lib_rules.ml | 4 +-- src/dune_rules/module_compilation.ml | 2 +- src/dune_rules/stanzas/buildable.ml | 2 +- 7 files changed, 29 insertions(+), 52 deletions(-) diff --git a/src/dune_rules/jsoo/js_of_ocaml.ml b/src/dune_rules/jsoo/js_of_ocaml.ml index 2c8c8e185f2..550b1028662 100644 --- a/src/dune_rules/jsoo/js_of_ocaml.ml +++ b/src/dune_rules/jsoo/js_of_ocaml.ml @@ -5,25 +5,6 @@ open Dune_lang.Decoder wasm_of_ocaml, since the compilation process is similar and generates a JavaScript file with basically the same behavior. *) -let field_oslu name = Ordered_set_lang.Unexpanded.field name - -module Sourcemap = struct - type t = - | No - | Inline - | File - - let decode = enum [ "no", No; "inline", Inline; "file", File ] - - let equal x y = - match x, y with - | No, No -> true - | Inline, Inline -> true - | File, File -> true - | No, _ | Inline, _ | File, _ -> false - ;; -end - module Mode = struct type t = | JS @@ -46,8 +27,7 @@ module Mode = struct ;; let decode = - let open Dune_sexp in - let open Decoder in + let open Dune_sexp.Decoder in sum [ "js", return JS; "wasm", return Wasm ] ;; @@ -58,7 +38,7 @@ module Mode = struct ;; let to_dyn t = Dyn.variant (to_string t) [] - let encode t = Dune_sexp.atom (to_string t) + let all = [ JS; Wasm ] module Pair = struct type 'a t = @@ -73,7 +53,6 @@ module Mode = struct ;; let make v = { js = v; wasm = v } - let init ~f = { js = f JS; wasm = f Wasm } let map ~f { js; wasm } = { js = f js; wasm = f wasm } let mapi ~f { js; wasm } = { js = f JS js; wasm = f Wasm wasm } @@ -86,16 +65,26 @@ module Mode = struct type t = bool Pair.t let inter = Pair.map2 ~f:( && ) - let union = Pair.map2 ~f:( || ) - let is_empty (x : t) = not (x.js || x.wasm) - - let to_list ({ js; wasm } : t) = - let l = if wasm then [ Wasm ] else [] in - if js then JS :: l else l - ;; end end +module Sourcemap = struct + type t = + | No + | Inline + | File + + let decode = enum [ "no", No; "inline", Inline; "file", File ] + + let equal x y = + match x, y with + | No, No -> true + | Inline, Inline -> true + | File, File -> true + | No, _ | Inline, _ | File, _ -> false + ;; +end + module Flags = struct type 'flags t = { build_runtime : 'flags @@ -110,6 +99,7 @@ module Flags = struct let build_runtime t = t.build_runtime let compile t = t.compile let link t = t.link + let field_oslu name = Ordered_set_lang.Unexpanded.field name let decode = let+ build_runtime = field_oslu "build_runtime_flags" @@ -332,7 +322,7 @@ module Env = struct { compilation_mode; sourcemap; runtest_alias; flags; enabled_if } ;; - let equal { compilation_mode; sourcemap; enabled_if; runtest_alias; flags } t = + let equal { compilation_mode; sourcemap; runtest_alias; flags; enabled_if } t = Option.equal Compilation_mode.equal compilation_mode t.compilation_mode && Option.equal Sourcemap.equal sourcemap t.sourcemap && Option.equal Alias.Name.equal runtest_alias t.runtest_alias diff --git a/src/dune_rules/jsoo/js_of_ocaml.mli b/src/dune_rules/jsoo/js_of_ocaml.mli index 429155fef4e..9889ccf1273 100644 --- a/src/dune_rules/jsoo/js_of_ocaml.mli +++ b/src/dune_rules/jsoo/js_of_ocaml.mli @@ -11,8 +11,8 @@ module Mode : sig val equal : t -> t -> bool val compare : t -> t -> Ordering.t val decode : t Dune_lang.Decoder.t - val encode : t Dune_lang.Encoder.t val to_dyn : t -> Dyn.t + val all : t list module Pair : sig type 'a t = @@ -22,7 +22,6 @@ module Mode : sig val select : mode:mode -> 'a t -> 'a val make : 'a -> 'a t - val init : f:(mode -> 'a) -> 'a t val map : f:('a -> 'b) -> 'a t -> 'b t val mapi : f:(mode -> 'a -> 'b) -> 'a t -> 'b t end @@ -31,9 +30,6 @@ module Mode : sig type t = bool Pair.t val inter : t -> t -> t - val union : t -> t -> t - val to_list : t -> mode list - val is_empty : t -> bool end end diff --git a/src/dune_rules/jsoo/jsoo_rules.ml b/src/dune_rules/jsoo/jsoo_rules.ml index c50b47edcc8..ce0d466d7c2 100644 --- a/src/dune_rules/jsoo/jsoo_rules.ml +++ b/src/dune_rules/jsoo/jsoo_rules.ml @@ -492,8 +492,6 @@ let build_cm' sctx ~dir ~in_context ~mode ~src ~target ~config ~sourcemap = ~sourcemap ;; -let iter_jsoo_modes ~f = Memo.parallel_iter [ Js_of_ocaml.Mode.JS; Wasm ] ~f - let build_cm sctx ~dir ~in_context ~mode ~src ~obj_dir ~config = let name = with_js_ext ~mode (Path.basename src) in let target = in_obj_dir ~obj_dir ~config [ name ] in @@ -535,7 +533,7 @@ let setup_separate_compilation_rules sctx components = archive "stdlib.cma" :: archive "std_exit.cmo" :: archives | _ -> archives in - iter_jsoo_modes ~f:(fun mode -> + Memo.parallel_iter Js_of_ocaml.Mode.all ~f:(fun mode -> Memo.parallel_iter archives ~f:(fun fn -> let build_context = Context.build_context ctx in let name = Path.basename fn in @@ -635,13 +633,8 @@ let build_exe = let sctx = Compilation_context.super_context cc in let dir = Compilation_context.dir cc in - let { Js_of_ocaml.In_context.javascript_files - ; wasm_files - ; flags - ; compilation_mode - ; sourcemap - ; _ - } + let { javascript_files; wasm_files; flags; compilation_mode; sourcemap; _ } + : Js_of_ocaml.In_context.t = in_context in diff --git a/src/dune_rules/jsoo/jsoo_rules.mli b/src/dune_rules/jsoo/jsoo_rules.mli index ec9a0365525..df7e768e62f 100644 --- a/src/dune_rules/jsoo/jsoo_rules.mli +++ b/src/dune_rules/jsoo/jsoo_rules.mli @@ -69,8 +69,6 @@ val jsoo_is_whole_program -> dir:Path.Build.t -> Js_of_ocaml.Mode.Set.t Memo.t -val iter_jsoo_modes : f:(Js_of_ocaml.Mode.t -> unit Memo.t) -> unit Memo.t - val js_of_ocaml_compilation_mode : Super_context.t -> dir:Path.Build.t diff --git a/src/dune_rules/lib_rules.ml b/src/dune_rules/lib_rules.ml index 140e40359e7..5919ad64359 100644 --- a/src/dune_rules/lib_rules.ml +++ b/src/dune_rules/lib_rules.ml @@ -474,7 +474,7 @@ let setup_build_archives (lib : Library.t) ~top_sorted_modules ~cctx ~expander ~ (* Build *.cma.js / *.wasma *) Memo.when_ modes.ocaml.byte (fun () -> let src = Library.archive lib ~dir ~ext:(Mode.compiled_lib_ext Mode.Byte) in - Jsoo_rules.iter_jsoo_modes ~f:(fun mode -> + Memo.parallel_iter Js_of_ocaml.Mode.all ~f:(fun mode -> let action_with_targets = List.map Jsoo_rules.Config.all ~f:(fun config -> Jsoo_rules.build_cm @@ -542,7 +542,7 @@ let cctx (lib : Library.t) ~sctx ~source_modules ~dir ~expander ~scope ~compile_ ~requires_link ~preprocessing:pp ~opaque:Inherit_from_settings - ~js_of_ocaml:(Js_of_ocaml.Mode.Pair.map ~f:(fun x -> Some x) js_of_ocaml) + ~js_of_ocaml:(Js_of_ocaml.Mode.Pair.map ~f:Option.some js_of_ocaml) ?stdlib:lib.stdlib ~package ?vimpl diff --git a/src/dune_rules/module_compilation.ml b/src/dune_rules/module_compilation.ml index f9a1fa26e40..3b469b24ae5 100644 --- a/src/dune_rules/module_compilation.ml +++ b/src/dune_rules/module_compilation.ml @@ -311,7 +311,7 @@ let build_module ?(force_write_cmi = false) ?(precompiled_cmi = false) cctx m = match Obj_dir.Module.cm_file obj_dir m ~kind:(Ocaml Cmo) with | None -> Memo.return () | Some src -> - Jsoo_rules.iter_jsoo_modes ~f:(fun mode -> + Memo.parallel_iter Js_of_ocaml.Mode.all ~f:(fun mode -> Compilation_context.js_of_ocaml cctx |> Js_of_ocaml.Mode.Pair.select ~mode |> Memo.Option.iter ~f:(fun in_context -> diff --git a/src/dune_rules/stanzas/buildable.ml b/src/dune_rules/stanzas/buildable.ml index a874578fed7..39d401ece93 100644 --- a/src/dune_rules/stanzas/buildable.ml +++ b/src/dune_rules/stanzas/buildable.ml @@ -182,7 +182,7 @@ let decode (for_ : for_) = ; extra_objects ; libraries ; flags - ; js_of_ocaml = { Js_of_ocaml.Mode.Pair.js = js_of_ocaml; wasm = wasm_of_ocaml } + ; js_of_ocaml = { js = js_of_ocaml; wasm = wasm_of_ocaml } ; allow_overlapping_dependencies ; ctypes } From be2bd4ac897eafe008e31a76342d595478aafaa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Vouillon?= Date: Tue, 5 Nov 2024 16:32:00 +0100 Subject: [PATCH 20/26] CR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Vouillon --- src/dune_rules/jsoo/js_of_ocaml.ml | 27 ++++++++++++--------------- src/dune_rules/jsoo/js_of_ocaml.mli | 2 +- src/dune_rules/jsoo/jsoo_rules.ml | 11 +---------- src/dune_rules/stanzas/buildable.ml | 28 +++++++--------------------- 4 files changed, 21 insertions(+), 47 deletions(-) diff --git a/src/dune_rules/jsoo/js_of_ocaml.ml b/src/dune_rules/jsoo/js_of_ocaml.ml index 550b1028662..2019498688f 100644 --- a/src/dune_rules/jsoo/js_of_ocaml.ml +++ b/src/dune_rules/jsoo/js_of_ocaml.ml @@ -188,7 +188,7 @@ module In_buildable = struct ; sourcemap : Sourcemap.t option } - let decode ~executable ~mode = + let decode ~in_library ~mode = let* syntax_version = Dune_lang.Syntax.get_exn Stanza.syntax in if syntax_version < (3, 0) then @@ -206,7 +206,8 @@ module In_buildable = struct ; compilation_mode = None ; sourcemap = None }) - else + else ( + let only_in_library decode = if in_library then decode else return None in fields (let+ flags = Flags.decode and+ enabled_if = @@ -223,21 +224,17 @@ module In_buildable = struct (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> repeat string) ~default:[] and+ compilation_mode = - if executable - then - field_o - "compilation_mode" - (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> Compilation_mode.decode) - else return None + only_in_library + (field_o + "compilation_mode" + (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> Compilation_mode.decode)) and+ sourcemap = - if executable - then - field_o - "sourcemap" - (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> Sourcemap.decode) - else return None + only_in_library + (field_o + "sourcemap" + (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> Sourcemap.decode)) in - { flags; enabled_if; javascript_files; wasm_files; compilation_mode; sourcemap }) + { flags; enabled_if; javascript_files; wasm_files; compilation_mode; sourcemap })) ;; let default = diff --git a/src/dune_rules/jsoo/js_of_ocaml.mli b/src/dune_rules/jsoo/js_of_ocaml.mli index 9889ccf1273..2201ecee6c3 100644 --- a/src/dune_rules/jsoo/js_of_ocaml.mli +++ b/src/dune_rules/jsoo/js_of_ocaml.mli @@ -88,7 +88,7 @@ module In_buildable : sig ; sourcemap : Sourcemap.t option } - val decode : executable:bool -> mode:Mode.t -> t Dune_lang.Decoder.t + val decode : in_library:bool -> mode:Mode.t -> t Dune_lang.Decoder.t val default : t end diff --git a/src/dune_rules/jsoo/jsoo_rules.ml b/src/dune_rules/jsoo/jsoo_rules.ml index ce0d466d7c2..79399ac1bdf 100644 --- a/src/dune_rules/jsoo/jsoo_rules.ml +++ b/src/dune_rules/jsoo/jsoo_rules.ml @@ -538,15 +538,6 @@ let setup_separate_compilation_rules sctx components = let build_context = Context.build_context ctx in let name = Path.basename fn in let dir = in_build_dir build_context ~config [ lib_name ] in - let in_context = - { Js_of_ocaml.In_context.flags = Js_of_ocaml.Flags.standard - ; enabled_if = Some Blang.true_ - ; javascript_files = [] - ; wasm_files = [] - ; compilation_mode = None - ; sourcemap = None - } - in let src = let src_dir = Lib_info.src_dir info in Path.relative src_dir name @@ -557,7 +548,7 @@ let setup_separate_compilation_rules sctx components = build_cm' sctx ~dir - ~in_context + ~in_context:Js_of_ocaml.In_context.default ~mode ~src ~target diff --git a/src/dune_rules/stanzas/buildable.ml b/src/dune_rules/stanzas/buildable.ml index 39d401ece93..5b6a3ca86ff 100644 --- a/src/dune_rules/stanzas/buildable.ml +++ b/src/dune_rules/stanzas/buildable.ml @@ -29,11 +29,12 @@ let decode (for_ : for_) = (2, 0) ~extra_info:"Use the (foreign_stubs ...) field instead." in - let only_in_library decode = + let in_library = match for_ with - | Executable -> return None - | Library _ -> decode + | Library _ -> true + | Executable -> false in + let only_in_library decode = if in_library then decode else return None in let add_stubs language ~loc ~names ~flags foreign_stubs = match names with | None -> foreign_stubs @@ -84,33 +85,18 @@ let decode (for_ : for_) = ~extra_info:"Use the (foreign_archives ...) field instead." >>> enter (maybe string)))) and+ libraries = - let allow_re_export = - match for_ with - | Library _ -> true - | Executable -> false - in - field "libraries" (Lib_dep.L.decode ~allow_re_export) ~default:[] + field "libraries" (Lib_dep.L.decode ~allow_re_export:in_library) ~default:[] and+ flags = Ocaml_flags.Spec.decode and+ js_of_ocaml = - let executable = - match for_ with - | Executable -> true - | Library _ -> false - in field "js_of_ocaml" - (Js_of_ocaml.In_buildable.decode ~executable ~mode:JS) + (Js_of_ocaml.In_buildable.decode ~in_library ~mode:JS) ~default:Js_of_ocaml.In_buildable.default and+ wasm_of_ocaml = - let executable = - match for_ with - | Executable -> true - | Library _ -> false - in field "wasm_of_ocaml" (Dune_lang.Syntax.since Stanza.syntax (3, 17) - >>> Js_of_ocaml.In_buildable.decode ~executable ~mode:Wasm) + >>> Js_of_ocaml.In_buildable.decode ~in_library ~mode:Wasm) ~default:Js_of_ocaml.In_buildable.default and+ allow_overlapping_dependencies = field_b "allow_overlapping_dependencies" and+ version = Dune_lang.Syntax.get_exn Stanza.syntax From 17e954af9c1ddea830d53d04e9453d36e145371f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Vouillon?= Date: Tue, 5 Nov 2024 16:49:28 +0100 Subject: [PATCH 21/26] CR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Vouillon --- src/dune_rules/jsoo/js_of_ocaml.ml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dune_rules/jsoo/js_of_ocaml.ml b/src/dune_rules/jsoo/js_of_ocaml.ml index 2019498688f..40b21d5eb53 100644 --- a/src/dune_rules/jsoo/js_of_ocaml.ml +++ b/src/dune_rules/jsoo/js_of_ocaml.ml @@ -207,7 +207,7 @@ module In_buildable = struct ; sourcemap = None }) else ( - let only_in_library decode = if in_library then decode else return None in + let only_in_executable decode = if in_library then return None else decode in fields (let+ flags = Flags.decode and+ enabled_if = @@ -224,12 +224,12 @@ module In_buildable = struct (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> repeat string) ~default:[] and+ compilation_mode = - only_in_library + only_in_executable (field_o "compilation_mode" (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> Compilation_mode.decode)) and+ sourcemap = - only_in_library + only_in_executable (field_o "sourcemap" (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> Sourcemap.decode)) From aea189c207efbd6be7bb9181ad3e80986158405b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Vouillon?= Date: Tue, 5 Nov 2024 16:14:04 +0100 Subject: [PATCH 22/26] Disallow `(wasm_of_ocaml (sourcemap file))` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Vouillon --- doc/reference/dune/executable.rst | 2 +- src/dune_rules/dune_env.ml | 4 ++-- src/dune_rules/jsoo/js_of_ocaml.ml | 12 ++++++++---- src/dune_rules/jsoo/js_of_ocaml.mli | 2 +- src/dune_rules/jsoo/jsoo_rules.ml | 14 ++++++++------ 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/doc/reference/dune/executable.rst b/doc/reference/dune/executable.rst index 39111b27429..9fad1969f56 100644 --- a/doc/reference/dune/executable.rst +++ b/doc/reference/dune/executable.rst @@ -297,7 +297,7 @@ options using ``(wasm_of_ocaml ())``. - ``(wasm_files ())`` to specify ``wasm_of_ocaml`` Wasm runtime files. -For the ``(sourcemap )`` option, source maps are generated when ``>`` is either ``file`` or ``inline``. They are put within the ``.bc.wasm.assets`` directory in both cases. +For the ``(sourcemap )`` option, ```` must be one of ``no`` or ``inline``. Source maps are put within the ``.bc.wasm.assets`` directory. The default values for ``flags``, ``compilation_mode`` and ``sourcemap`` depend on the selected build profile. The build profile ``dev`` (the default) will enable sourcemaps, separate compilation and pretty Wasm output. diff --git a/src/dune_rules/dune_env.ml b/src/dune_rules/dune_env.ml index 7411f9b2d68..b0aeffb4808 100644 --- a/src/dune_rules/dune_env.ml +++ b/src/dune_rules/dune_env.ml @@ -225,14 +225,14 @@ let js_of_ocaml_field = field "js_of_ocaml" ~default:Js_of_ocaml.Env.empty - (Dune_lang.Syntax.since Stanza.syntax (3, 0) >>> Js_of_ocaml.Env.decode) + (Dune_lang.Syntax.since Stanza.syntax (3, 0) >>> Js_of_ocaml.Env.decode ~mode:JS) ;; let wasm_of_ocaml_field = field "wasm_of_ocaml" ~default:Js_of_ocaml.Env.empty - (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> Js_of_ocaml.Env.decode) + (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> Js_of_ocaml.Env.decode ~mode:Wasm) ;; let bin_annot = field_o "bin_annot" (Dune_lang.Syntax.since Stanza.syntax (3, 8) >>> bool) diff --git a/src/dune_rules/jsoo/js_of_ocaml.ml b/src/dune_rules/jsoo/js_of_ocaml.ml index 40b21d5eb53..9411c647efc 100644 --- a/src/dune_rules/jsoo/js_of_ocaml.ml +++ b/src/dune_rules/jsoo/js_of_ocaml.ml @@ -74,7 +74,11 @@ module Sourcemap = struct | Inline | File - let decode = enum [ "no", No; "inline", Inline; "file", File ] + let decode ~mode = + match (mode : Mode.t) with + | JS -> enum [ "no", No; "inline", Inline; "file", File ] + | Wasm -> enum [ "no", No; "inline", Inline ] + ;; let equal x y = match x, y with @@ -232,7 +236,7 @@ module In_buildable = struct only_in_executable (field_o "sourcemap" - (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> Sourcemap.decode)) + (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> Sourcemap.decode ~mode)) in { flags; enabled_if; javascript_files; wasm_files; compilation_mode; sourcemap })) ;; @@ -301,13 +305,13 @@ module Env = struct ; enabled_if : Blang.t option } - let decode = + let decode ~mode = fields @@ let+ compilation_mode = field_o "compilation_mode" Compilation_mode.decode and+ sourcemap = field_o "sourcemap" - (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> Sourcemap.decode) + (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> Sourcemap.decode ~mode) and+ runtest_alias = field_o "runtest_alias" Dune_lang.Alias.decode and+ flags = Flags.decode and+ enabled_if = diff --git a/src/dune_rules/jsoo/js_of_ocaml.mli b/src/dune_rules/jsoo/js_of_ocaml.mli index 2201ecee6c3..82e590835fa 100644 --- a/src/dune_rules/jsoo/js_of_ocaml.mli +++ b/src/dune_rules/jsoo/js_of_ocaml.mli @@ -127,7 +127,7 @@ module Env : sig val map : f:('a -> 'b) -> 'a t -> 'b t val equal : Ordered_set_lang.Unexpanded.t t -> Ordered_set_lang.Unexpanded.t t -> bool - val decode : Ordered_set_lang.Unexpanded.t t Dune_lang.Decoder.t + val decode : mode:Mode.t -> Ordered_set_lang.Unexpanded.t t Dune_lang.Decoder.t val default : profile:Profile.t -> string list t val empty : Ordered_set_lang.Unexpanded.t t end diff --git a/src/dune_rules/jsoo/jsoo_rules.ml b/src/dune_rules/jsoo/jsoo_rules.ml index 79399ac1bdf..c20e4d77667 100644 --- a/src/dune_rules/jsoo/jsoo_rules.ml +++ b/src/dune_rules/jsoo/jsoo_rules.ml @@ -259,12 +259,14 @@ let js_of_ocaml_rule | Compile -> S [] | Link -> A "link" | Build_runtime -> A "build-runtime") - ; (match (sourcemap : Js_of_ocaml.Sourcemap.t), mode with - | No, _ -> A "--no-source-map" - | Inline, _ | File, Wasm -> - (* With wasm_of_ocaml, source maps are always inline *) - A "--source-map-inline" - | File, JS -> + ; (match (sourcemap : Js_of_ocaml.Sourcemap.t) with + | No -> A "--no-source-map" + | Inline -> A "--source-map-inline" + | File -> + assert ( + match mode with + | JS -> true + | Wasm -> false); S [ A "--source-map" ; Hidden_targets [ Path.Build.set_extension target ~ext:".map" ] From 2c0c5f658457cea0b3002b133c282c233671607d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Vouillon?= Date: Tue, 5 Nov 2024 17:51:17 +0100 Subject: [PATCH 23/26] Clean-up MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Vouillon --- src/dune_rules/dir_status.ml | 29 ++++++++++++-------------- src/dune_rules/exe_rules.ml | 6 +++--- src/dune_rules/gen_rules.ml | 8 +++---- src/dune_rules/jsoo/js_of_ocaml.ml | 30 +++++++-------------------- src/dune_rules/jsoo/js_of_ocaml.mli | 2 +- src/dune_rules/jsoo/jsoo_rules.ml | 16 ++++++-------- src/dune_rules/stanzas/executables.ml | 10 +++------ src/dune_rules/test_rules.ml | 4 +--- 8 files changed, 38 insertions(+), 67 deletions(-) diff --git a/src/dune_rules/dir_status.ml b/src/dune_rules/dir_status.ml index eaa1136042c..de7f19f1303 100644 --- a/src/dune_rules/dir_status.ml +++ b/src/dune_rules/dir_status.ml @@ -149,16 +149,17 @@ let directory_targets_of_executables { Executables.names; modes; enabled_if; buildable; _ } = let* directory_targets = - (* CR-someday rgrinberg: we don't necessarily need to evalute - [wasm_enabled] here *) - let+ wasm_enabled = jsoo_wasm_enabled ~jsoo_enabled ~dir ~buildable in - match Executables.Link_mode.(Map.mem modes wasm) && wasm_enabled with - | false -> Path.Build.Map.empty + match Executables.Link_mode.(Map.mem modes wasm) with + | false -> Memo.return Path.Build.Map.empty | true -> - Nonempty_list.to_list names - |> List.fold_left ~init:Path.Build.Map.empty ~f:(fun acc (_, name) -> - let dir_target = Path.Build.relative dir (name ^ Js_of_ocaml.Ext.wasm_dir) in - Path.Build.Map.set acc dir_target buildable.loc) + jsoo_wasm_enabled ~jsoo_enabled ~dir ~buildable + >>| (function + | false -> Path.Build.Map.empty + | true -> + Nonempty_list.to_list names + |> List.fold_left ~init:Path.Build.Map.empty ~f:(fun acc (_, name) -> + let dir_target = Path.Build.relative dir (name ^ Js_of_ocaml.Ext.wasm_dir) in + Path.Build.Map.set acc dir_target buildable.loc)) in when_enabled ~dir ~enabled_if directory_targets ;; @@ -177,14 +178,10 @@ let directory_targets_of_library | false -> Path.Build.Map.empty | true -> let dir_target = - let lib_name = snd name in - let name = - sprintf "inline_test_runner_%s" (Lib_name.Local.to_string lib_name) - in + let lib_name = Lib_name.Local.to_string (snd name) in + let name = sprintf "inline_test_runner_%s" lib_name in let inline_test_dir = - let inline_test_name = - sprintf "%s.inline-tests" (Lib_name.Local.to_string lib_name) - in + let inline_test_name = sprintf "%s.inline-tests" lib_name in Path.Build.relative dir ("." ^ inline_test_name) in Path.Build.relative inline_test_dir (name ^ Js_of_ocaml.Ext.wasm_dir) diff --git a/src/dune_rules/exe_rules.ml b/src/dune_rules/exe_rules.ml index f61ee3789c7..379f69ce84d 100644 --- a/src/dune_rules/exe_rules.ml +++ b/src/dune_rules/exe_rules.ml @@ -159,10 +159,10 @@ let executables_rules let explicit_js_mode = Dune_project.explicit_js_mode project in let js_of_ocaml = Js_of_ocaml.In_context.make ~dir exes.buildable.js_of_ocaml in let* linkages = - let* jsoo_enabled_modes = + let+ jsoo_enabled_modes = Jsoo_rules.jsoo_enabled_modes ~expander ~dir ~in_context:js_of_ocaml - and* jsoo_is_whole_program = Jsoo_rules.jsoo_is_whole_program sctx ~dir in - let+ dynamically_linked_foreign_archives = + and+ jsoo_is_whole_program = Jsoo_rules.jsoo_is_whole_program sctx ~dir + and+ dynamically_linked_foreign_archives = Context.dynamically_linked_foreign_archives ctx in linkages diff --git a/src/dune_rules/gen_rules.ml b/src/dune_rules/gen_rules.ml index 47bc054b2c7..0c98ce1287e 100644 --- a/src/dune_rules/gen_rules.ml +++ b/src/dune_rules/gen_rules.ml @@ -136,11 +136,9 @@ end = struct { (with_cctx_merlin ~loc:exes.buildable.loc cctx_merlin) with js = Some - (List.map (Nonempty_list.to_list exes.names) ~f:(fun (_, exe) -> - [ Path.Build.relative dir (exe ^ Js_of_ocaml.Ext.exe ~mode:JS) - ; Path.Build.relative dir (exe ^ Js_of_ocaml.Ext.exe ~mode:Wasm) - ]) - |> List.flatten) + (List.concat_map (Nonempty_list.to_list exes.names) ~f:(fun (_, exe) -> + List.map Js_of_ocaml.Mode.all ~f:(fun mode -> + Path.Build.relative dir (exe ^ Js_of_ocaml.Ext.exe ~mode)))) }) | Alias_conf.T alias -> let+ () = Simple_rules.alias sctx alias ~dir ~expander in diff --git a/src/dune_rules/jsoo/js_of_ocaml.ml b/src/dune_rules/jsoo/js_of_ocaml.ml index 9411c647efc..c8f74dd59dd 100644 --- a/src/dune_rules/jsoo/js_of_ocaml.ml +++ b/src/dune_rules/jsoo/js_of_ocaml.ml @@ -12,7 +12,7 @@ module Mode = struct let equal (a : t) b = Poly.equal a b - let select ~mode js wasm = + let select ~mode ~js ~wasm = match mode with | JS -> js | Wasm -> wasm @@ -31,12 +31,7 @@ module Mode = struct sum [ "js", return JS; "wasm", return Wasm ] ;; - let to_string s = - match s with - | JS -> "js" - | Wasm -> "wasm" - ;; - + let to_string mode = select ~mode ~js:"js" ~wasm:"wasm" let to_dyn t = Dyn.variant (to_string t) [] let all = [ JS; Wasm ] @@ -46,12 +41,7 @@ module Mode = struct ; wasm : 'a } - let select ~mode { js; wasm } = - match mode with - | JS -> js - | Wasm -> wasm - ;; - + let select ~mode { js; wasm } = select ~mode ~js ~wasm let make v = { js = v; wasm = v } let map ~f { js; wasm } = { js = f js; wasm = f wasm } let mapi ~f { js; wasm } = { js = f JS js; wasm = f Wasm wasm } @@ -152,11 +142,7 @@ module Flags = struct let+ build_runtime = t.build_runtime and+ compile = t.compile and+ link = t.link in - let prefix = - match (mode : Mode.t) with - | JS -> "js" - | Wasm -> "wasm" - in + let prefix = Mode.to_string mode in List.map ~f:Dune_lang.Encoder.(pair string (list string)) [ prefix ^ "_of_ocaml_flags", compile @@ -289,10 +275,10 @@ end module Ext = struct type t = string - let exe ~mode = Mode.select ~mode ".bc.js" ".bc.wasm.js" - let cmo ~mode = Mode.select ~mode ".cmo.js" ".wasmo" - let cma ~mode = Mode.select ~mode ".cma.js" ".wasma" - let runtime ~mode = Mode.select ~mode ".bc.runtime.js" ".bc.runtime.wasma" + let exe ~mode = Mode.select ~mode ~js:".bc.js" ~wasm:".bc.wasm.js" + let cmo ~mode = Mode.select ~mode ~js:".cmo.js" ~wasm:".wasmo" + let cma ~mode = Mode.select ~mode ~js:".cma.js" ~wasm:".wasma" + let runtime ~mode = Mode.select ~mode ~js:".bc.runtime.js" ~wasm:".bc.runtime.wasma" let wasm_dir = ".bc.wasm.assets" end diff --git a/src/dune_rules/jsoo/js_of_ocaml.mli b/src/dune_rules/jsoo/js_of_ocaml.mli index 82e590835fa..4b0a5e77a9c 100644 --- a/src/dune_rules/jsoo/js_of_ocaml.mli +++ b/src/dune_rules/jsoo/js_of_ocaml.mli @@ -7,7 +7,7 @@ module Mode : sig type mode := t - val select : mode:t -> 'a -> 'a -> 'a + val select : mode:t -> js:'a -> wasm:'a -> 'a val equal : t -> t -> bool val compare : t -> t -> Ordering.t val decode : t Dune_lang.Decoder.t diff --git a/src/dune_rules/jsoo/jsoo_rules.ml b/src/dune_rules/jsoo/jsoo_rules.ml index c20e4d77667..7ad41a6dddb 100644 --- a/src/dune_rules/jsoo/jsoo_rules.ml +++ b/src/dune_rules/jsoo/jsoo_rules.ml @@ -9,7 +9,9 @@ let compute_env ~mode = let+ profile = Per_context.profile ctx in Js_of_ocaml.Env.(map ~f:Action_builder.return (default ~profile))) ~f:(fun ~parent expander (local : Dune_env.config) -> - let local = Js_of_ocaml.Mode.select ~mode local.js_of_ocaml local.wasm_of_ocaml in + let local = + Js_of_ocaml.Mode.select ~mode ~js:local.js_of_ocaml ~wasm:local.wasm_of_ocaml + in let* parent = parent in let+ enabled_if = match Option.first_some local.enabled_if parent.enabled_if with @@ -37,7 +39,7 @@ let compute_env ~mode = let js_env = compute_env ~mode:JS let wasm_env = compute_env ~mode:Wasm -let jsoo_env ~dir ~mode = (Js_of_ocaml.Mode.select ~mode js_env wasm_env) ~dir +let jsoo_env ~dir ~mode = (Js_of_ocaml.Mode.select ~mode ~js:js_env ~wasm:wasm_env) ~dir module Config : sig type t @@ -263,10 +265,7 @@ let js_of_ocaml_rule | No -> A "--no-source-map" | Inline -> A "--source-map-inline" | File -> - assert ( - match mode with - | JS -> true - | Wasm -> false); + assert (Js_of_ocaml.Mode.select ~mode ~js:true ~wasm:false); S [ A "--source-map" ; Hidden_targets [ Path.Build.set_extension target ~ext:".map" ] @@ -654,10 +653,7 @@ let build_exe | None -> js_of_ocaml_sourcemap sctx ~dir ~mode | Some x -> Memo.return x in - assert ( - match mode with - | JS -> wasm_files = [] - | Wasm -> true); + assert (Js_of_ocaml.Mode.select ~mode ~js:(wasm_files = []) ~wasm:true); let runtime_files = javascript_files @ wasm_files in let directory_targets = match mode with diff --git a/src/dune_rules/stanzas/executables.ml b/src/dune_rules/stanzas/executables.ml index 7426073735f..2fb025d2488 100644 --- a/src/dune_rules/stanzas/executables.ml +++ b/src/dune_rules/stanzas/executables.ml @@ -299,17 +299,18 @@ module Link_mode = struct let to_dyn t = match t with | Byte_complete -> Dyn.Variant ("Byte_complete", []) + | Jsoo mode -> Dyn.Variant ("Jsoo", [ Js_of_ocaml.Mode.to_dyn mode ]) | Other { mode; kind } -> let open Dyn in Variant ( "Other" , [ record [ "mode", Mode_conf.to_dyn mode; "kind", Binary_kind.to_dyn kind ] ] ) - | Jsoo mode -> Dyn.Variant ("Jsoo", [ Js_of_ocaml.Mode.to_dyn mode ]) ;; let extension t ~loc ~ext_obj ~ext_dll = match t with | Byte_complete -> ".bc.exe" + | Jsoo mode -> Js_of_ocaml.Ext.exe ~mode | Other { mode; kind } -> let same_as_mode : Mode.t = match mode with @@ -330,10 +331,6 @@ module Link_mode = struct | Byte, Shared_object -> ".bc" ^ ext_dll | Native, Shared_object -> ext_dll | mode, Plugin -> Mode.plugin_ext mode) - | Jsoo kind -> - (match kind with - | JS -> Js_of_ocaml.Ext.exe ~mode:JS - | Wasm -> Js_of_ocaml.Ext.exe ~mode:Wasm) ;; module O = Comparable.Make (T) @@ -518,10 +515,9 @@ let common = let ext = match mode with | Byte_complete -> ".bc.exe" + | Jsoo mode -> Js_of_ocaml.Ext.exe ~mode | Other { mode = Byte; _ } -> ".bc" | Other { mode = Native | Best; _ } -> ".exe" - | Jsoo JS -> Js_of_ocaml.Ext.exe ~mode:JS - | Jsoo Wasm -> Js_of_ocaml.Ext.exe ~mode:Wasm in Names.install_conf names ~ext ~enabled_if ~dir:project_root in diff --git a/src/dune_rules/test_rules.ml b/src/dune_rules/test_rules.ml index 909ccb2a9d7..d1a5e1ceac9 100644 --- a/src/dune_rules/test_rules.ml +++ b/src/dune_rules/test_rules.ml @@ -48,9 +48,7 @@ let runtest_modes modes jsoo_enabled_modes project = (* We don't know how to run tests in these cases *) None | Jsoo mode -> - if Js_of_ocaml.Mode.Pair.select ~mode jsoo_enabled_modes - then Some (`js mode) - else None) + Option.some_if (Js_of_ocaml.Mode.Pair.select ~mode jsoo_enabled_modes) (`js mode)) |> List.sort_uniq ~compare:Poly.compare ;; From a4bc007a3d58a5d70e5d83e89f222f9d5450ff1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Vouillon?= Date: Tue, 5 Nov 2024 18:00:00 +0100 Subject: [PATCH 24/26] enabled_if not allowed in libraries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Vouillon --- src/dune_rules/jsoo/js_of_ocaml.ml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/dune_rules/jsoo/js_of_ocaml.ml b/src/dune_rules/jsoo/js_of_ocaml.ml index c8f74dd59dd..8ce2b5946f8 100644 --- a/src/dune_rules/jsoo/js_of_ocaml.ml +++ b/src/dune_rules/jsoo/js_of_ocaml.ml @@ -201,9 +201,10 @@ module In_buildable = struct fields (let+ flags = Flags.decode and+ enabled_if = - field_o - "enabled_if" - (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> Blang.decode) + only_in_executable + (field_o + "enabled_if" + (Dune_lang.Syntax.since Stanza.syntax (3, 17) >>> Blang.decode)) and+ javascript_files = field "javascript_files" (repeat string) ~default:[] and+ wasm_files = match (mode : Mode.t) with From f76b05ebfc81bae938cadc318b350766dfa2b996 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Vouillon?= Date: Tue, 5 Nov 2024 18:04:22 +0100 Subject: [PATCH 25/26] Doc: how to install wasm_of_ocaml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Vouillon --- doc/wasmoo.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/wasmoo.rst b/doc/wasmoo.rst index 3be8a4fe8cd..31380d69276 100644 --- a/doc/wasmoo.rst +++ b/doc/wasmoo.rst @@ -10,7 +10,7 @@ Wasm Compilation With Wasm_of_ocaml Wasm_of_ocaml_ is a compiler from OCaml to WebAssembly (Wasm for short). The compiler works by translating OCaml bytecode to Wasm code. - +The compiler can currently be installed from [its Github repository](https://github.com/ocaml-wasm/wasm_of_ocaml). Compiling to Wasm ================= From 906b5e09138d5a3f9b0433784081b7a6b2aeba0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Vouillon?= Date: Tue, 5 Nov 2024 20:11:42 +0100 Subject: [PATCH 26/26] CR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Vouillon --- .github/workflows/workflow.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index b1e1ef0be24..f81fb6d9ad8 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -246,9 +246,6 @@ jobs: uses: ocaml/setup-ocaml@v3 with: ocaml-compiler: 4.14.x - opam-pin: false - opam-depext: false - dune-cache: true - name: Update Dune working-directory: ./dune