DMD 0.174 release

Reiner Pope reiner.pope at REMOVE.THIS.gmail.com
Wed Nov 15 15:40:26 PST 2006


Jarrett Billingsley wrote:
> "Kirk McDonald" <kirklin.mcdonald at gmail.com> wrote in message 
> news:ejeepp$15n1$1 at digitaldaemon.com...
>> Jarrett Billingsley wrote:
>>> A few questions:
>>>
>>> 1) For the delegate .funcptr property, would it be possible for it to 
>>> include the context pointer as the first parameter?  Currently the 
>>> .funcptr allows us to get the type / call signature of the delegate but 
>>> it's not possible to actually use the resulting function as there is no 
>>> way to pass it the context short of dipping into ASM..
>>>
>> Not so: Walter added a .ptr property to delegates in 0.168. Between that 
>> and .funcptr, you've got all you need to mess with delegates right there.
> 
> Well even with the context pointer, how do you propose passing it to the 
> resulting func pointer?  The context is passed implicitly as the first 
> parameter to any delegate, and without that first parameter in the parameter 
> list, you can't pass the context.  So
> 
> class A { void fork(int x) { } }
> 
> A a = new A();
> auto dg = &a.fork;
> auto fp = dg.funcptr;
> 
> fp(3); // access violation
> 
> What's worse is that because the parameter list doesn't include the context, 
> trying to call fp will result in all the arguments being shifted down a 
> position from where they should be, i.e. 3 will now be in the 'this' slot, 
> and nothing useful will be in the 'x' slot.  :S  So you _have_ to use ASM to 
> call that func pointer, or maybe use some template trickery to create a 
> pointer to the function with an extra first param. 
> 
> 
I'm not sure if this is what you want, but here's a cast-free 'call' 
function:

import std.stdio : writefln;

class A {
     int a_m;
     this(int a)
     {
         this.a_m = a;
     }
     void fork(int b)
     {
         writefln(a_m,b);
     }
}

void main()
{
     A a = new A(1);
     A b = new A(2);
     auto dg = &a.fork;
     auto fp = dg.funcptr;

     call(fp, a, 3); // Prints 13
     call(fp, b, 3); // Prints 23
}

B call(A, B, Params...)(B function (Params) fp, A a, Params p)
{
     B delegate(Params) dg;
     dg.funcptr = fp;
     dg.ptr = a;
     return dg(p);
}



More information about the Digitalmars-d-announce mailing list