[pypy-commit] cffi windows: merge default into branch

matti noreply at buildbot.pypy.org
Thu Jul 18 21:48:30 CEST 2013


Author: matti
Branch: windows
Changeset: r1286:887dae2c707c
Date: 2013-07-18 22:43 +0300
http://bitbucket.org/cffi/cffi/changeset/887dae2c707c/

Log:	merge default into branch

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -3885,19 +3885,6 @@
         }
         assert(cf == NULL);
 
-#ifdef USE_C_LIBFFI_MSVC
-        /* MSVC returns small structures in registers.  Pretend int32 or
-           int64 return type.  This is needed as a workaround for what
-           is really a bug of libffi_msvc seen as an independent library
-           (ctypes has a similar workaround). */
-        if (is_result_type) {
-            if (ct->ct_size <= 4)
-                return &ffi_type_sint32;
-            if (ct->ct_size <= 8)
-                return &ffi_type_sint64;
-        }
-#endif
-
         /* next, allocate and fill the flattened list */
         elements = fb_alloc(fb, (nflat + 1) * sizeof(ffi_type*));
         nflat = 0;
diff --git a/c/libffi_msvc/ffi.c b/c/libffi_msvc/ffi.c
--- a/c/libffi_msvc/ffi.c
+++ b/c/libffi_msvc/ffi.c
@@ -46,7 +46,7 @@
   register ffi_type **p_arg;
 
   argp = stack;
-  if (ecif->cif->rtype->type == FFI_TYPE_STRUCT)
+  if (ecif->cif->flags == FFI_TYPE_STRUCT)
     {
       *(void **) argp = ecif->rvalue;
       argp += sizeof(void *);
@@ -102,6 +102,15 @@
 	      FFI_ASSERT(0);
 	    }
 	}
+#ifdef _WIN64
+      else if (z > 8)
+        {
+          /* On Win64, if a single argument takes more than 8 bytes,
+             then it is always passed by reference. */
+          *(void **)argp = *p_argv;
+          z = 8;
+        }
+#endif
       else
 	{
 	  memcpy(argp, *p_argv, z);
@@ -124,7 +133,6 @@
   switch (cif->rtype->type)
     {
     case FFI_TYPE_VOID:
-    case FFI_TYPE_STRUCT:
     case FFI_TYPE_SINT64:
     case FFI_TYPE_FLOAT:
     case FFI_TYPE_DOUBLE:
@@ -132,6 +140,18 @@
       cif->flags = (unsigned) cif->rtype->type;
       break;
 
+    case FFI_TYPE_STRUCT:
+      /* MSVC returns small structures in registers.  Put in cif->flags
+         the value FFI_TYPE_STRUCT only if the structure is big enough;
+         otherwise, put the 4- or 8-bytes integer type. */
+      if (cif->rtype->size <= 4)
+        cif->flags = FFI_TYPE_INT;
+      else if (cif->rtype->size <= 8)
+        cif->flags = FFI_TYPE_SINT64;
+      else
+        cif->flags = FFI_TYPE_STRUCT;
+      break;
+
     case FFI_TYPE_UINT64:
 #ifdef _WIN64
     case FFI_TYPE_POINTER:
@@ -180,7 +200,7 @@
   /* value address then we need to make one		        */
 
   if ((rvalue == NULL) && 
-      (cif->rtype->type == FFI_TYPE_STRUCT))
+      (cif->flags == FFI_TYPE_STRUCT))
     {
       /*@-sysunrecog@*/
       ecif.rvalue = alloca(cif->rtype->size);
@@ -338,7 +358,7 @@
 
   argp = stack;
 
-  if ( cif->rtype->type == FFI_TYPE_STRUCT ) {
+  if ( cif->flags == FFI_TYPE_STRUCT ) {
     *rvalue = *(void **) argp;
     argp += 4;
   }
diff --git a/c/libffi_msvc/prep_cif.c b/c/libffi_msvc/prep_cif.c
--- a/c/libffi_msvc/prep_cif.c
+++ b/c/libffi_msvc/prep_cif.c
@@ -116,9 +116,9 @@
 #if !defined M68K && !defined __x86_64__ && !defined S390
   /* Make space for the return structure pointer */
   if (cif->rtype->type == FFI_TYPE_STRUCT
-      /* MSVC returns small structures in registers.  But we have a different
-      workaround: pretend int32 or int64 return type, and converting to
-      structure afterwards. */
+#ifdef _WIN32
+      && (cif->rtype->size > 8)  /* MSVC returns small structs in registers */
+#endif
 #ifdef SPARC
       && (cif->abi != FFI_V9 || cif->rtype->size > 32)
 #endif
diff --git a/c/libffi_msvc/win64.obj b/c/libffi_msvc/win64.obj
new file mode 100644
index 0000000000000000000000000000000000000000..38d3cd166b0ecad62ea4d9aab86cc574de0c9fe7
GIT binary patch

[cut]

diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -63,15 +63,15 @@
     libraries[:] = []
     _filenames = [filename.lower() for filename in os.listdir(COMPILE_LIBFFI)]
     _filenames = [filename for filename in _filenames
-                           if filename.endswith('.c') or
-                              filename.endswith('.asm')]
-    if sys.maxsize <= 2**32:
-        _filenames.remove('win64.asm')
-    else:
+                           if filename.endswith('.c')]
+    if sys.maxsize > 2**32:
+        # 64-bit: unlist win32.c, and add instead win64.obj.  If the obj
+        # happens to get outdated at some point in the future, you need to
+        # rebuild it manually from win64.asm.
         _filenames.remove('win32.c')
+        extra_link_args.append(os.path.join(COMPILE_LIBFFI, 'win64.obj'))
     sources.extend(os.path.join(COMPILE_LIBFFI, filename)
                    for filename in _filenames)
-    define_macros.append(('USE_C_LIBFFI_MSVC', '1'))
 else:
     use_pkg_config()
 


More information about the pypy-commit mailing list