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