diff options
| author | Paul Eggert | 2018-08-21 02:16:50 -0700 |
|---|---|---|
| committer | Paul Eggert | 2018-08-21 02:38:53 -0700 |
| commit | d6a497dd887cdbb35c5b4e2929e83962ba708159 (patch) | |
| tree | 9f0441f9fe88419b71e568b05ef7f7bea0a0ff06 /src/lisp.h | |
| parent | 77fc2725985b4e5ef977ae6930835c7f0771c61c (diff) | |
| download | emacs-d6a497dd887cdbb35c5b4e2929e83962ba708159.tar.gz emacs-d6a497dd887cdbb35c5b4e2929e83962ba708159.zip | |
Avoid libgmp aborts by imposing limits
libgmp calls ‘abort’ when given numbers too big for its
internal data structures. The numeric limit is large and
platform-dependent; with 64-bit GMP 6.1.2 it is around
2**2**37. Work around the problem by refusing to call libgmp
functions with arguments that would cause an abort. With luck
libgmp will have a better way to do this in the future.
Also, introduce a variable integer-width that lets the user
control how large bignums can be. This currently defaults
to 2**16, i.e., it allows bignums up to 2**2**16. This
should be enough for ordinary computation, and should
help Emacs to avoid thrashing or hanging.
Problem noted by Pip Cet (Bug#32463#71).
* doc/lispref/numbers.texi, etc/NEWS:
Document recent bignum changes, including this one.
Improve documentation for bitwise operations, in the light
of bignums.
* src/alloc.c (make_number): Enforce integer-width.
(integer_overflow): New function.
(xrealloc_for_gmp, xfree_for_gmp):
Move here from emacs.c, as it's memory allocation.
(init_alloc): Initialize GMP here, rather than in emacs.c.
(integer_width): New var.
* src/data.c (GMP_NLIMBS_MAX, NLIMBS_LIMIT): New constants.
(emacs_mpz_size, emacs_mpz_mul)
(emacs_mpz_mul_2exp, emacs_mpz_pow_ui): New functions.
(arith_driver, Fash, expt_integer): Use them.
(expt_integer): New function, containing integer code
that was out of place in floatfns.c.
(check_bignum_size, xmalloc_for_gmp): Remove.
* src/emacs.c (main): Do not initialize GMP here.
* src/floatfns.c (Fexpt): Use expt_integer, which
now contains integer code moved from here.
* src/lisp.h (GMP_NUMB_BITS): Define if gmp.h doesn’t.
Diffstat (limited to 'src/lisp.h')
| -rw-r--r-- | src/lisp.h | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/src/lisp.h b/src/lisp.h index fe384d1844b..8f48a334844 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -996,6 +996,14 @@ enum More_Lisp_Bits | |||
| 996 | #define MOST_POSITIVE_FIXNUM (EMACS_INT_MAX >> INTTYPEBITS) | 996 | #define MOST_POSITIVE_FIXNUM (EMACS_INT_MAX >> INTTYPEBITS) |
| 997 | #define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM) | 997 | #define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM) |
| 998 | 998 | ||
| 999 | |||
| 1000 | /* GMP-related limits. */ | ||
| 1001 | |||
| 1002 | /* Number of data bits in a limb. */ | ||
| 1003 | #ifndef GMP_NUMB_BITS | ||
| 1004 | enum { GMP_NUMB_BITS = TYPE_WIDTH (mp_limb_t) }; | ||
| 1005 | #endif | ||
| 1006 | |||
| 999 | #if USE_LSB_TAG | 1007 | #if USE_LSB_TAG |
| 1000 | 1008 | ||
| 1001 | INLINE Lisp_Object | 1009 | INLINE Lisp_Object |
| @@ -3338,7 +3346,7 @@ extern void set_internal (Lisp_Object, Lisp_Object, Lisp_Object, | |||
| 3338 | enum Set_Internal_Bind); | 3346 | enum Set_Internal_Bind); |
| 3339 | extern void set_default_internal (Lisp_Object, Lisp_Object, | 3347 | extern void set_default_internal (Lisp_Object, Lisp_Object, |
| 3340 | enum Set_Internal_Bind bindflag); | 3348 | enum Set_Internal_Bind bindflag); |
| 3341 | 3349 | extern Lisp_Object expt_integer (Lisp_Object, Lisp_Object); | |
| 3342 | extern void syms_of_data (void); | 3350 | extern void syms_of_data (void); |
| 3343 | extern void swap_in_global_binding (struct Lisp_Symbol *); | 3351 | extern void swap_in_global_binding (struct Lisp_Symbol *); |
| 3344 | 3352 | ||
| @@ -3700,6 +3708,7 @@ extern void display_malloc_warning (void); | |||
| 3700 | extern ptrdiff_t inhibit_garbage_collection (void); | 3708 | extern ptrdiff_t inhibit_garbage_collection (void); |
| 3701 | extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object); | 3709 | extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object); |
| 3702 | extern void free_cons (struct Lisp_Cons *); | 3710 | extern void free_cons (struct Lisp_Cons *); |
| 3711 | extern _Noreturn void integer_overflow (void); | ||
| 3703 | extern void init_alloc_once (void); | 3712 | extern void init_alloc_once (void); |
| 3704 | extern void init_alloc (void); | 3713 | extern void init_alloc (void); |
| 3705 | extern void syms_of_alloc (void); | 3714 | extern void syms_of_alloc (void); |