Skip to content

Commit 416dfd2

Browse files
committed
Fix optimization of JavaScript interoperability primitives
Some optimizations were no longer applied after the array initialization fix in #113. The following functions from `Js.Unsafe` were affected: `call`, `fun_call`, `meth_call` and `new_obj`.
1 parent 73df0b4 commit 416dfd2

File tree

4 files changed

+28
-10
lines changed

4 files changed

+28
-10
lines changed

compiler/lib-wasm/generate.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1170,7 +1170,7 @@ let init () =
11701170
let l =
11711171
[ "caml_ensure_stack_capacity", "%identity"; "caml_callback", "caml_trampoline" ]
11721172
in
1173-
1173+
Primitive.register "caml_make_array" `Mutable None None;
11741174
let l =
11751175
if Config.Flag.effects ()
11761176
then ("caml_alloc_stack", "caml_cps_alloc_stack") :: l

compiler/lib/flow.ml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ let rec block_escape st x =
198198
| Immutable -> ()
199199
| Maybe_mutable -> Code.Var.ISet.add st.possibly_mutable y);
200200
Array.iter l ~f:(fun z -> block_escape st z)
201+
| Expr (Prim (Extern "caml_make_array", [ Pv y ])) -> block_escape st y
201202
| _ -> Code.Var.ISet.add st.possibly_mutable y))
202203
(Var.Tbl.get st.known_origins x)
203204

@@ -207,6 +208,7 @@ let expr_escape st _x e =
207208
| Apply { args; _ } -> List.iter args ~f:(fun x -> block_escape st x)
208209
| Prim (Array_get, [ Pv x; _ ]) -> block_escape st x
209210
| Prim ((Vectlength | Array_get | Not | IsInt | Eq | Neq | Lt | Le | Ult), _) -> ()
211+
| Prim (Extern "caml_make_array", [ Pv _ ]) -> ()
210212
| Prim (Extern name, l) ->
211213
let ka =
212214
match Primitive.kind_args name with
@@ -231,6 +233,11 @@ let expr_escape st _x e =
231233
| Expr (Constant (Tuple _)) -> ()
232234
| Expr (Block (_, a, _, _)) ->
233235
Array.iter a ~f:(fun x -> block_escape st x)
236+
| Expr (Prim (Extern "caml_make_array", [ Pv y ])) -> (
237+
match st.defs.(Var.idx y) with
238+
| Expr (Block (_, a, _, _)) ->
239+
Array.iter a ~f:(fun x -> block_escape st x)
240+
| _ -> assert false)
234241
| _ -> block_escape st v)
235242
| Pv v, `Object_literal -> (
236243
match st.defs.(Var.idx v) with
@@ -405,6 +412,15 @@ let the_native_string_of ~target info x =
405412
| Some (NativeString i) -> Some i
406413
| _ -> None
407414

415+
let the_block_contents_of info x =
416+
match the_def_of info x with
417+
| Some (Block (_, a, _, _)) -> Some a
418+
| Some (Prim (Extern "caml_make_array", [ x ])) -> (
419+
match the_def_of info x with
420+
| Some (Block (_, a, _, _)) -> Some a
421+
| _ -> None)
422+
| _ -> None
423+
408424
(*XXX Maybe we could iterate? *)
409425
let direct_approx (info : Info.t) x =
410426
match info.info_defs.(Var.idx x) with

compiler/lib/flow.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ val the_string_of :
6161
val the_native_string_of :
6262
target:[ `JavaScript | `Wasm ] -> Info.t -> Code.prim_arg -> Code.Native_string.t option
6363

64+
val the_block_contents_of : Info.t -> Code.prim_arg -> Code.Var.t array option
65+
6466
val the_int :
6567
target:[ `JavaScript | `Wasm ] -> Info.t -> Code.prim_arg -> Targetint.t option
6668

compiler/lib/specialize_js.ml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,22 +55,22 @@ let specialize_instr ~target info i =
5555
| Some _ -> Let (x, Constant (Int Targetint.zero))
5656
| None -> i)
5757
| Let (x, Prim (Extern "caml_js_call", [ f; o; a ])), _ -> (
58-
match the_def_of info a with
59-
| Some (Block (_, a, _, _)) ->
58+
match the_block_contents_of info a with
59+
| Some a ->
6060
let a = Array.map a ~f:(fun x -> Pv x) in
6161
Let (x, Prim (Extern "%caml_js_opt_call", f :: o :: Array.to_list a))
6262
| _ -> i)
6363
| Let (x, Prim (Extern "caml_js_fun_call", [ f; a ])), _ -> (
64-
match the_def_of info a with
65-
| Some (Block (_, a, _, _)) ->
64+
match the_block_contents_of info a with
65+
| Some a ->
6666
let a = Array.map a ~f:(fun x -> Pv x) in
6767
Let (x, Prim (Extern "%caml_js_opt_fun_call", f :: Array.to_list a))
6868
| _ -> i)
6969
| Let (x, Prim (Extern "caml_js_meth_call", [ o; m; a ])), _ -> (
7070
match the_string_of ~target info m with
7171
| Some m when Javascript.is_ident m -> (
72-
match the_def_of info a with
73-
| Some (Block (_, a, _, _)) ->
72+
match the_block_contents_of info a with
73+
| Some a ->
7474
let a = Array.map a ~f:(fun x -> Pv x) in
7575
Let
7676
( x
@@ -79,11 +79,11 @@ let specialize_instr ~target info i =
7979
, o
8080
:: Pc (NativeString (Native_string.of_string m))
8181
:: Array.to_list a ) )
82-
| _ -> i)
82+
| None -> i)
8383
| _ -> i)
8484
| Let (x, Prim (Extern "caml_js_new", [ c; a ])), _ -> (
85-
match the_def_of info a with
86-
| Some (Block (_, a, _, _)) ->
85+
match the_block_contents_of info a with
86+
| Some a ->
8787
let a = Array.map a ~f:(fun x -> Pv x) in
8888
Let (x, Prim (Extern "%caml_js_opt_new", c :: Array.to_list a))
8989
| _ -> i)

0 commit comments

Comments
 (0)