This is the mail archive of the
libffi-discuss@sourceware.org
mailing list for the libffi project.
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.