On Tue, 02 Mar 2010 21:02:51 -0500, Lionello Lunesu <[email protected]> wrote:
The following has been discussed for years, and the biggest problem
(years ago) was that it was too late to change the D (1) ABI.

Is the D2 ABI compatible with D1? Should it be? If not, please consider
the following change:

alias void delegate() action_d;
void Callback() { }             // global
action_d = &Callback;           // should work

A function should be assignable to a delegate (but not vice versa*.)
This can work, since the code invoking the delegate will end up calling
the function with a context pointer ("this") in a register that's simply
ignored by the code in the function.

Except this also effects member functions, nested functions, etc.

This is fairly easy too: the calling convention for functions and
delegates should be identical, except for the context pointer, which
should be stored in a register that's unused in the function calling
convention.

This breaks the synergy of returns in EAX and params in EAX.

The reason for this change is that many times classes expose delegates
for callbacks, but it's impossible to bind a function to those
delegates. The code above can easily be made to compile:

action_d = { Callback(); }; //wrapped, works

but causes a dummy function to be called, only because the parameter
ABI's don't overlap:

_D1t4mainFZi12__dgliteral1MFZi  comdat            ;delegate literal
        assume  CS:_D1t4mainFZi12__dgliteral1MFZi
L0:             push    EAX
                call    near ptr _D1t8FunctionFZi ;global function
                pop     ECX
                ret
_D1t4mainFZi12__dgliteral1MFZi  ends

Of course, all of this applies to extern "D" code only.

* Binding a delegate to a function pointer will always need a (dynamic)
thunk, because the function will have been invoked without any context
pointer and it's the thunk's responsibility to assign the correct
context pointer.

It would be fairly easy for D (or anyone else) to implicitly define a simple adapter that stores the function pointer in the delegate's this pointer. The adapter function pointer points to one of two common stub functions which either calls the this pointer or pops a value off the stack into EAX and then calls the this pointer.

Reply via email to