November 02, 2006
"Lionello Lunesu" <lio@lunesu.remove.com> wrote in message news:eic2t2$2hjj$1@digitaldaemon.com...
> Actually, it's passed in a register, so it could be made to work.

Ahh, but so are parameters.  Since the last parameter of a function is passed in EAX (as long as it fits), something like..

void fork(int x, int y)

Will take y on the stack and x in EAX.  But then converting it to a delegate, Y would end up past the end of the arguments, x in y's spot, and the context in x's spot.  :S


November 02, 2006
Jarrett Billingsley wrote:
> "Lionello Lunesu" <lio@lunesu.remove.com> wrote in message news:eic2t2$2hjj$1@digitaldaemon.com...
> 
>>Actually, it's passed in a register, so it could be made to work.
> 
> 
> Ahh, but so are parameters.  Since the last parameter of a function is passed in EAX (as long as it fits), something like..
> 
> void fork(int x, int y)
> 
> Will take y on the stack and x in EAX.  But then converting it to a delegate, Y would end up past the end of the arguments, x in y's spot, and the context in x's spot.  :S 
> 
> 

Like I said, it's passed as an argument, it's not magic.

 - Gregor Richards
November 02, 2006
Jarrett Billingsley wrote:
> "Lionello Lunesu" <lio@lunesu.remove.com> wrote in message news:eic2t2$2hjj$1@digitaldaemon.com...
>> Actually, it's passed in a register, so it could be made to work.
> 
> Ahh, but so are parameters.  Since the last parameter of a function is passed in EAX (as long as it fits), something like..
> 
> void fork(int x, int y)
> 
> Will take y on the stack and x in EAX.  But then converting it to a delegate, Y would end up past the end of the arguments, x in y's spot, and the context in x's spot.  :S 
> 
> 
It's not EAX, but a different register :)

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; }

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?

L.
November 02, 2006
"Lionello Lunesu" <lio@lunesu.remove.com> wrote in message news:eicths$9sn$1@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?


1 2
Next ›   Last »