/* -----------------------------------------------------------------------
- prep_cif.c - Copyright (c) 1996, 1998 Cygnus Solutions
+ prep_cif.c - Copyright (c) 1996, 1998, 2007 Red Hat, Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
#include <ffi_common.h>
#include <stdlib.h>
+/* Round up to FFI_SIZEOF_ARG. */
-/* Round up to SIZEOF_ARG. */
-
-#define STACK_ARG_SIZE(x) ALIGN(x, SIZEOF_ARG)
+#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG)
/* Perform machine independent initialization of aggregate type
specifications. */
-static ffi_status initialize_aggregate(/*@out@*/ ffi_type *arg)
+static ffi_status initialize_aggregate(ffi_type *arg)
{
- ffi_type **ptr;
+ ffi_type **ptr;
FFI_ASSERT(arg != NULL);
- /*@-usedef@*/
-
FFI_ASSERT(arg->elements != NULL);
FFI_ASSERT(arg->size == 0);
FFI_ASSERT(arg->alignment == 0);
{
if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
return FFI_BAD_TYPEDEF;
-
+
/* Perform a sanity check on the argument type */
- FFI_ASSERT(ffi_type_test((*ptr)));
+ FFI_ASSERT_VALID_TYPE(*ptr);
arg->size = ALIGN(arg->size, (*ptr)->alignment);
arg->size += (*ptr)->size;
- arg->alignment = (arg->alignment > (*ptr)->alignment) ?
+ arg->alignment = (arg->alignment > (*ptr)->alignment) ?
arg->alignment : (*ptr)->alignment;
ptr++;
return FFI_BAD_TYPEDEF;
else
return FFI_OK;
-
- /*@=usedef@*/
}
+#ifndef __CRIS__
+/* The CRIS ABI specifies structure elements to have byte
+ alignment only, so it completely overrides this functions,
+ which assumes "natural" alignment and padding. */
+
/* Perform machine independent ffi_cif preparation, then call
machine dependent routine. */
-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)
+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_LAST_ABI));
+ FFI_ASSERT((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI));
cif->abi = abi;
cif->arg_types = atypes;
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(ffi_type_test(cif->rtype));
+ 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
+#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
+ && (cif->rtype->size > 8)
+#endif
+ )
bytes = STACK_ARG_SIZE(sizeof(void*));
#endif
for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
{
- /* Perform a sanity check on the argument type */
- FFI_ASSERT(ffi_type_test(*ptr));
/* Initialize any uninitialized aggregate type definitions */
if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
return FFI_BAD_TYPEDEF;
-#if !defined __x86_64__ && !defined S390
+ /* 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 && !defined PA
#ifdef SPARC
if (((*ptr)->type == FFI_TYPE_STRUCT
&& ((*ptr)->size > 16 || cif->abi != FFI_V9))
/* Add any padding if necessary */
if (((*ptr)->alignment - 1) & bytes)
bytes = ALIGN(bytes, (*ptr)->alignment);
-
+
bytes += STACK_ARG_SIZE((*ptr)->size);
}
#endif
/* Perform machine dependent cif processing */
return ffi_prep_cif_machdep(cif);
}
+#endif /* not __CRIS__ */
+
+#if FFI_CLOSURES
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+ ffi_cif* cif,
+ void (*fun)(ffi_cif*,void*,void**,void*),
+ void *user_data)
+{
+ return ffi_prep_closure_loc (closure, cif, fun, user_data, closure);
+}
+
+#endif