birth of a new feature: Smalltalk callbacks

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

birth of a new feature: Smalltalk callbacks

Paolo Bonzini-2
I added the feature that Udo described, it was a good stimulus to
cleanup CFunctionDescriptor handling sensibly (of course there are good
reasons why Steve Byrne originally wrote them that way -- simplicity
mainly; with all the features that entered GNU Smalltalk over the years,
the simplest implementation is now a different one).

I'm not posting patches, I'm just describing them.  You can read the
patches at http://git.sv.gnu.org/gitweb/?p=smalltalk.git on savannah.

The first commit, 12fa4b57095d4b is a completion of a feature I began
last April, i.e. allowing creation of CFunctionDescriptors that host a
pointer to an arbitrary C function.  This didn't work because they
actually pointed to a C struct containing the libffi data.  I'm now
using a hash table to associate OOPs to libffi data.  This is not yet
perfect because OOPs can be reused, but I'll fix it soonish by
recreating the map upon GC.

The second, 3e98b86e3b, makes CFunctionDescriptor a subclass of CObject.
  This fixes in a better way the impossibility to subclass
CFunctionDescriptor.

The third, 81ef7546, does what I was thinking loudly about in my mail
from yesterday, i.e. move the creation of CFunctionDescriptors entirely
to Smalltalk code.  This adds a whole lot of flexibility, so that in the
next commit, 6c6e7e2ed, I create a separate class CCallable for
arbitrary function pointers.  Since CFunctionDescriptors have all the
functionality for rebinding the symbols on image load, it makes sense to
have an abstract class.

The intermezzo in 6f253188 just adds a way to call blocks using the
callin functions, without manually specifying selectors like
#value:value:value:value:value:...

Finally, closures are added in ffb3ff47.  It's just a SMOP, since the
functions for mapping C types to Smalltalk and vice versa is already
there.  I'll copy after my signature the relevant section of the manual.
  Improvements are very welcome!

Paolo


The Smalltalk callin mechanism can be used effectively to construct
bindings to C libraries that require callbacks into Smalltalk.
However, it is a ``static'' mechanism, as the callback functions
passed to the libraries have to be written in C and their type
signatures are fixed.

If the signatures of the callbacks are not known in advance,
and the only way to define callbacks is via C function pointers (as
opposed to reflective mechanisms such as the ones in GTK+), then
the @code{VMProxy} functions for Smalltalk callin are not enough.

@gst{} provides a more dynamic way to convert Smalltalk blocks into
C function pointers through the @code{CCallbackDescriptor} class.
This class has a constructor method that is similar to the
@code{cCall:} annotation used for callouts.  The method is
called @code{for:returning:withArgs:} and its parameters are:

@itemize @bullet
@item a block, whose number of arguments is variable
@item a symbol representing the return type
@item an array representing the type of the arguments.
@end itemize

The array passed as the third parameter represents values that
are passed @emph{from C to Smalltalk} and, as such, should be
filled with the same rules that are used by the @emph{return
   type} of a C callout.  In particular, if the C callback
accepts an @code{int *} it is possible (and indeed useful)
to specify the type of the argument as @code{#@{CInt@}},
so that the block will receive a @code{CInt} object.

Here is an example of creating a callback which is passed to
@code{glutReshapeFunc}@footnote{The GLUT bindings use a different
   scheme for setting up callbacks.}.  The desired
signature in C is @code{void (*) (int, int)}.
@example
| glut |
@r{@dots{}}
glut glutReshapeFunc: (CCallbackDescriptor
     for: [ :x :y | self reshape: x@@y ]
     returning: #void
     withArgs: #(#int #int))
@end example

It is important to note that this kind of callback does not survive
across an image load (this restriction may be lifted in a future version).
When the image is loaded, it has to be reset by sending it the @code{link}
message before it is passed to any C function.  Sending the @code{link}
message to an already valid callback is harmless and cheap.


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk