[pypy-svn] r50372 - in pypy/branch/applevel-ctypes2/pypy/module/_ffi: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Sun Jan 6 14:39:47 CET 2008


Author: cfbolz
Date: Sun Jan  6 14:39:46 2008
New Revision: 50372

Added:
   pypy/branch/applevel-ctypes2/pypy/module/_ffi/error.py   (contents, props changed)
Modified:
   pypy/branch/applevel-ctypes2/pypy/module/_ffi/__init__.py
   pypy/branch/applevel-ctypes2/pypy/module/_ffi/structure.py
   pypy/branch/applevel-ctypes2/pypy/module/_ffi/test/test__ffi.py
Log:
don't free structures automatically ever. Also don't keep alive the field inits


Modified: pypy/branch/applevel-ctypes2/pypy/module/_ffi/__init__.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/module/_ffi/__init__.py	(original)
+++ pypy/branch/applevel-ctypes2/pypy/module/_ffi/__init__.py	Sun Jan  6 14:39:46 2008
@@ -23,4 +23,5 @@
     }
 
     appleveldefs = {
+        'SegfaultException'  : 'error.SegfaultException',
     }

Added: pypy/branch/applevel-ctypes2/pypy/module/_ffi/error.py
==============================================================================
--- (empty file)
+++ pypy/branch/applevel-ctypes2/pypy/module/_ffi/error.py	Sun Jan  6 14:39:46 2008
@@ -0,0 +1,2 @@
+class SegfaultException(Exception):
+    pass

Modified: pypy/branch/applevel-ctypes2/pypy/module/_ffi/structure.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/module/_ffi/structure.py	(original)
+++ pypy/branch/applevel-ctypes2/pypy/module/_ffi/structure.py	Sun Jan  6 14:39:46 2008
@@ -103,6 +103,11 @@
     return rffi.cast(TP, pos)[0]
 cast_pos._annspecialcase_ = 'specialize:arg(2)'
 
+def segfault_exception(space, reason):
+    w_mod = space.getbuiltinmodule("_ffi")
+    w_exception = space.getattr(w_mod, space.wrap("SegfaultException"))
+    return OperationError(w_exception, space.wrap(reason))
+
 class W_StructureInstance(Wrappable):
     def __init__(self, space, shape, w_address, fieldinits_w):
         self.free_afterwards = False
@@ -110,15 +115,12 @@
         if w_address is not None:
             self.ll_buffer = rffi.cast(rffi.VOIDP, space.int_w(w_address))
         else:
-            self.free_afterwards = True
             self.ll_buffer = lltype.malloc(rffi.VOIDP.TO, shape.size, flavor='raw',
                                            zero=True)
         if fieldinits_w:
-            self.fieldinits_w = fieldinits_w
             for field, w_value in fieldinits_w.iteritems():
                 self.setattr(space, field, w_value)
-        else:
-            self.fieldinits_w = None
+
 
     def getindex(self, space, attr):
         try:
@@ -128,29 +130,38 @@
                 "C Structure has no attribute %s" % attr))
 
     def getattr(self, space, attr):
+        if not self.ll_buffer:
+            raise segfault_exception(space, "accessing NULL pointer")
         i = self.getindex(space, attr)
         _, c = self.shape.fields[i]
         return wrap_value(space, cast_pos, self, i, c)
     getattr.unwrap_spec = ['self', ObjSpace, str]
 
     def setattr(self, space, attr, w_value):
+        if not self.ll_buffer:
+            raise segfault_exception(space, "accessing NULL pointer")
         i = self.getindex(space, attr)
         _, c = self.shape.fields[i]
         unwrap_value(space, push_field, self, i, c, w_value, None)
     setattr.unwrap_spec = ['self', ObjSpace, str, W_Root]
 
-    def __del__(self):
-        if self.free_afterwards:
-            lltype.free(self.ll_buffer, flavor='raw')
+    def free(self, space):
+        if not self.ll_buffer:
+            raise segfault_exception(space, "freeing NULL pointer")
+        lltype.free(self.ll_buffer, flavor='raw')
+        self.ll_buffer = lltype.nullptr(rffi.VOIDP.TO)
+    free.unwrap_spec = ['self', ObjSpace]
 
     def getbuffer(space, self):
         return space.wrap(rffi.cast(rffi.INT, self.ll_buffer))
 
+
 W_StructureInstance.typedef = TypeDef(
     'StructureInstance',
     __getattr__ = interp2app(W_StructureInstance.getattr),
     __setattr__ = interp2app(W_StructureInstance.setattr),
     buffer      = GetSetProperty(W_StructureInstance.getbuffer),
+    free        = interp2app(W_StructureInstance.free),
 )
 W_StructureInstance.typedef.acceptable_as_base_class = False
 

Modified: pypy/branch/applevel-ctypes2/pypy/module/_ffi/test/test__ffi.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/module/_ffi/test/test__ffi.py	(original)
+++ pypy/branch/applevel-ctypes2/pypy/module/_ffi/test/test__ffi.py	Sun Jan  6 14:39:46 2008
@@ -187,6 +187,7 @@
         assert structure.tv_usec != struct2.tv_usec
         assert (structure.tv_sec == struct2.tv_sec) or (structure.tv_sec == struct2.tv_sec - 1)
         raises(AttributeError, "structure.xxx")
+        structure.free()
 
     def test_structreturn(self):
         import _ffi
@@ -208,17 +209,24 @@
         assert t.tm_year == 70
         assert t.tm_sec == 1
         assert t.tm_min == 2        
+        x.free()
 
     def test_nested_structures(self):
         import _ffi
         lib = _ffi.CDLL(self.lib_name)
         inner = lib.ptr("inner_struct_elem", ['P'], 'c')
         X = _ffi.Structure([('x1', 'i'), ('x2', 'h'), ('x3', 'c'), ('next', 'P')])
-        x = X(next=X(next=None, x3='x'), x1=1, x2=2, x3='x')
+        next = X(next=None, x3='x')
+        x = X(next=next, x1=1, x2=2, x3='x')
         assert X(x.next).x3 == 'x'
+        x.free()
+        next.free()
+        # XXX isn't that leaking memory?
         create_double_struct = lib.ptr("create_double_struct", [], 'P')
         x = create_double_struct()
-        assert X(X(x).next).x2 == 3
+        x = X(x)
+        assert X(x.next).x2 == 3
+        
 
     def test_array(self):
         import _ffi
@@ -250,6 +258,8 @@
         ptr1 = get_array_elem_s(a, 0)
         assert ptr1 is None
         assert X(get_array_elem_s(a, 1)).x2 == 3
+        assert get_array_elem_s(a, 1) == x.buffer
+        x.free()
 
     def test_bad_parameters(self):
         import _ffi
@@ -263,10 +273,6 @@
         raises(ValueError, "_ffi.Structure(['x1', 'xx'])")
         raises(ValueError, _ffi.Structure, [('x1', 'xx')])
         raises(ValueError, "_ffi.Array('xx')")
-        # XXX I don't think this should be allowed at all:
-        #A = _ffi.Array('i')
-        #A.of = 'xx'
-        #raises(ValueError, 'A(1)')
 
     def test_implicit_structure(self):
         skip("Does not work yet")
@@ -318,6 +324,7 @@
         assert x.value1 == 3
         raises(AttributeError, "x.foo")
         raises(AttributeError, "x.foo = 1")
+        x.free()
 
     def test_sizes_and_alignments(self):
         import _ffi



More information about the Pypy-commit mailing list