Author: Antonio Cuni <[email protected]>
Branch: ffistruct
Changeset: r55099:58e8161a5deb
Date: 2012-05-15 11:25 +0200
http://bitbucket.org/pypy/pypy/changeset/58e8161a5deb/
Log: kill support for _rawffi structures and add support for _ffi
structures. Some tests fail because we leak
W__StructDescr.ffistruct, in-progress
diff --git a/pypy/module/_ffi/interp_ffitype.py
b/pypy/module/_ffi/interp_ffitype.py
--- a/pypy/module/_ffi/interp_ffitype.py
+++ b/pypy/module/_ffi/interp_ffitype.py
@@ -1,4 +1,4 @@
-from pypy.rlib import libffi
+from pypy.rlib import libffi, clibffi
from pypy.rlib.rarithmetic import intmask
from pypy.rlib import jit
from pypy.interpreter.baseobjspace import Wrappable
@@ -12,12 +12,10 @@
def __init__(self, name, ffitype, w_datashape=None, w_pointer_to=None):
self.name = name
- self._ffitype = ffitype
+ self._ffitype = clibffi.FFI_TYPE_NULL
self.w_datashape = w_datashape
self.w_pointer_to = w_pointer_to
- ## XXX: re-enable this check when the ffistruct branch is done
- ## if self.is_struct():
- ## assert w_datashape is not None
+ self.set_ffitype(ffitype)
@jit.elidable
def get_ffitype(self):
@@ -29,6 +27,8 @@
if self._ffitype:
raise ValueError("The _ffitype is already set")
self._ffitype = ffitype
+ if ffitype and self.is_struct():
+ assert self.w_datashape is not None
def descr_deref_pointer(self, space):
if self.w_pointer_to is None:
diff --git a/pypy/module/_ffi/interp_funcptr.py
b/pypy/module/_ffi/interp_funcptr.py
--- a/pypy/module/_ffi/interp_funcptr.py
+++ b/pypy/module/_ffi/interp_funcptr.py
@@ -125,7 +125,7 @@
self.argchain.arg(singlefloatval)
def handle_struct(self, w_ffitype, w_structinstance):
- ptrval = w_structinstance.ll_buffer
+ ptrval = w_structinstance.rawmem
self.argchain.arg_raw(ptrval)
@@ -204,7 +204,7 @@
return self.func.call(self.argchain, rffi.FLOAT)
def get_struct(self, w_datashape):
- return self.func.call(self.argchain, rffi.ULONG, is_struct=True)
+ return self.func.call(self.argchain, rffi.LONG, is_struct=True)
def get_void(self, w_ffitype):
return self.func.call(self.argchain, lltype.Void)
diff --git a/pypy/module/_ffi/interp_struct.py
b/pypy/module/_ffi/interp_struct.py
--- a/pypy/module/_ffi/interp_struct.py
+++ b/pypy/module/_ffi/interp_struct.py
@@ -43,7 +43,8 @@
def __init__(self, space, name):
self.space = space
- self.w_ffitype = W_FFIType('struct %s' % name, clibffi.FFI_TYPE_NULL,
None)
+ self.w_ffitype = W_FFIType('struct %s' % name, clibffi.FFI_TYPE_NULL,
+ w_datashape=self)
self.fields_w = None
self.name2w_field = {}
@@ -65,12 +66,21 @@
self.ffistruct = clibffi.make_struct_ffitype_e(size, alignment,
field_types)
self.w_ffitype.set_ffitype(self.ffistruct.ffistruct)
- def allocate(self, space):
+ def check_complete(self):
if self.fields_w is None:
raise operationerrfmt(space.w_ValueError, "%s has an incomplete
type",
self.w_ffitype.name)
+
+ def allocate(self, space):
+ self.check_complete()
return W__StructInstance(self)
+ @unwrap_spec(addr=int)
+ def fromaddress(self, space, addr):
+ self.check_complete()
+ rawmem = rffi.cast(rffi.VOIDP, addr)
+ return W__StructInstance(self, allocate=False, autofree=True,
rawmem=rawmem)
+
@jit.elidable_promote('0')
def get_type_and_offset_for_field(self, name):
try:
@@ -121,24 +131,33 @@
ffitype = interp_attrproperty('w_ffitype', W__StructDescr),
define_fields = interp2app(W__StructDescr.define_fields),
allocate = interp2app(W__StructDescr.allocate),
+ fromaddress = interp2app(W__StructDescr.fromaddress),
)
#
==============================================================================
+NULL = lltype.nullptr(rffi.VOIDP.TO)
+
class W__StructInstance(Wrappable):
_immutable_fields_ = ['structdescr', 'rawmem']
- def __init__(self, structdescr):
+ def __init__(self, structdescr, allocate=True, autofree=True, rawmem=NULL):
self.structdescr = structdescr
- size = structdescr.w_ffitype.sizeof()
- self.rawmem = lltype.malloc(rffi.VOIDP.TO, size, flavor='raw',
- zero=True, add_memory_pressure=True)
+ self.autofree = autofree
+ if allocate:
+ assert not rawmem
+ assert autofree
+ size = structdescr.w_ffitype.sizeof()
+ self.rawmem = lltype.malloc(rffi.VOIDP.TO, size, flavor='raw',
+ zero=True, add_memory_pressure=True)
+ else:
+ self.rawmem = rawmem
@must_be_light_finalizer
def __del__(self):
- if self.rawmem:
+ if self.autofree and self.rawmem:
lltype.free(self.rawmem, flavor='raw')
self.rawmem = lltype.nullptr(rffi.VOIDP.TO)
diff --git a/pypy/module/_ffi/test/test_funcptr.py
b/pypy/module/_ffi/test/test_funcptr.py
--- a/pypy/module/_ffi/test/test_funcptr.py
+++ b/pypy/module/_ffi/test/test_funcptr.py
@@ -452,19 +452,19 @@
return p.x + p.y;
}
"""
- import _rawffi
- from _ffi import CDLL, types
- POINT = _rawffi.Structure([('x', 'l'), ('y', 'l')])
- ffi_point = POINT.get_ffi_type()
+ from _ffi import CDLL, types, _StructDescr, Field
+ Point = _StructDescr('Point', [
+ Field('x', types.slong),
+ Field('y', types.slong),
+ ])
libfoo = CDLL(self.libfoo_name)
- sum_point = libfoo.getfunc('sum_point', [ffi_point], types.slong)
+ sum_point = libfoo.getfunc('sum_point', [Point.ffitype], types.slong)
#
- p = POINT()
- p.x = 30
- p.y = 12
+ p = Point.allocate()
+ p.setfield('x', 30)
+ p.setfield('y', 12)
res = sum_point(p)
assert res == 42
- p.free()
def test_byval_result(self):
"""
@@ -475,17 +475,18 @@
return p;
}
"""
- import _rawffi
- from _ffi import CDLL, types
- POINT = _rawffi.Structure([('x', 'l'), ('y', 'l')])
- ffi_point = POINT.get_ffi_type()
+ from _ffi import CDLL, types, _StructDescr, Field
+ Point = _StructDescr('Point', [
+ Field('x', types.slong),
+ Field('y', types.slong),
+ ])
libfoo = CDLL(self.libfoo_name)
- make_point = libfoo.getfunc('make_point', [types.slong, types.slong],
ffi_point)
+ make_point = libfoo.getfunc('make_point', [types.slong, types.slong],
+ Point.ffitype)
#
p = make_point(12, 34)
- assert p.x == 12
- assert p.y == 34
- p.free()
+ assert p.getfield('x') == 12
+ assert p.getfield('y') == 34
def test_TypeError_numargs(self):
from _ffi import CDLL, types
diff --git a/pypy/module/_ffi/type_converter.py
b/pypy/module/_ffi/type_converter.py
--- a/pypy/module/_ffi/type_converter.py
+++ b/pypy/module/_ffi/type_converter.py
@@ -3,7 +3,6 @@
from pypy.rlib.rarithmetic import intmask, r_uint
from pypy.rpython.lltypesystem import rffi
from pypy.interpreter.error import operationerrfmt
-from pypy.module._rawffi.structure import W_StructureInstance, W_Structure
from pypy.module._ffi.interp_ffitype import app_types
class FromAppLevelConverter(object):
@@ -18,6 +17,7 @@
self.space = space
def unwrap_and_do(self, w_ffitype, w_obj):
+ from pypy.module._ffi.interp_struct import W__StructInstance
space = self.space
if w_ffitype.is_longlong():
# note that we must check for longlong first, because either
@@ -50,7 +50,7 @@
self._singlefloat(w_ffitype, w_obj)
elif w_ffitype.is_struct():
# arg_raw directly takes value to put inside ll_args
- w_obj = space.interp_w(W_StructureInstance, w_obj)
+ w_obj = space.interp_w(W__StructInstance, w_obj)
self.handle_struct(w_ffitype, w_obj)
else:
self.error(w_ffitype, w_obj)
@@ -183,6 +183,7 @@
self.space = space
def do_and_wrap(self, w_ffitype):
+ from pypy.module._ffi.interp_struct import W__StructDescr
space = self.space
if w_ffitype.is_longlong():
# note that we must check for longlong first, because either
@@ -222,9 +223,9 @@
return self._singlefloat(w_ffitype)
elif w_ffitype.is_struct():
w_datashape = w_ffitype.w_datashape
- assert isinstance(w_datashape, W_Structure)
- uintval = self.get_struct(w_datashape) # this is the ptr to the
struct
- return w_datashape.fromaddress(space, uintval)
+ assert isinstance(w_datashape, W__StructDescr)
+ addr = self.get_struct(w_datashape) # this is the ptr to the struct
+ return w_datashape.fromaddress(space, addr)
elif w_ffitype.is_void():
voidval = self.get_void(w_ffitype)
assert voidval is None
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit