[MLton] ffi improvements

Matthew Fluet fluet@cs.cornell.edu
Wed, 22 Sep 2004 19:54:32 -0400 (EDT)


> > 3) I've implemented indirect C calls.  However, I'm not sure which is a
> >    better syntax:
> >
> >      _import * : MLton.Pointer.t * t1 * ... * tn -> tr;
> >
> >      _import var : t1 * ... * tn -> tr;
>
> We discussed this a bit at ICFP and you said you'd like to send a new
> proposal.  IIRC, it was something like
>
> 	_import : t1 * ... * tn -> tr;
>
> where the type of the import expression is
>
> 	MLton.Pointer.t -> t1 * ... * tn -> tr

Not quite.  The problem with the above is that MLton.Pointer.t isn't
available from within the compiler; so, we would choose the pointer tycon.
Moreover, it would allow greater "precision" in imported functions if the
address could be opaque, the way we allow the other imported types to be
opaque, so long as they map to CTypes.  I'd like to be able to implement
the following:

signature DYN_LINK =
   sig
      type hndl
      type mode
      type fptr (* = MLton.Pointer.t *)

      val dlopen : string * mode -> hndl
      val dlsym : hndl * string -> fptr
      val dlclose : hndl -> unit

      val RTLD_LAZY : mode
      val RTLD_NOW : mode
   end
structure DynLink : DYN_LINK

val hndl = DynLink.dlopen ("libm.so", DynLink.RTLD_LAZY)

local
   val double_to_double =
      _import * : DynLink.fptr -> real -> real;
   val cos_fptr = DynLink.dlsym (hndl, "cos")
in
   val cos = double_to_double cos_fptr
end

So, that's my proposed syntax:

  _import * : t -> t1 * ... * tn -> tr;

> That is, the import expression is applied to the C function address to
> yield the callable function.  Then, we can view our existing static
> import
>
> 	_import "foo": t1 -> t2;
>
> as syntactic sugar for the application of the more basic import to
> another special syntactic form that gives the address of a function
> symbol.
>
> 	(_import : t1 -> t2;) (_address "foo";)

We can view it that way, but I don't suggest implementing it that way.
The above will necessitate an indirect function call.