[MLton] Re: [MLton-user] SVN r6941 MLton/MinGW32 and FFI
Matthew Fluet
fluet at tti-c.org
Wed Nov 12 09:46:17 PST 2008
On Tue, 11 Nov 2008, Wesley W. Terpstra wrote:
> On Tue, Nov 11, 2008 at 6:08 PM, Ville Laurikari <ville at laurikari.net> wrote:
>> On Tue, Nov 11, 2008 at 04:15:26PM +0100, Wesley W. Terpstra wrote:
>>> I'm also beginning to wonder if perhaps imports should default to
>>> public instead of external given the number of people who've run into
>>> the __imp__ link error.
>>
>> I think this is a good idea. We've certainly run into the problem.
>> Upgrading to a new version of MLton is problematic, because code
>> updated for the new version does not work with the old version. On
>> the other hand, code working with the old version does not work with
>> the new version.
>
> I feel your pain, but changing the default to public won't completely
> alleviate this. You *should* specify external for any symbols you
> import from a DLL if the default is public. Of course, if you only
> ever use _import (never _symbol or _address), you should be safe.
>
> The other problem case is osx/i386. It needs special stub code to
> access external functions and variables from a library. If MLton
> defaults to public, then any programs on that target which _import
> from a system library (functions like cos, sin, etc) will fail to link
> unless "external" is specified.
>
> Thus picking 'public' as the default would make a smooth upgrade for
> MinGW, but break darwin/i386. Currently it's a smooth upgrade for
> darwin, but not MinGW. For both situations and targets, though, you
> really should distinguish public/external.
>
> One could imagine a default of public for MinGW and external for
> darwin, but that seems pretty arcane.
It may be arcane, but it can be justified --- this is effectively what
previous versions of mlton did, albeit with some implicit help from the
platform binutils.
For MinGW (and, indeed, all {amd64,x86}-!darwin platforms), we produced
assembly code for all functions as we now produce code for 'private'
functions. For ELF platforms (compiling without
position-independent-code), private/public/external all produce identical
assembly sequences. For COEFF platforms, private&public produce identical
assembly sequences, but one does need a different sequence to call an
'external' function. However, if MinGW ld notices that a direct call (the
assembly sequence for private&public) is being satisfied by a DLL
function, it automagically inserts a stub function, that performs the
'external' function call.
For Darwin, we produced assembly code for all functions as we now produce
assembly code for 'external' functions. However, the MachO linker was
happy to patch, at link time, any function symbols that were satisfied by
static libraries (i.e., symbols from the same DSO).
However, this implicit help only comes with functions -- that is, symbols
used in a call instruction (I think). Symbols whose addresses are taken
(i.e., via _address and a mov or lea instruction) do not get any implicit
help (I think).
Nonetheless, it does seem as though 'external' is a better default.
I don't know if it is worth adding an 'ffiSymbolScope {error|ignore|warn}'
MLB annotation to signal when FFI is used without an explicit symbol
scope.
More information about the MLton
mailing list