[pypy-svn] r78125 - in pypy/trunk/pypy: module/_ffi module/_ffi/test rlib

arigo at codespeak.net arigo at codespeak.net
Wed Oct 20 13:35:29 CEST 2010


Author: arigo
Date: Wed Oct 20 13:35:27 2010
New Revision: 78125

Modified:
   pypy/trunk/pypy/module/_ffi/interp_ffi.py
   pypy/trunk/pypy/module/_ffi/test/test__ffi.py
   pypy/trunk/pypy/rlib/libffi.py
Log:
Adapt libffi.py and module/_ffi to get the same signed/unsigned
distinction.  Add tests.


Modified: pypy/trunk/pypy/module/_ffi/interp_ffi.py
==============================================================================
--- pypy/trunk/pypy/module/_ffi/interp_ffi.py	(original)
+++ pypy/trunk/pypy/module/_ffi/interp_ffi.py	Wed Oct 20 13:35:27 2010
@@ -11,6 +11,7 @@
 from pypy.rlib import jit
 from pypy.rlib import libffi
 from pypy.rlib.rdynload import DLOpenError
+from pypy.rlib.rarithmetic import intmask
 
 class W_FFIType(Wrappable):
     def __init__(self, name, ffitype):
@@ -74,6 +75,8 @@
             kind = libffi.types.getkind(argtype)
             if kind == 'i':
                 argchain.arg(space.int_w(w_arg))
+            elif kind == 'u':
+                argchain.arg(intmask(space.uint_w(w_arg)))
             elif kind == 'f':
                 argchain.arg(space.float_w(w_arg))
             else:
@@ -88,6 +91,9 @@
         if reskind == 'i':
             intres = self.func.call(argchain, rffi.LONG)
             return space.wrap(intres)
+        elif reskind == 'u':
+            intres = self.func.call(argchain, rffi.ULONG)
+            return space.wrap(intres)
         elif reskind == 'f':
             floatres = self.func.call(argchain, rffi.DOUBLE)
             return space.wrap(floatres)

Modified: pypy/trunk/pypy/module/_ffi/test/test__ffi.py
==============================================================================
--- pypy/trunk/pypy/module/_ffi/test/test__ffi.py	(original)
+++ pypy/trunk/pypy/module/_ffi/test/test__ffi.py	Wed Oct 20 13:35:27 2010
@@ -97,6 +97,36 @@
         assert set_dummy(42) is None
         assert get_dummy() == 42
 
+    def test_unsigned_long_args(self):
+        """
+            unsigned long sum_xy_ul(unsigned long x, unsigned long y)
+            {
+                return x+y;
+            }
+        """
+        import sys
+        from _ffi import CDLL, types
+        libfoo = CDLL(self.libfoo_name)
+        sum_xy = libfoo.getfunc('sum_xy_ul', [types.ulong, types.ulong],
+                                types.ulong)
+        assert sum_xy(sys.maxint, 12) == sys.maxint+12
+        assert sum_xy(sys.maxint+1, 12) == sys.maxint+13
+
+    def test_unsigned_short_args(self):
+        """
+            unsigned short sum_xy_us(unsigned short x, unsigned short y)
+            {
+                return x+y;
+            }
+        """
+        import sys
+        from _ffi import CDLL, types
+        libfoo = CDLL(self.libfoo_name)
+        sum_xy = libfoo.getfunc('sum_xy_us', [types.ushort, types.ushort],
+                                types.ushort)
+        assert sum_xy(32000, 8000) == 40000
+        assert sum_xy(60000, 30000) == 90000 % 65536
+
     def test_TypeError_numargs(self):
         from _ffi import CDLL, types
         libfoo = CDLL(self.libfoo_name)

Modified: pypy/trunk/pypy/rlib/libffi.py
==============================================================================
--- pypy/trunk/pypy/rlib/libffi.py	(original)
+++ pypy/trunk/pypy/rlib/libffi.py	Wed Oct 20 13:35:27 2010
@@ -35,27 +35,33 @@
     @staticmethod
     @jit.purefunction
     def getkind(ffi_type):
+        """Returns 'v' for void, 'f' for float, 'i' for signed integer,
+        and 'u' for unsigned integer.
+        """
         if   ffi_type is types.void:    return 'v'
         elif ffi_type is types.double:  return 'f'
         elif ffi_type is types.pointer: return 'i'
         #
         elif ffi_type is types.schar:   return 'i'
-        elif ffi_type is types.uchar:   return 'i'
+        elif ffi_type is types.uchar:   return 'u'
         elif ffi_type is types.sshort:  return 'i'
-        elif ffi_type is types.ushort:  return 'i'
+        elif ffi_type is types.ushort:  return 'u'
         elif ffi_type is types.sint:    return 'i'
-        elif ffi_type is types.uint:    return 'i'
+        elif ffi_type is types.uint:    return 'u'
         elif ffi_type is types.slong:   return 'i'
-        elif ffi_type is types.ulong:   return 'i'
+        elif ffi_type is types.ulong:   return 'u'
         #
         elif ffi_type is types.sint8:   return 'i'
-        elif ffi_type is types.uint8:   return 'i'
+        elif ffi_type is types.uint8:   return 'u'
         elif ffi_type is types.sint16:  return 'i'
-        elif ffi_type is types.uint16:  return 'i'
+        elif ffi_type is types.uint16:  return 'u'
         elif ffi_type is types.sint32:  return 'i'
-        elif ffi_type is types.uint32:  return 'i'
+        elif ffi_type is types.uint32:  return 'u'
+        ## we only support integers that fit in a lltype.Signed (==rffi.LONG)
+        ## (on 64-bit platforms, types.sint64 is types.slong and the case is
+        ## caught above)
         ## elif ffi_type is types.sint64:  return 'i'
-        ## elif ffi_type is types.uint64:  return 'i'
+        ## elif ffi_type is types.uint64:  return 'u'
         raise KeyError
 
 types._import()



More information about the Pypy-commit mailing list