[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