Author: Armin Rigo <ar...@tunes.org>
Branch: 
Changeset: r58708:dce53a683634
Date: 2012-11-04 10:43 +0100
http://bitbucket.org/pypy/pypy/changeset/dce53a683634/

Log:    Port the special-casing needed for libffi_msvc here.

diff --git a/pypy/module/_cffi_backend/ctypefunc.py 
b/pypy/module/_cffi_backend/ctypefunc.py
--- a/pypy/module/_cffi_backend/ctypefunc.py
+++ b/pypy/module/_cffi_backend/ctypefunc.py
@@ -171,56 +171,71 @@
 W_CTypeFunc.cif_descr = lltype.nullptr(CIF_DESCRIPTION)     # default value
 
 BIG_ENDIAN = sys.byteorder == 'big'
+USE_C_LIBFFI_MSVC = getattr(clibffi, 'USE_C_LIBFFI_MSVC', False)
 
 
 # ----------
 # We attach to the classes small methods that return a 'ffi_type'
-def _missing_ffi_type(self, cifbuilder):
+def _missing_ffi_type(self, cifbuilder, is_result_type):
     space = self.space
     if self.size < 0:
         raise operationerrfmt(space.w_TypeError,
                               "ctype '%s' has incomplete type",
                               self.name)
+    if is_result_type:
+        place = "return value"
+    else:
+        place = "argument"
     raise operationerrfmt(space.w_NotImplementedError,
-                          "ctype '%s' (size %d) not supported as argument"
-                          " or return value",
-                          self.name, self.size)
+                          "ctype '%s' (size %d) not supported as %s",
+                          self.name, self.size, place)
 
-def _struct_ffi_type(self, cifbuilder):
+def _struct_ffi_type(self, cifbuilder, is_result_type):
     if self.size >= 0:
+        if 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 self.size <= 4:
+                return clibffi.ffi_type_sint32
+            if self.size <= 8:
+                return clibffi.ffi_type_sint64
         return cifbuilder.fb_struct_ffi_type(self)
-    return _missing_ffi_type(self, cifbuilder)
+    return _missing_ffi_type(self, cifbuilder, is_result_type)
 
-def _primsigned_ffi_type(self, cifbuilder):
+def _primsigned_ffi_type(self, cifbuilder, is_result_type):
     size = self.size
     if   size == 1: return clibffi.ffi_type_sint8
     elif size == 2: return clibffi.ffi_type_sint16
     elif size == 4: return clibffi.ffi_type_sint32
     elif size == 8: return clibffi.ffi_type_sint64
-    return _missing_ffi_type(self, cifbuilder)
+    return _missing_ffi_type(self, cifbuilder, is_result_type)
 
-def _primunsigned_ffi_type(self, cifbuilder):
+def _primunsigned_ffi_type(self, cifbuilder, is_result_type):
     size = self.size
     if   size == 1: return clibffi.ffi_type_uint8
     elif size == 2: return clibffi.ffi_type_uint16
     elif size == 4: return clibffi.ffi_type_uint32
     elif size == 8: return clibffi.ffi_type_uint64
-    return _missing_ffi_type(self, cifbuilder)
+    return _missing_ffi_type(self, cifbuilder, is_result_type)
 
-def _primfloat_ffi_type(self, cifbuilder):
+def _primfloat_ffi_type(self, cifbuilder, is_result_type):
     size = self.size
     if   size == 4: return clibffi.ffi_type_float
     elif size == 8: return clibffi.ffi_type_double
-    return _missing_ffi_type(self, cifbuilder)
+    return _missing_ffi_type(self, cifbuilder, is_result_type)
 
-def _primlongdouble_ffi_type(self, cifbuilder):
+def _primlongdouble_ffi_type(self, cifbuilder, is_result_type):
     return clibffi.ffi_type_longdouble
 
-def _ptr_ffi_type(self, cifbuilder):
+def _ptr_ffi_type(self, cifbuilder, is_result_type):
     return clibffi.ffi_type_pointer
 
-def _void_ffi_type(self, cifbuilder):
-    return clibffi.ffi_type_void
+def _void_ffi_type(self, cifbuilder, is_result_type):
+    if is_result_type:
+        return clibffi.ffi_type_void
+    return _missing_ffi_type(self, cifbuilder, is_result_type)
 
 W_CType._get_ffi_type                       = _missing_ffi_type
 W_CTypeStruct._get_ffi_type                 = _struct_ffi_type
@@ -230,7 +245,7 @@
 W_CTypePrimitiveFloat._get_ffi_type         = _primfloat_ffi_type
 W_CTypePrimitiveLongDouble._get_ffi_type    = _primlongdouble_ffi_type
 W_CTypePtrBase._get_ffi_type                = _ptr_ffi_type
-#W_CTypeVoid._get_ffi_type                  = _void_ffi_type -- special-cased
+W_CTypeVoid._get_ffi_type                   = _void_ffi_type
 # ----------
 
 
@@ -253,9 +268,7 @@
 
 
     def fb_fill_type(self, ctype, is_result_type):
-        if is_result_type and isinstance(ctype, W_CTypeVoid):
-            return clibffi.ffi_type_void
-        return ctype._get_ffi_type(self)
+        return ctype._get_ffi_type(self, is_result_type)
 
     def fb_struct_ffi_type(self, ctype):
         # We can't pass a struct that was completed by verify().
diff --git a/pypy/rlib/clibffi.py b/pypy/rlib/clibffi.py
--- a/pypy/rlib/clibffi.py
+++ b/pypy/rlib/clibffi.py
@@ -121,6 +121,7 @@
          dict(prefix=r'c:\mingw64', include_dir='include', library_dir='lib'),
          ])
 else:
+    USE_C_LIBFFI_MSVC = True
     libffidir = py.path.local(pypydir).join('translator', 'c', 'src', 
'libffi_msvc')
     if not _WIN64:
         asm_ifc = 'win32.c'
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to