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