On 4 May 2012 19:18, Nicolas Cellier <nicolas.cellier.aka.nice@gmail.com> wrote:
Yes, on max too https://developer.apple.com/library/mac/#documentation/developertools/Concep...
Structures. The called function returns structures according to their aligned size.
  Structures 1 or 2 bytes in size are placed in EAX.
  Structures 4 or 8 bytes in size are placed in: EAX and EDX.
okay.. i fixed it in NativeBoost-Core-IgorStasenko.58
  Structures of other sizes are placed at the address supplied by the caller. For example, the C++ language occasionally forces the compiler to return a value in memory when it would normally be returned in registers. See âPassing Argumentsâ for more information.
I wonder if a structure of size 3 bytes can exist or is automatically extended on 4 bytes...
yes.. struct alignment is what i fear of.. IMO it is actually silly to not return struct in registers if it less than 8 bytes but not power of 2.. sounds like an artefact of establishing the standards :)
$ cat > test_call.c <<END
#include <stdio.h> typedef struct { char a,b,c; } abc; int main() { Â Â abc x; Â Â printf("sizeof(abc)=%d\n",sizeof x); Â Â return 0; } END
$ gcc test_call.c $ ./a.exe sizeof(abc)=3
And what would be the calling conventions of cygwin gcc ?
$ cat > test_call.c <<END
#include <stdio.h> typedef struct { char a,b,c; } abc; abc sub() { Â abc result; Â result.a='a'; Â result.b='b'; Â result.c='c'; Â return result; } int main() { Â Â abc x=sub(); Â Â printf("sizeof(abc)=%d abc.a=$c\n",sizeof x,x.a); Â Â return 0; } END
$ gcc test_call.c $ ./a.exe sizeof(abc)=3 abc.a=a
$ gcc -S test_call.c $ cat test_call.S
    .file  "test_call.c"     .text .globl _sub     .def   _sub;  .scl   2;    .type  32;   .endef _sub:     pushl  %ebp     movl   %esp, %ebp     subl   $16, %esp     movl   8(%ebp), %eax     movb   $97, -3(%ebp)     movb   $98, -2(%ebp)     movb   $99, -1(%ebp)     movzwl  -3(%ebp), %edx     movw   %dx, (%eax)     movzbl  -1(%ebp), %edx     movb   %dl, 2(%eax)     leave     ret   $4     .def   ___main;     .scl   2;    .type  32;   .endef     .section .rdata,"dr" LC0:     .ascii "sizeof(abc)=%d\12\0"     .text .globl _main     .def   _main;  .scl   2;    .type  32;   .endef _main:     leal   4(%esp), %ecx     andl   $-16, %esp     pushl  -4(%ecx)     pushl  %ebp     movl   %esp, %ebp     pushl  %ecx     subl   $36, %esp     call   ___main     leal   -11(%ebp), %eax     movl   %eax, (%esp)     call   _sub     subl   $4, %esp     movl   $3, 4(%esp)     movl   $LC0, (%esp)     call   _printf     movl   $0, %eax     movl   -4(%ebp), %ecx     leave     leal   -4(%ecx), %esp     ret     .def   _printf;     .scl   2;    .type  32;   .endef
But of course, you already were faster than me...
Nicolas
2012/5/4 Igor Stasenko <siguctua@gmail.com>:
On 4 May 2012 18:37, Eliot Miranda <eliot.miranda@gmail.com> wrote:
On Fri, May 4, 2012 at 6:13 AM, Igor Stasenko <siguctua@gmail.com> wrote:
On 4 May 2012 10:38, Luc Fabresse <luc.fabresse@gmail.com> wrote:
Hi Igor,
there is a workaround. all structs in C is returned via pointer. so, actually a true return type of a function is CvSize*
I agree that usually structs are returned through pointers. But here it is not the case.
I want to wrap this function: CvSize cvGetSize( const CvArr* arr );
and the CvSize struct is returned by value. Am I wrong?
i don't know.. this is a bit shady part of C ABI. Some compilers use return-by-value, some return by pointer by forcing a caller to pass a hidden implicit argument as a pointer to the struct, which then filled with values by the function you call.
IIRC x86 ABIs (all the ones I encountered at least, windows, mac, linux, solaris) Â support structure return (by-value structure return) by passing a hidden first argument which is a pointer to a structure into which to copy the result. Â The callee copies the result back through this pointer.
Where these ABIs differ is in returning small structures. Â On win32 structures a power-of-two in size of 8 bytes or less are returned in EAX:EDX. Â IIRC on linux and mac all structures are returned through the hidden first argument pointer. Â See ThreadedIA32FFIPlugin>>returnStructInRegisters:
on macs (at least what gcc generates) it also returns structs <=8 bytes size in registers:
so , currently i implemented it like that: if sizeof(struct) <= 8 then i assume function returns it in EAX: EDX otherwise via hidden pointer.
It is easy to add support for that, but to make it work correctly can be tricky. See this, for example:
http://stackoverflow.com/questions/161788/are-there-any-downsides-to-passing...
so, what you do is to change the return value to simple void* and then copy the contents of struct into instance of corresponding NBExternalStructure subclass using #fromPointer: method.. to conveniently access its fields values.
yes I saw that in NB tests.
but this is in general, in your case this function is actually inlined by compiler (as CV_INLINE suggests), so there could be even no exported symbol for it in dynamic library. and the function is actually so simple, that you don't need to wrap it at all. you can just create a subclass of NBExternalStructure , named CvSize, implement fieldDesc method as:
fieldsDesc ^ #( int width; int height )
and if you invoke:
CvSize new width: 1 height:2
it will be equivalent as if you will call cvSize(1,2) function.
yes it is exactly what I did.
So my problem is:
NBCvSize implemented as a subclass of NBExternalStruct with fieldDesc correctly set up. Then wrap the function cvGetSize:
getSize    self nbCall: #(NBCvSize cvGetSize(IplImage self)) module: LIB_CV.
But I get a debugger because:
NBExternalStruct>>coerceReturn: gen " ... should we support handling return of external structures? " self error: 'returning pointer to structure?'
And I have no idea how to implement this (black magic EAX pop push ;-)) to coerce result of struct.
you don't. if function takes an implicit struct pointer, you can just rewrite the function signature from NBCvSize cvGetSize(IplImage self) to:
void cvGetSize(NBCvSize hidden, IplImage self)
and so, you pass a fresh instance of NBCvSize as argument, which function then fill. But if C compiler using registers to return struct.. then you're screwed :)
Anyways, Luc i will try to read docs about C ABI and see if we can easily add support for that.
-- Best regards, Igor Stasenko.
-- best, Eliot
-- Best regards, Igor Stasenko.
-- Best regards, Igor Stasenko.