Back to index

python3.2  3.2.2
Defines | Functions
ffi.c File Reference
#include <ffi.h>
#include <ffi_common.h>
#include <stdbool.h>
#include <stdlib.h>

Go to the source code of this file.

Defines

#define STACK_ARG_SIZE(x)   ALIGN(x, FFI_SIZEOF_ARG)

Functions

static ffi_status initialize_aggregate (ffi_type *arg)
ffi_status ffi_prep_cif (ffi_cif *cif, ffi_abi abi, unsigned int nargs, ffi_type *rtype, ffi_type **atypes)

Define Documentation

#define STACK_ARG_SIZE (   x)    ALIGN(x, FFI_SIZEOF_ARG)

Definition at line 31 of file ffi.c.


Function Documentation

ffi_status ffi_prep_cif ( ffi_cif cif,
ffi_abi  abi,
unsigned int  nargs,
ffi_type rtype,
ffi_type **  atypes 
)

Definition at line 131 of file ffi.c.

{
       if (cif == NULL)
              return FFI_BAD_TYPEDEF;

       if (abi <= FFI_FIRST_ABI || abi > FFI_DEFAULT_ABI)
              return FFI_BAD_ABI;

       unsigned int  bytes  = 0;
       unsigned int  i;
       ffi_type**           ptr;

       cif->abi = abi;
       cif->arg_types = atypes;
       cif->nargs = nargs;
       cif->rtype = rtype;
       cif->flags = 0;

       /* Initialize the return type if necessary */
       /*@-usedef@*/
       if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK))
              return FFI_BAD_TYPEDEF;
       /*@=usedef@*/

       /* Perform a sanity check on the return type */
       FFI_ASSERT_VALID_TYPE(cif->rtype);

       /* x86-64 and s390 stack space allocation is handled in prep_machdep.  */
#if !defined M68K && !defined __x86_64__ && !defined S390 && !defined PA
       /* Make space for the return structure pointer */
       if (cif->rtype->type == FFI_TYPE_STRUCT
#ifdef SPARC
              && (cif->abi != FFI_V9 || cif->rtype->size > 32)
#endif
#ifdef X86_DARWIN
              && (struct_on_stack(cif->rtype->size))
#endif
              )
              bytes = STACK_ARG_SIZE(sizeof(void*));
#endif

       for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
       {
              /* Initialize any uninitialized aggregate type definitions */
              if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
                     return FFI_BAD_TYPEDEF;

              if ((*ptr)->alignment == 0)
                     return FFI_BAD_TYPEDEF;

              /* Perform a sanity check on the argument type, do this 
              check after the initialization.  */
              FFI_ASSERT_VALID_TYPE(*ptr);

#if defined(X86_DARWIN)
              {
                     int align = (*ptr)->alignment;

                     if (align > 4)
                            align = 4;

                     if ((align - 1) & bytes)
                            bytes = ALIGN(bytes, align);

                     bytes += STACK_ARG_SIZE((*ptr)->size);
              }
#elif !defined __x86_64__ && !defined S390 && !defined PA
#ifdef SPARC
              if (((*ptr)->type == FFI_TYPE_STRUCT
                     && ((*ptr)->size > 16 || cif->abi != FFI_V9))
                     || ((*ptr)->type == FFI_TYPE_LONGDOUBLE
                     && cif->abi != FFI_V9))
                            bytes += sizeof(void*);
              else
#endif
              {
                     /* Add any padding if necessary */
                     if (((*ptr)->alignment - 1) & bytes)
                            bytes = ALIGN(bytes, (*ptr)->alignment);

                     bytes += STACK_ARG_SIZE((*ptr)->size);
              }
#endif
       }

       cif->bytes = bytes;

       /* Perform machine dependent cif processing */
       return ffi_prep_cif_machdep(cif);
}

Here is the call graph for this function:

static ffi_status initialize_aggregate ( ffi_type arg) [static]

Definition at line 37 of file ffi.c.

{
/*@-usedef@*/

       if (arg == NULL || arg->elements == NULL ||
              arg->size != 0 || arg->alignment != 0)
              return FFI_BAD_TYPEDEF;

       ffi_type**    ptr = &(arg->elements[0]);

       while ((*ptr) != NULL)
       {
              if (((*ptr)->size == 0) && (initialize_aggregate(*ptr) != FFI_OK))
                     return FFI_BAD_TYPEDEF;

              /* Perform a sanity check on the argument type */
              FFI_ASSERT_VALID_TYPE(*ptr);

#ifdef POWERPC_DARWIN
              int curalign = (*ptr)->alignment;

              if (ptr != &(arg->elements[0]))
              {
                     if (curalign > 4 && curalign != 16)
                            curalign = 4;
              }

              arg->size            = ALIGN(arg->size, curalign);
              arg->size            += (*ptr)->size;
              arg->alignment       = (arg->alignment > curalign) ? 
                     arg->alignment : curalign;
#else
              arg->size            = ALIGN(arg->size, (*ptr)->alignment);
              arg->size            += (*ptr)->size;
              arg->alignment       = (arg->alignment > (*ptr)->alignment) ? 
                     arg->alignment : (*ptr)->alignment;
#endif

              ptr++;
    }

  /* Structure size includes tail padding.  This is important for
     structures that fit in one register on ABIs like the PowerPC64
     Linux ABI that right justify small structs in a register.
     It's also needed for nested structure layout, for example
     struct A { long a; char b; }; struct B { struct A x; char y; };
     should find y at an offset of 2*sizeof(long) and result in a
     total size of 3*sizeof(long).  */
       arg->size = ALIGN(arg->size, arg->alignment);

       if (arg->size == 0)
              return FFI_BAD_TYPEDEF;

       return FFI_OK;

/*@=usedef@*/
}

Here is the caller graph for this function: