Back to index

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

Go to the source code of this file.

Defines

#define FFI_INIT_TRAMPOLINE(TRAMP, FUN)

Functions

void ffi_prep_args (char *stack, extended_cif *ecif)
ffi_status ffi_prep_cif_machdep (ffi_cif *cif)
void ffi_call_SYSV (void(*)(char *, extended_cif *), extended_cif *, unsigned, unsigned, unsigned *, void(*fn)())
int ffi_call (ffi_cif *cif, void(*fn)(), void *rvalue, void **avalue)
static void ffi_prep_incoming_args_SYSV (char *stack, void **ret, void **args, ffi_cif *cif)
 private members
unsigned int ffi_closure_SYSV_inner (ffi_closure *closure, char *in_args, void *rvalue)
void ffi_closure_SYSV (void)
ffi_status ffi_prep_closure (ffi_closure *closure, ffi_cif *cif, void(*fun)(ffi_cif *, void *, void **, void *), void *user_data)

Define Documentation

#define FFI_INIT_TRAMPOLINE (   TRAMP,
  FUN 
)
Value:
{ \
    unsigned int *__tramp = (unsigned int *)(TRAMP); \
    __tramp[0] = 0xe24fc008;            /* add   ip, pc, #-8    */ \
    __tramp[1] = 0xe51ff004;            /* ldr   pc, [pc, #-4]  */ \
    __tramp[2] = (unsigned int)(FUN); \
  }

Definition at line 276 of file ffi.c.


Function Documentation

int ffi_call ( ffi_cif cif,
void(*)()  fn,
void rvalue,
void **  avalue 
)

Definition at line 156 of file ffi.c.

{
  extended_cif ecif;

  ecif.cif = cif;
  ecif.avalue = 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))
    {
      /*@-sysunrecog@*/
      ecif.rvalue = alloca(cif->rtype->size);
      /*@=sysunrecog@*/
    }
  else
    ecif.rvalue = rvalue;
    
  
  switch (cif->abi) 
    {
    case FFI_SYSV:
      /*@-usedef@*/
      ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, 
                  cif->flags, ecif.rvalue, fn);
      /*@=usedef@*/
      break;
    default:
      FFI_ASSERT(0);
      break;
    }
  /* I think calculating the real stack pointer delta is not useful
     because stdcall is not supported */
  return 0;
}

Here is the call graph for this function:

void ffi_call_SYSV ( void(*)(char *, extended_cif *)  ,
extended_cif ,
unsigned  ,
unsigned  ,
unsigned *  ,
void(*)()  fn 
)
unsigned int ffi_closure_SYSV_inner ( ffi_closure *  closure,
char *  in_args,
void rvalue 
)

Definition at line 205 of file ffi.c.

{
  ffi_cif *cif = closure->cif;
  void **out_args;

  out_args = (void **) alloca(cif->nargs * sizeof (void *));  

  /* this call will initialize out_args, such that each
   * element in that array points to the corresponding 
   * value on the stack; and if the function returns
   * a structure, it will re-set rvalue to point to the
   * structure return address.  */

  ffi_prep_incoming_args_SYSV(in_args, &rvalue, out_args, cif);
  
  (closure->fun)(cif, rvalue, out_args, closure->user_data);

  /* Tell ffi_closure_SYSV what the returntype is */
  return cif->flags;
}

Here is the call graph for this function:

void ffi_prep_args ( char *  stack,
extended_cif ecif 
)

Definition at line 40 of file ffi.c.

{
  register unsigned int i;
  register void **p_argv;
  register char *argp;
  register ffi_type **p_arg;

  argp = stack;

  if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) {
    *(void **) argp = ecif->rvalue;
    argp += 4;
  }

  p_argv = ecif->avalue;

  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
       (i != 0);
       i--, p_arg++)
    {
      size_t z;
      size_t argalign = (*p_arg)->alignment;

#ifdef _WIN32_WCE
      if (argalign > 4)
        argalign = 4;
#endif
      /* Align if necessary */
      if ((argalign - 1) & (unsigned) argp) {
       argp = (char *) ALIGN(argp, argalign);
      }

         z = (*p_arg)->size;
         if (z < sizeof(int))
           {
             z = sizeof(int);
             switch ((*p_arg)->type)
              {
              case FFI_TYPE_SINT8:
                *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
                break;
                
              case FFI_TYPE_UINT8:
                *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
                break;
                
              case FFI_TYPE_SINT16:
                *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
                break;
                
              case FFI_TYPE_UINT16:
                *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
                break;
                
              case FFI_TYPE_STRUCT:
                  /* *p_argv may not be aligned for a UINT32 */
                  memcpy(argp, *p_argv, z);
                break;

              default:
                FFI_ASSERT(0);
              }
           }
         else if (z == sizeof(int))
           {
             *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
           }
         else
           {
             memcpy(argp, *p_argv, z);
           }
         p_argv++;
         argp += z;
    }
  
  return;
}

Here is the call graph for this function:

Definition at line 120 of file ffi.c.

{
  /* Set the return type flag */
  switch (cif->rtype->type)
    {
    case FFI_TYPE_VOID:
    case FFI_TYPE_STRUCT:
    case FFI_TYPE_FLOAT:
    case FFI_TYPE_DOUBLE:
    case FFI_TYPE_SINT64:
      cif->flags = (unsigned) cif->rtype->type;
      break;

    case FFI_TYPE_UINT64:
      cif->flags = FFI_TYPE_SINT64;
      break;

    default:
      cif->flags = FFI_TYPE_INT;
      break;
    }

  return FFI_OK;
}
ffi_status ffi_prep_closure ( ffi_closure *  closure,
ffi_cif cif,
void(*)(ffi_cif *, void *, void **, void *)  fun,
void user_data 
)

Definition at line 290 of file ffi.c.

{
  FFI_ASSERT (cif->abi == FFI_SYSV);
  
  FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_SYSV);

  closure->cif  = cif;
  closure->user_data = user_data;
  closure->fun  = fun;

#ifdef _WIN32_WCE
  /* This is important to allow calling the trampoline safely */
  FlushInstructionCache(GetCurrentProcess(), 0, 0);
#endif

  return FFI_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ffi_prep_incoming_args_SYSV ( char *  stack,
void **  ret,
void **  args,
ffi_cif cif 
) [static]

private members

Definition at line 228 of file ffi.c.

{
  unsigned int i;
  void **p_argv;
  char *argp;
  ffi_type **p_arg;

  argp = stack;

  if ( cif->rtype->type == FFI_TYPE_STRUCT ) {
    *rvalue = *(void **) argp;
    argp += 4;
  }

  p_argv = avalue;

  for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
    {
      size_t z;
      size_t argalign = (*p_arg)->alignment;

#ifdef _WIN32_WCE
      if (argalign > 4)
        argalign = 4;
#endif
      /* Align if necessary */
      if ((argalign - 1) & (unsigned) argp) {
       argp = (char *) ALIGN(argp, argalign);
      }

      z = (*p_arg)->size;
      if (z < sizeof(int))
        z = sizeof(int);

      *p_argv = (void*) argp;

      p_argv++;
      argp += z;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function: