This is the mail archive of the libffi-discuss@sourceware.org mailing list for the libffi project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Closures without VA-stuff


William Ahern wrote:
> On Sun, Dec 20, 2009 at 02:20:22AM +0100, Jonathan Schmidt-Domin? - Developer wrote:

>> I am seeking a library providing a very simple feature like this:
>> int test(void *d, int x);
>> int main()
>> {
>>   struct data
>>   {
>>     int a, b;
>>   };
>>   data d;
>>   int(*fun)(int) = create_closure(test, &d);
>>   fun(4); // invokes test(d, 4)
>> }
>> So I have found two libraries: ffcall and libffi.
>> Such things are possible with libffi (and even ffcall), but there is no way to 
>> do simply that, you always need this "varaidic stuff". Why isn't there any 
>> simple function to create closures? Any suggestions what I should try to do?
>> I am asking you, because libffi looks promising. ;)
> 
> While not providing exactly that, you may be able to get some ideas and
> working code from this:
> 
> 	http://www.25thandclement.com/~william/projects/delegate.c.html
> 
> It uses libffi underneath, and provides the convenience that you're
> expecting by using GCC's extensive build-time typing and conditional
> built-ins. To get the ability to pass the dynamic "4" you'll need to hack it
> a little to recognize "placeholder" values (I need to add this eventually
> myself). Also delegate.c doesn't use FFI's closure abilities, but this
> shouldn't be difficult to add as a layer above the stuff that delegate.c
> does.

This is a really neat hack.  I wonder if it could usefully be separated
from libevent and included in libffi.

I love the way a simple example

  struct delegate del = DELEGATE_INITIALIZER;
  int m = 3;
  int n = 4;

  delegate(&del, &plus, m, n);
  ffi_arg res = invoke(&del);

expands into some nightmarish C code (I won't reproduce it here) which then
collapses into

  del = {};
  m = 3;
  n = 4;
  {
    {
      int32_t argT;

      D.3399 = n;
      D.3575 = &del.args + 16;
      memcpy (D.3575, &D.3399, 4);
      del.types[1] = &ffi_type_sint32;
      D.3400 = del.types[1];
    }
    {
      int32_t argT;

      D.3415 = m;
      D.3576 = (int32_t * {ref-all}) &del.args;
      D.3577 = D.3415;
      *D.3576 = D.3577;
      del.types[0] = &ffi_type_sint32;
      D.3416 = del.types[0];
    }
    plus.17 = (void (*<T132>) (void)) plus;
    D.3579 = delegate_init (&del, &ffi_type_sint32, plus.17, 2);
    D.3573 = D.3579;
  }
  res.18 = invoke (&del);

(I can't help wondering, though, if C++ template metaprogramming
wouldn't be a more natural home for this kind of thing.  But that's
just me :-)

Andrew.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]