diff options
Diffstat (limited to 'libffi/src/x86/ffi.c')
-rw-r--r-- | libffi/src/x86/ffi.c | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/libffi/src/x86/ffi.c b/libffi/src/x86/ffi.c index f643b34..611e221 100644 --- a/libffi/src/x86/ffi.c +++ b/libffi/src/x86/ffi.c @@ -58,7 +58,8 @@ void ffi_prep_args(char *stack, extended_cif *ecif) argp = stack; - if (ecif->cif->flags == FFI_TYPE_STRUCT + if ((ecif->cif->flags == FFI_TYPE_STRUCT + || ecif->cif->flags == FFI_TYPE_MS_STRUCT) #ifdef X86_WIN64 && (ecif->cif->rtype->size != 1 && ecif->cif->rtype->size != 2 && ecif->cif->rtype->size != 4 && ecif->cif->rtype->size != 8) @@ -279,7 +280,12 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) else #endif { - cif->flags = FFI_TYPE_STRUCT; +#ifdef X86_WIN32 + if (cif->abi == FFI_MS_CDECL) + cif->flags = FFI_TYPE_MS_STRUCT; + else +#endif + cif->flags = FFI_TYPE_STRUCT; /* allocate space for return value pointer */ cif->bytes += ALIGN(sizeof(void*), FFI_SIZEOF_ARG); } @@ -349,7 +355,8 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) } #else if (rvalue == NULL - && cif->flags == FFI_TYPE_STRUCT) + && (cif->flags == FFI_TYPE_STRUCT + || cif->flags == FFI_TYPE_MS_STRUCT)) { ecif.rvalue = alloca(cif->rtype->size); } @@ -368,6 +375,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) #elif defined(X86_WIN32) case FFI_SYSV: case FFI_STDCALL: + case FFI_MS_CDECL: ffi_call_win32(ffi_prep_args, &ecif, cif->abi, cif->bytes, cif->flags, ecif.rvalue, fn); break; @@ -513,7 +521,8 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue, argp += sizeof(void *); } #else - if ( cif->flags == FFI_TYPE_STRUCT ) { + if ( cif->flags == FFI_TYPE_STRUCT + || cif->flags == FFI_TYPE_MS_STRUCT ) { *rvalue = *(void **) argp; argp += sizeof(void *); } @@ -673,6 +682,12 @@ ffi_prep_closure_loc (ffi_closure* closure, &ffi_closure_STDCALL, (void*)codeloc, cif->bytes); } + else if (cif->abi == FFI_MS_CDECL) + { + FFI_INIT_TRAMPOLINE (&closure->tramp[0], + &ffi_closure_SYSV, + (void*)codeloc); + } #endif /* X86_WIN32 */ #endif /* !X86_WIN64 */ else @@ -762,8 +777,9 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue) /* If the return value is a struct and we don't have a return */ /* value address then we need to make one */ - if ((rvalue == NULL) && - (cif->rtype->type == FFI_TYPE_STRUCT)) + if (rvalue == NULL + && (cif->flags == FFI_TYPE_STRUCT + || cif->flags == FFI_TYPE_MS_STRUCT)) { ecif.rvalue = alloca(cif->rtype->size); } @@ -776,6 +792,7 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue) #ifdef X86_WIN32 case FFI_SYSV: case FFI_STDCALL: + case FFI_MS_CDECL: ffi_call_win32(ffi_prep_args_raw, &ecif, cif->abi, cif->bytes, cif->flags, ecif.rvalue, fn); break; |