Am 27.02.2025 um 17:55 schrieb Mike Gran:
Can you share details about your compilation and testing setup?
I applied the patches to main and added some VMs at
github.com/spk121/guile-jonas
Thanks, very helpful.
Also, what exactly is not functional in your build?
Well, the very first problems I run into have nothing to do with the
64-bit problem, but, just basic bitrot. For some time, I had tried to ensure
that the 32-bit, non-threaded, non-LTO, non-JIT version of Guile
on MinGW kept working. But, it is broken on `main` again. The very first
problems are
- need win32 version of pagesize()
- need to make sure that dlopen searches PATH on Win32 and handles
DLLs of the form libfoo-X.dll in load-foreign-library
I've got patches for these.
Okay, so it seems these problems are somewhat orthogonal to the ones we
address
with our patches.
I have some more patches here that I contributed to fix Guile-Windows issues
in Lilypond. I can try to set up a repo on Github with all these patches applied
on top of current Guile 'main'.
However, as we currently use Guile 3.0.10 to do releases, I would first have to
make sure it still works with main.
Don't worry about rebasing for now. I'd just like to see what you have
working already in whatever form it is currently. My hope is that we can
prefer your patches, and then I can tweak around them for any problems
that remain.
Find the patches attached. I'm hoping to get a Mingw64 build environment
running under Windows 10 going with
the setup described in your repo.
Michael
From d637d8155566087243ee4afbbcd4296ad6f2480f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20K=C3=A4ppler?= <xmichae...@web.de>
Date: Tue, 25 Jun 2024 23:30:41 +0200
Subject: [PATCH 3/3] mpz->integer: do not convert to bignum if inum is
sufficient
Before, `take_mpz` would convert to bignum if the `mpz` value
does not fit into a signed long, even though `scm_t_inum` is not
coupled to `long` anymore. This leads to problems with functions
that expect values that numerically fit into a fixnum to be of
inum type, e.g., during bytecode compilation of long-long-immediates,
where `ash` returns a bignum, while the assembler requires an inum.
Call `scm_integer_from_mpz` instead, which will convert back to inum
if the number fits into an inum.
* libguile/integers.c (take_mpz): use `scm_integer_from_mpz`
---
libguile/integers.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libguile/integers.c b/libguile/integers.c
index 1560c5d17..092345b1d 100644
--- a/libguile/integers.c
+++ b/libguile/integers.c
@@ -335,7 +335,7 @@ take_mpz (mpz_ptr mpz)
if (mpz_fits_slong_p (mpz))
ret = scm_from_inum (mpz_get_si (mpz));
else
- ret = scm_from_bignum (make_bignum_from_mpz (mpz));
+ ret = scm_integer_from_mpz (mpz);
mpz_clear (mpz);
return ret;
}
--
2.34.1
From 7d21acce0f94b8fd372e6bb3e55d8b04d964c85b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20K=C3=A4ppler?= <xmichae...@web.de>
Date: Wed, 19 Jun 2024 22:07:09 +0200
Subject: [PATCH 2/3] Avoid using `long` integers literals
Bit manipulation on `long` integer literals caused overflow in
some cases (e.g., when calculating high powers of two) on Windows,
where `long` is only 32 bit width.
* libguile/integers.c (scm_integer_expt_ii, scm_integer_round_rsh_iu,
scm_integer_bit_extract_i): Use `scm_t_inum` type instead of `long`
in places where `long` could overflow.
---
libguile/integers.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/libguile/integers.c b/libguile/integers.c
index aab49428e..1560c5d17 100644
--- a/libguile/integers.c
+++ b/libguile/integers.c
@@ -2299,7 +2299,7 @@ scm_integer_expt_ii (scm_t_inum n, scm_t_inum k)
if (n == 2)
{
if (k < SCM_I_FIXNUM_BIT - 1)
- return SCM_I_MAKINUM (1L << k);
+ return SCM_I_MAKINUM (((scm_t_inum) 1) << k);
if (k < 64)
return scm_integer_from_uint64 (((uint64_t) 1) << k);
size_t nlimbs = k / (sizeof (mp_limb_t)*8) + 1;
@@ -2458,12 +2458,12 @@ scm_integer_round_rsh_iu (scm_t_inum n, unsigned long
count)
{
scm_t_inum q = SCM_SRS (n, count);
- if (0 == (n & (1L << (count-1))))
+ if (0 == (n & (((scm_t_inum) 1) << (count-1))))
return SCM_I_MAKINUM (q); /* round down */
- else if (n & ((1L << (count-1)) - 1))
+ else if (n & ((((scm_t_inum) 1) << (count-1)) - 1))
return SCM_I_MAKINUM (q + 1); /* round up */
else
- return SCM_I_MAKINUM ((~1L) & (q + 1)); /* round to even */
+ return SCM_I_MAKINUM (~((scm_t_inum) 1) & (q + 1)); /* round to even
*/
}
}
@@ -2505,7 +2505,7 @@ scm_integer_bit_extract_i (scm_t_inum n, unsigned long
start,
/* mask down to requisite bits */
bits = MIN (bits, SCM_I_FIXNUM_BIT);
- return SCM_I_MAKINUM (n & ((1L << bits) - 1));
+ return SCM_I_MAKINUM (n & ((((scm_t_inum) 1) << bits) - 1));
}
SCM
--
2.34.1
From 6f1ff1036bec220c0ade16d0ae37a82293a13c35 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20K=C3=A4ppler?= <xmichae...@web.de>
Date: Sat, 15 Jun 2024 22:18:56 +0200
Subject: [PATCH 1/3] Fix inum negation
The use of `negative_long` can lead to overflow if called
on inums that do not fit into a `long`. This led to
problems when normalizing bignums on Windows.
* libguile/integers.c: use new `negative_inum` for negating inums,
drop now unused function `negative_long`.
---
libguile/integers.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/libguile/integers.c b/libguile/integers.c
index 380ff193c..aab49428e 100644
--- a/libguile/integers.c
+++ b/libguile/integers.c
@@ -109,13 +109,6 @@ long_magnitude (long l)
return l < 0 ? ~mag + 1 : mag;
}
-static inline long
-negative_long (unsigned long mag)
-{
- ASSERT (mag <= (unsigned long) LONG_MIN);
- return ~mag + 1;
-}
-
static inline int64_t
negative_int64 (uint64_t mag)
{
@@ -141,6 +134,14 @@ inum_magnitude (scm_t_inum i)
return mag;
}
+static inline scm_t_inum
+negative_inum (scm_t_bits mag)
+{
+ scm_t_inum i = ~mag + 1;
+ ASSERT (i >= SCM_MOST_NEGATIVE_FIXNUM);
+ return i;
+}
+
static struct scm_bignum *
allocate_bignum (size_t nlimbs)
{
@@ -313,7 +314,7 @@ normalize_bignum (struct scm_bignum *z)
{
case -1:
if (bignum_limbs (z)[0] <= inum_magnitude (SCM_MOST_NEGATIVE_FIXNUM))
- return SCM_I_MAKINUM (negative_long (bignum_limbs (z)[0]));
+ return SCM_I_MAKINUM (negative_inum (bignum_limbs (z)[0]));
break;
case 0:
return SCM_INUM0;
@@ -429,7 +430,7 @@ negative_uint32_to_int32 (uint32_t magnitude, int32_t *val)
{
if (magnitude > long_magnitude (INT32_MIN))
return 0;
- *val = negative_long (magnitude);
+ *val = -magnitude;
return 1;
}
@@ -3070,7 +3071,7 @@ scm_integer_mul_ii (scm_t_inum x, scm_t_inum y)
if (negative)
{
if (lo <= inum_magnitude (SCM_MOST_NEGATIVE_FIXNUM))
- return SCM_I_MAKINUM (negative_long (lo));
+ return SCM_I_MAKINUM (negative_inum (lo));
}
else if (lo <= SCM_MOST_POSITIVE_FIXNUM)
return SCM_I_MAKINUM (lo);
--
2.34.1