Skip to content

Commit c344a51

Browse files
vouillonrickyvetter
andcommitted
Int64.of_string fixes
- Fix overflow check for positive integers - Fix the failure message Co-authored-by: Ricky Vetter <rickywvetter@gmail.com>
1 parent c055786 commit c344a51

File tree

2 files changed

+28
-9
lines changed

2 files changed

+28
-9
lines changed

compiler/tests-jsoo/test_ints.ml

+17
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,20 @@ let%expect_test _ =
6666
[%expect {| -481418970354774920 |}];
6767
Printf.printf "%Ld\n" (Int64.of_string "0U17965325103354776696");
6868
[%expect {| -481418970354774920 |}]
69+
70+
71+
let%expect_test _ =
72+
let check_fail x =
73+
try
74+
Printf.printf "%Lx\n" (Int64.of_string x)
75+
with Failure _ ->
76+
Format.printf "overflow\n"
77+
in
78+
Printf.printf "%Ld\n" (Int64.of_string "9223372036854775807");
79+
[%expect {| 9223372036854775807 |}];
80+
Printf.printf "%Ld\n" (Int64.of_string "-9223372036854775808");
81+
[%expect {| -9223372036854775808 |}];
82+
check_fail "9223372036854775808";
83+
[%expect {| overflow |}];
84+
check_fail "-9223372036854775809";
85+
[%expect {| overflow |}]

runtime/js/int64.js

+11-9
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ class MlInt64 {
3030
this.caml_custom = "_j";
3131
}
3232

33+
static UNSIGNED_MAX = new MlInt64(0xffffff, 0xffffff, 0xffff);
34+
static SIGNED_MAX = new MlInt64(0xffffff, 0xffffff, 0x7fff);
35+
static SIGNED_MIN = new MlInt64(0x000000, 0x000000, 0x8000);
36+
3337
slice() {
3438
return new MlInt64(this.lo, this.mi, this.hi);
3539
}
@@ -399,12 +403,10 @@ function caml_int64_of_string(s) {
399403
base = r[2],
400404
signedness = r[3];
401405
var base64 = caml_int64_of_int32(base);
402-
var threshold = new MlInt64(0xffffff, 0xfffffff, 0xffff).udivmod(
403-
base64,
404-
).quotient;
406+
var threshold = MlInt64.UNSIGNED_MAX.udivmod(base64).quotient;
405407
var c = caml_string_unsafe_get(s, i);
406408
var d = caml_parse_digit(c);
407-
if (d < 0 || d >= base) caml_failwith("int_of_string");
409+
if (d < 0 || d >= base) caml_failwith("Int64.of_string");
408410
var res = caml_int64_of_int32(d);
409411
for (;;) {
410412
i++;
@@ -413,15 +415,15 @@ function caml_int64_of_string(s) {
413415
d = caml_parse_digit(c);
414416
if (d < 0 || d >= base) break;
415417
/* Detect overflow in multiplication base * res */
416-
if (caml_int64_ult(threshold, res)) caml_failwith("int_of_string");
418+
if (caml_int64_ult(threshold, res)) caml_failwith("Int64.of_string");
417419
d = caml_int64_of_int32(d);
418420
res = caml_int64_add(caml_int64_mul(base64, res), d);
419421
/* Detect overflow in addition (base * res) + d */
420-
if (caml_int64_ult(res, d)) caml_failwith("int_of_string");
422+
if (caml_int64_ult(res, d)) caml_failwith("Int64.of_string");
421423
}
422-
if (i !== caml_ml_string_length(s)) caml_failwith("int_of_string");
423-
if (signedness && caml_int64_ult(new MlInt64(0, 0, 0x8000), res))
424-
caml_failwith("int_of_string");
424+
if (i !== caml_ml_string_length(s)) caml_failwith("Int64.of_string");
425+
if (signedness && caml_int64_ult(sign < 0 ? MlInt64.SIGNED_MIN : MlInt64.SIGNED_MAX, res))
426+
caml_failwith("Int64.of_string");
425427
if (sign < 0) res = caml_int64_neg(res);
426428
return res;
427429
}

0 commit comments

Comments
 (0)