mirror of
https://github.com/partic2/libffi
synced 2026-11-10 01:57:19 +00:00
2014-07-22 Dominik Vogt <vogt@linux.vnet.ibm.com>
* src/types.c (FFI_TYPEDEF, FFI_NONCONST_TYPEDEF): Merge the macros by adding another argument that controls whether the result is const or not (FFI_LDBL_CONST): Temporary macro to reduce ifdef confusion * src/prep_cif.c (ffi_prep_cif_core): Replace list of systems with new macro FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION * src/pa/ffitarget.h (FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION): Define. * src/s390/ffitarget.h (FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION): Define. * src/x86/ffitarget.h (FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION): Define. 2014-07-22 Dominik Vogt <vogt@linux.vnet.ibm.com> * doc/libffi.texi (Primitive Types): Document ffi_type_complex_float, ffi_type_complex_double and ffi_type_complex_longdouble (Complex Types): New subsection. (Complex Type Example): Ditto. * testsuite/libffi.call/cls_align_complex_double.c: New FFI_TYPE_COMPLEX test. * testsuite/libffi.call/cls_align_complex_float.c: Ditto. * testsuite/libffi.call/cls_align_complex_longdouble.c: Ditto. * testsuite/libffi.call/cls_complex_double.c: Ditto. * testsuite/libffi.call/cls_complex_float.c: Ditto. * testsuite/libffi.call/cls_complex_longdouble.c: Ditto. * testsuite/libffi.call/cls_complex_struct_double.c: Ditto. * testsuite/libffi.call/cls_complex_struct_float.c: Ditto. * testsuite/libffi.call/cls_complex_struct_longdouble.c: Ditto. * testsuite/libffi.call/cls_complex_va_double.c: Ditto. * testsuite/libffi.call/cls_complex_va_float.c: Ditto. * testsuite/libffi.call/cls_complex_va_longdouble.c: Ditto. * testsuite/libffi.call/complex_double.c: Ditto. * testsuite/libffi.call/complex_defs_double.c: Ditto. * testsuite/libffi.call/complex_float.c: Ditto. * testsuite/libffi.call/complex_defs_float.c: Ditto. * testsuite/libffi.call/complex_longdouble.c: Ditto. * testsuite/libffi.call/complex_defs_longdouble.c: Ditto. * testsuite/libffi.call/complex_int.c: Ditto. * testsuite/libffi.call/many_complex_double.c: Ditto. * testsuite/libffi.call/many_complex_float.c: Ditto. * testsuite/libffi.call/many_complex_longdouble.c: Ditto. * testsuite/libffi.call/return_complex1_double.c: Ditto. * testsuite/libffi.call/return_complex1_float.c: Ditto. * testsuite/libffi.call/return_complex1_longdouble.c: Ditto. * testsuite/libffi.call/return_complex2_double.c: Ditto. * testsuite/libffi.call/return_complex2_float.c: Ditto. * testsuite/libffi.call/return_complex2_longdouble.c: Ditto. * testsuite/libffi.call/return_complex_double.c: Ditto. * testsuite/libffi.call/return_complex_float.c: Ditto. * testsuite/libffi.call/return_complex_longdouble.c: Ditto. * src/raw_api.c (ffi_raw_to_ptrarray): Handle FFI_TYPE_COMPLEX (ffi_ptrarray_to_raw): Ditto. * src/prep_cif.c (ffi_prep_cif_core): Abort if FFI_TYPE_COMPLEX is not implemented in libffi for the target. * src/java_raw_api.c (ffi_java_raw_size): FFI_TYPE_COMPLEX not supported yet (abort). (ffi_java_raw_to_ptrarray): Ditto. (ffi_java_rvalue_to_raw): Ditto. (ffi_java_raw_to_rvalue): Ditto. * src/debug.c (ffi_type_test): Add debug tests for complex types. * include/ffi.h.in (FFI_TYPE_COMPLEX): Add new FFI_TYPE_COMPLEX. (FFI_TYPE_LAST): Bump. (ffi_type_complex_float): Add new ffi_type_.... (ffi_type_complex_double): Ditto. (ffi_type_complex_longdouble): Ditto. 2014-07-22 Dominik Vogt <vogt@linux.vnet.ibm.com> * src/s390/ffitarget.h (FFI_TARGET_HAS_COMPLEX_TYPE): Define to provide FFI_TYPE_COMPLEX support. * src/s390/ffi.c (ffi_check_struct_type): Implement FFI_TYPE_COMPLEX (ffi_prep_args): Ditto. (ffi_prep_cif_machdep): Ditto. (ffi_closure_helper_SYSV): Ditto.
This commit is contained in:
committed by
Anthony Green
parent
4c5c4088aa
commit
6e8a446083
+6
-1
@@ -54,6 +54,11 @@ void ffi_type_test(ffi_type *a, char *file, int line)
|
||||
FFI_ASSERT_AT(a->type <= FFI_TYPE_LAST, file, line);
|
||||
FFI_ASSERT_AT(a->type == FFI_TYPE_VOID || a->size > 0, file, line);
|
||||
FFI_ASSERT_AT(a->type == FFI_TYPE_VOID || a->alignment > 0, file, line);
|
||||
FFI_ASSERT_AT(a->type != FFI_TYPE_STRUCT || a->elements != NULL, file, line);
|
||||
FFI_ASSERT_AT((a->type != FFI_TYPE_STRUCT && a->type != FFI_TYPE_COMPLEX)
|
||||
|| a->elements != NULL, file, line);
|
||||
FFI_ASSERT_AT(a->type != FFI_TYPE_COMPLEX
|
||||
|| (a->elements != NULL
|
||||
&& a->elements[0] != NULL && a->elements[1] == NULL),
|
||||
file, line);
|
||||
|
||||
}
|
||||
|
||||
@@ -60,6 +60,9 @@ ffi_java_raw_size (ffi_cif *cif)
|
||||
case FFI_TYPE_STRUCT:
|
||||
/* No structure parameters in Java. */
|
||||
abort();
|
||||
case FFI_TYPE_COMPLEX:
|
||||
/* Not supported yet. */
|
||||
abort();
|
||||
default:
|
||||
result += FFI_SIZEOF_JAVA_RAW;
|
||||
}
|
||||
@@ -104,6 +107,10 @@ ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args)
|
||||
*args = (void*) &(raw++)->ptr;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_COMPLEX:
|
||||
/* Not supported yet. */
|
||||
abort();
|
||||
|
||||
default:
|
||||
*args = raw;
|
||||
raw +=
|
||||
@@ -126,6 +133,9 @@ ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args)
|
||||
*args = (void*) raw;
|
||||
raw += 2;
|
||||
break;
|
||||
case FFI_TYPE_COMPLEX:
|
||||
/* Not supported yet. */
|
||||
abort();
|
||||
default:
|
||||
*args = (void*) raw++;
|
||||
}
|
||||
@@ -254,6 +264,10 @@ ffi_java_rvalue_to_raw (ffi_cif *cif, void *rvalue)
|
||||
*(SINT64 *)rvalue <<= 32;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_COMPLEX:
|
||||
/* Not supported yet. */
|
||||
abort();
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -279,6 +293,10 @@ ffi_java_raw_to_rvalue (ffi_cif *cif, void *rvalue)
|
||||
*(SINT64 *)rvalue >>= 32;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_COMPLEX:
|
||||
/* Not supported yet. */
|
||||
abort();
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -62,6 +62,8 @@ typedef enum ffi_abi {
|
||||
} ffi_abi;
|
||||
#endif
|
||||
|
||||
#define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
|
||||
|
||||
/* ---- Definitions for closures ----------------------------------------- */
|
||||
|
||||
#define FFI_CLOSURES 1
|
||||
|
||||
+10
-2
@@ -136,11 +136,15 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi,
|
||||
if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK))
|
||||
return FFI_BAD_TYPEDEF;
|
||||
|
||||
#ifndef FFI_TARGET_HAS_COMPLEX_TYPE
|
||||
if (rtype->type == FFI_TYPE_COMPLEX)
|
||||
abort();
|
||||
#endif
|
||||
/* Perform a sanity check on the return type */
|
||||
FFI_ASSERT_VALID_TYPE(cif->rtype);
|
||||
|
||||
/* x86, x86-64 and s390 stack space allocation is handled in prep_machdep. */
|
||||
#if !defined M68K && !defined X86_ANY && !defined S390 && !defined PA
|
||||
#if !defined FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
|
||||
/* Make space for the return structure pointer */
|
||||
if (cif->rtype->type == FFI_TYPE_STRUCT
|
||||
#ifdef SPARC
|
||||
@@ -166,11 +170,15 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi,
|
||||
if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
|
||||
return FFI_BAD_TYPEDEF;
|
||||
|
||||
#ifndef FFI_TARGET_HAS_COMPLEX_TYPE
|
||||
if ((*ptr)->type == FFI_TYPE_COMPLEX)
|
||||
abort();
|
||||
#endif
|
||||
/* Perform a sanity check on the argument type, do this
|
||||
check after the initialization. */
|
||||
FFI_ASSERT_VALID_TYPE(*ptr);
|
||||
|
||||
#if !defined X86_ANY && !defined S390 && !defined PA
|
||||
#if !defined FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
|
||||
#ifdef SPARC
|
||||
if (((*ptr)->type == FFI_TYPE_STRUCT
|
||||
&& ((*ptr)->size > 16 || cif->abi != FFI_V9))
|
||||
|
||||
@@ -88,6 +88,10 @@ ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args)
|
||||
break;
|
||||
#endif
|
||||
|
||||
case FFI_TYPE_COMPLEX:
|
||||
*args = (raw++)->ptr;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_POINTER:
|
||||
*args = (void*) &(raw++)->ptr;
|
||||
break;
|
||||
@@ -112,6 +116,11 @@ ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args)
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if ((*tp)->type == FFI_TYPE_COMPLEX)
|
||||
{
|
||||
*args = (raw++)->ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
*args = (void*) raw;
|
||||
raw += ALIGN ((*tp)->size, sizeof (void*)) / sizeof (void*);
|
||||
@@ -167,6 +176,10 @@ ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw)
|
||||
break;
|
||||
#endif
|
||||
|
||||
case FFI_TYPE_COMPLEX:
|
||||
(raw++)->ptr = *args;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_POINTER:
|
||||
(raw++)->ptr = **(void***) args;
|
||||
break;
|
||||
|
||||
+18
-7
@@ -215,9 +215,12 @@ ffi_prep_args (unsigned char *stack, extended_cif *ecif)
|
||||
#endif
|
||||
|
||||
/* Check how a structure type is passed. */
|
||||
if (type == FFI_TYPE_STRUCT)
|
||||
if (type == FFI_TYPE_STRUCT || type == FFI_TYPE_COMPLEX)
|
||||
{
|
||||
type = ffi_check_struct_type (*ptr);
|
||||
if (type == FFI_TYPE_COMPLEX)
|
||||
type = FFI_TYPE_POINTER;
|
||||
else
|
||||
type = ffi_check_struct_type (*ptr);
|
||||
|
||||
/* If we pass the struct via pointer, copy the data. */
|
||||
if (type == FFI_TYPE_POINTER)
|
||||
@@ -356,8 +359,9 @@ ffi_prep_cif_machdep(ffi_cif *cif)
|
||||
cif->flags = FFI390_RET_VOID;
|
||||
break;
|
||||
|
||||
/* Structures are returned via a hidden pointer. */
|
||||
/* Structures and complex are returned via a hidden pointer. */
|
||||
case FFI_TYPE_STRUCT:
|
||||
case FFI_TYPE_COMPLEX:
|
||||
cif->flags = FFI390_RET_STRUCT;
|
||||
n_gpr++; /* We need one GPR to pass the pointer. */
|
||||
break;
|
||||
@@ -420,9 +424,12 @@ ffi_prep_cif_machdep(ffi_cif *cif)
|
||||
#endif
|
||||
|
||||
/* Check how a structure type is passed. */
|
||||
if (type == FFI_TYPE_STRUCT)
|
||||
if (type == FFI_TYPE_STRUCT || type == FFI_TYPE_COMPLEX)
|
||||
{
|
||||
type = ffi_check_struct_type (*ptr);
|
||||
if (type == FFI_TYPE_COMPLEX)
|
||||
type = FFI_TYPE_POINTER;
|
||||
else
|
||||
type = ffi_check_struct_type (*ptr);
|
||||
|
||||
/* If we pass the struct via pointer, we must reserve space
|
||||
to copy its data for proper call-by-value semantics. */
|
||||
@@ -588,9 +595,12 @@ ffi_closure_helper_SYSV (ffi_closure *closure,
|
||||
#endif
|
||||
|
||||
/* Check how a structure type is passed. */
|
||||
if (type == FFI_TYPE_STRUCT)
|
||||
if (type == FFI_TYPE_STRUCT || type == FFI_TYPE_COMPLEX)
|
||||
{
|
||||
type = ffi_check_struct_type (*ptr);
|
||||
if (type == FFI_TYPE_COMPLEX)
|
||||
type = FFI_TYPE_POINTER;
|
||||
else
|
||||
type = ffi_check_struct_type (*ptr);
|
||||
|
||||
/* If we pass the struct via pointer, remember to
|
||||
retrieve the pointer later. */
|
||||
@@ -687,6 +697,7 @@ ffi_closure_helper_SYSV (ffi_closure *closure,
|
||||
/* Void is easy, and so is struct. */
|
||||
case FFI_TYPE_VOID:
|
||||
case FFI_TYPE_STRUCT:
|
||||
case FFI_TYPE_COMPLEX:
|
||||
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
#endif
|
||||
|
||||
@@ -52,6 +52,8 @@ typedef enum ffi_abi {
|
||||
} ffi_abi;
|
||||
#endif
|
||||
|
||||
#define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
|
||||
#define FFI_TARGET_HAS_COMPLEX_TYPE
|
||||
|
||||
/* ---- Definitions for closures ----------------------------------------- */
|
||||
|
||||
|
||||
+41
-27
@@ -33,26 +33,30 @@
|
||||
|
||||
/* Type definitions */
|
||||
|
||||
#define FFI_TYPEDEF(name, type, id) \
|
||||
#define FFI_TYPEDEF(name, type, id, maybe_const)\
|
||||
struct struct_align_##name { \
|
||||
char c; \
|
||||
type x; \
|
||||
}; \
|
||||
const ffi_type ffi_type_##name = { \
|
||||
maybe_const ffi_type ffi_type_##name = { \
|
||||
sizeof(type), \
|
||||
offsetof(struct struct_align_##name, x), \
|
||||
id, NULL \
|
||||
}
|
||||
|
||||
#define FFI_NONCONST_TYPEDEF(name, type, id) \
|
||||
struct struct_align_##name { \
|
||||
char c; \
|
||||
type x; \
|
||||
}; \
|
||||
ffi_type ffi_type_##name = { \
|
||||
sizeof(type), \
|
||||
offsetof(struct struct_align_##name, x), \
|
||||
id, NULL \
|
||||
#define FFI_COMPLEX_TYPEDEF(name, type, maybe_const) \
|
||||
static ffi_type *ffi_elements_complex_##name [2] = { \
|
||||
(ffi_type *)(&ffi_type_##name), NULL \
|
||||
}; \
|
||||
struct struct_align_complex_##name { \
|
||||
char c; \
|
||||
_Complex type x; \
|
||||
}; \
|
||||
maybe_const ffi_type ffi_type_complex_##name = { \
|
||||
sizeof(_Complex type), \
|
||||
offsetof(struct struct_align_complex_##name, x), \
|
||||
FFI_TYPE_COMPLEX, \
|
||||
(ffi_type **)ffi_elements_complex_##name \
|
||||
}
|
||||
|
||||
/* Size and alignment are fake here. They must not be 0. */
|
||||
@@ -60,19 +64,25 @@ const ffi_type ffi_type_void = {
|
||||
1, 1, FFI_TYPE_VOID, NULL
|
||||
};
|
||||
|
||||
FFI_TYPEDEF(uint8, UINT8, FFI_TYPE_UINT8);
|
||||
FFI_TYPEDEF(sint8, SINT8, FFI_TYPE_SINT8);
|
||||
FFI_TYPEDEF(uint16, UINT16, FFI_TYPE_UINT16);
|
||||
FFI_TYPEDEF(sint16, SINT16, FFI_TYPE_SINT16);
|
||||
FFI_TYPEDEF(uint32, UINT32, FFI_TYPE_UINT32);
|
||||
FFI_TYPEDEF(sint32, SINT32, FFI_TYPE_SINT32);
|
||||
FFI_TYPEDEF(uint64, UINT64, FFI_TYPE_UINT64);
|
||||
FFI_TYPEDEF(sint64, SINT64, FFI_TYPE_SINT64);
|
||||
FFI_TYPEDEF(uint8, UINT8, FFI_TYPE_UINT8, const);
|
||||
FFI_TYPEDEF(sint8, SINT8, FFI_TYPE_SINT8, const);
|
||||
FFI_TYPEDEF(uint16, UINT16, FFI_TYPE_UINT16, const);
|
||||
FFI_TYPEDEF(sint16, SINT16, FFI_TYPE_SINT16, const);
|
||||
FFI_TYPEDEF(uint32, UINT32, FFI_TYPE_UINT32, const);
|
||||
FFI_TYPEDEF(sint32, SINT32, FFI_TYPE_SINT32, const);
|
||||
FFI_TYPEDEF(uint64, UINT64, FFI_TYPE_UINT64, const);
|
||||
FFI_TYPEDEF(sint64, SINT64, FFI_TYPE_SINT64, const);
|
||||
|
||||
FFI_TYPEDEF(pointer, void*, FFI_TYPE_POINTER);
|
||||
FFI_TYPEDEF(pointer, void*, FFI_TYPE_POINTER, const);
|
||||
|
||||
FFI_TYPEDEF(float, float, FFI_TYPE_FLOAT);
|
||||
FFI_TYPEDEF(double, double, FFI_TYPE_DOUBLE);
|
||||
FFI_TYPEDEF(float, float, FFI_TYPE_FLOAT, const);
|
||||
FFI_TYPEDEF(double, double, FFI_TYPE_DOUBLE, const);
|
||||
|
||||
#if !defined HAVE_LONG_DOUBLE_VARIANT || defined __alpha__
|
||||
#define FFI_LDBL_CONST const
|
||||
#else
|
||||
#define FFI_LDBL_CONST
|
||||
#endif
|
||||
|
||||
#ifdef __alpha__
|
||||
/* Even if we're not configured to default to 128-bit long double,
|
||||
@@ -84,9 +94,13 @@ FFI_TYPEDEF(double, double, FFI_TYPE_DOUBLE);
|
||||
# endif
|
||||
const ffi_type ffi_type_longdouble = { 16, 16, 4, NULL };
|
||||
#elif FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
|
||||
# if HAVE_LONG_DOUBLE_VARIANT
|
||||
FFI_NONCONST_TYPEDEF(longdouble, long double, FFI_TYPE_LONGDOUBLE);
|
||||
# else
|
||||
FFI_TYPEDEF(longdouble, long double, FFI_TYPE_LONGDOUBLE);
|
||||
# endif
|
||||
FFI_TYPEDEF(longdouble, long double, FFI_TYPE_LONGDOUBLE, FFI_LDBL_CONST);
|
||||
#endif
|
||||
|
||||
#ifdef FFI_TARGET_HAS_COMPLEX_TYPE
|
||||
FFI_COMPLEX_TYPEDEF(float, float, const);
|
||||
FFI_COMPLEX_TYPEDEF(double, double, const);
|
||||
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
|
||||
FFI_COMPLEX_TYPEDEF(longdouble, long double, FFI_LDBL_CONST);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -49,6 +49,8 @@
|
||||
#define USE_BUILTIN_FFS 0 /* not yet implemented in mingw-64 */
|
||||
#endif
|
||||
|
||||
#define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
|
||||
|
||||
/* ---- Generic type definitions ----------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
|
||||
Reference in New Issue
Block a user