One minute to twelve: last chance to fix D2 ABI?
Lionello Lunesu
lio at lunesu.remove.com
Tue Mar 2 18:02:51 PST 2010
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.
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.
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.
More information about the Digitalmars-d
mailing list