Author: Armin Rigo <[email protected]>
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
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit