[MLton] Support for link options in ML Basis files
Matthew Fluet
fluet@cs.cornell.edu
Tue, 18 Jan 2005 09:03:54 -0500 (EST)
> > * MLton's FFI isn't expressive enough to pass a struct/union from ML to
> > C. I can fake it on the x86 because the calling convention is to pass
> > the struct "in pieces", so one can simulate the call by extracting the
> > struct fields and passing them in order. Unfortunately, this doesn't
> > work on all architectures.
>
> Can we avoid portability problems by automatically generating a
> wrapper to translate between the calling convention we understand
> (n-ary C functions with basic types) and the calling convention we
> don't (passing C structs)?
That is an option. It is more information to carry around in CFunction.t,
but it would appear to get us most of the way there. I don't know how to
designate unions (nor how to make an appropriate wrapper for them).
Also, it doesn't solve the circular dependencies issue. (Although,
C-code that gives rise to these situations may not be valid; gcc usually
gives me a warning when I try compiling it.)
The problem is that on the ML side, ML-NLFFI always passes structs/unions
around as pointers. So, if C-code gave rise to:
> For example, if someone does
>
> _import "f": char * {x: int, y: double} -> unit;
>
> then on the SML side we turn this into
>
> fn (c, {x, y}) => _import "f_wrapper": char * int * double -> unit; (c, x, y)
then mlnlffigen still wants to export a "wrapped" version of "f" that
takes care of converting to and from ML representations. So, it would
generate a function that is the ML equivalent of:
void call_f (char c, struct zzz *z) {
f_wrapper (c, z->i, z->d);
}
In order to translate this into ML, we use the generated code for
extracting fields of a struct zzz.
I'll note that what SML/NJ does is the following; rather than passing the
struct in pieces to the wrapper, it passes the pointer. So,
_import "f": char * {x: int, y: double} -> unit;
turns into
fn (c, p) => _import "f_wrapper": char * pointer -> unit; (c, p)
and in the codegen, they produce the following:
----------------------------------------
struct zzz {
int i;
double d;
};
void f (char c, struct zzz z);
void f_wrapper (char c, struct zzz *z) {
f (c, *z);
}
----------------------------------------
> > * mlnlffigen also has it's shortcomings, independent of MLton. The most
> > glaring of which is that it doesn't export #define constants. It is a
> > recognized problem, but as of right now there doesn't appear to be a
> > solution out there. I suspect it requires modifying the ckit Library.
>
> Might it work to use the same approach that we use for
> build/lib/<target>/constants?
Depends what you mean? I believe the hope is that the programmer doesn't
need to specify which #define constants should be exported, but that might
be too much to ask of a tool.