unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
From: Maxime Devos <maximedevos@telenet.be>
To: Mike Gran <spk121@yahoo.com>,
	"guile-devel@gnu.org" <guile-devel@gnu.org>
Subject: Re: Guile 64-bit Windows support, redux
Date: Thu, 8 Jun 2023 21:50:59 +0200	[thread overview]
Message-ID: <dabaddaf-e1d4-51c2-1062-e0b14f9523a2@telenet.be> (raw)
In-Reply-To: <1629803116.370682.1686084646758@mail.yahoo.com>


[-- Attachment #1.1.1: Type: text/plain, Size: 9604 bytes --]



Op 06-06-2023 om 22:50 schreef Mike Gran:
> Hello Guile,
> 
> There have been a few times where I made Guile work on
> MinGW -- usually the 32-bit, unthreaded variety -- because I wanted it
> for my own entertainment.  Often around the time of the Lisp Game Jam.
> The Game Jam just happened, so I was poking it again.  Although
> I never actually delivered my game this year.
> 
> Janneke has also poked at Windows support a few times as well, and
> he actually got it to run on 64-bit Windows.
> 
> I'd be willing [1] to update the patches for MinGW support for
> review and inclusion into the main branch
> for 3.0.10 or 3.2 but, only if maintainers are open, in principle,
> to committing the most disruptive patch: the one where all
> long integers become intptr_t to deal with Window's stupid
> 4-byte longs on 64-bit OSs.  Without agreeing on that as a
> possibility, 64-bit Windows support is DOA.

(The following response should be read with the following proverb in mind:

<https://en.wiktionary.org/wiki/de_beste_stuurlui_staan_aan_wal>
Proverb
de beste stuurlui staan aan wal

    1. It's easy to criticize other people's work when you're not the 
one doing it. Compare also a backseat driver.

I haven't tried any alternative approached myself.)

(The following response is a bit muddled -- it initially says I don't 
follow but later I will.  Still, there is some stuff of which I really 
disagree with the implementation.)

I don't quite follow why the change from 'long' to 'intptr_t'.  I mean,
reading the commit message you linked to:

 > As long is used for SCM_FIXNUM_BIT, that would mean incompatible
 > .go files, [...]

... how is this a problem?  .go files are already incompatible between 
architectures and Guile already supports cross-compilation; adding 
incompatibility between OS doesn't really make a difference.

(For other readers: SCM_FIXNUM_BIT has been renamed to SCM_I_FIXNUM_BIT.)

Also:

 > [...] and a waste of cell space.

IIUC, Guile currently uses a 'long' (minus a few bits for typing) 
embedded in a SCM/scm_t_bits/uintptr_t for fixnums.  If 
sizeof(long)<sizeof(uintptr_t), that's indeed a waste (I assume that's 
what you are referring to).

In that case, why not change the fixnum implementation to use 
'uintptr_t' or 'scm_t_bits' instead of 'long'?  Reading a bit further,
such a thing appears to already have thought of:

 > So we would like to use long long, but the GMP interface
 > uses long.

and the new problem is already resolved.  Though I don't get why a new 
SCM_INTPTR_T_BIT is defined instead of changing SCM_FIXNUM_BIT to use 
(64-bit) uintptr_t instead of (32-bit) long -- I mean, wasn't 
compatibility and space-savings (i.e. avoiding bignums) a concern?

Also, why not patch GMP to also have 'long long' variants?  Sure, it 
will take a while to reach distributions ... but Windows doesn't really 
do distributions much anyway, so that doesn't seem a problem to me.
That would avoid a lot of GMP-related changes and avoid the need for the 
non-standard minigmp on Windows.

(There are some downsides, like having to pick different functions 
depending on whether 'long' or 'long long' is used, though to a degree 
that can be resolved with some #define.  Maybe that was one of the 
reasons why not.)

Looking at the changelog, I'm thinking it changes too much: changing 
configure.ac and {numbers,integers}.{c,h}, sure, but why why hash.c, 
symbols.c, array-map.c?

It also changes too little: it forgets to change scm_t_inum from 'long' 
to 'uintptr_t' -- if you want to have uintptr_t (minus type bits) 
fixnums, then you need to change scm_t_inum, otherwise the comment 
becomes invalid:

/* Immediate Numbers, also known as fixnums
  *
  * Inums are exact integers that fit within an SCM word
  * (along with two tagging bits).
  *
  * In the current implementation, Inums must also fit within a long
  * because that's what GMP's mpz_*_si functions accept.  */
typedef long scm_t_inum;

(It also becomes invalid because with the new minigmp, minigmp accepts 
uintptr_t instead of long.)

Looking closer at some of them, the changes to array_compare makes sense 
to me, even if Windows didn't have 32-bit longs, but some of the other 
changes don't.

For example, the first change is to scm_array_in_bounds_p.  Now you can 
have INTPTR_T_MAX dimensions instead of LONG_MAX dimensions!  Seems 
useless to me; 2**32 is already a stupidly high limit.

The change to array_to_list makes sense to me, even if long were 64-bit.

Now consider the change to scm_array_contents:

 > -                  SCM_I_ARRAY_BASE (ra) % SCM_LONG_BIT ||
 > -                  len % SCM_LONG_BIT))
 > +                  SCM_I_ARRAY_BASE (ra) % SCM_INTPTR_T_BIT ||
 > +                  len % SCM_INTPTR_T_BIT))

Neither version makes much sense to me -- SCM_I_ARRAY_BASE nominally 
returns a size_t, not an intptr_t:

#define SCM_I_ARRAY_BASE(a) ((size_t) SCM_CELL_WORD_2 (a))

so it should use SCM_SIZE_T_BIT instead of SCM_LONG_BIT/SCM_INTPTR_T_BIT.

Sure, Guile assumes that intptr=size_t elsewhere, but it's an assumption 
that can trivially be avoided here.

Now, on to libguile/bytevectors.c:

+#if !(__MINGW32__ && __x86_64__)
  #define is_signed_int32(_x)     (((_x) >= -2147483648L) && ((_x) <= 
2147483647L))
  #define is_unsigned_int32(_x)   ((_x) <= 4294967295UL)
+#else /* (__MINGW32__ && __x86_64__) */
+#define is_signed_int32(_x)     (((_x) >= -2147483648LL) && ((_x) <= 
2147483647LL))
+#define is_unsigned_int32(_x)   ((_x) <= 4294967295ULL)
+#endif /* (__MINGW32__ && __x86_64__) */

These #if / #else suck.  What if there exists some other system where 
long is 32-bit?

They are also unnecessary, it is possible to just use LL/ULL 
unconditionally (Guile already assumes that 'long long' exists, in 
test-num2integral.c):

#define is_signed_int32(_x)     (((_x) >= -2147483648LL) && ((_x) <= 
2147483647LL))
#define is_unsigned_int32(_x)   ((_x) <= 4294967295ULL)
#define is_unsigned_int32(_x)   ((_x) <= 4294967295ULL)

Also, in twos_complement, the implementation is confusingly written -- 
the MPZ API accepts longs, not uintptr, going by the official 
documentation. There is a reason for this, but it needs comments for 
people not aware that Guile replaces the GMP implementation on Windows.

About libguile/deprecated.c: this change is unnecessary if the 
definition of scm_t_inum is fixed.

About libguile/hash.c / libguile/hash.h: I don't get the type changes -- 
if 32-bit hashes have too high risk of collisions, why not also have 
64-bit hashes on 32-bit architectures instead of only when uintptr_t is 
64-bit?  It looks like an overly general search+replace long->intptr_t 
to me.

About libguile/integers.c:

+#if !(__MINGW32__ && __x86_64__)
+#define L1 1L
+#else /* (__MINGW32__ && __x86_64__) */
+#define L1 1LL
+#endif /* (__MINGW32__ && __x86_64__) */

Again, these #if/#else suck. Looking at the uses of L1, L1 should be an 
uintptr_t -- this code doesn't need to know whether L1 is long or long 
long, it just needs to be an intptr_t. It can be replaced by INTPTR_C(1) 
instead -- ok, bah, INTPTR_C doesn't actually exist, but you can define 
it in terms of INT<N>_C and some (cross-platform!!) #if/#else that 
compare UINTN_MAX with UINTPTR_MAX.

(Likewise, the configure.ac test is bad.)

Also, because integers.c deals with fixnums, it should be using 
scm_t_inum instead of intptr_t.

About scmsigs.c: unless signal numbers have more than 32-bits on 
Windows, I don't think that change accomplishes anything.

About srfi-60.c: unless the goal was to improve performance by using 
larger integers, these changes don't seem to accomplish anything.  And 
if the goal is performance, then this needs a benchmark.

About strings.h and symbols.c: see my comments about hashes.

Overall, I think there are some places were Guile really needs to stop 
using 'long' and instead use a more specific type like 'size_t' / 
'uintptr_t', for example when representing sizes and offsets of 
array-like stuff, whether or not Guile is ported to Windows.

> To get around this, the x86-64-MinGW port now requires the use of
> mini-GMP.  Mini-GMP has been changed to use intptr_t and uintptr_t.

Then the local copy should state that, otherwise people updating Guile's 
minigmp will introduce bugs.

> Let me know what you think.

More cross-platform support = good and out-of-tree = inconvenient, but 
the current patch makes some questionable choices and doesn't document 
stuff properly; it's really inconvenient for a newcomer from, say, 2050, 
to have to dig through multiple decades of commits and e-mails to avoid 
pitfalls like ‘this comment used to be true but now is a lie’ and 
‘hidden assumptions’ when doing some refactoring or porting.

Also, regardless of whether the uintptr stuff is accepted, there seem to 
be some Windows-independent patches that seem fit for the main branch:

  * Avoid mysterious "error no error" message in pipe
  * fixes for chmodat test

(Also, not actually a maintainer myself.)

> -Mike Gran
> 
> [1] Last two times I volunteered myself for something on Guile/Guix,
> I got quite ill. Let's not hope for a repeat.

Ill, like in, bad social interactions, or like in independent medical 
issues that happened at the same time as working on Guile/Guix stuff?
I don't need to know per se but this footnote is ambiguous.

Greetings,
Maxime.

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 929 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 236 bytes --]

  parent reply	other threads:[~2023-06-08 19:50 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1629803116.370682.1686084646758.ref@mail.yahoo.com>
2023-06-06 20:50 ` Guile 64-bit Windows support, redux Mike Gran
2023-06-06 20:56   ` Jean Abou Samra
2023-06-06 21:10   ` [EXT] " Thompson, David
2023-06-06 21:58     ` Mike Gran
2023-06-08 19:50   ` Maxime Devos [this message]
2023-06-08 20:46     ` Mike Gran
2023-06-09 11:01       ` Maxime Devos
2023-06-22 13:36         ` Mike Gran
2023-10-29 21:34   ` Jonas Hahnfeld via Developers list for Guile, the GNU extensibility library
2023-11-28 21:04     ` Jonas Hahnfeld via Developers list for Guile, the GNU extensibility library
2023-11-28 22:04       ` Dr. Arne Babenhauserheide
2024-01-04 10:40       ` Jonas Hahnfeld via Developers list for Guile, the GNU extensibility library
2024-02-06  6:44         ` Dr. Arne Babenhauserheide
2024-02-07 14:19         ` Thompson, David
2024-02-07 20:19           ` Jonas Hahnfeld via Developers list for Guile, the GNU extensibility library
2024-02-07 20:23             ` Thompson, David
2024-02-07 20:29               ` Jonas Hahnfeld via Developers list for Guile, the GNU extensibility library
2024-03-20 20:28                 ` Jonas Hahnfeld via Developers list for Guile, the GNU extensibility library
2024-03-20 20:40                   ` Thompson, David
2024-03-23 15:09                     ` Jonas Hahnfeld via Developers list for Guile, the GNU extensibility library
2024-03-29 17:20                       ` Thompson, David

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=dabaddaf-e1d4-51c2-1062-e0b14f9523a2@telenet.be \
    --to=maximedevos@telenet.be \
    --cc=guile-devel@gnu.org \
    --cc=spk121@yahoo.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).