Re: D's exact stack convention for D and C/C++

2016-07-17 Thread bitwise via Digitalmars-d

On Sunday, 17 July 2016 at 01:30:31 UTC, Adam Sansier wrote:
I am trying to debug some really messed up code that makes no 
sense. It calls in some code that doesn't seem to be using the 
standard calling convention. The function definitions are 
exactly the same in both D and C++.


->func(param1, param2, param3, param4);

The call stack setup by C++ before the call is

001fa18d 002aff3c 0014 00c0 002b10f8 00c7fa34 001f16cc 
7f383000


The order is ret EIP, param1, param2, param3, param4, this

For D(naked asm)

00403ff3 002dc108 00c0 0014 002e73e8 026236f0 02ae4a78 
0019fe54


The order is ret EIP, param4, param3, param2, param1,

as one can see, the order is reversed. The functions are 
declared exactly the same in C++ and D(I just copied to D and 
marked extern(C++). It is part of a method(It is COM but that 
shouldn't matter?)).


Forget all that, What I'm really interested in is the exact 
calling conventions used in D and C and C++ and what they mean 
so I can make sure I know whats going on, cause something funky 
is happening and it's not on my end(I'm not messing with the 
order of this stuff directly).


So,

extern(C) = ?
extern(D) = ?
extern(C++) = ?
extern(Windows) = ?

C++ standard convention = ?
C standard convetion = ?
D standard convention = ?

Also, how is this pointer passed in method calls? ECX? Stack? 
If Stack, first or last? Does it change with calling convention?


I'm looking for only the facts, hopefully from the man himself.


Is this a member function or global function that you're talking 
about?


If you mean that you made a D class and then marked the function 
extern(C++), I don't believe that is the correct way to do it. 
You need to use an interface instead of a class in D, as 
described here:


https://dlang.org/spec/cpp_interface.html

I'm not sure if it has been fixed at this point, but classes with 
virtual destructors were not working for me last time I used this 
stuff.


If it's a global function, then you could try changing it to 
extern(C) instead, and your mark your C++ functions extern"C". 
extern(C++) seemed to be giving me compiler-dependant 
difficulties last time I tried it.


Bit



Re: D's exact stack convention for D and C/C++

2016-07-17 Thread Guillaume Piolat via Digitalmars-d

On Sunday, 17 July 2016 at 01:30:31 UTC, Adam Sansier wrote:


Forget all that, What I'm really interested in is the exact 
calling conventions used in D and C and C++ and what they mean 
so I can make sure I know whats going on, cause something funky 
is happening and it's not on my end(I'm not messing with the 
order of this stuff directly).


If you don't use naked asm, you won't have to know this. And you 
get other benefits like being able to use the same x86 code 
across OSes (and sometimes across x86 and x86_64).


The problem with calling conventions is that they can be sublty 
different eg. between OS X and Linux 64-bit. It's a big trap that 
is worth avoiding.


Re: D's exact stack convention for D and C/C++

2016-07-16 Thread Joakim via Digitalmars-d

On Sunday, 17 July 2016 at 01:30:31 UTC, Adam Sansier wrote:
I am trying to debug some really messed up code that makes no 
sense. It calls in some code that doesn't seem to be using the 
standard calling convention. The function definitions are 
exactly the same in both D and C++.


->func(param1, param2, param3, param4);

The call stack setup by C++ before the call is

001fa18d 002aff3c 0014 00c0 002b10f8 00c7fa34 001f16cc 
7f383000


The order is ret EIP, param1, param2, param3, param4, this

For D(naked asm)

00403ff3 002dc108 00c0 0014 002e73e8 026236f0 02ae4a78 
0019fe54


The order is ret EIP, param4, param3, param2, param1,

as one can see, the order is reversed. The functions are 
declared exactly the same in C++ and D(I just copied to D and 
marked extern(C++). It is part of a method(It is COM but that 
shouldn't matter?)).


Forget all that, What I'm really interested in is the exact 
calling conventions used in D and C and C++ and what they mean 
so I can make sure I know whats going on, cause something funky 
is happening and it's not on my end(I'm not messing with the 
order of this stuff directly).


So,

extern(C) = ?
extern(D) = ?
extern(C++) = ?
extern(Windows) = ?

C++ standard convention = ?
C standard convetion = ?
D standard convention = ?

Also, how is this pointer passed in method calls? ECX? Stack? 
If Stack, first or last? Does it change with calling convention?


I'm looking for only the facts, hopefully from the man himself.


According to the spec,

"The extern (C) and extern (D) calling convention matches the C 
calling convention used by the supported C compiler on the host 
system."

https://dlang.org/spec/abi.html

There are tests for C and C++ compatibility that you can look at, 
from the compiler testsuite:


https://github.com/dlang/dmd/blob/master/test/runnable/cpp_abi_tests.d
https://github.com/dlang/dmd/blob/master/test/runnable/cppa.d
https://github.com/dlang/dmd/blob/master/test/runnable/cabi1.d

The corresponding C/C++ files can be found here:

https://github.com/dlang/dmd/tree/master/test/runnable/extra-files


D's exact stack convention for D and C/C++

2016-07-16 Thread Adam Sansier via Digitalmars-d
I am trying to debug some really messed up code that makes no 
sense. It calls in some code that doesn't seem to be using the 
standard calling convention. The function definitions are exactly 
the same in both D and C++.


->func(param1, param2, param3, param4);

The call stack setup by C++ before the call is

001fa18d 002aff3c 0014 00c0 002b10f8 00c7fa34 001f16cc 
7f383000


The order is ret EIP, param1, param2, param3, param4, this

For D(naked asm)

00403ff3 002dc108 00c0 0014 002e73e8 026236f0 02ae4a78 
0019fe54


The order is ret EIP, param4, param3, param2, param1,

as one can see, the order is reversed. The functions are declared 
exactly the same in C++ and D(I just copied to D and marked 
extern(C++). It is part of a method(It is COM but that shouldn't 
matter?)).


Forget all that, What I'm really interested in is the exact 
calling conventions used in D and C and C++ and what they mean so 
I can make sure I know whats going on, cause something funky is 
happening and it's not on my end(I'm not messing with the order 
of this stuff directly).


So,

extern(C) = ?
extern(D) = ?
extern(C++) = ?
extern(Windows) = ?

C++ standard convention = ?
C standard convetion = ?
D standard convention = ?

Also, how is this pointer passed in method calls? ECX? Stack? If 
Stack, first or last? Does it change with calling convention?


I'm looking for only the facts, hopefully from the man himself.