]> granicus.if.org Git - python/commitdiff
fix libffi compilation on FreeBSD (#23042)
authorBenjamin Peterson <benjamin@python.org>
Sat, 9 May 2015 01:31:36 +0000 (21:31 -0400)
committerBenjamin Peterson <benjamin@python.org>
Sat, 9 May 2015 01:31:36 +0000 (21:31 -0400)
Patch from Marc-Andre Lemburg.

Modules/_ctypes/libffi/src/x86/ffi.c

index 64b19ecfd4f6306d7d3897d42c6c070b1f44d73c..dbf9c8e3263b7727bb17c1801ce6fcfdd3f18633 100644 (file)
@@ -331,10 +331,11 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
 extern int
 ffi_call_win64(void (*)(char *, extended_cif *), extended_cif *,
                unsigned, unsigned, unsigned *, void (*fn)(void));
-#else
+#elif defined(X86_WIN32)
 extern void
 ffi_call_win32(void (*)(char *, extended_cif *), extended_cif *,
                unsigned, unsigned, unsigned, unsigned *, void (*fn)(void));
+#else
 extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
                           unsigned, unsigned, unsigned *, void (*fn)(void));
 #endif
@@ -376,16 +377,9 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
       ffi_call_win64(ffi_prep_args, &ecif, cif->bytes,
                      cif->flags, ecif.rvalue, fn);
       break;
-#else
-#ifndef X86_WIN32
-    case FFI_SYSV:
-      ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
-                    fn);
-      break;
-#else
+#elif defined(X86_WIN32)
     case FFI_SYSV:
     case FFI_MS_CDECL:
-#endif
     case FFI_STDCALL:
       ffi_call_win32(ffi_prep_args, &ecif, cif->abi, cif->bytes, cif->flags,
                     ecif.rvalue, fn);
@@ -419,6 +413,11 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
                        ecif.rvalue, fn);
       }
       break;
+#else
+    case FFI_SYSV:
+      ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
+                    fn);
+      break;
 #endif
     default:
       FFI_ASSERT(0);
@@ -787,28 +786,36 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
   /* If the return value is a struct and we don't have a return */
   /* value address then we need to make one                     */
 
+#ifdef X86_WIN64
+  if (rvalue == NULL
+      && cif->flags == FFI_TYPE_STRUCT
+      && cif->rtype->size != 1 && cif->rtype->size != 2
+      && cif->rtype->size != 4 && cif->rtype->size != 8)
+    {
+      ecif.rvalue = alloca((cif->rtype->size + 0xF) & ~0xF);
+    }
+#else
   if (rvalue == NULL
       && (cif->flags == FFI_TYPE_STRUCT
           || cif->flags == FFI_TYPE_MS_STRUCT))
     {
       ecif.rvalue = alloca(cif->rtype->size);
     }
+#endif
   else
     ecif.rvalue = rvalue;
     
   
   switch (cif->abi) 
     {
-#ifndef X86_WIN32
-    case FFI_SYSV:
-      ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
-                    ecif.rvalue, fn);
+#ifdef X86_WIN64
+    case FFI_WIN64:
+      ffi_call_win64(ffi_prep_args_raw, &ecif, cif->bytes,
+                     cif->flags, ecif.rvalue, fn);
       break;
-#else
+#elif defined(X86_WIN32)
     case FFI_SYSV:
     case FFI_MS_CDECL:
-#endif
-#ifndef X86_WIN64
     case FFI_STDCALL:
       ffi_call_win32(ffi_prep_args_raw, &ecif, cif->abi, cif->bytes, cif->flags,
                     ecif.rvalue, fn);
@@ -835,13 +842,18 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
            ++passed_regs;
          }
        if (passed_regs < 2 && abi == FFI_FASTCALL)
-         cif->abi = abi = FFI_THISCALL;
+         abi = FFI_THISCALL;
        if (passed_regs < 1 && abi == FFI_THISCALL)
-         cif->abi = abi = FFI_STDCALL;
+         abi = FFI_STDCALL;
         ffi_call_win32(ffi_prep_args_raw, &ecif, abi, cif->bytes, cif->flags,
                        ecif.rvalue, fn);
       }
       break;
+#else
+    case FFI_SYSV:
+      ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags, ecif.rvalue,
+                    fn);
+      break;
 #endif
     default:
       FFI_ASSERT(0);