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

ag0aep6g via Digitalmars-d digitalmars-d at puremagic.com
Mon May 15 16:10:00 PDT 2017


On 05/15/2017 11:56 PM, Jonathan Marler wrote:
> your proposal would require every function to use the same ABI as it's
> delegate counterpart, which includes the code to unwind the stack if the
> context pointer was passed in there or any extra setup code in the caller.

I don't see how that's true. Stack cleanup of the context pointer would 
be done in the caller, not the callee. And no extra setup (or cleanup) 
is needed in the caller when the callee is a non-delegate function.

And that's the point. The goal is to keep normal, non-delegate function 
calls exactly as they are. That's why the context pointer is passed in a 
spot where it doesn't affect the rest of the call (i.e. in a free 
register or before the other args on the stack).

> If this proposal was integrated I could also imagine applications
> wanting to create functions that are not delegate compatible so they
> don't have to incur the delegate ABI overhead, i.e.

There should be zero overhead.

[...]
> In short, this proposal modifies existing the function ABI to use the
> delegate ABI which will have a runtime cost in the general case (even
> though some cases may have zero cost).

No. At least, that's not how it's supposed to work. The idea is to 
modify the delegate ABI to be compatible with the function ABI. I 
wouldn't touch the function ABI.

Every call to a delegate would contain code that's exactly the same as a 
call to a non-delegate function with the same visible parameters. That 
piece of code would look the same as it does today.

For example, if `f(1, 2);` results in machine code `foo` today, then 
`void delegate(int, int) dg = &f; dg(1, 2);` would be made to result in

     mov parameter_register_not_used_in_foo, context_pointer;
     foo;

or if `foo` already uses all registers

     push context_pointer;
     foo;
     pop;

If this doesn't work for some specific `foo`, I'd appreciate an example 
where it falls apart.

It doesn't work with `extern(C++)` methods, because we have to follow 
established calling conventions and put the `this` pointer somewhere 
else. So, implicit conversion wouldn't work here. That's ok.

I suspect that variadic functions might also be problematic. But I 
haven't checked, because I don't care much about them. Worst case, you 
can't implicitly convert a variadic function to a variadic delegate. Not 
a big issue.


More information about the Digitalmars-d mailing list