simple ABI change to enable implicit conversion of functions to delegates?

Jonathan Marler via Digitalmars-d digitalmars-d at puremagic.com
Mon May 15 12:34:34 PDT 2017


On Monday, 15 May 2017 at 17:06:34 UTC, ag0aep6g wrote:
> On 05/15/2017 05:44 PM, Jonathan Marler wrote:
>> Not sure if members in this conversation were aware of my DIP 
>> to address
>> this issue:
>>
>> https://github.com/dlang/DIPs/pull/61
>>
>> The DIP uses a different approach to solve this same problem. 
>> It adds
>> new semantics to specify whether a function should use the 
>> same ABI as a
>> delegate, called a "delegateable function".
>>
>> The solution you have proposed would remove the need for my 
>> DIP by
>> reconciling the difference between the function ABI and 
>> delegate ABI.
>
> I was aware of your DIP. I think they're related, but don't 
> really overlap that much.
>
> You want to add a special kind of parameter that is taken as 
> the context pointer when making a delegate of the function. You 
> also add syntax to combine such a function with a matching 
> `this` into a delegate.
>
> I'd like the context pointer to be passed differently, so that 
> a normal function doesn't mistake it for one of its parameters.
>
> I don't think my thing would make your thing obsolete.
>
>> You have two ways to go about this, either modify the delegate 
>> ABI to
>> match the function ABI, or the reverse.  The specific change 
>> could be
>> stated as:
>>
>> Modify the function/delegate ABI so that the first parameter 
>> of every
>> function is passed in the same way as the context pointer of a 
>> delegate.
>
> If I'm reading it right, with that rule this would be valid:
>
> ----
> struct Foo { int x; }
> void baz(Foo* foo, int y) { import std.stdio; writeln(foo.x, " 
> ", y); }
> void main()
> {
>     void delegate(int y) dg;
>     dg.funcptr = &baz; /* parameter `foo` is taken as context 
> pointer */
>     dg.ptr = new Foo(1);
>     dg(2); /* would print "1 2" */
> }
> ----
>
> That's not what I'm after. With my (crude) idea, that code 
> would be just as invalid as it is now. A function's parameters 
> would have to match the (visible) parameters of the delegate 
> type. Any context pointer would be passed in a spot where the 
> function doesn't look.
>
> The point is to allow using functions as delegates that don't 
> use the context pointer.

Ah ok, you're proposing that the language guarantees that 
functions with the same "visible" parameters as delegates use the 
same ABI for those parameters.  So in this example, foo and bar 
would use the same ABI to pass in x:

void foo(int x)
{
}
struct Bar
{
     void bar(int x)
     {
     }
}

The drawback I can see is that it restricts the ABI that 
functions can use.  Say that our x86 ABI passes all context 
pointers using the EAX register (no matter what the other 
parameters are).  That would imply that function's couldn't use 
the EAX register to accept arguments.  Note that this would apply 
to ALL functions, not just the ones that are going to be called 
through delegates, which is a small subset of ALL functions.  An 
interesting idea but IMO it seems like an odd restriction to put 
on all functions.

I do understand wanting a solution to this use case though 
(passing a function pointer to a delegate).  That is why I 
created my DIP after all.  However, one could argue that even if 
the context pointer is ignored, it might be worth it to 
explicitly put it in your function which makes it clear that you 
want your function to be ABI compatible with a delegate:


void foo(void* this, int x)
{
     // the function doesn't really need the 'this' parameter.  
That's
     // kind of passing a function to a delegate anyway.
}
struct Bar
{
     void bar(int x)
     {
     }
}

The only drawback here is that you have a 'this' parameter that 
you should ignore, but I would actually prefer the more verbose 
syntax of adding a "void* this" parameter than forcing all 
functions to not use whatever mechanism the equivalent delegate 
would use to pass in context pointer.



More information about the Digitalmars-d mailing list