diff options
| author | Paul Eggert | 2019-08-21 00:06:00 -0700 |
|---|---|---|
| committer | Paul Eggert | 2019-08-21 00:11:45 -0700 |
| commit | 39fee209942ab7c35b4789f0010264cd6a52197b (patch) | |
| tree | 96f1858c890436713ba0da0fca93d1f33d7dd33a /src | |
| parent | 3881542edeac3e94291c2ce574edf0b0e52764a8 (diff) | |
| download | emacs-39fee209942ab7c35b4789f0010264cd6a52197b.tar.gz emacs-39fee209942ab7c35b4789f0010264cd6a52197b.zip | |
Be more careful about pointers to bignum vals
This uses ‘const’ to be better at catching bugs that
mistakenly attempt to modify a bignum value.
Lisp bignums are supposed to be immutable.
* src/alloc.c (make_pure_bignum):
* src/fns.c (sxhash_bignum):
Accept Lisp_Object instead of struct Lisp_Bignum *, as that’s
simpler now. Caller changed.
* src/bignum.h (bignum_val, xbignum_val): New inline functions.
Prefer them to &i->value and XBIGNUM (i)->value, since they
apply ‘const’ to the result.
* src/timefns.c (lisp_to_timespec): Use mpz_t const *
to point to a bignum value.
Diffstat (limited to 'src')
| -rw-r--r-- | src/alloc.c | 11 | ||||
| -rw-r--r-- | src/bignum.c | 10 | ||||
| -rw-r--r-- | src/bignum.h | 17 | ||||
| -rw-r--r-- | src/data.c | 30 | ||||
| -rw-r--r-- | src/floatfns.c | 6 | ||||
| -rw-r--r-- | src/fns.c | 22 | ||||
| -rw-r--r-- | src/pdumper.c | 15 | ||||
| -rw-r--r-- | src/timefns.c | 13 |
8 files changed, 69 insertions, 55 deletions
diff --git a/src/alloc.c b/src/alloc.c index bb8e97f8737..53af7325f47 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -5290,9 +5290,10 @@ make_pure_float (double num) | |||
| 5290 | space. */ | 5290 | space. */ |
| 5291 | 5291 | ||
| 5292 | static Lisp_Object | 5292 | static Lisp_Object |
| 5293 | make_pure_bignum (struct Lisp_Bignum *value) | 5293 | make_pure_bignum (Lisp_Object value) |
| 5294 | { | 5294 | { |
| 5295 | size_t i, nlimbs = mpz_size (value->value); | 5295 | mpz_t const *n = xbignum_val (value); |
| 5296 | size_t i, nlimbs = mpz_size (*n); | ||
| 5296 | size_t nbytes = nlimbs * sizeof (mp_limb_t); | 5297 | size_t nbytes = nlimbs * sizeof (mp_limb_t); |
| 5297 | mp_limb_t *pure_limbs; | 5298 | mp_limb_t *pure_limbs; |
| 5298 | mp_size_t new_size; | 5299 | mp_size_t new_size; |
| @@ -5303,10 +5304,10 @@ make_pure_bignum (struct Lisp_Bignum *value) | |||
| 5303 | int limb_alignment = alignof (mp_limb_t); | 5304 | int limb_alignment = alignof (mp_limb_t); |
| 5304 | pure_limbs = pure_alloc (nbytes, - limb_alignment); | 5305 | pure_limbs = pure_alloc (nbytes, - limb_alignment); |
| 5305 | for (i = 0; i < nlimbs; ++i) | 5306 | for (i = 0; i < nlimbs; ++i) |
| 5306 | pure_limbs[i] = mpz_getlimbn (value->value, i); | 5307 | pure_limbs[i] = mpz_getlimbn (*n, i); |
| 5307 | 5308 | ||
| 5308 | new_size = nlimbs; | 5309 | new_size = nlimbs; |
| 5309 | if (mpz_sgn (value->value) < 0) | 5310 | if (mpz_sgn (*n) < 0) |
| 5310 | new_size = -new_size; | 5311 | new_size = -new_size; |
| 5311 | 5312 | ||
| 5312 | mpz_roinit_n (b->value, pure_limbs, new_size); | 5313 | mpz_roinit_n (b->value, pure_limbs, new_size); |
| @@ -5456,7 +5457,7 @@ purecopy (Lisp_Object obj) | |||
| 5456 | return obj; | 5457 | return obj; |
| 5457 | } | 5458 | } |
| 5458 | else if (BIGNUMP (obj)) | 5459 | else if (BIGNUMP (obj)) |
| 5459 | obj = make_pure_bignum (XBIGNUM (obj)); | 5460 | obj = make_pure_bignum (obj); |
| 5460 | else | 5461 | else |
| 5461 | { | 5462 | { |
| 5462 | AUTO_STRING (fmt, "Don't know how to purify: %S"); | 5463 | AUTO_STRING (fmt, "Don't know how to purify: %S"); |
diff --git a/src/bignum.c b/src/bignum.c index 90b1ebea876..167b73eee02 100644 --- a/src/bignum.c +++ b/src/bignum.c | |||
| @@ -63,7 +63,7 @@ init_bignum (void) | |||
| 63 | double | 63 | double |
| 64 | bignum_to_double (Lisp_Object n) | 64 | bignum_to_double (Lisp_Object n) |
| 65 | { | 65 | { |
| 66 | return mpz_get_d_rounded (XBIGNUM (n)->value); | 66 | return mpz_get_d_rounded (*xbignum_val (n)); |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | /* Return D, converted to a Lisp integer. Discard any fraction. | 69 | /* Return D, converted to a Lisp integer. Discard any fraction. |
| @@ -264,13 +264,13 @@ intmax_t | |||
| 264 | bignum_to_intmax (Lisp_Object x) | 264 | bignum_to_intmax (Lisp_Object x) |
| 265 | { | 265 | { |
| 266 | intmax_t i; | 266 | intmax_t i; |
| 267 | return mpz_to_intmax (XBIGNUM (x)->value, &i) ? i : 0; | 267 | return mpz_to_intmax (*xbignum_val (x), &i) ? i : 0; |
| 268 | } | 268 | } |
| 269 | uintmax_t | 269 | uintmax_t |
| 270 | bignum_to_uintmax (Lisp_Object x) | 270 | bignum_to_uintmax (Lisp_Object x) |
| 271 | { | 271 | { |
| 272 | uintmax_t i; | 272 | uintmax_t i; |
| 273 | return mpz_to_uintmax (XBIGNUM (x)->value, &i) ? i : 0; | 273 | return mpz_to_uintmax (*xbignum_val (x), &i) ? i : 0; |
| 274 | } | 274 | } |
| 275 | 275 | ||
| 276 | /* Yield an upper bound on the buffer size needed to contain a C | 276 | /* Yield an upper bound on the buffer size needed to contain a C |
| @@ -284,7 +284,7 @@ mpz_bufsize (mpz_t const num, int base) | |||
| 284 | ptrdiff_t | 284 | ptrdiff_t |
| 285 | bignum_bufsize (Lisp_Object num, int base) | 285 | bignum_bufsize (Lisp_Object num, int base) |
| 286 | { | 286 | { |
| 287 | return mpz_bufsize (XBIGNUM (num)->value, base); | 287 | return mpz_bufsize (*xbignum_val (num), base); |
| 288 | } | 288 | } |
| 289 | 289 | ||
| 290 | /* Convert NUM to a nearest double, as opposed to mpz_get_d which | 290 | /* Convert NUM to a nearest double, as opposed to mpz_get_d which |
| @@ -318,7 +318,7 @@ ptrdiff_t | |||
| 318 | bignum_to_c_string (char *buf, ptrdiff_t size, Lisp_Object num, int base) | 318 | bignum_to_c_string (char *buf, ptrdiff_t size, Lisp_Object num, int base) |
| 319 | { | 319 | { |
| 320 | eassert (bignum_bufsize (num, abs (base)) == size); | 320 | eassert (bignum_bufsize (num, abs (base)) == size); |
| 321 | mpz_get_str (buf, base, XBIGNUM (num)->value); | 321 | mpz_get_str (buf, base, *xbignum_val (num)); |
| 322 | ptrdiff_t n = size - 2; | 322 | ptrdiff_t n = size - 2; |
| 323 | return !buf[n - 1] ? n - 1 : n + !!buf[n]; | 323 | return !buf[n - 1] ? n - 1 : n + !!buf[n]; |
| 324 | } | 324 | } |
diff --git a/src/bignum.h b/src/bignum.h index 9a32ffb0374..bf7b3669537 100644 --- a/src/bignum.h +++ b/src/bignum.h | |||
| @@ -80,6 +80,19 @@ mpz_set_uintmax (mpz_t result, uintmax_t v) | |||
| 80 | mpz_set_uintmax_slow (result, v); | 80 | mpz_set_uintmax_slow (result, v); |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | /* Return a pointer to the mpz_t value represented by the bignum I. | ||
| 84 | It is const because the value should not change. */ | ||
| 85 | INLINE mpz_t const * | ||
| 86 | bignum_val (struct Lisp_Bignum const *i) | ||
| 87 | { | ||
| 88 | return &i->value; | ||
| 89 | } | ||
| 90 | INLINE mpz_t const * | ||
| 91 | xbignum_val (Lisp_Object i) | ||
| 92 | { | ||
| 93 | return bignum_val (XBIGNUM (i)); | ||
| 94 | } | ||
| 95 | |||
| 83 | /* Return a pointer to an mpz_t that is equal to the Lisp integer I. | 96 | /* Return a pointer to an mpz_t that is equal to the Lisp integer I. |
| 84 | If I is a bignum this returns a pointer to I's representation; | 97 | If I is a bignum this returns a pointer to I's representation; |
| 85 | otherwise this sets *TMP to I's value and returns TMP. */ | 98 | otherwise this sets *TMP to I's value and returns TMP. */ |
| @@ -91,7 +104,7 @@ bignum_integer (mpz_t *tmp, Lisp_Object i) | |||
| 91 | mpz_set_intmax (*tmp, XFIXNUM (i)); | 104 | mpz_set_intmax (*tmp, XFIXNUM (i)); |
| 92 | return tmp; | 105 | return tmp; |
| 93 | } | 106 | } |
| 94 | return &XBIGNUM (i)->value; | 107 | return xbignum_val (i); |
| 95 | } | 108 | } |
| 96 | 109 | ||
| 97 | /* Set RESULT to the value stored in the Lisp integer I. If I is a | 110 | /* Set RESULT to the value stored in the Lisp integer I. If I is a |
| @@ -103,7 +116,7 @@ mpz_set_integer (mpz_t result, Lisp_Object i) | |||
| 103 | if (FIXNUMP (i)) | 116 | if (FIXNUMP (i)) |
| 104 | mpz_set_intmax (result, XFIXNUM (i)); | 117 | mpz_set_intmax (result, XFIXNUM (i)); |
| 105 | else | 118 | else |
| 106 | mpz_set (result, XBIGNUM (i)->value); | 119 | mpz_set (result, *xbignum_val (i)); |
| 107 | } | 120 | } |
| 108 | 121 | ||
| 109 | INLINE_HEADER_END | 122 | INLINE_HEADER_END |
diff --git a/src/data.c b/src/data.c index cf9f8e56133..8344bfdd3d5 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -525,7 +525,7 @@ DEFUN ("natnump", Fnatnump, Snatnump, 1, 1, 0, | |||
| 525 | (Lisp_Object object) | 525 | (Lisp_Object object) |
| 526 | { | 526 | { |
| 527 | return ((FIXNUMP (object) ? 0 <= XFIXNUM (object) | 527 | return ((FIXNUMP (object) ? 0 <= XFIXNUM (object) |
| 528 | : BIGNUMP (object) && 0 <= mpz_sgn (XBIGNUM (object)->value)) | 528 | : BIGNUMP (object) && 0 <= mpz_sgn (*xbignum_val (object))) |
| 529 | ? Qt : Qnil); | 529 | ? Qt : Qnil); |
| 530 | } | 530 | } |
| 531 | 531 | ||
| @@ -2481,7 +2481,7 @@ arithcompare (Lisp_Object num1, Lisp_Object num2, | |||
| 2481 | else if (isnan (f1)) | 2481 | else if (isnan (f1)) |
| 2482 | lt = eq = gt = false; | 2482 | lt = eq = gt = false; |
| 2483 | else | 2483 | else |
| 2484 | i2 = mpz_cmp_d (XBIGNUM (num2)->value, f1); | 2484 | i2 = mpz_cmp_d (*xbignum_val (num2), f1); |
| 2485 | } | 2485 | } |
| 2486 | else if (FIXNUMP (num1)) | 2486 | else if (FIXNUMP (num1)) |
| 2487 | { | 2487 | { |
| @@ -2502,7 +2502,7 @@ arithcompare (Lisp_Object num1, Lisp_Object num2, | |||
| 2502 | i2 = XFIXNUM (num2); | 2502 | i2 = XFIXNUM (num2); |
| 2503 | } | 2503 | } |
| 2504 | else | 2504 | else |
| 2505 | i2 = mpz_sgn (XBIGNUM (num2)->value); | 2505 | i2 = mpz_sgn (*xbignum_val (num2)); |
| 2506 | } | 2506 | } |
| 2507 | else if (FLOATP (num2)) | 2507 | else if (FLOATP (num2)) |
| 2508 | { | 2508 | { |
| @@ -2510,12 +2510,12 @@ arithcompare (Lisp_Object num1, Lisp_Object num2, | |||
| 2510 | if (isnan (f2)) | 2510 | if (isnan (f2)) |
| 2511 | lt = eq = gt = false; | 2511 | lt = eq = gt = false; |
| 2512 | else | 2512 | else |
| 2513 | i1 = mpz_cmp_d (XBIGNUM (num1)->value, f2); | 2513 | i1 = mpz_cmp_d (*xbignum_val (num1), f2); |
| 2514 | } | 2514 | } |
| 2515 | else if (FIXNUMP (num2)) | 2515 | else if (FIXNUMP (num2)) |
| 2516 | i1 = mpz_sgn (XBIGNUM (num1)->value); | 2516 | i1 = mpz_sgn (*xbignum_val (num1)); |
| 2517 | else | 2517 | else |
| 2518 | i1 = mpz_cmp (XBIGNUM (num1)->value, XBIGNUM (num2)->value); | 2518 | i1 = mpz_cmp (*xbignum_val (num1), *xbignum_val (num2)); |
| 2519 | 2519 | ||
| 2520 | if (eq) | 2520 | if (eq) |
| 2521 | { | 2521 | { |
| @@ -3005,7 +3005,7 @@ usage: (- &optional NUMBER-OR-MARKER &rest MORE-NUMBERS-OR-MARKERS) */) | |||
| 3005 | return make_int (-XFIXNUM (a)); | 3005 | return make_int (-XFIXNUM (a)); |
| 3006 | if (FLOATP (a)) | 3006 | if (FLOATP (a)) |
| 3007 | return make_float (-XFLOAT_DATA (a)); | 3007 | return make_float (-XFLOAT_DATA (a)); |
| 3008 | mpz_neg (mpz[0], XBIGNUM (a)->value); | 3008 | mpz_neg (mpz[0], *xbignum_val (a)); |
| 3009 | return make_integer_mpz (); | 3009 | return make_integer_mpz (); |
| 3010 | } | 3010 | } |
| 3011 | return arith_driver (Asub, nargs, args, a); | 3011 | return arith_driver (Asub, nargs, args, a); |
| @@ -3214,7 +3214,7 @@ representation. */) | |||
| 3214 | 3214 | ||
| 3215 | if (BIGNUMP (value)) | 3215 | if (BIGNUMP (value)) |
| 3216 | { | 3216 | { |
| 3217 | mpz_t *nonneg = &XBIGNUM (value)->value; | 3217 | mpz_t const *nonneg = xbignum_val (value); |
| 3218 | if (mpz_sgn (*nonneg) < 0) | 3218 | if (mpz_sgn (*nonneg) < 0) |
| 3219 | { | 3219 | { |
| 3220 | mpz_com (mpz[0], *nonneg); | 3220 | mpz_com (mpz[0], *nonneg); |
| @@ -3245,10 +3245,10 @@ In this case, the sign bit is duplicated. */) | |||
| 3245 | { | 3245 | { |
| 3246 | if (EQ (value, make_fixnum (0))) | 3246 | if (EQ (value, make_fixnum (0))) |
| 3247 | return value; | 3247 | return value; |
| 3248 | if (mpz_sgn (XBIGNUM (count)->value) < 0) | 3248 | if (mpz_sgn (*xbignum_val (count)) < 0) |
| 3249 | { | 3249 | { |
| 3250 | EMACS_INT v = (FIXNUMP (value) ? XFIXNUM (value) | 3250 | EMACS_INT v = (FIXNUMP (value) ? XFIXNUM (value) |
| 3251 | : mpz_sgn (XBIGNUM (value)->value)); | 3251 | : mpz_sgn (*xbignum_val (value))); |
| 3252 | return make_fixnum (v < 0 ? -1 : 0); | 3252 | return make_fixnum (v < 0 ? -1 : 0); |
| 3253 | } | 3253 | } |
| 3254 | overflow_error (); | 3254 | overflow_error (); |
| @@ -3291,8 +3291,8 @@ expt_integer (Lisp_Object x, Lisp_Object y) | |||
| 3291 | if (TYPE_RANGED_FIXNUMP (unsigned long, y)) | 3291 | if (TYPE_RANGED_FIXNUMP (unsigned long, y)) |
| 3292 | exp = XFIXNUM (y); | 3292 | exp = XFIXNUM (y); |
| 3293 | else if (MOST_POSITIVE_FIXNUM < ULONG_MAX && BIGNUMP (y) | 3293 | else if (MOST_POSITIVE_FIXNUM < ULONG_MAX && BIGNUMP (y) |
| 3294 | && mpz_fits_ulong_p (XBIGNUM (y)->value)) | 3294 | && mpz_fits_ulong_p (*xbignum_val (y))) |
| 3295 | exp = mpz_get_ui (XBIGNUM (y)->value); | 3295 | exp = mpz_get_ui (*xbignum_val (y)); |
| 3296 | else | 3296 | else |
| 3297 | overflow_error (); | 3297 | overflow_error (); |
| 3298 | 3298 | ||
| @@ -3311,7 +3311,7 @@ Markers are converted to integers. */) | |||
| 3311 | return make_int (XFIXNUM (number) + 1); | 3311 | return make_int (XFIXNUM (number) + 1); |
| 3312 | if (FLOATP (number)) | 3312 | if (FLOATP (number)) |
| 3313 | return (make_float (1.0 + XFLOAT_DATA (number))); | 3313 | return (make_float (1.0 + XFLOAT_DATA (number))); |
| 3314 | mpz_add_ui (mpz[0], XBIGNUM (number)->value, 1); | 3314 | mpz_add_ui (mpz[0], *xbignum_val (number), 1); |
| 3315 | return make_integer_mpz (); | 3315 | return make_integer_mpz (); |
| 3316 | } | 3316 | } |
| 3317 | 3317 | ||
| @@ -3326,7 +3326,7 @@ Markers are converted to integers. */) | |||
| 3326 | return make_int (XFIXNUM (number) - 1); | 3326 | return make_int (XFIXNUM (number) - 1); |
| 3327 | if (FLOATP (number)) | 3327 | if (FLOATP (number)) |
| 3328 | return (make_float (-1.0 + XFLOAT_DATA (number))); | 3328 | return (make_float (-1.0 + XFLOAT_DATA (number))); |
| 3329 | mpz_sub_ui (mpz[0], XBIGNUM (number)->value, 1); | 3329 | mpz_sub_ui (mpz[0], *xbignum_val (number), 1); |
| 3330 | return make_integer_mpz (); | 3330 | return make_integer_mpz (); |
| 3331 | } | 3331 | } |
| 3332 | 3332 | ||
| @@ -3337,7 +3337,7 @@ DEFUN ("lognot", Flognot, Slognot, 1, 1, 0, | |||
| 3337 | CHECK_INTEGER (number); | 3337 | CHECK_INTEGER (number); |
| 3338 | if (FIXNUMP (number)) | 3338 | if (FIXNUMP (number)) |
| 3339 | return make_fixnum (~XFIXNUM (number)); | 3339 | return make_fixnum (~XFIXNUM (number)); |
| 3340 | mpz_com (mpz[0], XBIGNUM (number)->value); | 3340 | mpz_com (mpz[0], *xbignum_val (number)); |
| 3341 | return make_integer_mpz (); | 3341 | return make_integer_mpz (); |
| 3342 | } | 3342 | } |
| 3343 | 3343 | ||
diff --git a/src/floatfns.c b/src/floatfns.c index a913aad5aac..0a85df47dec 100644 --- a/src/floatfns.c +++ b/src/floatfns.c | |||
| @@ -268,9 +268,9 @@ DEFUN ("abs", Fabs, Sabs, 1, 1, 0, | |||
| 268 | } | 268 | } |
| 269 | else | 269 | else |
| 270 | { | 270 | { |
| 271 | if (mpz_sgn (XBIGNUM (arg)->value) < 0) | 271 | if (mpz_sgn (*xbignum_val (arg)) < 0) |
| 272 | { | 272 | { |
| 273 | mpz_neg (mpz[0], XBIGNUM (arg)->value); | 273 | mpz_neg (mpz[0], *xbignum_val (arg)); |
| 274 | arg = make_integer_mpz (); | 274 | arg = make_integer_mpz (); |
| 275 | } | 275 | } |
| 276 | } | 276 | } |
| @@ -315,7 +315,7 @@ This is the same as the exponent of a float. */) | |||
| 315 | value = ivalue - 1; | 315 | value = ivalue - 1; |
| 316 | } | 316 | } |
| 317 | else if (!FIXNUMP (arg)) | 317 | else if (!FIXNUMP (arg)) |
| 318 | value = mpz_sizeinbase (XBIGNUM (arg)->value, 2) - 1; | 318 | value = mpz_sizeinbase (*xbignum_val (arg), 2) - 1; |
| 319 | else | 319 | else |
| 320 | { | 320 | { |
| 321 | EMACS_INT i = XFIXNUM (arg); | 321 | EMACS_INT i = XFIXNUM (arg); |
| @@ -47,7 +47,6 @@ static void sort_vector_copy (Lisp_Object, ptrdiff_t, | |||
| 47 | enum equal_kind { EQUAL_NO_QUIT, EQUAL_PLAIN, EQUAL_INCLUDING_PROPERTIES }; | 47 | enum equal_kind { EQUAL_NO_QUIT, EQUAL_PLAIN, EQUAL_INCLUDING_PROPERTIES }; |
| 48 | static bool internal_equal (Lisp_Object, Lisp_Object, | 48 | static bool internal_equal (Lisp_Object, Lisp_Object, |
| 49 | enum equal_kind, int, Lisp_Object); | 49 | enum equal_kind, int, Lisp_Object); |
| 50 | static EMACS_UINT sxhash_bignum (struct Lisp_Bignum *); | ||
| 51 | 50 | ||
| 52 | DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0, | 51 | DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0, |
| 53 | doc: /* Return the argument unchanged. */ | 52 | doc: /* Return the argument unchanged. */ |
| @@ -1444,7 +1443,7 @@ DEFUN ("nthcdr", Fnthcdr, Snthcdr, 2, 2, 0, | |||
| 1444 | } | 1443 | } |
| 1445 | else | 1444 | else |
| 1446 | { | 1445 | { |
| 1447 | if (mpz_sgn (XBIGNUM (n)->value) < 0) | 1446 | if (mpz_sgn (*xbignum_val (n)) < 0) |
| 1448 | return tail; | 1447 | return tail; |
| 1449 | num = large_num; | 1448 | num = large_num; |
| 1450 | } | 1449 | } |
| @@ -1482,11 +1481,11 @@ DEFUN ("nthcdr", Fnthcdr, Snthcdr, 2, 2, 0, | |||
| 1482 | CYCLE_LENGTH. */ | 1481 | CYCLE_LENGTH. */ |
| 1483 | /* Add N mod CYCLE_LENGTH to NUM. */ | 1482 | /* Add N mod CYCLE_LENGTH to NUM. */ |
| 1484 | if (cycle_length <= ULONG_MAX) | 1483 | if (cycle_length <= ULONG_MAX) |
| 1485 | num += mpz_tdiv_ui (XBIGNUM (n)->value, cycle_length); | 1484 | num += mpz_tdiv_ui (*xbignum_val (n), cycle_length); |
| 1486 | else | 1485 | else |
| 1487 | { | 1486 | { |
| 1488 | mpz_set_intmax (mpz[0], cycle_length); | 1487 | mpz_set_intmax (mpz[0], cycle_length); |
| 1489 | mpz_tdiv_r (mpz[0], XBIGNUM (n)->value, mpz[0]); | 1488 | mpz_tdiv_r (mpz[0], *xbignum_val (n), mpz[0]); |
| 1490 | intptr_t iz; | 1489 | intptr_t iz; |
| 1491 | mpz_export (&iz, NULL, -1, sizeof iz, 0, 0, mpz[0]); | 1490 | mpz_export (&iz, NULL, -1, sizeof iz, 0, 0, mpz[0]); |
| 1492 | num += iz; | 1491 | num += iz; |
| @@ -1595,7 +1594,7 @@ The value is actually the tail of LIST whose car is ELT. */) | |||
| 1595 | { | 1594 | { |
| 1596 | Lisp_Object tem = XCAR (tail); | 1595 | Lisp_Object tem = XCAR (tail); |
| 1597 | if (BIGNUMP (tem) | 1596 | if (BIGNUMP (tem) |
| 1598 | && mpz_cmp (XBIGNUM (elt)->value, XBIGNUM (tem)->value) == 0) | 1597 | && mpz_cmp (*xbignum_val (elt), *xbignum_val (tem)) == 0) |
| 1599 | return tail; | 1598 | return tail; |
| 1600 | } | 1599 | } |
| 1601 | } | 1600 | } |
| @@ -2307,7 +2306,7 @@ This differs from numeric comparison: (eql 0.0 -0.0) returns nil and | |||
| 2307 | return FLOATP (obj2) && same_float (obj1, obj2) ? Qt : Qnil; | 2306 | return FLOATP (obj2) && same_float (obj1, obj2) ? Qt : Qnil; |
| 2308 | else if (BIGNUMP (obj1)) | 2307 | else if (BIGNUMP (obj1)) |
| 2309 | return ((BIGNUMP (obj2) | 2308 | return ((BIGNUMP (obj2) |
| 2310 | && mpz_cmp (XBIGNUM (obj1)->value, XBIGNUM (obj2)->value) == 0) | 2309 | && mpz_cmp (*xbignum_val (obj1), *xbignum_val (obj2)) == 0) |
| 2311 | ? Qt : Qnil); | 2310 | ? Qt : Qnil); |
| 2312 | else | 2311 | else |
| 2313 | return EQ (obj1, obj2) ? Qt : Qnil; | 2312 | return EQ (obj1, obj2) ? Qt : Qnil; |
| @@ -2437,7 +2436,7 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, enum equal_kind equal_kind, | |||
| 2437 | if (ASIZE (o2) != size) | 2436 | if (ASIZE (o2) != size) |
| 2438 | return false; | 2437 | return false; |
| 2439 | if (BIGNUMP (o1)) | 2438 | if (BIGNUMP (o1)) |
| 2440 | return mpz_cmp (XBIGNUM (o1)->value, XBIGNUM (o2)->value) == 0; | 2439 | return mpz_cmp (*xbignum_val (o1), *xbignum_val (o2)) == 0; |
| 2441 | if (OVERLAYP (o1)) | 2440 | if (OVERLAYP (o1)) |
| 2442 | { | 2441 | { |
| 2443 | if (!internal_equal (OVERLAY_START (o1), OVERLAY_START (o2), | 2442 | if (!internal_equal (OVERLAY_START (o1), OVERLAY_START (o2), |
| @@ -4640,13 +4639,14 @@ sxhash_bool_vector (Lisp_Object vec) | |||
| 4640 | /* Return a hash for a bignum. */ | 4639 | /* Return a hash for a bignum. */ |
| 4641 | 4640 | ||
| 4642 | static EMACS_UINT | 4641 | static EMACS_UINT |
| 4643 | sxhash_bignum (struct Lisp_Bignum *bignum) | 4642 | sxhash_bignum (Lisp_Object bignum) |
| 4644 | { | 4643 | { |
| 4645 | size_t i, nlimbs = mpz_size (bignum->value); | 4644 | mpz_t const *n = xbignum_val (bignum); |
| 4645 | size_t i, nlimbs = mpz_size (*n); | ||
| 4646 | EMACS_UINT hash = 0; | 4646 | EMACS_UINT hash = 0; |
| 4647 | 4647 | ||
| 4648 | for (i = 0; i < nlimbs; ++i) | 4648 | for (i = 0; i < nlimbs; ++i) |
| 4649 | hash = sxhash_combine (hash, mpz_getlimbn (bignum->value, i)); | 4649 | hash = sxhash_combine (hash, mpz_getlimbn (*n, i)); |
| 4650 | 4650 | ||
| 4651 | return SXHASH_REDUCE (hash); | 4651 | return SXHASH_REDUCE (hash); |
| 4652 | } | 4652 | } |
| @@ -4680,7 +4680,7 @@ sxhash (Lisp_Object obj, int depth) | |||
| 4680 | /* This can be everything from a vector to an overlay. */ | 4680 | /* This can be everything from a vector to an overlay. */ |
| 4681 | case Lisp_Vectorlike: | 4681 | case Lisp_Vectorlike: |
| 4682 | if (BIGNUMP (obj)) | 4682 | if (BIGNUMP (obj)) |
| 4683 | hash = sxhash_bignum (XBIGNUM (obj)); | 4683 | hash = sxhash_bignum (obj); |
| 4684 | else if (VECTORP (obj) || RECORDP (obj)) | 4684 | else if (VECTORP (obj) || RECORDP (obj)) |
| 4685 | /* According to the CL HyperSpec, two arrays are equal only if | 4685 | /* According to the CL HyperSpec, two arrays are equal only if |
| 4686 | they are `eq', except for strings and bit-vectors. In | 4686 | they are `eq', except for strings and bit-vectors. In |
diff --git a/src/pdumper.c b/src/pdumper.c index 326a346a632..73a50cee53a 100644 --- a/src/pdumper.c +++ b/src/pdumper.c | |||
| @@ -2211,7 +2211,7 @@ dump_bignum (struct dump_context *ctx, Lisp_Object object) | |||
| 2211 | const struct Lisp_Bignum *bignum = XBIGNUM (object); | 2211 | const struct Lisp_Bignum *bignum = XBIGNUM (object); |
| 2212 | START_DUMP_PVEC (ctx, &bignum->header, struct Lisp_Bignum, out); | 2212 | START_DUMP_PVEC (ctx, &bignum->header, struct Lisp_Bignum, out); |
| 2213 | verify (sizeof (out->value) >= sizeof (struct bignum_reload_info)); | 2213 | verify (sizeof (out->value) >= sizeof (struct bignum_reload_info)); |
| 2214 | dump_field_fixup_later (ctx, out, bignum, &bignum->value); | 2214 | dump_field_fixup_later (ctx, out, bignum, xbignum_val (object)); |
| 2215 | dump_off bignum_offset = finish_dump_pvec (ctx, &out->header); | 2215 | dump_off bignum_offset = finish_dump_pvec (ctx, &out->header); |
| 2216 | if (ctx->flags.dump_object_contents) | 2216 | if (ctx->flags.dump_object_contents) |
| 2217 | { | 2217 | { |
| @@ -3397,19 +3397,18 @@ dump_cold_buffer (struct dump_context *ctx, Lisp_Object data) | |||
| 3397 | static void | 3397 | static void |
| 3398 | dump_cold_bignum (struct dump_context *ctx, Lisp_Object object) | 3398 | dump_cold_bignum (struct dump_context *ctx, Lisp_Object object) |
| 3399 | { | 3399 | { |
| 3400 | const struct Lisp_Bignum *bignum = XBIGNUM (object); | 3400 | mpz_t const *n = xbignum_val (object); |
| 3401 | size_t sz_nlimbs = mpz_size (bignum->value); | 3401 | size_t sz_nlimbs = mpz_size (*n); |
| 3402 | eassert (sz_nlimbs < DUMP_OFF_MAX); | 3402 | eassert (sz_nlimbs < DUMP_OFF_MAX); |
| 3403 | dump_align_output (ctx, alignof (mp_limb_t)); | 3403 | dump_align_output (ctx, alignof (mp_limb_t)); |
| 3404 | dump_off nlimbs = (dump_off) sz_nlimbs; | 3404 | dump_off nlimbs = (dump_off) sz_nlimbs; |
| 3405 | Lisp_Object descriptor | 3405 | Lisp_Object descriptor |
| 3406 | = list2 (dump_off_to_lisp (ctx->offset), | 3406 | = list2 (dump_off_to_lisp (ctx->offset), |
| 3407 | dump_off_to_lisp ((mpz_sgn (bignum->value) < 0 | 3407 | dump_off_to_lisp (mpz_sgn (*n) < 0 ? -nlimbs : nlimbs)); |
| 3408 | ? -nlimbs : nlimbs))); | ||
| 3409 | Fputhash (object, descriptor, ctx->bignum_data); | 3408 | Fputhash (object, descriptor, ctx->bignum_data); |
| 3410 | for (mp_size_t i = 0; i < nlimbs; ++i) | 3409 | for (mp_size_t i = 0; i < nlimbs; ++i) |
| 3411 | { | 3410 | { |
| 3412 | mp_limb_t limb = mpz_getlimbn (bignum->value, i); | 3411 | mp_limb_t limb = mpz_getlimbn (*n, i); |
| 3413 | dump_write (ctx, &limb, sizeof (limb)); | 3412 | dump_write (ctx, &limb, sizeof (limb)); |
| 3414 | } | 3413 | } |
| 3415 | } | 3414 | } |
| @@ -5205,8 +5204,8 @@ dump_do_dump_relocation (const uintptr_t dump_base, | |||
| 5205 | { | 5204 | { |
| 5206 | struct Lisp_Bignum *bignum = dump_ptr (dump_base, reloc_offset); | 5205 | struct Lisp_Bignum *bignum = dump_ptr (dump_base, reloc_offset); |
| 5207 | struct bignum_reload_info reload_info; | 5206 | struct bignum_reload_info reload_info; |
| 5208 | verify (sizeof (reload_info) <= sizeof (bignum->value)); | 5207 | verify (sizeof (reload_info) <= sizeof (*bignum_val (bignum))); |
| 5209 | memcpy (&reload_info, &bignum->value, sizeof (reload_info)); | 5208 | memcpy (&reload_info, bignum_val (bignum), sizeof (reload_info)); |
| 5210 | const mp_limb_t *limbs = | 5209 | const mp_limb_t *limbs = |
| 5211 | dump_ptr (dump_base, reload_info.data_location); | 5210 | dump_ptr (dump_base, reload_info.data_location); |
| 5212 | mpz_roinit_n (bignum->value, limbs, reload_info.nlimbs); | 5211 | mpz_roinit_n (bignum->value, limbs, reload_info.nlimbs); |
diff --git a/src/timefns.c b/src/timefns.c index 3c4c15b6576..6c9473f22a6 100644 --- a/src/timefns.c +++ b/src/timefns.c | |||
| @@ -91,7 +91,7 @@ static Lisp_Object timespec_hz; | |||
| 91 | #define TRILLION 1000000000000 | 91 | #define TRILLION 1000000000000 |
| 92 | #if FIXNUM_OVERFLOW_P (TRILLION) | 92 | #if FIXNUM_OVERFLOW_P (TRILLION) |
| 93 | static Lisp_Object trillion; | 93 | static Lisp_Object trillion; |
| 94 | # define ztrillion (XBIGNUM (trillion)->value) | 94 | # define ztrillion (*xbignum_val (trillion)) |
| 95 | #else | 95 | #else |
| 96 | # define trillion make_fixnum (TRILLION) | 96 | # define trillion make_fixnum (TRILLION) |
| 97 | # if ULONG_MAX < TRILLION || !FASTER_TIMEFNS | 97 | # if ULONG_MAX < TRILLION || !FASTER_TIMEFNS |
| @@ -534,7 +534,7 @@ lisp_time_hz_ticks (struct lisp_time t, Lisp_Object hz) | |||
| 534 | return make_int (ticks / XFIXNUM (t.hz) | 534 | return make_int (ticks / XFIXNUM (t.hz) |
| 535 | - (ticks % XFIXNUM (t.hz) < 0)); | 535 | - (ticks % XFIXNUM (t.hz) < 0)); |
| 536 | } | 536 | } |
| 537 | else if (! (BIGNUMP (hz) && 0 < mpz_sgn (XBIGNUM (hz)->value))) | 537 | else if (! (BIGNUMP (hz) && 0 < mpz_sgn (*xbignum_val (hz)))) |
| 538 | invalid_hz (hz); | 538 | invalid_hz (hz); |
| 539 | 539 | ||
| 540 | mpz_mul (mpz[0], | 540 | mpz_mul (mpz[0], |
| @@ -906,6 +906,7 @@ lisp_to_timespec (struct lisp_time t) | |||
| 906 | struct timespec result = invalid_timespec (); | 906 | struct timespec result = invalid_timespec (); |
| 907 | int ns; | 907 | int ns; |
| 908 | mpz_t *q = &mpz[0]; | 908 | mpz_t *q = &mpz[0]; |
| 909 | mpz_t const *qt = q; | ||
| 909 | 910 | ||
| 910 | if (FASTER_TIMEFNS && EQ (t.hz, timespec_hz)) | 911 | if (FASTER_TIMEFNS && EQ (t.hz, timespec_hz)) |
| 911 | { | 912 | { |
| @@ -924,7 +925,7 @@ lisp_to_timespec (struct lisp_time t) | |||
| 924 | return result; | 925 | return result; |
| 925 | } | 926 | } |
| 926 | else | 927 | else |
| 927 | ns = mpz_fdiv_q_ui (*q, XBIGNUM (t.ticks)->value, TIMESPEC_HZ); | 928 | ns = mpz_fdiv_q_ui (*q, *xbignum_val (t.ticks), TIMESPEC_HZ); |
| 928 | } | 929 | } |
| 929 | else if (FASTER_TIMEFNS && EQ (t.hz, make_fixnum (1))) | 930 | else if (FASTER_TIMEFNS && EQ (t.hz, make_fixnum (1))) |
| 930 | { | 931 | { |
| @@ -941,7 +942,7 @@ lisp_to_timespec (struct lisp_time t) | |||
| 941 | return result; | 942 | return result; |
| 942 | } | 943 | } |
| 943 | else | 944 | else |
| 944 | q = &XBIGNUM (t.ticks)->value; | 945 | qt = xbignum_val (t.ticks); |
| 945 | } | 946 | } |
| 946 | else | 947 | else |
| 947 | { | 948 | { |
| @@ -953,7 +954,7 @@ lisp_to_timespec (struct lisp_time t) | |||
| 953 | /* With some versions of MinGW, tv_sec is a 64-bit type, whereas | 954 | /* With some versions of MinGW, tv_sec is a 64-bit type, whereas |
| 954 | time_t is a 32-bit type. */ | 955 | time_t is a 32-bit type. */ |
| 955 | time_t sec; | 956 | time_t sec; |
| 956 | if (mpz_time (*q, &sec)) | 957 | if (mpz_time (*qt, &sec)) |
| 957 | { | 958 | { |
| 958 | result.tv_sec = sec; | 959 | result.tv_sec = sec; |
| 959 | result.tv_nsec = ns; | 960 | result.tv_nsec = ns; |
| @@ -1038,7 +1039,7 @@ lispint_arith (Lisp_Object a, Lisp_Object b, bool subtract) | |||
| 1038 | if (eabs (XFIXNUM (b)) <= ULONG_MAX) | 1039 | if (eabs (XFIXNUM (b)) <= ULONG_MAX) |
| 1039 | { | 1040 | { |
| 1040 | ((XFIXNUM (b) < 0) == subtract ? mpz_add_ui : mpz_sub_ui) | 1041 | ((XFIXNUM (b) < 0) == subtract ? mpz_add_ui : mpz_sub_ui) |
| 1041 | (mpz[0], XBIGNUM (a)->value, eabs (XFIXNUM (b))); | 1042 | (mpz[0], *xbignum_val (a), eabs (XFIXNUM (b))); |
| 1042 | mpz_done = true; | 1043 | mpz_done = true; |
| 1043 | } | 1044 | } |
| 1044 | } | 1045 | } |