[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