aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2019-08-21 00:06:00 -0700
committerPaul Eggert2019-08-21 00:11:45 -0700
commit39fee209942ab7c35b4789f0010264cd6a52197b (patch)
tree96f1858c890436713ba0da0fca93d1f33d7dd33a /src
parent3881542edeac3e94291c2ce574edf0b0e52764a8 (diff)
downloademacs-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.c11
-rw-r--r--src/bignum.c10
-rw-r--r--src/bignum.h17
-rw-r--r--src/data.c30
-rw-r--r--src/floatfns.c6
-rw-r--r--src/fns.c22
-rw-r--r--src/pdumper.c15
-rw-r--r--src/timefns.c13
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
5292static Lisp_Object 5292static Lisp_Object
5293make_pure_bignum (struct Lisp_Bignum *value) 5293make_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)
63double 63double
64bignum_to_double (Lisp_Object n) 64bignum_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
264bignum_to_intmax (Lisp_Object x) 264bignum_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}
269uintmax_t 269uintmax_t
270bignum_to_uintmax (Lisp_Object x) 270bignum_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)
284ptrdiff_t 284ptrdiff_t
285bignum_bufsize (Lisp_Object num, int base) 285bignum_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
318bignum_to_c_string (char *buf, ptrdiff_t size, Lisp_Object num, int base) 318bignum_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. */
85INLINE mpz_t const *
86bignum_val (struct Lisp_Bignum const *i)
87{
88 return &i->value;
89}
90INLINE mpz_t const *
91xbignum_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
109INLINE_HEADER_END 122INLINE_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);
diff --git a/src/fns.c b/src/fns.c
index 920addeaf13..6c47b3e5b1c 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -47,7 +47,6 @@ static void sort_vector_copy (Lisp_Object, ptrdiff_t,
47enum equal_kind { EQUAL_NO_QUIT, EQUAL_PLAIN, EQUAL_INCLUDING_PROPERTIES }; 47enum equal_kind { EQUAL_NO_QUIT, EQUAL_PLAIN, EQUAL_INCLUDING_PROPERTIES };
48static bool internal_equal (Lisp_Object, Lisp_Object, 48static bool internal_equal (Lisp_Object, Lisp_Object,
49 enum equal_kind, int, Lisp_Object); 49 enum equal_kind, int, Lisp_Object);
50static EMACS_UINT sxhash_bignum (struct Lisp_Bignum *);
51 50
52DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0, 51DEFUN ("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
4642static EMACS_UINT 4641static EMACS_UINT
4643sxhash_bignum (struct Lisp_Bignum *bignum) 4642sxhash_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)
3397static void 3397static void
3398dump_cold_bignum (struct dump_context *ctx, Lisp_Object object) 3398dump_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)
93static Lisp_Object trillion; 93static 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 }