diff options
| author | Paul Eggert | 2018-08-27 21:27:50 -0700 |
|---|---|---|
| committer | Paul Eggert | 2018-08-27 21:45:22 -0700 |
| commit | 9abaf5f3581ecb76f30e8a6e7ee0e9633c133d1c (patch) | |
| tree | c39260a6e26845b0a1307be98b38581468925c58 /src/data.c | |
| parent | bf1b147b55e1328efca6e40181e79dd9a369895d (diff) | |
| download | emacs-9abaf5f3581ecb76f30e8a6e7ee0e9633c133d1c.tar.gz 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/data.c')
| -rw-r--r-- | src/data.c | 38 |
1 files changed, 17 insertions, 21 deletions
diff --git a/src/data.c b/src/data.c index 170a74a6589..ece76a5bc6f 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -29,6 +29,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 29 | #include <intprops.h> | 29 | #include <intprops.h> |
| 30 | 30 | ||
| 31 | #include "lisp.h" | 31 | #include "lisp.h" |
| 32 | #include "bignum.h" | ||
| 32 | #include "puresize.h" | 33 | #include "puresize.h" |
| 33 | #include "character.h" | 34 | #include "character.h" |
| 34 | #include "buffer.h" | 35 | #include "buffer.h" |
| @@ -525,9 +526,9 @@ DEFUN ("natnump", Fnatnump, Snatnump, 1, 1, 0, | |||
| 525 | attributes: const) | 526 | attributes: const) |
| 526 | (Lisp_Object object) | 527 | (Lisp_Object object) |
| 527 | { | 528 | { |
| 528 | if (NATNUMP (object)) | 529 | return ((FIXNUMP (object) ? 0 <= XFIXNUM (object) |
| 529 | return Qt; | 530 | : BIGNUMP (object) && 0 <= mpz_sgn (XBIGNUM (object)->value)) |
| 530 | return Qnil; | 531 | ? Qt : Qnil); |
| 531 | } | 532 | } |
| 532 | 533 | ||
| 533 | DEFUN ("numberp", Fnumberp, Snumberp, 1, 1, 0, | 534 | DEFUN ("numberp", Fnumberp, Snumberp, 1, 1, 0, |
| @@ -2400,7 +2401,7 @@ emacs_mpz_size (mpz_t const op) | |||
| 2400 | the library code aborts when a number is too large. These wrappers | 2401 | the library code aborts when a number is too large. These wrappers |
| 2401 | avoid the problem for functions that can return numbers much larger | 2402 | avoid the problem for functions that can return numbers much larger |
| 2402 | than their arguments. For slowly-growing numbers, the integer | 2403 | than their arguments. For slowly-growing numbers, the integer |
| 2403 | width check in make_number should suffice. */ | 2404 | width checks in bignum.c should suffice. */ |
| 2404 | 2405 | ||
| 2405 | static void | 2406 | static void |
| 2406 | emacs_mpz_mul (mpz_t rop, mpz_t const op1, mpz_t const op2) | 2407 | emacs_mpz_mul (mpz_t rop, mpz_t const op1, mpz_t const op2) |
| @@ -2770,12 +2771,7 @@ NUMBER may be an integer or a floating point number. */) | |||
| 2770 | int len; | 2771 | int len; |
| 2771 | 2772 | ||
| 2772 | if (BIGNUMP (number)) | 2773 | if (BIGNUMP (number)) |
| 2773 | { | 2774 | return bignum_to_string (number, 10); |
| 2774 | ptrdiff_t count = SPECPDL_INDEX (); | ||
| 2775 | char *str = mpz_get_str (NULL, 10, XBIGNUM (number)->value); | ||
| 2776 | record_unwind_protect_ptr (xfree, str); | ||
| 2777 | return unbind_to (count, make_unibyte_string (str, strlen (str))); | ||
| 2778 | } | ||
| 2779 | 2775 | ||
| 2780 | CHECK_FIXNUM_OR_FLOAT (number); | 2776 | CHECK_FIXNUM_OR_FLOAT (number); |
| 2781 | 2777 | ||
| @@ -3011,7 +3007,7 @@ arith_driver (enum arithop code, ptrdiff_t nargs, Lisp_Object *args) | |||
| 3011 | } | 3007 | } |
| 3012 | } | 3008 | } |
| 3013 | 3009 | ||
| 3014 | return unbind_to (count, make_number (accum)); | 3010 | return unbind_to (count, make_integer (accum)); |
| 3015 | } | 3011 | } |
| 3016 | 3012 | ||
| 3017 | static Lisp_Object | 3013 | static Lisp_Object |
| @@ -3141,7 +3137,7 @@ Both must be integers or markers. */) | |||
| 3141 | 3137 | ||
| 3142 | mpz_init (result); | 3138 | mpz_init (result); |
| 3143 | mpz_tdiv_r (result, *xmp, *ymp); | 3139 | mpz_tdiv_r (result, *xmp, *ymp); |
| 3144 | val = make_number (result); | 3140 | val = make_integer (result); |
| 3145 | mpz_clear (result); | 3141 | mpz_clear (result); |
| 3146 | 3142 | ||
| 3147 | if (xmp == &xm) | 3143 | if (xmp == &xm) |
| @@ -3221,7 +3217,7 @@ Both X and Y must be numbers or markers. */) | |||
| 3221 | if (cmpy < 0 ? cmpr > 0 : cmpr < 0) | 3217 | if (cmpy < 0 ? cmpr > 0 : cmpr < 0) |
| 3222 | mpz_add (result, result, *ymp); | 3218 | mpz_add (result, result, *ymp); |
| 3223 | 3219 | ||
| 3224 | val = make_number (result); | 3220 | val = make_integer (result); |
| 3225 | mpz_clear (result); | 3221 | mpz_clear (result); |
| 3226 | 3222 | ||
| 3227 | if (xmp == &xm) | 3223 | if (xmp == &xm) |
| @@ -3351,7 +3347,7 @@ In this case, the sign bit is duplicated. */) | |||
| 3351 | emacs_mpz_mul_2exp (result, XBIGNUM (value)->value, XFIXNUM (count)); | 3347 | emacs_mpz_mul_2exp (result, XBIGNUM (value)->value, XFIXNUM (count)); |
| 3352 | else | 3348 | else |
| 3353 | mpz_fdiv_q_2exp (result, XBIGNUM (value)->value, - XFIXNUM (count)); | 3349 | mpz_fdiv_q_2exp (result, XBIGNUM (value)->value, - XFIXNUM (count)); |
| 3354 | val = make_number (result); | 3350 | val = make_integer (result); |
| 3355 | mpz_clear (result); | 3351 | mpz_clear (result); |
| 3356 | } | 3352 | } |
| 3357 | else if (XFIXNUM (count) <= 0) | 3353 | else if (XFIXNUM (count) <= 0) |
| @@ -3378,7 +3374,7 @@ In this case, the sign bit is duplicated. */) | |||
| 3378 | else | 3374 | else |
| 3379 | mpz_fdiv_q_2exp (result, result, - XFIXNUM (count)); | 3375 | mpz_fdiv_q_2exp (result, result, - XFIXNUM (count)); |
| 3380 | 3376 | ||
| 3381 | val = make_number (result); | 3377 | val = make_integer (result); |
| 3382 | mpz_clear (result); | 3378 | mpz_clear (result); |
| 3383 | } | 3379 | } |
| 3384 | 3380 | ||
| @@ -3407,7 +3403,7 @@ expt_integer (Lisp_Object x, Lisp_Object y) | |||
| 3407 | ? (mpz_set_intmax (val, XFIXNUM (x)), val) | 3403 | ? (mpz_set_intmax (val, XFIXNUM (x)), val) |
| 3408 | : XBIGNUM (x)->value), | 3404 | : XBIGNUM (x)->value), |
| 3409 | exp); | 3405 | exp); |
| 3410 | Lisp_Object res = make_number (val); | 3406 | Lisp_Object res = make_integer (val); |
| 3411 | mpz_clear (val); | 3407 | mpz_clear (val); |
| 3412 | return res; | 3408 | return res; |
| 3413 | } | 3409 | } |
| @@ -3427,7 +3423,7 @@ Markers are converted to integers. */) | |||
| 3427 | mpz_t num; | 3423 | mpz_t num; |
| 3428 | mpz_init (num); | 3424 | mpz_init (num); |
| 3429 | mpz_add_ui (num, XBIGNUM (number)->value, 1); | 3425 | mpz_add_ui (num, XBIGNUM (number)->value, 1); |
| 3430 | number = make_number (num); | 3426 | number = make_integer (num); |
| 3431 | mpz_clear (num); | 3427 | mpz_clear (num); |
| 3432 | } | 3428 | } |
| 3433 | else | 3429 | else |
| @@ -3440,7 +3436,7 @@ Markers are converted to integers. */) | |||
| 3440 | mpz_t num; | 3436 | mpz_t num; |
| 3441 | mpz_init (num); | 3437 | mpz_init (num); |
| 3442 | mpz_set_intmax (num, XFIXNUM (number) + 1); | 3438 | mpz_set_intmax (num, XFIXNUM (number) + 1); |
| 3443 | number = make_number (num); | 3439 | number = make_integer (num); |
| 3444 | mpz_clear (num); | 3440 | mpz_clear (num); |
| 3445 | } | 3441 | } |
| 3446 | } | 3442 | } |
| @@ -3462,7 +3458,7 @@ Markers are converted to integers. */) | |||
| 3462 | mpz_t num; | 3458 | mpz_t num; |
| 3463 | mpz_init (num); | 3459 | mpz_init (num); |
| 3464 | mpz_sub_ui (num, XBIGNUM (number)->value, 1); | 3460 | mpz_sub_ui (num, XBIGNUM (number)->value, 1); |
| 3465 | number = make_number (num); | 3461 | number = make_integer (num); |
| 3466 | mpz_clear (num); | 3462 | mpz_clear (num); |
| 3467 | } | 3463 | } |
| 3468 | else | 3464 | else |
| @@ -3475,7 +3471,7 @@ Markers are converted to integers. */) | |||
| 3475 | mpz_t num; | 3471 | mpz_t num; |
| 3476 | mpz_init (num); | 3472 | mpz_init (num); |
| 3477 | mpz_set_intmax (num, XFIXNUM (number) - 1); | 3473 | mpz_set_intmax (num, XFIXNUM (number) - 1); |
| 3478 | number = make_number (num); | 3474 | number = make_integer (num); |
| 3479 | mpz_clear (num); | 3475 | mpz_clear (num); |
| 3480 | } | 3476 | } |
| 3481 | } | 3477 | } |
| @@ -3492,7 +3488,7 @@ DEFUN ("lognot", Flognot, Slognot, 1, 1, 0, | |||
| 3492 | mpz_t value; | 3488 | mpz_t value; |
| 3493 | mpz_init (value); | 3489 | mpz_init (value); |
| 3494 | mpz_com (value, XBIGNUM (number)->value); | 3490 | mpz_com (value, XBIGNUM (number)->value); |
| 3495 | number = make_number (value); | 3491 | number = make_integer (value); |
| 3496 | mpz_clear (value); | 3492 | mpz_clear (value); |
| 3497 | } | 3493 | } |
| 3498 | else | 3494 | else |