Skip to content

Commit 5d2bd9b

Browse files
committed
Use type analysis to avoid using JavasScript strict equality
If we know that one of the compared values is not a JavaScript value, we can directly use physical equality.
1 parent 86beb38 commit 5d2bd9b

File tree

3 files changed

+35
-10
lines changed

3 files changed

+35
-10
lines changed

compiler/lib-wasm/gc_target.ml

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -565,9 +565,21 @@ module Value = struct
565565
return ())
566566
(if negate then Arith.eqz n else n)
567567

568-
let eq x y = eq_gen ~negate:false x y
568+
let phys_eq ~relaxed x y =
569+
if relaxed
570+
then eq_gen ~negate:false x y
571+
else
572+
let* x = x in
573+
let* y = y in
574+
return (W.RefEq (x, y))
569575

570-
let neq x y = eq_gen ~negate:true x y
576+
let phys_neq ~relaxed x y =
577+
if relaxed
578+
then eq_gen ~negate:true x y
579+
else
580+
let* x = x in
581+
let* y = y in
582+
Arith.eqz (return (W.RefEq (x, y)))
571583

572584
let ult = Arith.ult
573585

compiler/lib-wasm/generate.ml

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -215,15 +215,26 @@ module Generate (Target : Target_sig.S) = struct
215215
(transl_prim_arg ctx ~typ:(Int Normalized) x)
216216
(transl_prim_arg ctx ~typ:(Int Normalized) y)
217217

218-
let translate_int_equality ctx op op' x y =
218+
let translate_int_equality ctx ~negate x y =
219219
match get_type ctx x, get_type ctx y with
220220
| (Int Normalized as typ), Int Normalized ->
221-
op (transl_prim_arg ctx ~typ x) (transl_prim_arg ctx ~typ y)
221+
(if negate then Arith.( = ) else Arith.( <> ))
222+
(transl_prim_arg ctx ~typ x)
223+
(transl_prim_arg ctx ~typ y)
222224
| Int (Normalized | Unnormalized), Int (Normalized | Unnormalized) ->
223-
op
225+
(if negate then Arith.( = ) else Arith.( <> ))
224226
Arith.(transl_prim_arg ctx ~typ:(Int Unnormalized) x lsl const 1l)
225227
Arith.(transl_prim_arg ctx ~typ:(Int Unnormalized) y lsl const 1l)
226-
| _ -> op' (transl_prim_arg ctx ~typ:Top x) (transl_prim_arg ctx ~typ:Top y)
228+
| Top, Top ->
229+
(if negate then Value.phys_eq else Value.phys_neq)
230+
~relaxed:true
231+
(transl_prim_arg ctx ~typ:Top x)
232+
(transl_prim_arg ctx ~typ:Top y)
233+
| _ ->
234+
(if negate then Value.phys_eq else Value.phys_neq)
235+
~relaxed:false
236+
(transl_prim_arg ctx ~typ:Top x)
237+
(transl_prim_arg ctx ~typ:Top y)
227238

228239
let internal_primitives =
229240
let h = String.Hashtbl.create 128 in
@@ -864,8 +875,8 @@ module Generate (Target : Target_sig.S) = struct
864875
| Prim (Lt, [ x; y ]) -> translate_int_comparison ctx Arith.( < ) x y
865876
| Prim (Le, [ x; y ]) -> translate_int_comparison ctx Arith.( <= ) x y
866877
| Prim (Ult, [ x; y ]) -> translate_int_comparison ctx Arith.ult x y
867-
| Prim (Eq, [ x; y ]) -> translate_int_equality ctx Arith.( = ) Value.eq x y
868-
| Prim (Neq, [ x; y ]) -> translate_int_equality ctx Arith.( <> ) Value.neq x y
878+
| Prim (Eq, [ x; y ]) -> translate_int_equality ctx ~negate:false x y
879+
| Prim (Neq, [ x; y ]) -> translate_int_equality ctx ~negate:true x y
869880
| Prim (Array_get, [ x; y ]) ->
870881
Memory.array_get
871882
(transl_prim_arg ctx x)

compiler/lib-wasm/target_sig.ml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,11 @@ module type S = sig
124124

125125
val le : expression -> expression -> expression
126126

127-
val eq : expression -> expression -> expression
127+
(* Relaxed means using JavaScript strict equality to compare
128+
JavaScript values *)
129+
val phys_eq : relaxed:bool -> expression -> expression -> expression
128130

129-
val neq : expression -> expression -> expression
131+
val phys_neq : relaxed:bool -> expression -> expression -> expression
130132

131133
val ult : expression -> expression -> expression
132134

0 commit comments

Comments
 (0)