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