[pypy-svn] r79782 - in pypy/branch/jitypes2: lib_pypy/_ctypes pypy/module/_ffi pypy/module/_ffi/test pypy/rlib

antocuni at codespeak.net antocuni at codespeak.net
Fri Dec 3 17:00:13 CET 2010


Author: antocuni
Date: Fri Dec  3 17:00:12 2010
New Revision: 79782

Modified:
   pypy/branch/jitypes2/lib_pypy/_ctypes/function.py
   pypy/branch/jitypes2/pypy/module/_ffi/interp_ffi.py
   pypy/branch/jitypes2/pypy/module/_ffi/test/test__ffi.py
   pypy/branch/jitypes2/pypy/rlib/libffi.py
Log:
cast pointers to unsigned long, not signed. This make it possible to use app-level longs to represent them in _ffi


Modified: pypy/branch/jitypes2/lib_pypy/_ctypes/function.py
==============================================================================
--- pypy/branch/jitypes2/lib_pypy/_ctypes/function.py	(original)
+++ pypy/branch/jitypes2/lib_pypy/_ctypes/function.py	Fri Dec  3 17:00:12 2010
@@ -199,7 +199,7 @@
         restype = self._restype_
         funcptr = self._getfuncptr(argtypes, restype, thisarg)
         result = funcptr(*newargs)
-        if restype._ffishape == 'u':
+        if restype and restype._ffishape == 'u':
             # XXX: maybe it's a job of _ffi?
             result = unichr(result)
         ## resbuffer = funcptr(*[arg._get_buffer_for_param()._buffer
@@ -384,14 +384,25 @@
         return wrapped_args
 
     def _unwrap_args(self, argtypes, args):
+        """
+        Convert from ctypes high-level values to low-level values suitables to
+        be passed to _ffi
+        """
         assert len(argtypes) == len(args)
         newargs = []
         for argtype, arg in zip(argtypes, args):
-            value = arg.value
             if argtype._ffishape == 'u':
                 # XXX: who should do this conversion? Maybe _ffi?
+                value = arg.value
                 assert isinstance(value, basestring) and len(value) == 1
                 value = ord(value)
+            elif argtype._ffishape == 'P':
+                value = arg._buffer.buffer
+                if value > sys.maxint:
+                    # XXX: simulate overflow so that _ffi receive and int, not a long
+                    value = (-sys.maxint-1)*2 + value
+            else:
+                value = arg.value
             newargs.append(value)
         return newargs
 

Modified: pypy/branch/jitypes2/pypy/module/_ffi/interp_ffi.py
==============================================================================
--- pypy/branch/jitypes2/pypy/module/_ffi/interp_ffi.py	(original)
+++ pypy/branch/jitypes2/pypy/module/_ffi/interp_ffi.py	Fri Dec  3 17:00:12 2010
@@ -124,8 +124,6 @@
             intres = rffi.cast(rffi.LONG, call(argchain, rffi.SHORT))
         elif restype is libffi.types.schar:
             intres = rffi.cast(rffi.LONG, call(argchain, rffi.SIGNEDCHAR))
-        elif restype is libffi.types.pointer:
-            intres = rffi.cast(rffi.LONG, call(argchain, rffi.VOIDP))
         else:
             raise OperationError(space.w_ValueError,
                                  space.wrap('Unsupported restype'))
@@ -149,6 +147,9 @@
             # special case
             uintres = call(argchain, rffi.ULONG)
             return space.wrap(uintres)
+        elif restype is libffi.types.pointer:
+            uintres = rffi.cast(rffi.ULONG, call(argchain, rffi.VOIDP))
+            return space.wrap(uintres)
         elif restype is libffi.types.uint:
             intres = rffi.cast(rffi.LONG, call(argchain, rffi.UINT))
         elif restype is libffi.types.ushort:

Modified: pypy/branch/jitypes2/pypy/module/_ffi/test/test__ffi.py
==============================================================================
--- pypy/branch/jitypes2/pypy/module/_ffi/test/test__ffi.py	(original)
+++ pypy/branch/jitypes2/pypy/module/_ffi/test/test__ffi.py	Fri Dec  3 17:00:12 2010
@@ -124,6 +124,17 @@
         assert get_dummy() == 123
         set_val_to_ptr(ptr, 0)
 
+    def test_huge_pointer_args(self):
+        """
+            #include <stdlib.h>
+            long is_null_ptr(void* ptr) { return ptr == NULL; }
+        """
+        import sys
+        from _ffi import CDLL, types
+        libfoo = CDLL(self.libfoo_name)
+        is_null_ptr = libfoo.getfunc('is_null_ptr', [types.pointer], types.ulong)
+        assert not is_null_ptr(sys.maxint+1)
+
     def test_unsigned_long_args(self):
         """
             unsigned long sum_xy_ul(unsigned long x, unsigned long y)

Modified: pypy/branch/jitypes2/pypy/rlib/libffi.py
==============================================================================
--- pypy/branch/jitypes2/pypy/rlib/libffi.py	(original)
+++ pypy/branch/jitypes2/pypy/rlib/libffi.py	Fri Dec  3 17:00:12 2010
@@ -41,7 +41,7 @@
         if   ffi_type is types.void:    return 'v'
         elif ffi_type is types.double:  return 'f'
         elif ffi_type is types.float:   return 's'
-        elif ffi_type is types.pointer: return 'i'
+        elif ffi_type is types.pointer: return 'u'
         #
         elif ffi_type is types.schar:   return 'i'
         elif ffi_type is types.uchar:   return 'u'



More information about the Pypy-commit mailing list