Mercurial > pub > dyncall > dyncall
diff dyncallback/dyncall_args_x64.c @ 557:b36a738c8975
- dyncallback: fix for calling back win/x64 C++ methods returning non-trivial aggregates (thanks Raphael!)
- test/callback_plain_c++:
* added test code for C++ method callbacks returning non-trivial aggregates
* makefile linker command fix (was linking assuming c and not c++)
- test/plain_c++: comments for completeness
author | Tassilo Philipp |
---|---|
date | Sat, 20 Aug 2022 21:04:15 +0200 |
parents | 4d87bd4890b0 |
children | 93ce63d72d59 |
line wrap: on
line diff
--- a/dyncallback/dyncall_args_x64.c Mon Jul 11 23:17:50 2022 +0200 +++ b/dyncallback/dyncall_args_x64.c Sat Aug 20 21:04:15 2022 +0200 @@ -149,30 +149,28 @@ } -/* A 16 byte struct would be sufficient for System V (because at most two of the four registers can be full). */ -/* But then it's much more complicated to copy the result to the correct registers in assembly. */ -typedef struct { - DClonglong r[2]; /* rax, rdx */ - DCdouble x[2]; /* xmm0, xmm1 */ -} DCRetRegs_SysV; - void dcbReturnAggr(DCArgs *args, DCValue *result, DCpointer ret) { int i; DCaggr *ag = *(args->aggrs++); - if(!ag) { - /* non-trivial aggr: all we can do is to provide the ptr to the output space, user has to make copy */ - result->p = (DCpointer) args->reg_data.i[0]; - return; - } - - if (args->aggr_return_register >= 0) { + if(args->aggr_return_register >= 0) { DCpointer dest = (DCpointer) args->reg_data.i[args->aggr_return_register]; - memcpy(dest, ret, ag->size); + if(ag) + memcpy(dest, ret, ag->size); + else { + /* non-trivial aggr: all we can do is to provide the ptr to the output space, user has to make copy */ + } result->p = dest; } else { #if defined(DC_UNIX) + /* A 16 byte struct would be sufficient for System V (because at most two of the four registers can be full). */ + /* But then it's much more complicated to copy the result to the correct registers in assembly. */ + typedef struct { + DClonglong r[2]; /* rax, rdx */ + DCdouble x[2]; /* xmm0, xmm1 */ + } DCRetRegs_SysV; + /* a max of 2 regs are used in this case, out of rax, rdx, xmm0 and xmm1 */ /* space for 4 qwords is pointed to by (DCRetRegs_SysV*)result */ DClonglong *intRegs = ((DCRetRegs_SysV*)result)->r;