[MLton-devel] mGTK for MLton

Stephen Weeks MLton@mlton.org
Tue, 25 Mar 2003 16:17:58 -0800


Hi guys.  We've had some time to consider your request for additional
MLton features to support mGTK.  In short, here are our thoughts about
the features.  More detail follows.

Callbacks
	We've added a very simple facility for this that we hope is
	sufficient. 
Finalization
	We can add support for weak pointers without too much
	difficulty.  Hopefully that is enough.
Allocation of SML aggregate values from C
	We don't think this is necessary, and don't have plans to
	support it.  We have many examples of how to work around this
	missing feature in our implementation of the basis library.

So, if you agree with our thoughts, then it should be possible to port
mGTK to MLton.  Either way, please let us know and we can continue
discussion to try to achieve the port.  And please keep us up to date
on the port's progress.

Thanks.


Here's the details.

> Summary of the needed features in order of importance:
> 
>    * Callback (ie., call a SML function from C).  We have designed
>      mGTK so that we only need to call two specific SML functions.
...
> Thus, we need to know how:
>   * to register a SML function so that we can call it from C
>   * to call this registered function

To address this need, we've added to MLton the ability to call a
single SML function from C.  On the SML side, we export the function
  
  	val MLton.FFI.handleCallFromC: (unit -> unit) -> unit

which allows you to register the SML function that is called from C.
On the C side, we export a single function that allows you to call
back to SML:
  
  	void MLton_callFromC ();

So, after calling "MLton.FFI.handleCallFromC f", then a call from C to
MLton_callFromC will cause "f ()" to be run.

Since you need to call multiple SML functions, you can build C
wrappers around MLton_callFromC that set some global integer, which
you then dispatch on from the SML side to call the appropriate
function.  You can also pass arguments using a simple hand implemented
calling convention in which you set globals in the C wrapper and fetch
them with _ffi from the SML code.

>    * Finalized values.  We need a way to hook-up the Gtk+ memory
>      management (GObjects) to the SML GC.

We're not convinced of the need for full-fledged finalization, and
hope that weak pointers will be sufficient for your needs.  Thus, we
propose to add the following structure to MLton.

structure MLton.Weak:
   sig
      type 'a t

      val get: 'a t -> 'a option
      val new: 'a -> 'a t
   end

MLton.Weak.new creates a weak pointer to an object and get returns
SOME of the pointer value, unless it has become unreachable in which
case get returns NONE.  With weak pointers, mGTK can maintain a list
of pairs of GObjects and a weak pointer to the corresponding SML
object.  At regular intervals, say once per callback, you can walk
this list, checking the weak pointers, and if the SML object is
unreachable, decrement the refcount (or whatever) for the GObject.

>    * Allocation of SML aggregate values (tuples, lists, vectors,
>      arrays) from C.  Some Gtk+ functions return a dynamically sized
>      data structure (for example, a list of selected cells in a grid
>      widget).

Here are the more detailed examples you give

>   * The return value from gtk_init (not really essential, but it cause
>     us some deep thinking).

Not sure about this one.

>   * We allocate a number of tuples to transfer some constants.  These
>     cases can be eliminated by allocating an array in SML and let a C
>     fill it out.

Great.  That seems like a nice way to us.

>   * We allocate a triple each time we do a callback.  Again, this case
>     can perhaps be eliminated depending on how callbacks from C to SML
>     is implemented.

This should be easy to avoid.  Simply store the three components of
the triple in C globals and access them from SML, where you can build
the tuple if you need it.

>   * When a C function returns a dynamically sized data structure.

This can be handled with MLton's current infrastructure, with no need
to allocate a dynamically sized SML structure from C.  Instead, one
can simply allocate a dynamically sized C structure, and then from the
SML side copy the structure into an SML structure.  To do this, you
can use MLton's _ffi to create functions that obtain the size of the C
structure and to extract each element of the C structure.  You might
also need an _ffi to free the C structure.

One example of how we do this in the basis library is in the handling
of CommandLine.arguments: unit -> string list.  In this case, C has a
a char** that we need to convert to a string list.  So, to convert
from C to SML, from the SML side we fetch the size of the C array and 
allocate the SML array.  We then walk through the C array elements
using an _ffi function to subscript each element, converting the C
strings to SML strings (using a similar process) and updating the SML
array.


-------------------------------------------------------
This SF.net email is sponsored by:
The Definitive IT and Networking Event. Be There!
NetWorld+Interop Las Vegas 2003 -- Register today!
http://ads.sourceforge.net/cgi-bin/redirect.pl?keyn0001en
_______________________________________________
MLton-devel mailing list
MLton-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mlton-devel