Exemple #1
0
ffi_status
ffi_prep_cif (ffi_cif * cif,
	      ffi_abi abi, unsigned int nargs,
	      ffi_type * rtype, ffi_type ** atypes)
{
  unsigned bytes = 0;
  unsigned int i;
  ffi_type **ptr;

  FFI_ASSERT (cif != NULL);
  FFI_ASSERT ((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI));

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

  cif->flags = 0;

  if ((cif->rtype->size == 0)
      && (initialize_aggregate_packed_struct (cif->rtype) != FFI_OK))
    return FFI_BAD_TYPEDEF;

  FFI_ASSERT_VALID_TYPE (cif->rtype);

  for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
    {
      if (((*ptr)->size == 0)
	  && (initialize_aggregate_packed_struct ((*ptr)) != FFI_OK))
	return FFI_BAD_TYPEDEF;

      FFI_ASSERT_VALID_TYPE (*ptr);

      if (((*ptr)->alignment - 1) & bytes)
	bytes = ALIGN (bytes, (*ptr)->alignment);
      if ((*ptr)->type == FFI_TYPE_STRUCT)
	{
	  if ((*ptr)->size > 8)
	    {
	      bytes += (*ptr)->size;
	      bytes += sizeof (void *);
	    }
	  else
	    {
	      if ((*ptr)->size > 4)
		bytes += 8;
	      else
		bytes += 4;
	    }
	}
      else
	bytes += STACK_ARG_SIZE ((*ptr)->size);
    }

  cif->bytes = bytes;

  return ffi_prep_cif_machdep (cif);
}
Exemple #2
0
// Arguments' ffi_type->alignment must be nonzero.
ffi_status
ffi_prep_cif(
    /*@out@*/ /*@partial@*/	ffi_cif*		cif,
    ffi_abi			abi,
    unsigned int	nargs,
    /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type*	rtype,
    /*@dependent@*/			ffi_type**		atypes)
{
    unsigned int	bytes	= 0;
    unsigned int	i;
    ffi_type**		ptr;

    if (cif == NULL)
        return FFI_BAD_TYPEDEF;

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

    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);
}
Exemple #3
0
Fichier : ffi.c Projet : 620book/nu
ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,
			ffi_type *rtype, ffi_type **atypes)
{
  unsigned bytes = 0;
  unsigned int i;
  ffi_type **ptr;

  FFI_ASSERT(cif != NULL);
  FFI_ASSERT((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI));

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

  cif->flags = 0;

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

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

  /* x86-64 stack space allocation is handled in prep_machdep.  */
#if !defined __x86_64__ 
  /* Make space for the return structure pointer */
  if (cif->rtype->type == FFI_TYPE_STRUCT
#ifdef X86_DARWIN
      && (cif->rtype->size > 8)
#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;

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

#if !defined __x86_64__ 
	{
	  /* 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);
}
Exemple #4
0
ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, 
			ffi_abi abi, unsigned int nargs, 
			/*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype, 
			/*@dependent@*/ ffi_type **atypes)
{
  unsigned bytes = 0;
  unsigned int i;
  ffi_type **ptr;

  FFI_ASSERT(cif != NULL);
  FFI_ASSERT((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI));

  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
  /* Make space for the return structure pointer */
  if (cif->rtype->type == FFI_TYPE_STRUCT
#ifdef _WIN32
      && (cif->rtype->size > 8)  /* MSVC returns small structs in registers */
#endif
#ifdef SPARC
      && (cif->abi != FFI_V9 || cif->rtype->size > 32)
#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;

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

#if !defined __x86_64__ && !defined S390
#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
	{
#if !defined(_MSC_VER) && !defined(__MINGW32__)
		/* Don't know if this is a libffi bug or not.  At least on
		   Windows with MSVC, function call parameters are *not*
		   aligned in the same way as structure fields are, they are
		   only aligned in integer boundaries.

		   This doesn't do any harm for cdecl functions and closures,
		   since the caller cleans up the stack, but it is wrong for
		   stdcall functions where the callee cleans.
		*/

	  /* Add any padding if necessary */
	  if (((*ptr)->alignment - 1) & bytes)
	    bytes = ALIGN(bytes, (*ptr)->alignment);
	  
#endif
	  bytes += STACK_ARG_SIZE((*ptr)->size);
	}
#endif
    }

#ifdef _WIN64
  /* Function call needs at least 40 bytes stack size, on win64 AMD64 */
  if (bytes < 40)
      bytes = 40;
#endif

  cif->bytes = bytes;

  /* Perform machine dependent cif processing */
  return ffi_prep_cif_machdep(cif);
}
Exemple #5
0
ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi,
			     unsigned int isvariadic,
                             unsigned int nfixedargs,
                             unsigned int ntotalargs,
			     ffi_type *rtype, ffi_type **atypes)
{
  unsigned bytes = 0;
  unsigned int i;
  ffi_type **ptr;

  FFI_ASSERT(cif != NULL);
  FFI_ASSERT((!isvariadic) || (nfixedargs >= 1));
  FFI_ASSERT(nfixedargs <= ntotalargs);

#ifndef X86_WIN32
  if (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI))
    return FFI_BAD_ABI;
#else
  if (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI || abi == FFI_THISCALL))
    return FFI_BAD_ABI;
#endif

  cif->abi = abi;
  cif->arg_types = atypes;
  cif->nargs = ntotalargs;
  cif->rtype = rtype;

  cif->flags = 0;

#if HAVE_LONG_DOUBLE_VARIANT
  ffi_prep_types (abi);
#endif

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

  /* 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
  /* 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 TILE
      && (cif->rtype->size > 10 * FFI_SIZEOF_ARG)
#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;

      /* 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
#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);

#ifdef TILE
	  if (bytes < 10 * FFI_SIZEOF_ARG &&
	      bytes + STACK_ARG_SIZE((*ptr)->size) > 10 * FFI_SIZEOF_ARG)
	    {
	      /* An argument is never split between the 10 parameter
		 registers and the stack.  */
	      bytes = 10 * FFI_SIZEOF_ARG;
	    }
#endif

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

  cif->bytes = bytes;

  /* Perform machine dependent cif processing */
#ifdef FFI_TARGET_SPECIFIC_VARIADIC
  if (isvariadic)
	return ffi_prep_cif_machdep_var(cif, nfixedargs, ntotalargs);
#endif

  return ffi_prep_cif_machdep(cif);
}
Exemple #6
0
ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,
			ffi_type *rtype, ffi_type **atypes)
{
  unsigned bytes = 0;
  unsigned int i;
  ffi_type **ptr;

  FFI_ASSERT(cif != NULL);
#ifndef X86_WIN32
  if (! (abi > FFI_FIRST_ABI) && (abi <= FFI_LAST_ABI))
    return FFI_BAD_ABI;
#else
  if (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI || abi == FFI_THISCALL))
    return FFI_BAD_ABI;
#endif

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

  cif->flags = 0;

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

  /* 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
  /* 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
     )
    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;

      /* 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
#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);
}