* libguile/integers.c (scm_integer_logtest_ii, scm_integer_logtest_zi)
(scm_integer_logtest_zz): New internal functions.
* libguile/integers.h: Declare the new internal functions.
* libguile/numbers.c (scm_logtest): Use new internal functions.
* libguile/integers.c (scm_integer_logxor_ii, scm_integer_logxor_zi)
(scm_integer_logxor_zz): New internal functions.
* libguile/integers.h: Declare the new internal functions.
* libguile/numbers.c (scm_logxor): Use new internal functions.
* libguile/integers.c (scm_integer_logior_ii, scm_integer_logior_zi)
(scm_integer_logior_zz): New internal functions.
* libguile/integers.h: Declare the new internal functions.
* libguile/numbers.c (scm_logior): Use new internal functions.
* libguile/integers.c (scm_integer_logand_ii, scm_integer_logand_zi)
(scm_integer_logand_zz): New internal functions.
* libguile/integers.h: Declare the new internal functions.
* libguile/numbers.c (scm_logand): Use new internal functions.
* libguile/integers.c (scm_integer_lcm_ii)
(scm_integer_lcm_zi, scm_integer_lcm_zz): New internal functions.
* libguile/integers.h: Declare internal functions.
* libguile/numbers.c (scm_lcm): Use the new functions.
* libguile/integers.c (scm_integer_gcd_ii)
(scm_integer_gcd_zi, scm_integer_gcd_zz): New internal functions.
* libguile/integers.h: Declare internal functions.
* libguile/numbers.c (scm_gcd): Use the new functions.
* libguile/integers.c (scm_integer_ceiling_remainder_ii)
(scm_integer_ceiling_remainder_iz, scm_integer_ceiling_remainder_zi)
(scm_integer_ceiling_remainder_zz): New internal functions.
(bignum_is_positive): New helper.
* libguile/integers.h: Declare internal functions.
* libguile/numbers.c (scm_ceiling_remainder): Use the new functions.
* libguile/integers.c (scm_integer_ceiling_quotient_ii)
(scm_integer_ceiling_quotient_iz, scm_integer_ceiling_quotient_zi)
(scm_integer_ceiling_quotient_zz): New internal functions.
(take_bignum_from_mpz): Change to also normalize the mpz, as all callers
required.
(long_sign, bignum_cmp_long): New helpers.
* libguile/integers.h: Declare internal functions.
* libguile/numbers.c (scm_ceiling_quotient): Use the new functions.
* libguile/integers.c (scm_integer_abs_i, scm_integer_abs_z): New
internal functions.
* libguile/integers.h: Declare internal functions.
* libguile/numbers.c (scm_abs): Use the new functions.
* libguile/integers.c (scm_is_integer_odd_i):
(scm_is_integer_odd_z): New internal functions. Add a number of
internal support routines.
* libguile/integers.h: Declare internal functions.
* libguile/numbers.c (scm_odd_p, scm_even_p): Use the new functions.
This avoids gmp aborting e.g. with (ash 1 (expt 2 37)). The new limit is
such that (ash 1 (expt 30)) is accepted but (ash 1 (expt 31)) throws.
Fixes https://bugs.gnu.org/48150
* libguile/numbers.c (ash, round-ash): As stated.
* test-suite/tests/numbers.test: Test a case known to make gmp abort before.
This suggests moving the conditional that determines if mini-gmp is used
into scmconfig.h.
* configure.ac: replace PKG_CHECK_MODULES for gmp with AC_LIB_HAVE_LINKFLAGS
Remove ENABLE_MINI_GMP define. Also don't run mpz_inits test for
--enable-mini-gmp.
* libguile/gen-scmconfig.c (main) [ENABLE_MINI_GMP]: replace ENABLE_MINI_GMP
with SCM_I_GSC_ENABLE_MINI_GMP
* libguile/bytevectors.c [ENABLE_MINI_GMP]: replace ENABLE_MINI_GMP
with SCM_ENABLE_MINI_GMP
* libguile/init.c [ENABLE_MINI_GMP]: replace ENABLE_MINI_GMP
with SCM_ENABLE_MINI_GMP
* libguile/numbers.c: include scm.h
[SCM_ENABLE_MINI_GMP]: provide mpz_inits and mpz_clears
[ENABLE_MINI_GMP]: prefer SCM_ENABLE_MINI_GMP to ENABLE_MINI_GMP
* libguile/numbers.h: include scm.h
* libguile/random.c [ENABLE_MINI_GMP]: replace ENABLE_MINI_GMP
with SCM_ENABLE_MINI_GMP
* libguile/socket.c [ENABLE_MINI_GMP]: replace ENABLE_MINI_GMP
with SCM_ENABLE_MINI_GMP
This significantly speeds up loads that create lots of bignums, like
(language cps slot-allocation) for files with many top-level
definitions. Compiling such a file is typically 2.5 times faster.
See <https://lists.gnu.org/archive/html/guile-devel/2020-02/msg00023.html>.
* libguile/numbers.c (custom_gmp_malloc): Use
'scm_gc_malloc_pointerless' instead of 'scm_malloc'.
(custom_gmp_realloc): Use 'scm_gc_realloc'.
(custom_gmp_free): Remove call to 'free'.
(make_bignum): Use 'scm_gc_malloc' instead of 'scm_gc_malloc_pointerless'.
Call 'scm_i_set_finalizer' only when SCM_INSTALL_GMP_MEMORY_FUNCTIONS is
false.
* libguile/numbers.c (scm_exact_integer_sqrt, scm_sqrt)
(exact_integer_is_perfect_square, exact_integer_floor_square_root):
Where it is trivial to do so, use GMP's low-level mpn functions to
avoid heap allocation.
Fixes <https://bugs.gnu.org/21901>.
Reported by Zefram <zefram@fysh.org>.
* libguile/numbers.c: Add another top-level 'verify' to ensure that
LONG_MIN is not a fixnum.
(scm_ash, scm_round_ash): Ensure that when the shift count is LONG_MIN,
it is not handled via the normal code path, to avoid signed overflow
when the shift count is negated.
* test-suite/tests/numbers.test: Add tests.
This is a followup to commit 011aec7e24.
When rounding, right shifting a negative integer by a huge shift count
results in 0, not -1.
* libguile/numbers.c: Add top-level 'verify' to ensure that the
assumptions in 'scm_ash' and 'scm_round_ash' are valid.
(scm_round_ash): In the case that handles huge right shifts, require
that the shift count _exceeds_ the integer length, and return 0 instead
of -1.
* test-suite/tests/numbers.test: Adjust tests accordingly.
Fixes <https://bugs.gnu.org/32644>.
Reported by Stefan Israelsson Tampe <stefan.itampe@gmail.com>.
The need for this arose because the type inferrer for 'ursh' sometimes
passes (- 1 (expt 2 64)) as the second argument to 'ash'.
* libguile/numbers.c (scm_ash, scm_round_ash): Gracefully handle several
cases where the shift count does not fit in a C 'long'.
* test-suite/tests/numbers.test: Add tests.
* libguile/scm.h (scm_tc7_values): New tc7. Never seen by Scheme, so we
don't need to update it anywhere else.
* libguile/values.h (scm_is_values): New public static inline function.
(scm_i_nvalues, scm_i_value_ref): New private static inline
functions.
(SCM_VALUESP): Use scm_is_value.
(scm_values_2, scm_values_3): New functions.
(scm_values_vtable): Remove; values objects are not structs any more.
* libguile/values.c (scm_i_extract_values_2): Adapt to new values
representation.
(print_values): Remove now-unused function.
(scm_c_nvalues): Use scm_i_nvalues.
(scm_c_value_ref): Use scm_i_value_ref.
(scm_values, scm_c_values): Make the new-style objects, which store
their values inline.
(scm_values_2, scm_values_3): New helpers, to avoid consing little
useless lists.
* libguile/vm-engine.c (halt, subr-call)
* libguile/eval.c (eval): Adapt to new values representation.
* libguile/i18n.c (scm_locale_string_to_integer)
(scm_locale_string_to_integer)
* libguile/numbers.c (scm_i_floor_divide, scm_i_ceiling_divide)
(scm_i_truncate_divide, scm_i_centered_divide, scm_i_round_divide)
(scm_i_exact_integer_sqrt)
* libguile/r6rs-ports.c (make_bytevector_output_port)
* libguile/srfi-1.c (scm_srfi1_partition, scm_srfi1_partition_x)
* libguile/srfi-14.c (scm_char_set_diff_plus_intersection)
(scm_char_set_diff_plus_intersection_x)
* libguile/posix.c (scm_getrlimit, scm_open_process): Adapt to use
scm_values_2 or scm_values_3.
* libguile/print.c (iprin1): Add printer for values objects.
As the FSF advises, 'There is no legal significance to using the
three-character sequence “(C)”, but it does no harm.' It does take up
space though! For that reason, we remove it here from our C files.