@@ -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