[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] master b184020: Minor fixups for intmax_t→mpz_t conversio
From: |
Paul Eggert |
Subject: |
[Emacs-diffs] master b184020: Minor fixups for intmax_t→mpz_t conversion |
Date: |
Sat, 18 Aug 2018 23:41:15 -0400 (EDT) |
branch: master
commit b1840206ff22359fc099236602928e0fb3828d66
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>
Minor fixups for intmax_t→mpz_t conversion
* src/alloc.c (mpz_set_intmax_slow): Tighten assertion.
Work even in the unlikely case where libgmp uses nails.
* src/data.c (FIXNUMS_FIT_IN_LONG): New constant.
(arith_driver): Use it to tighten compile-time checks.
* src/lisp.h (mpz_set_intmax): Do not assume that converting
an out-of-range value to ‘long’ is harmless, as it might raise
a signal. Use simpler expression; compiler can optimize.
---
src/alloc.c | 17 ++++++++++-------
src/data.c | 9 ++++++---
src/lisp.h | 11 ++++++-----
3 files changed, 22 insertions(+), 15 deletions(-)
diff --git a/src/alloc.c b/src/alloc.c
index 60850f7..ddc0696 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -3785,18 +3785,21 @@ make_number (mpz_t value)
void
mpz_set_intmax_slow (mpz_t result, intmax_t v)
{
- /* If long is larger then a faster path is taken. */
- eassert (sizeof (intmax_t) > sizeof (long));
+ /* If V fits in long, a faster path is taken. */
+ eassert (! (LONG_MIN <= v && v <= LONG_MAX));
bool complement = v < 0;
if (complement)
v = -1 - v;
- /* COUNT = 1 means just a single word of the given size. ORDER = -1
- is arbitrary since there's only a single word. ENDIAN = 0 means
- use the native endian-ness. NAILS = 0 means use the whole
- word. */
- mpz_import (result, 1, -1, sizeof v, 0, 0, &v);
+ enum { nails = sizeof v * CHAR_BIT - INTMAX_WIDTH };
+# ifndef HAVE_GMP
+ /* mini-gmp requires NAILS to be zero, which is true for all
+ likely Emacs platforms. Sanity-check this. */
+ verify (nails == 0);
+# endif
+
+ mpz_import (result, 1, -1, sizeof v, 0, nails, &v);
if (complement)
mpz_com (result, result);
}
diff --git a/src/data.c b/src/data.c
index 0754d4c..7a8179e 100644
--- a/src/data.c
+++ b/src/data.c
@@ -2775,6 +2775,9 @@ enum arithop
Alogxor
};
+enum { FIXNUMS_FIT_IN_LONG = (LONG_MIN <= MOST_NEGATIVE_FIXNUM
+ && MOST_POSITIVE_FIXNUM <= LONG_MAX) };
+
static void
free_mpz_value (void *value_ptr)
{
@@ -2829,7 +2832,7 @@ arith_driver (enum arithop code, ptrdiff_t nargs,
Lisp_Object *args)
case Aadd:
if (BIGNUMP (val))
mpz_add (accum, accum, XBIGNUM (val)->value);
- else if (sizeof (EMACS_INT) > sizeof (long))
+ else if (! FIXNUMS_FIT_IN_LONG)
{
mpz_t tem;
mpz_init (tem);
@@ -2854,7 +2857,7 @@ arith_driver (enum arithop code, ptrdiff_t nargs,
Lisp_Object *args)
}
else if (BIGNUMP (val))
mpz_sub (accum, accum, XBIGNUM (val)->value);
- else if (sizeof (EMACS_INT) > sizeof (long))
+ else if (! FIXNUMS_FIT_IN_LONG)
{
mpz_t tem;
mpz_init (tem);
@@ -2870,7 +2873,7 @@ arith_driver (enum arithop code, ptrdiff_t nargs,
Lisp_Object *args)
case Amult:
if (BIGNUMP (val))
mpz_mul (accum, accum, XBIGNUM (val)->value);
- else if (sizeof (EMACS_INT) > sizeof (long))
+ else if (! FIXNUMS_FIT_IN_LONG)
{
mpz_t tem;
mpz_init (tem);
diff --git a/src/lisp.h b/src/lisp.h
index f2cfe81..fe384d1 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -30,10 +30,11 @@ along with GNU Emacs. If not, see
<https://www.gnu.org/licenses/>. */
#include <float.h>
#include <inttypes.h>
#include <limits.h>
+
#ifdef HAVE_GMP
-#include <gmp.h>
+# include <gmp.h>
#else
-#include "mini-gmp.h"
+# include "mini-gmp.h"
#endif
#include <intprops.h>
@@ -3566,10 +3567,10 @@ mpz_set_intmax (mpz_t result, intmax_t v)
/* mpz_set_si works in terms of long, but Emacs may use a wider
integer type, and so sometimes will have to construct the mpz_t
by hand. */
- if (sizeof (intmax_t) > sizeof (long) && (long) v != v)
- mpz_set_intmax_slow (result, v);
- else
+ if (LONG_MIN <= v && v <= LONG_MAX)
mpz_set_si (result, v);
+ else
+ mpz_set_intmax_slow (result, v);
}
/* Build a frequently used 2/3/4-integer lists. */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] master b184020: Minor fixups for intmax_t→mpz_t conversion,
Paul Eggert <=