[MLton] ffi improvements

Stephen Weeks MLton@mlton.org
Wed, 22 Sep 2004 16:38:14 -0700


> Looking through some of the FFI stuff, here are some items of note:
> 
> 1) The CType structure (in the compiler) distinguishes between Pointer and
>    Word32.  However, MLton.Pointer.t (in the basis), while abstract, is
>    defined to be equal to word.  I think it might be cleaner to have a
>    primitive pointer tycon.

I agree.  We used to have it and I don't think there is any strong
reason not to.  Here's what I wrote in the commitlog on December 1,
2003 when I checked in the code to replace the primitive pointer tycon
with Word32.word.

  I went ahead and implemented MLton.Pointer.t as Word32.word, which
  made it easy to do some stuff without adding more primitives.
  Eliminating the built in pointer type also let me remove some code
  from the compiler.  If we decide that we don't like having the
  knowledge of the word size of pointers in the basis library, then it
  will be easy enough to add a couple of primitives and the primitive
  type.  Although if we do, I would recommend replacing the primitive
  type in the front end with the appropriate word size instead of
  pushing it all the way to the backend as we used to.

That still makes sense to me.  The issue with primitives is that if
pointer is an abstract type, then we need primitives to do pointer
arithmetic and maybe to convert between pointers and words.

So, go ahead and add the tycon and primitives, and eliminate them as
early as possible, either in the front end or in defunctorize.fun.

> 2) I don't see that the thread/preThread distinction is really used within
>    the compiler.  In light of the above, I suggest dropping the
>    thread and preThread tycons and in the basis define:
>      structure Thread :> sig type t end = struct type t = pointer end
>      structure PreThread :> sig type t end = struct type t = pointer end
>    which will keep threads and preThreads distinct in the Basis.

You are right that threads and preThreads do not need to be
distinguished within the compiler.  However, it is important to
distinguish them from C pointers, since they are heap allocated
objects.  So, I've checked in a change to eliminate the preThread
primitive tycon and to put the following in the basis library.

  structure PreThread:> sig type t end = struct type t = thread end
  structure Thread:> sig type t end = struct type t = thread end

> 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

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";)