Skip to content

Commit 90dcf52

Browse files
committed
fix some edge cases for equal too
1 parent 2822554 commit 90dcf52

File tree

4 files changed

+277
-84
lines changed

4 files changed

+277
-84
lines changed

jscomp/runtime/caml_obj.ml

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -226,37 +226,43 @@ type eq = Obj.t -> Obj.t -> bool
226226
let rec caml_equal (a : Obj.t) (b : Obj.t) : bool =
227227
(*front and formoest, we do not compare function values*)
228228
if a == b then true
229-
else if Js.typeof a = "string"
230-
|| Js.typeof a = "number"
231-
|| Js.typeof a = "boolean"
232-
|| Js.typeof a = "undefined"
233-
|| Js.typeof a = "null"
234-
then false
235-
else if Js.typeof a = "function" || Js.typeof b = "function"
236-
then raise (Invalid_argument "equal: functional value")
237-
(* first, check using reference equality *)
238-
else
239-
let tag_a = Bs_obj.tag a in
240-
let tag_b = Bs_obj.tag b in
241-
(* double_array_tag: 254
242-
forward_tag:250
243-
*)
244-
if tag_a = 250 then
245-
caml_equal (Obj.field a 0) b
246-
else if tag_b = 250 then
247-
caml_equal a (Obj.field b 0)
248-
else if tag_a = 248 (* object/exception *) then
249-
(Obj.magic @@ Obj.field a 1) == (Obj.magic @@ Obj.field b 1 )
250-
else if tag_a = 251 (* abstract_tag *) then
251-
raise (Invalid_argument "equal: abstract value")
252-
else if tag_a <> tag_b then
253-
false
254-
else
255-
let len_a = Bs_obj.length a in
256-
let len_b = Bs_obj.length b in
257-
if len_a = len_b then
258-
aux_equal_length a b 0 len_a
259-
else false
229+
else
230+
let a_type = Js.typeof a in
231+
if a_type = "string"
232+
|| a_type = "number"
233+
|| a_type = "boolean"
234+
|| a_type = "undefined"
235+
|| a_type = "null"
236+
then false
237+
else
238+
let b_type = Js.typeof b in
239+
if a_type = "function" || b_type = "function"
240+
then raise (Invalid_argument "equal: functional value")
241+
(* first, check using reference equality *)
242+
else (* a_type = "object" || "symbol" *)
243+
if b_type = "number" || b_type = "null" || b_type = "undefined" then false
244+
else
245+
let tag_a = Bs_obj.tag a in
246+
let tag_b = Bs_obj.tag b in
247+
(* double_array_tag: 254
248+
forward_tag:250
249+
*)
250+
if tag_a = 250 then
251+
caml_equal (Obj.field a 0) b
252+
else if tag_b = 250 then
253+
caml_equal a (Obj.field b 0)
254+
else if tag_a = 248 (* object/exception *) then
255+
(Obj.magic @@ Obj.field a 1) == (Obj.magic @@ Obj.field b 1 )
256+
else if tag_a = 251 (* abstract_tag *) then
257+
raise (Invalid_argument "equal: abstract value")
258+
else if tag_a <> tag_b then
259+
false
260+
else
261+
let len_a = Bs_obj.length a in
262+
let len_b = Bs_obj.length b in
263+
if len_a = len_b then
264+
aux_equal_length a b 0 len_a
265+
else false
260266
and aux_equal_length (a : Obj.t) (b : Obj.t) i same_length =
261267
if i = same_length then
262268
true

jscomp/test/caml_compare_test.js

Lines changed: 165 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,171 @@ var suites_001 = /* :: */[
335335
]);
336336
}
337337
],
338-
/* [] */0
338+
/* :: */[
339+
/* tuple */[
340+
'File "caml_compare_test.ml", line 41, characters 4-11',
341+
function () {
342+
return /* Eq */Block.__(0, [
343+
/* false */0,
344+
+(/* None */0 === /* Some */[/* int array */[
345+
1,
346+
30
347+
]])
348+
]);
349+
}
350+
],
351+
/* :: */[
352+
/* tuple */[
353+
'File "caml_compare_test.ml", line 44, characters 4-11',
354+
function () {
355+
return /* Eq */Block.__(0, [
356+
/* false */0,
357+
+(/* Some */[/* int array */[
358+
1,
359+
30
360+
]] === /* None */0)
361+
]);
362+
}
363+
],
364+
/* :: */[
365+
/* tuple */[
366+
'File "caml_compare_test.ml", line 47, characters 4-11',
367+
function () {
368+
return /* Eq */Block.__(0, [
369+
/* false */0,
370+
Caml_obj.caml_equal(/* :: */[
371+
2,
372+
/* :: */[
373+
6,
374+
/* :: */[
375+
1,
376+
/* :: */[
377+
1,
378+
/* :: */[
379+
2,
380+
/* :: */[
381+
1,
382+
/* :: */[
383+
4,
384+
/* :: */[
385+
2,
386+
/* :: */[
387+
1,
388+
/* [] */0
389+
]
390+
]
391+
]
392+
]
393+
]
394+
]
395+
]
396+
]
397+
], /* :: */[
398+
2,
399+
/* :: */[
400+
6,
401+
/* :: */[
402+
1,
403+
/* :: */[
404+
1,
405+
/* :: */[
406+
2,
407+
/* :: */[
408+
1,
409+
/* :: */[
410+
4,
411+
/* :: */[
412+
2,
413+
/* :: */[
414+
1,
415+
/* :: */[
416+
409,
417+
/* [] */0
418+
]
419+
]
420+
]
421+
]
422+
]
423+
]
424+
]
425+
]
426+
]
427+
])
428+
]);
429+
}
430+
],
431+
/* :: */[
432+
/* tuple */[
433+
'File "caml_compare_test.ml", line 50, characters 4-11',
434+
function () {
435+
return /* Eq */Block.__(0, [
436+
/* false */0,
437+
Caml_obj.caml_equal(/* :: */[
438+
2,
439+
/* :: */[
440+
6,
441+
/* :: */[
442+
1,
443+
/* :: */[
444+
1,
445+
/* :: */[
446+
2,
447+
/* :: */[
448+
1,
449+
/* :: */[
450+
4,
451+
/* :: */[
452+
2,
453+
/* :: */[
454+
1,
455+
/* :: */[
456+
409,
457+
/* [] */0
458+
]
459+
]
460+
]
461+
]
462+
]
463+
]
464+
]
465+
]
466+
]
467+
], /* :: */[
468+
2,
469+
/* :: */[
470+
6,
471+
/* :: */[
472+
1,
473+
/* :: */[
474+
1,
475+
/* :: */[
476+
2,
477+
/* :: */[
478+
1,
479+
/* :: */[
480+
4,
481+
/* :: */[
482+
2,
483+
/* :: */[
484+
1,
485+
/* [] */0
486+
]
487+
]
488+
]
489+
]
490+
]
491+
]
492+
]
493+
]
494+
])
495+
]);
496+
}
497+
],
498+
/* [] */0
499+
]
500+
]
501+
]
502+
]
339503
]
340504
]
341505
]

jscomp/test/caml_compare_test.ml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,21 @@ let suites = Mt.[
3636
end;
3737
__LOC__ , begin fun _ ->
3838
Eq(true, [2;6;1;1;2;1;4;2;1;409] > [2;6;1;1;2;1;4;2;1])
39-
end
39+
end;
40+
41+
__LOC__, begin fun _ ->
42+
Eq(false, None = Some [|1;30|] )
43+
end;
44+
__LOC__, begin fun _ ->
45+
Eq(false, Some [|1;30|] = None )
46+
end;
47+
__LOC__ , begin fun _ ->
48+
Eq(false, [2;6;1;1;2;1;4;2;1] = [2;6;1;1;2;1;4;2;1;409])
49+
end;
50+
__LOC__ , begin fun _ ->
51+
Eq(false, [2;6;1;1;2;1;4;2;1;409] = [2;6;1;1;2;1;4;2;1])
52+
end;
53+
4054
]
4155
;;
4256

lib/js/caml_obj.js

Lines changed: 60 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -231,65 +231,74 @@ function caml_equal(_a, _b) {
231231
if (a === b) {
232232
return /* true */1;
233233
}
234-
else if (typeof a === "string" || typeof a === "number" || typeof a === "boolean" || typeof a === "undefined" || typeof a === "null") {
235-
return /* false */0;
236-
}
237-
else if (typeof a === "function" || typeof b === "function") {
238-
throw [
239-
Caml_builtin_exceptions.invalid_argument,
240-
"equal: functional value"
241-
];
242-
}
243234
else {
244-
var tag_a = a.tag | 0;
245-
var tag_b = b.tag | 0;
246-
if (tag_a === 250) {
247-
_a = a[0];
248-
continue ;
249-
250-
}
251-
else if (tag_b === 250) {
252-
_b = b[0];
253-
continue ;
254-
255-
}
256-
else if (tag_a === 248) {
257-
return +(a[1] === b[1]);
258-
}
259-
else if (tag_a === 251) {
260-
throw [
261-
Caml_builtin_exceptions.invalid_argument,
262-
"equal: abstract value"
263-
];
264-
}
265-
else if (tag_a !== tag_b) {
235+
var a_type = typeof a;
236+
if (a_type === "string" || a_type === "number" || a_type === "boolean" || a_type === "undefined" || a_type === "null") {
266237
return /* false */0;
267238
}
268239
else {
269-
var len_a = a.length;
270-
var len_b = b.length;
271-
if (len_a === len_b) {
272-
var a$1 = a;
273-
var b$1 = b;
274-
var _i = 0;
275-
var same_length = len_a;
276-
while(true) {
277-
var i = _i;
278-
if (i === same_length) {
279-
return /* true */1;
280-
}
281-
else if (caml_equal(a$1[i], b$1[i])) {
282-
_i = i + 1 | 0;
283-
continue ;
284-
240+
var b_type = typeof b;
241+
if (a_type === "function" || b_type === "function") {
242+
throw [
243+
Caml_builtin_exceptions.invalid_argument,
244+
"equal: functional value"
245+
];
246+
}
247+
else if (b_type === "number" || b_type === "null" || b_type === "undefined") {
248+
return /* false */0;
249+
}
250+
else {
251+
var tag_a = a.tag | 0;
252+
var tag_b = b.tag | 0;
253+
if (tag_a === 250) {
254+
_a = a[0];
255+
continue ;
256+
257+
}
258+
else if (tag_b === 250) {
259+
_b = b[0];
260+
continue ;
261+
262+
}
263+
else if (tag_a === 248) {
264+
return +(a[1] === b[1]);
265+
}
266+
else if (tag_a === 251) {
267+
throw [
268+
Caml_builtin_exceptions.invalid_argument,
269+
"equal: abstract value"
270+
];
271+
}
272+
else if (tag_a !== tag_b) {
273+
return /* false */0;
274+
}
275+
else {
276+
var len_a = a.length;
277+
var len_b = b.length;
278+
if (len_a === len_b) {
279+
var a$1 = a;
280+
var b$1 = b;
281+
var _i = 0;
282+
var same_length = len_a;
283+
while(true) {
284+
var i = _i;
285+
if (i === same_length) {
286+
return /* true */1;
287+
}
288+
else if (caml_equal(a$1[i], b$1[i])) {
289+
_i = i + 1 | 0;
290+
continue ;
291+
292+
}
293+
else {
294+
return /* false */0;
295+
}
296+
};
285297
}
286298
else {
287299
return /* false */0;
288300
}
289-
};
290-
}
291-
else {
292-
return /* false */0;
301+
}
293302
}
294303
}
295304
}

0 commit comments

Comments
 (0)