diff options
author | Tom Tromey <tom@tromey.com> | 2015-11-17 21:18:20 -0700 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2016-02-22 16:07:55 -0700 |
commit | 38a4d72c95936d27cba1ac6e84e3094ffdfaa77c (patch) | |
tree | 389d99afd9cb696fc3ac6b35ee91b8d6d4dce64f /src/prep_cif.c | |
parent | f2f234aef203a5e836b83cb772f9473f7ea0d5ce (diff) | |
download | libffi-38a4d72c95936d27cba1ac6e84e3094ffdfaa77c.tar.gz |
add ffi_get_struct_offsets
Diffstat (limited to 'src/prep_cif.c')
-rw-r--r-- | src/prep_cif.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/src/prep_cif.c b/src/prep_cif.c index 5881ceb..43f0487 100644 --- a/src/prep_cif.c +++ b/src/prep_cif.c @@ -34,7 +34,7 @@ /* Perform machine independent initialization of aggregate type specifications. */ -static ffi_status initialize_aggregate(ffi_type *arg) +static ffi_status initialize_aggregate(ffi_type *arg, size_t *offsets) { ffi_type **ptr; @@ -52,13 +52,15 @@ static ffi_status initialize_aggregate(ffi_type *arg) while ((*ptr) != NULL) { if (UNLIKELY(((*ptr)->size == 0) - && (initialize_aggregate((*ptr)) != FFI_OK))) + && (initialize_aggregate((*ptr), NULL) != FFI_OK))) return FFI_BAD_TYPEDEF; /* Perform a sanity check on the argument type */ FFI_ASSERT_VALID_TYPE(*ptr); arg->size = ALIGN(arg->size, (*ptr)->alignment); + if (offsets) + *offsets++ = arg->size; arg->size += (*ptr)->size; arg->alignment = (arg->alignment > (*ptr)->alignment) ? @@ -133,7 +135,8 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi, #endif /* Initialize the return type if necessary */ - if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK)) + if ((cif->rtype->size == 0) + && (initialize_aggregate(cif->rtype, NULL) != FFI_OK)) return FFI_BAD_TYPEDEF; #ifndef FFI_TARGET_HAS_COMPLEX_TYPE @@ -164,7 +167,8 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi, { /* Initialize any uninitialized aggregate type definitions */ - if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK)) + if (((*ptr)->size == 0) + && (initialize_aggregate((*ptr), NULL) != FFI_OK)) return FFI_BAD_TYPEDEF; #ifndef FFI_TARGET_HAS_COMPLEX_TYPE @@ -240,3 +244,18 @@ ffi_prep_closure (ffi_closure* closure, } #endif + +ffi_status +ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type, size_t *offsets) +{ + if (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI)) + return FFI_BAD_ABI; + if (struct_type->type != FFI_TYPE_STRUCT) + return FFI_BAD_TYPEDEF; + +#if HAVE_LONG_DOUBLE_VARIANT + ffi_prep_types (abi); +#endif + + return initialize_aggregate(struct_type, offsets); +} |