Skip to content

Commit 89f175d

Browse files
committed
Wasm_of_ocaml: make it possible to disable effects with --effects disabled
There can be a significant cost to call a JavaScript function from Wasm due to stack switching when JSPI is enabled (which will happen with node 25).
1 parent ea538fb commit 89f175d

File tree

7 files changed

+53
-26
lines changed

7 files changed

+53
-26
lines changed

compiler/bin-js_of_ocaml/cmd_arg.ml

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,16 @@ let trim_trailing_dir_sep s =
3939

4040
let normalize_include_dirs dirs = List.map dirs ~f:trim_trailing_dir_sep
4141

42-
let normalize_effects (effects : [ `Cps | `Double_translation ] option) common :
43-
Config.effects_backend =
42+
let normalize_effects (effects : [ `Disabled | `Cps | `Double_translation ] option) common
43+
: Config.effects_backend =
4444
match effects with
4545
| None ->
4646
(* For backward compatibility, consider that [--enable effects] alone means
4747
[--effects cps] *)
4848
if List.mem ~eq:String.equal "effects" common.Jsoo_cmdline.Arg.optim.enable
4949
then `Cps
5050
else `Disabled
51-
| Some ((`Cps | `Double_translation) as e) -> (e :> Config.effects_backend)
51+
| Some ((`Disabled | `Cps | `Double_translation) as e) -> e
5252

5353
type t =
5454
{ common : Jsoo_cmdline.Arg.t
@@ -273,12 +273,20 @@ let options =
273273
in
274274
let effects =
275275
let doc =
276-
"Select an implementation of effect handlers. [$(docv)] should be one of $(b,cps) \
277-
or $(b,double-translation). Effects won't be supported if unspecified."
276+
"Select an implementation of effect handlers. [$(docv)] should be one of $(b,cps), \
277+
$(b,double-translation) or $(b,disabled) (the default). Effects won't be \
278+
supported if unspecified."
278279
in
279280
Arg.(
280281
value
281-
& opt (some (enum [ "cps", `Cps; "double-translation", `Double_translation ])) None
282+
& opt
283+
(some
284+
(enum
285+
[ "cps", `Cps
286+
; "double-translation", `Double_translation
287+
; "disabled", `Disabled
288+
]))
289+
None
282290
& info [ "effects" ] ~docv:"KIND" ~doc)
283291
in
284292
let build_t
@@ -543,12 +551,20 @@ let options_runtime_only =
543551
in
544552
let effects =
545553
let doc =
546-
"Select an implementation of effect handlers. [$(docv)] should be one of $(b,cps) \
547-
or $(b,double-translation). Effects won't be supported if unspecified."
554+
"Select an implementation of effect handlers. [$(docv)] should be one of $(b,cps), \
555+
$(b,double-translation), or $(b,disabled) (the default). Effects won't be \
556+
supported if unspecified."
548557
in
549558
Arg.(
550559
value
551-
& opt (some (enum [ "cps", `Cps; "double-translation", `Double_translation ])) None
560+
& opt
561+
(some
562+
(enum
563+
[ "cps", `Cps
564+
; "double-translation", `Double_translation
565+
; "disabled", `Disabled
566+
]))
567+
None
552568
& info [ "effects" ] ~docv:"KIND" ~doc)
553569
in
554570
let build_t

compiler/bin-wasm_of_ocaml/cmd_arg.ml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,16 @@ let trim_trailing_dir_sep s =
3838

3939
let normalize_include_dirs dirs = List.map dirs ~f:trim_trailing_dir_sep
4040

41-
let normalize_effects (effects : [ `Cps | `Jspi ] option) common : Config.effects_backend
42-
=
41+
let normalize_effects (effects : [ `Disabled | `Cps | `Jspi ] option) common :
42+
Config.effects_backend =
4343
match effects with
4444
| None ->
4545
(* For backward compatibility, consider that [--enable effects] alone means
4646
[--effects cps] *)
4747
if List.mem ~eq:String.equal "effects" common.Jsoo_cmdline.Arg.optim.enable
4848
then `Cps
4949
else `Jspi
50-
| Some ((`Cps | `Jspi) as e) -> e
50+
| Some ((`Disabled | `Cps | `Jspi) as e) -> e
5151

5252
type t =
5353
{ common : Jsoo_cmdline.Arg.t
@@ -120,11 +120,11 @@ let options () =
120120
let effects =
121121
let doc =
122122
"Select an implementation of effect handlers. [$(docv)] should be one of $(b,jspi) \
123-
(the default) or $(b,cps)."
123+
(the default), $(b,cps), or $(b,disabled)."
124124
in
125125
Arg.(
126126
value
127-
& opt (some (enum [ "jspi", `Jspi; "cps", `Cps ])) None
127+
& opt (some (enum [ "jspi", `Jspi; "cps", `Cps; "disabled", `Disabled ])) None
128128
& info [ "effects" ] ~docv:"KIND" ~doc)
129129
in
130130
let build_t
@@ -235,11 +235,11 @@ let options_runtime_only () =
235235
let effects =
236236
let doc =
237237
"Select an implementation of effect handlers. [$(docv)] should be one of $(b,jspi) \
238-
(the default) or $(b,cps)."
238+
(the default), $(b,cps), or $(b,disabled)."
239239
in
240240
Arg.(
241241
value
242-
& opt (some (enum [ "jspi", `Jspi; "cps", `Cps ])) None
242+
& opt (some (enum [ "jspi", `Jspi; "cps", `Cps; "disabled", `Disabled ])) None
243243
& info [ "effects" ] ~docv:"KIND" ~doc)
244244
in
245245
let build_t

compiler/bin-wasm_of_ocaml/compile.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,9 @@ let build_runtime ~runtime_file =
9090
[ ( "effects"
9191
, Wat_preprocess.String
9292
(match Config.effects () with
93-
| `Jspi -> "jspi"
93+
| `Disabled | `Jspi -> "jspi"
9494
| `Cps -> "cps"
95-
| `Disabled | `Double_translation -> assert false) )
95+
| `Double_translation -> assert false) )
9696
]
9797
in
9898
match

compiler/lib-wasm/generate.ml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ let times = Debug.find "times"
2525

2626
let effects_cps () =
2727
match Config.effects () with
28-
| `Cps | `Double_translation -> true
29-
| `Jspi -> false
30-
| `Disabled -> assert false
28+
| `Cps -> true
29+
| `Disabled | `Jspi -> false
30+
| `Double_translation -> assert false
3131

3232
module Generate (Target : Target_sig.S) = struct
3333
open Target

compiler/lib-wasm/link.ml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,7 @@ let build_runtime_arguments
533533
[ EVar (Javascript.ident Global_constant.global_object_) ]
534534
N
535535
in
536-
obj
536+
let props : (string * Javascript.expression) list =
537537
[ ( "link"
538538
, EArr
539539
(List.map
@@ -559,6 +559,14 @@ let build_runtime_arguments
559559
; "generated", generated_js
560560
; "src", EStr (Utf8_string.of_string_exn (Filename.basename wasm_dir))
561561
]
562+
in
563+
let props =
564+
match Config.effects () with
565+
| `Disabled -> ("disable_effects", Javascript.EBool true) :: props
566+
| `Jspi | `Cps -> props
567+
| `Double_translation -> assert false
568+
in
569+
obj props
562570

563571
let source_name i j file =
564572
let prefix =

compiler/lib/driver.ml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -628,8 +628,9 @@ let optimize ~profile p =
628628
+> map_fst
629629
(match Config.target (), Config.effects () with
630630
| `JavaScript, `Disabled -> Generate_closure.f
631-
| `JavaScript, (`Cps | `Double_translation) | `Wasm, (`Jspi | `Cps) -> Fun.id
632-
| `JavaScript, `Jspi | `Wasm, (`Disabled | `Double_translation) -> assert false)
631+
| `JavaScript, (`Cps | `Double_translation) | `Wasm, (`Disabled | `Jspi | `Cps)
632+
-> Fun.id
633+
| `JavaScript, `Jspi | `Wasm, `Double_translation -> assert false)
633634
+> map_fst deadcode'
634635
in
635636
if times () then Format.eprintf "Start Optimizing...@.";

runtime/wasm/runtime.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
(js) => async (args) => {
1919
// biome-ignore lint/suspicious/noRedundantUseStrict:
2020
"use strict";
21-
const { link, src, generated } = args;
21+
const { link, src, generated, disable_effects } = args;
2222

2323
const isNode = globalThis.process?.versions?.node;
2424

@@ -124,7 +124,9 @@
124124
return WebAssembly?.Suspending ? new WebAssembly.Suspending(f) : f;
125125
}
126126
function make_promising(f) {
127-
return WebAssembly?.promising && f ? WebAssembly.promising(f) : f;
127+
return !disable_effects && WebAssembly?.promising && f
128+
? WebAssembly.promising(f)
129+
: f;
128130
}
129131

130132
const decoder = new TextDecoder("utf-8", { ignoreBOM: 1 });

0 commit comments

Comments
 (0)