[pypy-svn] r53564 - in pypy/dist/pypy: lib/_ctypes lib/app_test/ctypes_tests rlib rlib/test

pedronis at codespeak.net pedronis at codespeak.net
Tue Apr 8 12:02:23 CEST 2008


Author: pedronis
Date: Tue Apr  8 12:02:21 2008
New Revision: 53564

Modified:
   pypy/dist/pypy/lib/_ctypes/pointer.py
   pypy/dist/pypy/lib/app_test/ctypes_tests/test_parameters.py
   pypy/dist/pypy/rlib/libffi.py
   pypy/dist/pypy/rlib/test/test_libffi.py
Log:
merging back to trunk fixes and changes done on the ctypes-stable branch



Modified: pypy/dist/pypy/lib/_ctypes/pointer.py
==============================================================================
--- pypy/dist/pypy/lib/_ctypes/pointer.py	(original)
+++ pypy/dist/pypy/lib/_ctypes/pointer.py	Tue Apr  8 12:02:21 2008
@@ -106,12 +106,6 @@
 
     contents = property(getcontents, setcontents)
 
-    def __eq__(self, other):
-        return self._buffer[0] == other
-
-    def __ne__(self, other):
-        return not self == other
-
 def _cast_addr(obj, _, tp):
     if not (isinstance(tp, _CDataMeta) and tp._is_pointer_like()):
         raise TypeError("cast() argument 2 must be a pointer type, not %s"

Modified: pypy/dist/pypy/lib/app_test/ctypes_tests/test_parameters.py
==============================================================================
--- pypy/dist/pypy/lib/app_test/ctypes_tests/test_parameters.py	(original)
+++ pypy/dist/pypy/lib/app_test/ctypes_tests/test_parameters.py	Tue Apr  8 12:02:21 2008
@@ -100,7 +100,7 @@
         assert x.contents.value == 42
         assert LPINT(c_int(42)).contents.value == 42
 
-        assert LPINT.from_param(None) == 0
+        assert not LPINT.from_param(None)
 
         if c_int != c_long:
             raises(TypeError, LPINT.from_param, pointer(c_long(42)))

Modified: pypy/dist/pypy/rlib/libffi.py
==============================================================================
--- pypy/dist/pypy/rlib/libffi.py	(original)
+++ pypy/dist/pypy/rlib/libffi.py	Tue Apr  8 12:02:21 2008
@@ -49,6 +49,8 @@
                                                  ('type', rffi.USHORT),
                                                  ('elements', FFI_TYPE_PP)])
 
+    ffi_closure = rffi_platform.Struct('ffi_closure', [])
+
 def add_simple_type(type_name):
     for name in ['size', 'alignment', 'type']:
         setattr(CConfig, type_name + '_' + name,
@@ -119,8 +121,7 @@
 FFI_CIFP = rffi.COpaquePtr('ffi_cif', compilation_info=CConfig.
                            _compilation_info_)
 
-FFI_CLOSUREP = rffi.COpaquePtr('ffi_closure', compilation_info=CConfig.
-                               _compilation_info_)
+FFI_CLOSUREP = lltype.Ptr(cConfig.ffi_closure)
 
 VOIDPP = rffi.CArrayPtr(rffi.VOIDP)
 
@@ -209,6 +210,39 @@
     userdata = rffi.cast(USERDATA_P, ll_userdata)
     userdata.callback(ll_args, ll_res, userdata)
 
+# heap for closures
+from pypy.jit.codegen.i386 import codebuf_posix
+
+CHUNK = 4096
+CLOSURES = rffi.CArrayPtr(FFI_CLOSUREP.TO)
+
+class ClosureHeap(object):
+
+    def __init__(self):
+        self.free_list = lltype.nullptr(rffi.VOIDP.TO)
+
+    def _more(self):
+        chunk = rffi.cast(CLOSURES, codebuf_posix.alloc(CHUNK))
+        count = CHUNK//rffi.sizeof(FFI_CLOSUREP.TO)
+        for i in range(count):
+            rffi.cast(rffi.VOIDPP, chunk)[0] = self.free_list
+            self.free_list = rffi.cast(rffi.VOIDP, chunk)
+            chunk = rffi.ptradd(chunk, 1)
+
+    def alloc(self):
+        if not self.free_list:
+            self._more()
+        p = self.free_list
+        self.free_list = rffi.cast(rffi.VOIDPP, p)[0]
+        return rffi.cast(FFI_CLOSUREP, p)
+
+    def free(self, p):
+        rffi.cast(rffi.VOIDPP, p)[0] = self.free_list
+        self.free_list = rffi.cast(rffi.VOIDP, p)
+
+closureHeap = ClosureHeap()
+    
+
 class AbstractFuncPtr(object):
     ll_cif = lltype.nullptr(FFI_CIFP.TO)
     ll_argtypes = lltype.nullptr(FFI_TYPE_PP.TO)
@@ -246,7 +280,7 @@
     # it cannot be any kind of movable gc reference
     def __init__(self, argtypes, restype, func, additional_arg=0):
         AbstractFuncPtr.__init__(self, "callback", argtypes, restype)
-        self.ll_closure = lltype.malloc(FFI_CLOSUREP.TO, flavor='raw')
+        self.ll_closure = closureHeap.alloc()
         self.ll_userdata = lltype.malloc(USERDATA_P.TO, flavor='raw')
         self.ll_userdata.callback = rffi.llhelper(CALLBACK_TP, func)
         self.ll_userdata.addarg = additional_arg
@@ -259,7 +293,7 @@
     def __del__(self):
         AbstractFuncPtr.__del__(self)
         if self.ll_closure:
-            lltype.free(self.ll_closure, flavor='raw')
+            closureHeap.free(self.ll_closure)
             self.ll_closure = lltype.nullptr(FFI_CLOSUREP.TO)
         if self.ll_userdata:
             lltype.free(self.ll_userdata, flavor='raw')

Modified: pypy/dist/pypy/rlib/test/test_libffi.py
==============================================================================
--- pypy/dist/pypy/rlib/test/test_libffi.py	(original)
+++ pypy/dist/pypy/rlib/test/test_libffi.py	Tue Apr  8 12:02:21 2008
@@ -109,6 +109,36 @@
         del libc
         assert not ALLOCATED
 
+    def test_closure_heap(self):
+        ch = ClosureHeap()
+
+        assert not ch.free_list
+        a = ch.alloc()
+        assert ch.free_list        
+        b = ch.alloc()
+        
+        chunks = [a, b]
+        p = ch.free_list
+        while p:
+            chunks.append(p)
+            p = rffi.cast(rffi.VOIDPP, p)[0]
+        closure_size = rffi.sizeof(FFI_CLOSUREP.TO)
+        assert len(chunks) == CHUNK//closure_size
+        for i in range(len(chunks) -1 ):
+            s = rffi.cast(rffi.UINT, chunks[i+1])
+            e = rffi.cast(rffi.UINT, chunks[i])
+            assert (e-s) >= rffi.sizeof(FFI_CLOSUREP.TO)
+
+        ch.free(a)
+        assert ch.free_list == rffi.cast(rffi.VOIDP, a)
+        snd = rffi.cast(rffi.VOIDPP, a)[0]
+        assert snd == chunks[2]
+
+        ch.free(b)
+        assert ch.free_list == rffi.cast(rffi.VOIDP, b)
+        snd = rffi.cast(rffi.VOIDPP, b)[0]
+        assert snd == rffi.cast(rffi.VOIDP, a)
+        
     def test_callback(self):
         libc = CDLL('libc.so.6')
         qsort = libc.getpointer('qsort', [ffi_type_pointer, ffi_type_slong,



More information about the Pypy-commit mailing list