diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2018-08-27 21:27:50 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2018-08-27 21:45:22 -0700 |
commit | 9abaf5f3581ecb76f30e8a6e7ee0e9633c133d1c (patch) | |
tree | c39260a6e26845b0a1307be98b38581468925c58 /src/alloc.c | |
parent | bf1b147b55e1328efca6e40181e79dd9a369895d (diff) | |
download | emacs-9abaf5f3581ecb76f30e8a6e7ee0e9633c133d1c.tar.gz emacs-9abaf5f3581ecb76f30e8a6e7ee0e9633c133d1c.tar.bz2 emacs-9abaf5f3581ecb76f30e8a6e7ee0e9633c133d1c.zip |
Modularize bignums better
* src/bignum.c, src/bignum.h: New files. Only modules that
need to know how bignums are implemented should include
bignum.h. Currently these are alloc.c, bignum.c (of course),
data.c, emacs.c, emacs-module.c, floatfns.c, fns.c, print.c.
* src/Makefile.in (base_obj): Add bignum.o.
* src/alloc.c (make_bignum_str): Move to bignum.c.
(make_number): Remove; replaced by bignum.c’s make_integer.
All callers changed.
* src/conf_post.h (ARG_NONNULL): New macro.
* src/json.c (json_to_lisp): Use it.
* src/data.c (Fnatnump):
Move NATNUMP’s implementation here from lisp.h.
* src/data.c (Fnumber_to_string):
* src/editfns.c (styled_format):
Move conversion of string to bignum to bignum_to_string, and
call it here.
* src/emacs-module.c (module_make_integer):
* src/floatfns.c (Fabs):
Simplify by using make_int.
* src/emacs.c: Include bignum.h, to expand its inline fns.
* src/floatfns.c (Ffloat): Simplify by using XFLOATINT.
(rounding_driver): Simplify by using double_to_bignum.
(rounddiv_q): Clarify use of temporaries.
* src/lisp.h: Move decls that need to know bignum internals to
bignum.h. Do not include gmp.h or mini-gmp.h; that is now
bignum.h’s job.
(GMP_NUM_BITS, struct Lisp_Bignum, XBIGNUM, mpz_set_intmax):
Move to bignum.h.
(make_int): New function.
(NATNUMP): Remove; all callers changed to use Fnatnump.
(XFLOATINT): If arg is a bignum, use bignum_to_double, so that
bignum internals are not exposed here.
* src/print.c (print_vectorlike): Use SAFE_ALLOCA to avoid the
need for a record_unwind_protect_ptr.
Diffstat (limited to 'src/alloc.c')
-rw-r--r-- | src/alloc.c | 78 |
1 files changed, 1 insertions, 77 deletions
diff --git a/src/alloc.c b/src/alloc.c index c9788ab4c6b..350b668ec61 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -31,6 +31,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ #endif #include "lisp.h" +#include "bignum.h" #include "dispextern.h" #include "intervals.h" #include "ptr-bounds.h" @@ -3728,83 +3729,6 @@ build_marker (struct buffer *buf, ptrdiff_t charpos, ptrdiff_t bytepos) } - -Lisp_Object -make_bignum_str (const char *num, int base) -{ - struct Lisp_Bignum *b = ALLOCATE_PSEUDOVECTOR (struct Lisp_Bignum, value, - PVEC_BIGNUM); - mpz_init (b->value); - int check = mpz_set_str (b->value, num, base); - eassert (check == 0); - return make_lisp_ptr (b, Lisp_Vectorlike); -} - -/* Given an mpz_t, make a number. This may return a bignum or a - fixnum depending on VALUE. */ - -Lisp_Object -make_number (mpz_t value) -{ - size_t bits = mpz_sizeinbase (value, 2); - - if (bits <= FIXNUM_BITS) - { - EMACS_INT v = 0; - int i = 0, shift = 0; - - do - { - EMACS_INT limb = mpz_getlimbn (value, i++); - v += limb << shift; - shift += GMP_NUMB_BITS; - } - while (shift < bits); - - if (mpz_sgn (value) < 0) - v = -v; - - if (!FIXNUM_OVERFLOW_P (v)) - return make_fixnum (v); - } - - /* The documentation says integer-width should be nonnegative, so - a single comparison suffices even though 'bits' is unsigned. */ - if (integer_width < bits) - range_error (); - - struct Lisp_Bignum *b = ALLOCATE_PSEUDOVECTOR (struct Lisp_Bignum, value, - PVEC_BIGNUM); - /* We could mpz_init + mpz_swap here, to avoid a copy, but the - resulting API seemed possibly confusing. */ - mpz_init_set (b->value, value); - - return make_lisp_ptr (b, Lisp_Vectorlike); -} - -void -mpz_set_intmax_slow (mpz_t result, intmax_t v) -{ - /* 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; - - 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); -} - - /* Return a newly created vector or string with specified arguments as elements. If all the arguments are characters that can fit in a string of events, make a string; otherwise, make a vector. |