[前][次][番号順一覧][スレッド一覧]

ruby-changes:72407

From: Jeremy <ko1@a...>
Date: Mon, 4 Jul 2022 01:44:00 +0900 (JST)
Subject: [ruby-changes:72407] fe6245b430 (master): Fix rb_fix_mul_fix on OpenBSD/mips64

https://git.ruby-lang.org/ruby.git/commit/?id=fe6245b430

From fe6245b4309c855e6aca5b786ad50a72d53d278a Mon Sep 17 00:00:00 2001
From: Jeremy Evans <code@j...>
Date: Sun, 3 Jul 2022 09:42:44 -0700
Subject: Fix rb_fix_mul_fix on OpenBSD/mips64

This fixes invalid and inconsistent results for the Fixnum*Fixnum case
where the result of the multiplication does not fit in 64-bit
on OpenBSD/mips64.  For example:

  $  for x in 1 23; do ruby31 -e 'p(54306000000000*86400)'; done
  14409380628474329524
  11410664325873689790

Cases where an argument was Bignum, as well as cases where the result
of the multiplication fits in 64-bit are fine:

  $ for x in 1 23; do ruby31 -e 'p(54306000*86400)'; done
  4692038400000
  4692038400000

  $ for x in 1 23; do ruby31 -e 'p(5430600000000000000000*86400)'; done
  469203840000000000000000000
  469203840000000000000000000

This was originally discovered by running the tests for the openssl gem
on OpenBSD/mips64 and having one test fail for a date far in the future.
I eventually traced this to the generic multiplication issue.

The underlying cause is using the int128_t type. This avoids use of the
int128_t type in this case, falling back to the slower conversion code,
which in the overflow case, turns the Fixnums into Bignums, then
performs the multiplication.
---
 internal/fixnum.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/internal/fixnum.h b/internal/fixnum.h
index cdb60ee1ff..8c251adef1 100644
--- a/internal/fixnum.h
+++ b/internal/fixnum.h
@@ -18,7 +18,7 @@ https://github.com/ruby/ruby/blob/trunk/internal/fixnum.h#L18
 #if HAVE_LONG_LONG && SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG
 # define DLONG LONG_LONG
 # define DL2NUM(x) LL2NUM(x)
-#elif defined(HAVE_INT128_T)
+#elif defined(HAVE_INT128_T) && !(defined(__OpenBSD__) && defined(__mips64__))
 # define DLONG int128_t
 # define DL2NUM(x) (RB_FIXABLE(x) ? LONG2FIX(x) : rb_int128t2big(x))
 VALUE rb_int128t2big(int128_t n); /* in bignum.c */
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]