@@ -131,6 +131,18 @@ let caml_update_dummy x y =
131
131
132
132
type 'a selector = 'a -> 'a -> 'a
133
133
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
134
146
135
147
let unsafe_js_compare x y =
136
148
if x == y then 0 else
@@ -199,7 +211,9 @@ let rec caml_compare (a : Obj.t) (b : Obj.t) : int =
199
211
let len_a = Bs_obj. length a in
200
212
let len_b = Bs_obj. length b in
201
213
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
203
217
else if len_a < len_b then
204
218
aux_length_a_short a b 0 len_a
205
219
else
@@ -223,6 +237,27 @@ and aux_length_b_short (a : Obj.t) (b : Obj.t) i short_length =
223
237
let res = caml_compare (Obj. field a i) (Obj. field b i) in
224
238
if res <> 0 then res
225
239
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
226
261
227
262
type eq = Obj .t -> Obj .t -> bool
228
263
@@ -268,15 +303,28 @@ let rec caml_equal (a : Obj.t) (b : Obj.t) : bool =
268
303
let len_a = Bs_obj. length a in
269
304
let len_b = Bs_obj. length b in
270
305
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
272
309
else false
273
310
and aux_equal_length (a : Obj.t ) (b : Obj.t ) i same_length =
274
311
if i = same_length then
275
312
true
276
313
else
277
314
caml_equal (Obj. field a i) (Obj. field b i)
278
315
&& 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
280
328
281
329
let caml_equal_null (x : Obj.t ) (y : Obj.t Js.null ) =
282
330
match Js. nullToOption y with
0 commit comments