[Python-checkins] r60944 - python/branches/libffi3-branch/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c

thomas.heller python-checkins at python.org
Fri Feb 22 08:44:46 CET 2008


Author: thomas.heller
Date: Fri Feb 22 08:44:45 2008
New Revision: 60944

Modified:
   python/branches/libffi3-branch/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c
Log:
More files from libffi-3.0.2 (added function prototypes).

Modified: python/branches/libffi3-branch/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c
==============================================================================
--- python/branches/libffi3-branch/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c	(original)
+++ python/branches/libffi3-branch/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c	Fri Feb 22 08:44:45 2008
@@ -1,12 +1,13 @@
 #if !(defined(__APPLE__) && !defined(__ppc__))
 /* -----------------------------------------------------------------------
-   ffi.c - Copyright (c) 1998 Geoffrey Keating
+   ffi_darwin.c
 
-   PowerPC Foreign Function Interface
-
-   Darwin ABI support (c) 2001 John Hornkvist
-   AIX ABI support (c) 2002 Free Software Foundation, Inc.
+   Copyright (C) 1998 Geoffrey Keating
+   Copyright (C) 2001 John Hornkvist
+   Copyright (C) 2002, 2006, 2007 Free Software Foundation, Inc.
 
+   FFI support for Darwin and AIX.
+   
    Permission is hereby granted, free of charge, to any person obtaining
    a copy of this software and associated documentation files (the
    ``Software''), to deal in the Software without restriction, including
@@ -80,9 +81,7 @@
 
    */
 
-/*@-exportheader@*/
 void ffi_prep_args(extended_cif *ecif, unsigned *const stack)
-/*@=exportheader@*/
 {
   const unsigned bytes = ecif->cif->bytes;
   const unsigned flags = ecif->cif->flags;
@@ -228,6 +227,48 @@
   //FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
 }
 
+/* Adjust the size of S to be correct for Darwin.
+   On Darwin, the first field of a structure has natural alignment.  */
+
+static void
+darwin_adjust_aggregate_sizes (ffi_type *s)
+{
+  int i;
+
+  if (s->type != FFI_TYPE_STRUCT)
+    return;
+
+  s->size = 0;
+  for (i = 0; s->elements[i] != NULL; i++)
+    {
+      ffi_type *p;
+      int align;
+      
+      p = s->elements[i];
+      darwin_adjust_aggregate_sizes (p);
+      if (i == 0
+	  && (p->type == FFI_TYPE_UINT64
+	      || p->type == FFI_TYPE_SINT64
+	      || p->type == FFI_TYPE_DOUBLE
+	      || p->alignment == 8))
+	align = 8;
+      else if (p->alignment == 16 || p->alignment < 4)
+	align = p->alignment;
+      else
+	align = 4;
+      s->size = ALIGN(s->size, align) + p->size;
+    }
+  
+  s->size = ALIGN(s->size, s->alignment);
+  
+  if (s->elements[0]->type == FFI_TYPE_UINT64
+      || s->elements[0]->type == FFI_TYPE_SINT64
+      || s->elements[0]->type == FFI_TYPE_DOUBLE
+      || s->elements[0]->alignment == 8)
+    s->alignment = s->alignment > 8 ? s->alignment : 8;
+  /* Do not add additional tail padding.  */
+}
+
 /* Perform machine dependent cif processing.  */
 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
 {
@@ -240,8 +281,16 @@
   unsigned size_al = 0;
 
   /* All the machine-independent calculation of cif->bytes will be wrong.
+     All the calculation of structure sizes will also be wrong.
      Redo the calculation for DARWIN.  */
 
+  if (cif->abi == FFI_DARWIN)
+    {
+      darwin_adjust_aggregate_sizes (cif->rtype);
+      for (i = 0; i < cif->nargs; i++)
+	darwin_adjust_aggregate_sizes (cif->arg_types[i]);
+    }
+
   /* Space for the frame pointer, callee's LR, CR, etc, and for
      the asm's temp regs.  */
 
@@ -376,25 +425,12 @@
   return FFI_OK;
 }
 
-/*@-declundef@*/
-/*@-exportheader@*/
-extern void ffi_call_AIX(/*@out@*/ extended_cif *,
-			 unsigned, unsigned,
-			 /*@out@*/ unsigned *,
-			 void (*fn)(void),
-			 void (*fn2)(extended_cif *, unsigned *const));
-extern void ffi_call_DARWIN(/*@out@*/ extended_cif *,
-			    unsigned, unsigned,
-			    /*@out@*/ unsigned *,
-			    void (*fn)(void),
-			    void (*fn2)(extended_cif *, unsigned *const));
-/*@=declundef@*/
-/*@=exportheader@*/
-
-void ffi_call(/*@dependent@*/ ffi_cif *cif,
-	      void (*fn)(void),
-	      /*@out@*/ void *rvalue,
-	      /*@dependent@*/ void **avalue)
+extern void ffi_call_AIX(extended_cif *, unsigned, unsigned, unsigned *,
+			 void (*fn)(void), void (*fn2)(void));
+extern void ffi_call_DARWIN(extended_cif *, unsigned, unsigned, unsigned *,
+			    void (*fn)(void), void (*fn2)(void));
+
+void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
 {
   extended_cif ecif;
 
@@ -407,9 +443,7 @@
   if ((rvalue == NULL) &&
       (cif->rtype->type == FFI_TYPE_STRUCT))
     {
-      /*@-sysunrecog@*/
       ecif.rvalue = alloca(cif->rtype->size);
-      /*@=sysunrecog@*/
     }
   else
     ecif.rvalue = rvalue;
@@ -417,16 +451,12 @@
   switch (cif->abi)
     {
     case FFI_AIX:
-      /*@-usedef@*/
-      ffi_call_AIX(&ecif, -cif->bytes,
-		   cif->flags, ecif.rvalue, fn, ffi_prep_args);
-      /*@=usedef@*/
+      ffi_call_AIX(&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn,
+		   ffi_prep_args);
       break;
     case FFI_DARWIN:
-      /*@-usedef@*/
-      ffi_call_DARWIN(&ecif, -cif->bytes,
-		      cif->flags, ecif.rvalue, fn, ffi_prep_args);
-      /*@=usedef@*/
+      ffi_call_DARWIN(&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn,
+		      ffi_prep_args);
       break;
     default:
       FFI_ASSERT(0);
@@ -499,10 +529,11 @@
 
 */
 ffi_status
-ffi_prep_closure (ffi_closure* closure,
-		  ffi_cif* cif,
-		  void (*fun)(ffi_cif*, void*, void**, void*),
-		  void *user_data)
+ffi_prep_closure_loc (ffi_closure* closure,
+		      ffi_cif* cif,
+		      void (*fun)(ffi_cif*, void*, void**, void*),
+		      void *user_data,
+		      void *codeloc)
 {
   unsigned int *tramp;
   struct ffi_aix_trampoline_struct *tramp_aix;
@@ -524,14 +555,14 @@
       tramp[8] = 0x816b0004;  /*   lwz     r11,4(r11) static chain  */
       tramp[9] = 0x4e800420;  /*   bctr  */
       tramp[2] = (unsigned long) ffi_closure_ASM; /* function  */
-      tramp[3] = (unsigned long) closure; /* context  */
+      tramp[3] = (unsigned long) codeloc; /* context  */
 
       closure->cif = cif;
       closure->fun = fun;
       closure->user_data = user_data;
 
       /* Flush the icache. Only necessary on Darwin.  */
-      flush_range(&closure->tramp[0],FFI_TRAMPOLINE_SIZE);
+      flush_range(codeloc, FFI_TRAMPOLINE_SIZE);
 
       break;
 
@@ -544,7 +575,7 @@
 
       tramp_aix->code_pointer = fd->code_pointer;
       tramp_aix->toc = fd->toc;
-      tramp_aix->static_chain = closure;
+      tramp_aix->static_chain = codeloc;
       closure->cif = cif;
       closure->fun = fun;
       closure->user_data = user_data;


More information about the Python-checkins mailing list