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/lisp.h | |
parent | bf1b147b55e1328efca6e40181e79dd9a369895d (diff) | |
download | emacs-9abaf5f3581ecb76f30e8a6e7ee0e9633c133d1c.tar.gz |
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/lisp.h')
-rw-r--r-- | src/lisp.h | 72 |
1 files changed, 19 insertions, 53 deletions
diff --git a/src/lisp.h b/src/lisp.h index fb11a11fda3..555496bc271 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -31,12 +31,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ #include <inttypes.h> #include <limits.h> -#ifdef HAVE_GMP -# include <gmp.h> -#else -# include "mini-gmp.h" -#endif - #include <intprops.h> #include <verify.h> @@ -589,6 +583,10 @@ enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = false }; INLINE void set_sub_char_table_contents (Lisp_Object, ptrdiff_t, Lisp_Object); +/* Defined in bignum.c. */ +extern double bignum_to_double (Lisp_Object); +extern Lisp_Object make_bigint (intmax_t); + /* Defined in chartab.c. */ extern Lisp_Object char_table_ref (Lisp_Object, int); extern void char_table_set (Lisp_Object, int, Lisp_Object); @@ -1013,14 +1011,6 @@ enum More_Lisp_Bits #define MOST_POSITIVE_FIXNUM (EMACS_INT_MAX >> INTTYPEBITS) #define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM) - -/* GMP-related limits. */ - -/* Number of data bits in a limb. */ -#ifndef GMP_NUMB_BITS -enum { GMP_NUMB_BITS = TYPE_WIDTH (mp_limb_t) }; -#endif - #if USE_LSB_TAG INLINE Lisp_Object @@ -2460,31 +2450,25 @@ XUSER_PTR (Lisp_Object a) } #endif -struct Lisp_Bignum -{ - union vectorlike_header header; - mpz_t value; -}; - INLINE bool BIGNUMP (Lisp_Object x) { return PSEUDOVECTORP (x, PVEC_BIGNUM); } -INLINE struct Lisp_Bignum * -XBIGNUM (Lisp_Object a) -{ - eassert (BIGNUMP (a)); - return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Bignum); -} - INLINE bool INTEGERP (Lisp_Object x) { return FIXNUMP (x) || BIGNUMP (x); } +/* Return a Lisp integer with value taken from n. */ +INLINE Lisp_Object +make_int (intmax_t n) +{ + return FIXNUM_OVERFLOW_P (n) ? make_bigint (n) : make_fixnum (n); +} + /* Forwarding pointer to an int variable. This is allowed only in the value cell of a symbol, @@ -2698,13 +2682,6 @@ FIXNATP (Lisp_Object x) return FIXNUMP (x) && 0 <= XFIXNUM (x); } INLINE bool -NATNUMP (Lisp_Object x) -{ - if (BIGNUMP (x)) - return mpz_sgn (XBIGNUM (x)->value) >= 0; - return FIXNUMP (x) && 0 <= XFIXNUM (x); -} -INLINE bool NUMBERP (Lisp_Object x) { return INTEGERP (x) || FLOATP (x); @@ -2848,9 +2825,9 @@ CHECK_FIXNAT (Lisp_Object x) INLINE double XFLOATINT (Lisp_Object n) { - if (BIGNUMP (n)) - return mpz_get_d (XBIGNUM (n)->value); - return FLOATP (n) ? XFLOAT_DATA (n) : XFIXNUM (n); + return (FIXNUMP (n) ? XFIXNUM (n) + : FLOATP (n) ? XFLOAT_DATA (n) + : bignum_to_double (n)); } INLINE void @@ -3310,6 +3287,11 @@ set_sub_char_table_contents (Lisp_Object table, ptrdiff_t idx, Lisp_Object val) XSUB_CHAR_TABLE (table)->contents[idx] = val; } +/* Defined in bignum.c. */ +extern Lisp_Object bignum_to_string (Lisp_Object, int); +extern Lisp_Object make_bignum_str (char const *, int); +extern Lisp_Object double_to_bignum (double); + /* Defined in data.c. */ extern _Noreturn void wrong_choice (Lisp_Object, Lisp_Object); extern void notify_variable_watchers (Lisp_Object, Lisp_Object, @@ -3582,22 +3564,6 @@ extern Lisp_Object list5 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, enum constype {CONSTYPE_HEAP, CONSTYPE_PURE}; extern Lisp_Object listn (enum constype, ptrdiff_t, Lisp_Object, ...); -extern Lisp_Object make_bignum_str (const char *num, int base); -extern Lisp_Object make_number (mpz_t value); -extern void mpz_set_intmax_slow (mpz_t result, intmax_t v); - -INLINE void -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 (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. */ INLINE Lisp_Object |