6565
6666 {[
6767 var u = caml_obj_dup (x)
68- var new_record = u.slice ()
68+ var new_record = u.slice ()
6969
7070 ]}
7171*)
@@ -99,19 +99,19 @@ let caml_obj_truncate (x : Obj.t) (new_size : int) =
9999let caml_lazy_make_forward x = lazy x
100100
101101(* *
102- For the empty dummy object, whether it's
103- `[]` or `{}` depends on how
104- runtime encoding works, and will affect
105- js polymorphic comparison(Js.(=)) (fine with caml polymoprhic comparison (Pervasives.equal))
106- In most cases, rec value comes from record/modules,
107- whose tag is 0, we optimize that case
108- *)
102+ For the empty dummy object, whether it's
103+ `[]` or `{}` depends on how
104+ runtime encoding works, and will affect
105+ js polymorphic comparison(Js.(=)) (fine with caml polymoprhic comparison (Pervasives.equal))
106+ In most cases, rec value comes from record/modules,
107+ whose tag is 0, we optimize that case
108+ *)
109109let caml_update_dummy x y =
110110 (* let len = Bs_obj.length y in
111- for i = 0 to len - 1 do
112- Array.unsafe_set x i (Obj.field y i)
113- done;
114- Obj.set_tag (Obj.magic x) (Obj.tag y)
111+ for i = 0 to len - 1 do
112+ Array.unsafe_set x i (Obj.field y i)
113+ done;
114+ Obj.set_tag (Obj.magic x) (Obj.tag y)
115115 *)
116116 let len = Bs_obj. length y in
117117 for i = 0 to len - 1 do
@@ -120,10 +120,10 @@ let caml_update_dummy x y =
120120 let y_tag = Obj. tag y in
121121 if y_tag <> 0 then
122122 Obj. set_tag x y_tag
123-
124- (* Bs_obj.set_length x (Bs_obj.length y) *)
125- (* [set_length] seems redundant here given that it is initialized as an array
126- *)
123+
124+ (* Bs_obj.set_length x (Bs_obj.length y) *)
125+ (* [set_length] seems redundant here given that it is initialized as an array
126+ *)
127127let caml_int_compare (x : int ) (y : int ) : int =
128128 if x < y then - 1 else if x = y then 0 else 1
129129
@@ -153,45 +153,54 @@ let unsafe_js_compare x y =
153153*)
154154let rec caml_compare (a : Obj.t ) (b : Obj.t ) : int =
155155 (* front and formoest, we do not compare function values*)
156- if Js. typeof a = " string" then
156+ let a_type = Js. typeof a in
157+ let b_type = Js. typeof b in
158+ if a_type = " string" then
157159 caml_string_compare (Obj. magic a) (Obj. magic b )
158- else if Js. typeof a = " number" then
159- caml_int_compare (Obj. magic a) (Obj. magic b )
160- else if Js. typeof a = " boolean"
161- || Js. typeof a = " null"
162- || Js. typeof a = " undefined"
163- then
164- unsafe_js_compare a b
165- else if Js. typeof a = " function" || Js. typeof b = " function"
166- then raise (Invalid_argument " compare: functional value" )
167- else
168- (* if js_is_instance_array a then *)
169- (* 0 *)
170- (* else *)
171- let tag_a = Bs_obj. tag a in
172- let tag_b = Bs_obj. tag b in
173- (* double_array_tag: 254
174- forward_tag:250
175- *)
176- if tag_a = 250 then
177- caml_compare (Obj. field a 0 ) b
178- else if tag_b = 250 then
179- caml_compare a (Obj. field b 0 )
180- else if tag_a = 248 (* object/exception *) then
181- caml_int_compare (Obj. magic @@ Obj. field a 1 ) (Obj. magic @@ Obj. field b 1 )
182- else if tag_a = 251 (* abstract_tag *) then
183- raise (Invalid_argument " equal: abstract value" )
184- else if tag_a <> tag_b then
185- if tag_a < tag_b then (- 1 ) else 1
186- else
187- let len_a = Bs_obj. length a in
188- let len_b = Bs_obj. length b in
189- if len_a = len_b then
190- aux_same_length a b 0 len_a
191- else if len_a < len_b then
192- aux_length_a_short a b 0 len_a
160+ else
161+ let is_a_number = a_type = " number" in
162+ let is_b_number = b_type = " number" in
163+ match is_a_number , is_b_number with
164+ | true , true ->
165+ caml_int_compare (Obj. magic a) (Obj. magic b )
166+ | true , false -> - 1 (* Integer < Block in OCaml runtime GPR #1195 *)
167+ | false , true -> 1
168+ | false , false ->
169+ if a_type = " boolean"
170+ || a_type = " null"
171+ || a_type = " undefined"
172+ then
173+ unsafe_js_compare a b
174+ else if a_type = " function" || b_type = " function"
175+ then raise (Invalid_argument " compare: functional value" )
193176 else
194- aux_length_b_short a b 0 len_b
177+ (* if js_is_instance_array a then *)
178+ (* 0 *)
179+ (* else *)
180+ let tag_a = Bs_obj. tag a in
181+ let tag_b = Bs_obj. tag b in
182+ (* double_array_tag: 254
183+ forward_tag:250
184+ *)
185+ if tag_a = 250 then
186+ caml_compare (Obj. field a 0 ) b
187+ else if tag_b = 250 then
188+ caml_compare a (Obj. field b 0 )
189+ else if tag_a = 248 (* object/exception *) then
190+ caml_int_compare (Obj. magic @@ Obj. field a 1 ) (Obj. magic @@ Obj. field b 1 )
191+ else if tag_a = 251 (* abstract_tag *) then
192+ raise (Invalid_argument " equal: abstract value" )
193+ else if tag_a <> tag_b then
194+ if tag_a < tag_b then (- 1 ) else 1
195+ else
196+ let len_a = Bs_obj. length a in
197+ let len_b = Bs_obj. length b in
198+ if len_a = len_b then
199+ aux_same_length a b 0 len_a
200+ else if len_a < len_b then
201+ aux_length_a_short a b 0 len_a
202+ else
203+ aux_length_b_short a b 0 len_b
195204and aux_same_length (a : Obj.t ) (b : Obj.t ) i same_length =
196205 if i = same_length then
197206 0
@@ -218,10 +227,10 @@ let rec caml_equal (a : Obj.t) (b : Obj.t) : bool =
218227 (* front and formoest, we do not compare function values*)
219228 if a == b then true
220229 else if Js. typeof a = " string"
221- || Js. typeof a = " number"
222- || Js. typeof a = " boolean"
223- || Js. typeof a = " undefined"
224- || Js. typeof a = " null"
230+ || Js. typeof a = " number"
231+ || Js. typeof a = " boolean"
232+ || Js. typeof a = " undefined"
233+ || Js. typeof a = " null"
225234 then false
226235 else if Js. typeof a = " function" || Js. typeof b = " function"
227236 then raise (Invalid_argument " equal: functional value" )
0 commit comments