Before it's too late: delegate calling convention

Jarrett Billingsley kb3ctd2 at yahoo.com
Thu Nov 2 11:44:00 PST 2006


"Lionello Lunesu" <lio at lunesu.remove.com> wrote in message 
news:eicths$9sn$1 at digitaldaemon.com..

> It's not EAX, but a different register :)

It's EAX and EBX, but delegates only access EAX as the context, as it's 
treated as the first parameter.  The EBX is superfluous.

mov EAX, dg.ptr
mov EBX, dg.ptr
mov EDX, dg.function
call [EDX]

Is what DMD generates for a delegate call.

> IIRC, Thomas has made a working example once, using inline assembly. I 
> think it was indeed putting the context pointer of a delegate to null 
> (ignoring it would work to) and calling the function-pointer as a normal 
> function.
>
> To make this work without changing the ABI would mean an extra null-check 
> before calling the delegate:
>
> if (dg.ptr !is null)
>   // push/mov for delegate ABI
> else
>   // push/mov for function-pointer ABI
> asm { call dg.func; }

I guess that works :)  Of course, it means having to do an extra comparison 
every time you call a function through a pointer or a delegate, but..

> Making the two calling conventions compatible would mean that the context 
> pointer would be stored somewhere where it doesn't interfere with C's 
> function-pointer ABI. ... Right?

Hmm.. if all function pointers became delegates technically, then.. I guess 
since C functions would be expecting extern(C) pointers, they wouldn't need 
the context at all.  So it'd be

extern(C) void function() f;

if(dg.ptr is null)
    f = dg.function; // don't need context
else
    // error, can't pass delegate with context to a C function

CFunction(f);

Maybe? 





More information about the Digitalmars-d mailing list