[MLton] implement _address and _symbol

Wesley W. Terpstra wesley@terpstra.ca
Tue, 19 Jul 2005 13:42:10 +0200

On Mon, Jul 18, 2005 at 05:43:36PM -0700, Stephen Weeks wrote:
> Nonsense.

Ok, ok. You guys win. :-P

Matthew wrote:
> > '_import *: int -> int;' right now gives MLton.Pointer.t -> int -> int.
> The above is not allowed by the current implementation.  You must make the
> pointer type explicit in the annotation.

Somehow I thought it was the other way.
So, the only mismatch in the signature is with _export, atm.

> It is a (minor, as in relatively easily fixed) deficiency of the 
> runtime system that there is no way to register ML pointers with the 
> runtime to be treated as roots and updated at a GC.

Wouldn't this be a good thing to change?

Being able to guarantee that heap objects remain valid for the duration of a
C function call seems like an important thing to me. In fact, wasn't there
someone on this list who has having this problem a month or so gone?

OTOH, if there are significant performance penalties...

> > Another frightening aspect no one has brought up: what about pointers?
> > val set : int vector -> unit = _store "x"

It seems to me that being able to mark "x" as a GC root fixes that case.

However, _store * (or _symbol *) can't be fixed that easily....
You would get a build up of roots with no way to clear them.

> > val get : unit -> int vector = _fetch "x"
> > 
> > After the C call which set the symbol, on return to SML the GC might run.
> > Thus, _fetch doesn't make sense either.
> > 
> > So, _fetch/_store of heap types should fail to compile, right?
> Not necessarily, but possibly.

Again, I think the reader for _symbol * is going to be a big problem.
It could be fixed for _symbol "x", but only with new GC roots.

> Bear in mind, this is an interface to *C*!  The programmer is leaving a 
> type safe language, and so they had better know what is going on.

I don't really see this as relevant. C may not be type-safe, but it has
well-defined lifetime guarantees. The FFI is breaking them.

We can't just allow _symbol of heap types and say: oh yeah, it might work,
but we don't promise you anything. Far better would be to just fail to
compile that code (or else fix what we can).

Stephen said:
> it's not hard to write #1 or #2 if you just want the getter or setter.

Right; I didn't think of this.

> > (* Fails to compile (cannot export polymorphism): *)
> > val () = _export "id" (fn x => x)
> This points out a problem with the type inference approach. 


> MLton will quite happily infer the type "unit -> unit" for "fn x => x", in
> which case the export may succeed.

I'm not sure what you're saying here?

> > I don't mind that a 'define'-ed _symbol is not initialized; this is *C* 
> >   and that behavior is allowed.
> Not requiring initialization seems better to me.

I'm not talking about initializing it for C, but SML.
Here the expectation is that the variables are always 'initialized'.

If the symbol came from C, then it is statically initialized before main().
If the symbol came from SML, the best we can do is initialize it before
it can be referenced inside the SML code.

> > I don't think that type-inference is necessary; I think the current 
> >   annotations are fine.  Also, whatever decision is reached wrt 
> >   type-inference, it would certainly make more sense to first implement 
> >   the new FFI with annotation before tackling inference as well.
> Definitely.  Doing both the new keywords and dropping the type
> annotations is too much.

This certainly makes it easier for me to get my feet wet.

Wesley W. Terpstra