Skip to content

Commit e665fec

Browse files
author
Cristiano Calcagno
committed
Make compare order independent, add equal and tests.
To make the comparison order-independent, sort the keys before comparing them.
1 parent 495428a commit e665fec

File tree

5 files changed

+506
-51
lines changed

5 files changed

+506
-51
lines changed

jscomp/runtime/caml_obj.ml

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ module O = struct
138138
type key = Obj.t
139139
external keys : Obj.t -> keys = "Object.keys" [@@bs.val]
140140
external length : keys -> int = "%array_length"
141+
external sort : unit -> unit [@bs.meth] = "" [@@bs.val]
142+
let sort (keys:keys) : unit = (Obj.magic keys)##sort ()
141143
external get_key : keys -> int -> key = "%array_unsafe_get"
142144
external get_value : Obj.t -> key -> Obj.t = "%array_unsafe_get"
143145
end
@@ -212,6 +214,8 @@ let rec caml_compare (a : Obj.t) (b : Obj.t) : int =
212214
begin
213215
let keys_a = O.keys a in
214216
let keys_b = O.keys b in
217+
O.sort(keys_a);
218+
O.sort(keys_b);
215219
let len_a = O.length keys_a in
216220
let len_b = O.length keys_b in
217221
let min_len = min len_a len_b in
@@ -298,6 +302,18 @@ let rec caml_equal (a : Obj.t) (b : Obj.t) : bool =
298302
else
299303
let len_a = Bs_obj.length a in
300304
let len_b = Bs_obj.length b in
305+
if len_a = 0 && len_b = 0 && O.is_object a && O.is_object b then
306+
begin
307+
let keys_a = O.keys a in
308+
let keys_b = O.keys b in
309+
let len_a = O.length keys_a in
310+
let len_b = O.length keys_b in
311+
len_a = len_b &&
312+
let () = O.sort(keys_a) in
313+
let () = O.sort(keys_b) in
314+
aux_obj_equal a keys_a b keys_b 0 len_a
315+
end
316+
else
301317
if len_a = len_b then
302318
aux_equal_length a b 0 len_a
303319
else false
@@ -307,7 +323,14 @@ and aux_equal_length (a : Obj.t) (b : Obj.t) i same_length =
307323
else
308324
caml_equal (Obj.field a i) (Obj.field b i)
309325
&& aux_equal_length a b (i + 1) same_length
310-
326+
and aux_obj_equal (a: Obj.t) keys_a (b: Obj.t) keys_b i length =
327+
if i = length then true
328+
else
329+
let key_a = O.get_key keys_a i in
330+
let key_b = O.get_key keys_b i in
331+
caml_equal key_a key_b &&
332+
caml_equal (O.get_value a key_a) (O.get_value b key_b) &&
333+
aux_obj_equal a keys_a b keys_b (i+1) length
311334

312335
let caml_equal_null (x : Obj.t) (y : Obj.t Js.null) =
313336
match Js.nullToOption y with

0 commit comments

Comments
 (0)