summaryrefslogtreecommitdiff
path: root/src/prep_cif.c
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2015-11-17 21:18:20 -0700
committerTom Tromey <tom@tromey.com>2016-02-22 16:07:55 -0700
commit38a4d72c95936d27cba1ac6e84e3094ffdfaa77c (patch)
tree389d99afd9cb696fc3ac6b35ee91b8d6d4dce64f /src/prep_cif.c
parentf2f234aef203a5e836b83cb772f9473f7ea0d5ce (diff)
downloadlibffi-38a4d72c95936d27cba1ac6e84e3094ffdfaa77c.tar.gz
add ffi_get_struct_offsets
Diffstat (limited to 'src/prep_cif.c')
-rw-r--r--src/prep_cif.c27
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);
+}