Author: Antonio Cuni <[email protected]>
Branch: ffistruct
Changeset: r55119:15f1a0ac245f
Date: 2012-05-17 09:24 +0200
http://bitbucket.org/pypy/pypy/changeset/15f1a0ac245f/
Log: temporarly re-add support for _rawffi structures. This way, it
should be possible to merge the branch without breaking ctypes. In
the longterm, the plan is to implement ctypes.Structure on top of
_ffi._StructDescr
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
@@ -129,6 +129,11 @@
ptrval = w_structinstance.rawmem
self.argchain.arg_raw(ptrval)
+ def handle_struct_rawffi(self, w_ffitype, w_structinstance):
+ # arg_raw directly takes value to put inside ll_args
+ ptrval = w_structinstance.ll_buffer
+ self.argchain.arg_raw(ptrval)
+
class CallFunctionConverter(ToAppLevelConverter):
"""
@@ -208,6 +213,10 @@
addr = self.func.call(self.argchain, rffi.LONG, is_struct=True)
return w_structdescr.fromaddress(self.space, addr)
+ def get_struct_rawffi(self, w_ffitype, w_structdescr):
+ uintval = self.func.call(self.argchain, rffi.ULONG, is_struct=True)
+ return w_structdescr.fromaddress(self.space, uintval)
+
def get_void(self, w_ffitype):
return self.func.call(self.argchain, lltype.Void)
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
@@ -488,6 +488,47 @@
assert p.getfield('x') == 12
assert p.getfield('y') == 34
+ # XXX: support for _rawffi structures should be killed as soon as we
+ # implement ctypes.Structure on top of _ffi. In the meantime, we support
+ # both
+ def test_byval_argument__rawffi(self):
+ """
+ // defined above
+ struct Point;
+ DLLEXPORT long sum_point(struct Point p);
+ """
+ import _rawffi
+ from _ffi import CDLL, types
+ POINT = _rawffi.Structure([('x', 'l'), ('y', 'l')])
+ ffi_point = POINT.get_ffi_type()
+ libfoo = CDLL(self.libfoo_name)
+ sum_point = libfoo.getfunc('sum_point', [ffi_point], types.slong)
+ #
+ p = POINT()
+ p.x = 30
+ p.y = 12
+ res = sum_point(p)
+ assert res == 42
+ p.free()
+
+ def test_byval_result__rawffi(self):
+ """
+ // defined above
+ DLLEXPORT struct Point make_point(long x, long y);
+ """
+ import _rawffi
+ from _ffi import CDLL, types
+ POINT = _rawffi.Structure([('x', 'l'), ('y', 'l')])
+ ffi_point = POINT.get_ffi_type()
+ libfoo = CDLL(self.libfoo_name)
+ make_point = libfoo.getfunc('make_point', [types.slong, types.slong],
ffi_point)
+ #
+ p = make_point(12, 34)
+ assert p.x == 12
+ assert p.y == 34
+ p.free()
+
+
def test_TypeError_numargs(self):
from _ffi import CDLL, types
libfoo = CDLL(self.libfoo_name)
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,6 +3,7 @@
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):
@@ -49,8 +50,11 @@
elif w_ffitype.is_singlefloat():
self._singlefloat(w_ffitype, w_obj)
elif w_ffitype.is_struct():
- w_obj = space.interp_w(W__StructInstance, w_obj)
- self.handle_struct(w_ffitype, w_obj)
+ if isinstance(w_obj, W_StructureInstance):
+ self.handle_struct_rawffi(w_ffitype, w_obj)
+ else:
+ w_obj = space.interp_w(W__StructInstance, w_obj)
+ self.handle_struct(w_ffitype, w_obj)
else:
self.error(w_ffitype, w_obj)
@@ -168,6 +172,14 @@
"""
self.error(w_ffitype, w_structinstance)
+ def handle_struct_rawffi(self, w_ffitype, w_structinstance):
+ """
+ This method should be killed as soon as we remove support for _rawffi
structures
+
+ w_structinstance: W_StructureInstance
+ """
+ self.error(w_ffitype, w_structinstance)
+
class ToAppLevelConverter(object):
@@ -222,8 +234,12 @@
return self._singlefloat(w_ffitype)
elif w_ffitype.is_struct():
w_structdescr = w_ffitype.w_structdescr
- assert isinstance(w_structdescr, W__StructDescr)
- return self.get_struct(w_ffitype, w_structdescr)
+ if isinstance(w_structdescr, W__StructDescr):
+ return self.get_struct(w_ffitype, w_structdescr)
+ elif isinstance(w_structdescr, W_Structure):
+ return self.get_struct_rawffi(w_ffitype, w_structdescr)
+ else:
+ raise OperationError(self.space.w_TypeError, "Unsupported
struct shape")
elif w_ffitype.is_void():
voidval = self.get_void(w_ffitype)
assert voidval is None
@@ -325,6 +341,15 @@
def get_struct(self, w_ffitype, w_structdescr):
"""
+ Return type: lltype.Signed
+ (the address of the structure)
+ """
+ self.error(w_ffitype)
+
+ def get_struct_rawffi(self, w_ffitype, w_structdescr):
+ """
+ This should be killed as soon as we kill support for _rawffi structures
+
Return type: lltype.Unsigned
(the address of the structure)
"""
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit