View mode: basic / threaded / horizontal-split · Log in · Help
November 01, 2006
reflection / D's function calling convention?
Is D's functions calling convention somewhere documented?

I've been tinkering with a reflection module for D.
Gaining access to all dynamic and static symbols is
currently possible as well as calling C functions
(see below) but calling functions with D linkage isn't
yet implemented:

#
# import kuehne.reflection;
# 
# int main(){
#    Symbol s = symbols["strlen"];
#
#    char* test = "unter den Birnen";
#    size_t len = 0;
#
#    Argument[] arg = new Argument[1];
#    arg[0].size = test.sizeof;
#    arg[0].data = &test;
#
#    Argument[] result;
#    result = s.call(CallingConvention.C, arg);
#    foreach(x; result){
#    	if(x.type == "<?>"){
#    		len = *(cast(size_t*) x.data);
#    		break;
#    	}
#    }
#
#    printf("strlen('%s') -> %zu", test, len);
#    return 0;
# }

output:
>
> strlen('unter den Birnen') -> 16
>

Thomas
November 01, 2006
Re: reflection / D's function calling convention?
Thomas Kuehne wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> Is D's functions calling convention somewhere documented?

Not really. It's callee clean stack, args pushed right to left, last arg 
passed in EAX.
November 01, 2006
Re: reflection / D's function calling convention?
Walter Bright wrote:
> Thomas Kuehne wrote:
>> -----BEGIN PGP SIGNED MESSAGE-----
>> Hash: SHA1
>>
>> Is D's functions calling convention somewhere documented?
> 
> Not really. It's callee clean stack, args pushed right to left, last arg 
> passed in EAX.

Could you please copy & paste that into the "Function Calling 
Conventions" part of the ABI page on the spec? It's better than nothing.
And maybe add 'this pointer passed in EBX' (if that's true).
November 01, 2006
Re: reflection / D's function calling convention?
On Wed, 01 Nov 2006 05:40:18 -0500, Walter Bright  
<newshound@digitalmars.com> wrote:

> Thomas Kuehne wrote:
>> -----BEGIN PGP SIGNED MESSAGE-----
>> Hash: SHA1
>>  Is D's functions calling convention somewhere documented?
>
> Not really. It's callee clean stack, args pushed right to left, last arg  
> passed in EAX.

Can you please explain some more...

For variadic functions, the caller probably cleans up and the last arg not  
put in EAX.

What if the last arg does not fit in EAX; e.g. a char[], is half put in  
EAX / half on the stack, or all on the stack?

Return value: EAX, or also I believe EAX and EDX for 64-bit values.

Returning floating point: in floating point register?

Bigger return types probably first push a pointer to a return buffer?

Variadic TypeInfo[] _arguments pushed last or first or something else?
November 01, 2006
Re: reflection / D's function calling convention?
> I've been tinkering with a reflection module for D.

Attached is rudimental reflection module for D.

limitations:
* only supported on *nix systems (porting to Windows should be straight forward)
* read permissions required in addition to execution permission for finding symbols
* the symbol sizes generated by DMD are defective, thus no class/struct support
* the D calling convention is undocumented, thus unsupported

license:
ZLIB

Thomas
November 01, 2006
Re: reflection / D's function calling convention?
"Chris Miller" <chris@dprogramming.com> wrote in message 
news:op.tib3szvnpo9bzi@tanu...
> Can you please explain some more...

Here's all that I've researched:

DMD FUNCTION CALLING CONVENTION:

params are passed, in general, l-to-r.

in functions with varargs, all params are passed r-to-l, and are all pushed.
varargs also push the _arguments array as the last (furthest left) param.
caller is responsible for cleaning up params to vararg function.

typesafe variadic functions just take an array as their variadic arg; the 
array is
built by the caller and passed as a regular array - because it's basically
a non-vararg function, params are passed l-to-r.

all kinds of ints, pointers, class refs, bools, char, wchar, dchar, func 
pointers:
if not last, push; else, put in EAX

longs:
push hi, push lo

float, ifloat:
push

double, idouble:
push hi, push lo

real, ireal:
push really hi, push hi, push lo

cfloat:
push float im, push float re

cdouble:
push double im, push double re

creal:
push real im, push real re

arrays:
push pointer (hi), push length (lo)

delegates:
push address, push context ptr ('this' or frame ptr)

structs:
push the whole damn thing, starting at the beginning

D METHOD CALLING CONVENTION:

Similar to above, with following differences:

all kinds of ints, ptrs, refs etc:
push

'this' goes into EAX

D DELEGATE CALLING CONVENTION:

put context in both EAX and EBX -- EBX is not actually used in the delegate 
though
put address in EDX
call EDX

> For variadic functions, the caller probably cleans up and the last arg not 
> put in EAX.

Right.

> What if the last arg does not fit in EAX; e.g. a char[], is half put in 
> EAX / half on the stack, or all on the stack?

It's pushed entirely.

> Return value: EAX, or also I believe EAX and EDX for 64-bit values.

I'm pretty sure longs are put in EDX:EAX as you say.

> Returning floating point: in floating point register?

Ooh, not sure about that one.

> Bigger return types probably first push a pointer to a return buffer?

Hmm, guess I didn't do much return type research :S

> Variadic TypeInfo[] _arguments pushed last or first or something else?

It's pushed last, so it's technically the furthest-left param (before all 
other params).
November 01, 2006
Re: reflection / D's function calling convention?
Jarrett Billingsley wrote:
> "Chris Miller" <chris@dprogramming.com> wrote in message 
> news:op.tib3szvnpo9bzi@tanu...
>> Can you please explain some more...
> 
> Here's all that I've researched:
> 
[snip]

A great collection! How about tidying it up, and giving the whole thing 
to Walter to put into the spec?

>> Returning floating point: in floating point register?
> 
> Ooh, not sure about that one.

Yes, they are returned on top of the x87 floating point stack.
This applies to complex types as well:

Example:

// Calculate cos(y) + i sin(y).
creal expi(real y)
{
        asm
        {
            fld y;
            fsincos;
            fxch st(1), st(0);
        }
}
November 01, 2006
Re: reflection / D's function calling convention?
Don Clugston wrote:
> Could you please copy & paste that into the "Function Calling 
> Conventions" part of the ABI page on the spec? It's better than nothing.
> And maybe add 'this pointer passed in EBX' (if that's true).

I just uploaded a new http://www.digitalmars.com/d/abi.html with more 
complete information on the D calling convention.
November 01, 2006
Re: reflection / D's function calling convention?
Jarrett Billingsley schrieb am 2006-11-01:
> "Chris Miller" <chris@dprogramming.com> wrote in message 
> news:op.tib3szvnpo9bzi@tanu...
>> Can you please explain some more...
>
> Here's all that I've researched:
>
> DMD FUNCTION CALLING CONVENTION:

Thanks.

> params are passed, in general, l-to-r.
>
> in functions with varargs, all params are passed r-to-l
<snip>

Wouldn't it be easier and less bug prone to use r-to-l for all?

Even unidirectional __cdecl/extern(C) seems hard to implement:
"Random Testing of C Calling Conventions"; Christian Lindig; 2005
http://www.st.cs.uni-sb.de/~lindig/papers/quest/quest.pdf

> > Bigger return types probably first push a pointer to a return buffer?
> 
> Hmm, guess I didn't do much return type research :S

Defining that seems to be crucial.
The C++ people have serious problems with structs:

http://www.agner.org/optimize/calling_conventions.pdf

Table 7(methods for returning structure, class and union objects)
shows how everybody and his dog uses a different approach.

Thomas
November 01, 2006
Re: reflection / D's function calling convention?
That looks a way more complete, great!

On Wed, 2006-11-01 at 11:33 -0800, Walter Bright wrote:
> Don Clugston wrote:
> > Could you please copy & paste that into the "Function Calling 
> > Conventions" part of the ABI page on the spec? It's better than nothing.
> > And maybe add 'this pointer passed in EBX' (if that's true).
> 
> I just uploaded a new http://www.digitalmars.com/d/abi.html with more 
> complete information on the D calling convention.
« First   ‹ Prev
1 2
Top | Discussion index | About this forum | D home