1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-05 03:30:24 +02:00

Simplify struct scm_bignum

* libguile/integers.c (struct scm_bignum): Now that SCM_I_BIG_MPZ is
gone with other deprecated code, we can simplify the bignum
representation.  Adapt all users.
This commit is contained in:
Andy Wingo 2025-05-28 11:22:29 +02:00
parent 0a0ecc518b
commit 75842cf215

View file

@ -1,4 +1,4 @@
/* Copyright 1995-2016,2018-2022
/* Copyright 1995-2016,2018-2022,2025
Free Software Foundation, Inc.
This file is part of Guile.
@ -58,23 +58,14 @@ verify (SCM_MOST_POSITIVE_FIXNUM <= (mp_limb_t) -1);
struct scm_bignum
{
scm_t_bits tag;
/* FIXME: In Guile 3.2, replace this union with just a "size" member.
Digits are always allocated inline. */
union {
mpz_t mpz;
struct {
int zero;
int size;
mp_limb_t *limbs;
} z;
} u;
int size;
mp_limb_t limbs[];
};
static int
bignum_size (struct scm_bignum *z)
{
return z->u.z.size;
return z->size;
}
static int
@ -98,8 +89,7 @@ bignum_limb_count (struct scm_bignum *z)
static mp_limb_t*
bignum_limbs (struct scm_bignum *z)
{
// FIXME: In the future we can just return z->limbs.
return z->u.z.limbs;
return z->limbs;
}
static inline unsigned long
@ -151,17 +141,7 @@ allocate_bignum (size_t nlimbs)
struct scm_bignum *z = scm_gc_malloc_pointerless (size, "bignum");
z->tag = scm_tc16_big;
z->u.z.zero = 0;
z->u.z.size = nlimbs;
z->u.z.limbs = z->limbs;
// _mp_alloc == 0 means GMP will never try to free this memory.
ASSERT (z->u.mpz[0]._mp_alloc == 0);
// Our "size" field should alias the mpz's _mp_size field.
ASSERT (z->u.mpz[0]._mp_size == nlimbs);
// Limbs are always allocated inline.
ASSERT (z->u.mpz[0]._mp_d == z->limbs);
z->size = nlimbs;
// z->limbs left uninitialized.
return z;
@ -170,24 +150,24 @@ allocate_bignum (size_t nlimbs)
static struct scm_bignum *
bignum_trim1 (struct scm_bignum *z)
{
ASSERT (z->u.z.size > 0);
z->u.z.size -= (z->limbs[z->u.z.size - 1] == 0);
ASSERT (z->size > 0);
z->size -= (z->limbs[z->size - 1] == 0);
return z;
}
static struct scm_bignum *
bignum_trimn (struct scm_bignum *z)
{
ASSERT (z->u.z.size > 0);
while (z->u.z.size > 0 && z->limbs[z->u.z.size - 1] == 0)
z->u.z.size--;
ASSERT (z->size > 0);
while (z->size > 0 && z->limbs[z->size - 1] == 0)
z->size--;
return z;
}
static struct scm_bignum *
negate_bignum (struct scm_bignum *z)
{
z->u.z.size = -z->u.z.size;
z->size = -z->size;
return z;
}
@ -2851,7 +2831,7 @@ do_add_1 (int negative, mp_limb_t *xd, size_t xn, mp_limb_t y)
if (mpn_add_1 (rd, xd, xn, y))
rd[xn] = 1;
else
result->u.z.size--;
result->size--;
// No need to normalize as magnitude is increasing and one operand
// already a bignum.
return scm_from_bignum (bignum_negate_if (negative, result));
@ -2866,7 +2846,7 @@ do_add (int negative, mp_limb_t *xd, size_t xn, mp_limb_t *yd, size_t yn)
if (mpn_add (rd, xd, xn, yd, yn))
rd[xn] = 1;
else
result->u.z.size--;
result->size--;
// No need to normalize as magnitude is increasing and one operand
// already a bignum.
return scm_from_bignum (bignum_negate_if (negative, result));
@ -3102,7 +3082,7 @@ scm_integer_mul_zi (struct scm_bignum *x, scm_t_inum y)
if (hi)
rd[xn] = hi;
else
result->u.z.size--;
result->size--;
scm_remember_upto_here_1 (x);
return normalize_bignum (bignum_negate_if (negate, (result)));
}