[MLton] Problem with MinGW
Matthew Fluet
fluet@cs.cornell.edu
Thu, 8 Jun 2006 18:22:35 -0400 (EDT)
>> The codegens are very different outside the Basis Library.
>
> I know this, of course. I just thought that as a windows system call was
> returning a different error code, that the methods called before it must be
> different. I presumed that the codegen doesn't particularly influence the
> runtime methods invoked.
Yes, good point. And you are correct that the dynamic behavior of which
runtime methods are invoked should be pretty much the same in the
codegens.
>>> The parameters passed to the open3 method are identical in both cases. The
>>> only difference is the stack. The first argument is 00 aligned for the C
>>> codegen, and 1a aligned for the native codgen. However, I think this
>>> should be ok... right?
>>
>> Maybe yes, maybe no. Could MinGW have a different calling convention than
>> x86-linux and x86-cygwin? In particular, does MinGW demand different stack
>> alignment. I could see that causing a problem very much like that which we
>> are seeing.
>
> This is indeed the problem!
>
> MinGW functions seem perfectly happy with a stack aligned on 2 bytes.
> However, some windows system calls (not all) fail when called this way. The
> MinGW code also appears to preserve 4 byte alignment, so if you call a MinGW
> compiled method (Posix_FileSys_open3) with offset 2, 6, a, or c, then the
> windows system call gets it too.
Good. It also explains why MinGW was working before with the native
codegen but breaks on the x86_64 branch. On the x86_64 branch, we are
handling many more C-side types (like mode_t) in their native C
representation. On most x86 platforms, mode_t is 32bits, but on MinGW, it
is 16bits.
On the other hand, I was a bit curious how we got off of 4 byte alignment.
It turns out it is a bug in the native codegen's implementation of the C
calling convention. It promotes an 8bit integral value to 32bits before
pushing on the stack, but it pushes a 16bit value without widening it.
It should be widening all arguments to multiples of 32bits. Previous to
the revisions on the x86_64 branch, the C-side implementation of the Basis
Library was predominantly using 32bit arguments.
I'll check in a fix.