@@ -540,30 +540,46 @@ module Value = struct
540540
541541 let ( >>| ) x f = map f x
542542
543+ let may_be_js js x =
544+ let * ty = expression_type x in
545+ match ty with
546+ | None -> return true
547+ | Some (Ref { typ; _ } ) -> heap_type_sub (Type js) typ
548+ | Some (I32 | I64 | F32 | F64 ) -> return false
549+
543550 let eq_gen ~negate x y =
544- let xv = Code.Var. fresh () in
545- let yv = Code.Var. fresh () in
551+ let * x = x in
552+ let * y = y in
546553 let * js = Type. js_type in
547- let n =
548- if_expr
549- I32
550- (* We mimic an "and" on the two conditions, but in a way that is nicer to the
554+ let * bx = may_be_js js x in
555+ let * by = may_be_js js y in
556+ if bx && by
557+ then
558+ let xv = Code.Var. fresh () in
559+ let yv = Code.Var. fresh () in
560+ let n =
561+ if_expr
562+ I32
563+ (* We mimic an "and" on the two conditions, but in a way that is nicer to the
551564 binaryen optimizer. *)
552- (if_expr
553- I32
554- (ref_test (ref js) (load xv))
555- (ref_test (ref js) (load yv))
556- (Arith. const 0l ))
557- (caml_js_strict_equals (load xv) (load yv)
558- >> | (fun e -> W. RefCast ({ nullable = false ; typ = I31 }, e))
559- >> | fun e -> W. I31Get (S , e))
560- (ref_eq (load xv) (load yv))
561- in
562- seq
563- (let * () = store xv x in
564- let * () = store yv y in
565- return () )
566- (if negate then Arith. eqz n else n)
565+ (if_expr
566+ I32
567+ (ref_test (ref js) (load xv))
568+ (ref_test (ref js) (load yv))
569+ (Arith. const 0l ))
570+ (caml_js_strict_equals (load xv) (load yv)
571+ >> | (fun e -> W. RefCast ({ nullable = false ; typ = I31 }, e))
572+ >> | fun e -> W. I31Get (S , e))
573+ (ref_eq (load xv) (load yv))
574+ in
575+ seq
576+ (let * () = store xv (return x) in
577+ let * () = store yv (return y) in
578+ return () )
579+ (if negate then Arith. eqz n else n)
580+ else
581+ let n = ref_eq (return x) (return y) in
582+ if negate then Arith. eqz n else n
567583
568584 let eq x y = eq_gen ~negate: false x y
569585
0 commit comments