@@ -131,6 +131,18 @@ let caml_update_dummy x y =
131131
132132type 'a selector = 'a -> 'a -> 'a
133133
134+ module O = struct
135+ external isArray : 'a -> bool = " Array.isArray" [@@ bs.val]
136+ type key = string
137+ let for_in : (Obj.t -> (key -> unit) -> unit) [@bs] = [% bs.raw
138+ {| function (o, foo) {
139+ for (var x in o) { foo(x) }
140+ }
141+ | }]
142+ external hasOwnProperty : key -> bool [@ bs.meth] = " " [@@ bs.val]
143+ let hasOwnProperty (o : Obj.t ) (key : key ) : bool = (Obj. magic o)##hasOwnProperty (key)
144+ external get_value : Obj .t -> key -> Obj .t = " %array_unsafe_get"
145+ end
134146
135147let unsafe_js_compare x y =
136148 if x == y then 0 else
@@ -199,7 +211,9 @@ let rec caml_compare (a : Obj.t) (b : Obj.t) : int =
199211 let len_a = Bs_obj. length a in
200212 let len_b = Bs_obj. length b in
201213 if len_a = len_b then
202- aux_same_length a b 0 len_a
214+ if O. isArray(a)
215+ then aux_same_length a b 0 len_a
216+ else aux_obj_compare a b
203217 else if len_a < len_b then
204218 aux_length_a_short a b 0 len_a
205219 else
@@ -223,6 +237,27 @@ and aux_length_b_short (a : Obj.t) (b : Obj.t) i short_length =
223237 let res = caml_compare (Obj. field a i) (Obj. field b i) in
224238 if res <> 0 then res
225239 else aux_length_b_short a b (i+ 1 ) short_length
240+ and aux_obj_compare (a : Obj.t ) (b : Obj.t ) =
241+ let min_key_lhs = ref None in
242+ let min_key_rhs = ref None in
243+ let do_key (a , b , min_key ) key =
244+ if not (O. hasOwnProperty b key) ||
245+ caml_compare (O. get_value a key) (O. get_value b key) > 0
246+ then
247+ match ! min_key with
248+ | None -> min_key := Some key
249+ | Some mk ->
250+ if key < mk then min_key := Some key in
251+ let do_key_a = do_key (a, b, min_key_rhs) in
252+ let do_key_b = do_key (b, a, min_key_lhs) in
253+ O. for_in a do_key_a [@ bs];
254+ O. for_in b do_key_b [@ bs];
255+ let res = match ! min_key_lhs, ! min_key_rhs with
256+ | None , None -> 0
257+ | (Some _ ), None -> - 1
258+ | None , (Some _ ) -> 1
259+ | (Some x ), (Some y ) -> compare x y in
260+ res
226261
227262type eq = Obj .t -> Obj .t -> bool
228263
@@ -268,15 +303,28 @@ let rec caml_equal (a : Obj.t) (b : Obj.t) : bool =
268303 let len_a = Bs_obj. length a in
269304 let len_b = Bs_obj. length b in
270305 if len_a = len_b then
271- aux_equal_length a b 0 len_a
306+ if O. isArray(a)
307+ then aux_equal_length a b 0 len_a
308+ else aux_obj_equal a b
272309 else false
273310and aux_equal_length (a : Obj.t ) (b : Obj.t ) i same_length =
274311 if i = same_length then
275312 true
276313 else
277314 caml_equal (Obj. field a i) (Obj. field b i)
278315 && aux_equal_length a b (i + 1 ) same_length
279-
316+ and aux_obj_equal (a : Obj.t ) (b : Obj.t ) =
317+ let result = ref true in
318+ let do_key_a key =
319+ if not (O. hasOwnProperty b key)
320+ then result := false in
321+ let do_key_b key =
322+ if not (O. hasOwnProperty a key) ||
323+ not (caml_equal (O. get_value b key) (O. get_value a key))
324+ then result := false in
325+ O. for_in a do_key_a [@ bs];
326+ if ! result then O. for_in b do_key_b [@ bs];
327+ ! result
280328
281329let caml_equal_null (x : Obj.t ) (y : Obj.t Js.null ) =
282330 match Js. nullToOption y with
0 commit comments