One minute to twelve: last chance to fix D2 ABI?
Robert Jacques
sandford at jhu.edu
Tue Mar 2 18:49:16 PST 2010
On Tue, 02 Mar 2010 21:02:51 -0500, Lionello Lunesu
<lio at lunesu.remove.com> 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.
More information about the Digitalmars-d
mailing list