[pypy-svn] pypy jitypes2: introduce 'typed pointers', which carry info on which type they are pointing to; also, pass the argtype to the _as_ffi_pointer_ method; this should allow _ctypes to do type check on pointers when converting arguments
antocuni
commits-noreply at bitbucket.org
Thu Mar 24 12:22:51 CET 2011
Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: jitypes2
Changeset: r42897:888a6561b67a
Date: 2011-03-24 12:22 +0100
http://bitbucket.org/pypy/pypy/changeset/888a6561b67a/
Log: introduce 'typed pointers', which carry info on which type they are
pointing to; also, pass the argtype to the _as_ffi_pointer_ method;
this should allow _ctypes to do type check on pointers when
converting arguments
diff --git a/pypy/module/_ffi/test/test__ffi.py b/pypy/module/_ffi/test/test__ffi.py
--- a/pypy/module/_ffi/test/test__ffi.py
+++ b/pypy/module/_ffi/test/test__ffi.py
@@ -169,7 +169,8 @@
class MyPointerWrapper(object):
def __init__(self, value):
self.value = value
- def _as_ffi_pointer_(self):
+ def _as_ffi_pointer_(self, ffitype):
+ assert ffitype is types.pointer
return self.value
libfoo = CDLL(self.libfoo_name)
@@ -186,6 +187,31 @@
assert get_dummy() == 123
set_val_to_ptr(ptr2, 0)
+ def test_typed_pointer(self):
+ from _ffi import types
+ intptr = types.Pointer(types.sint) # create a typed pointer to sint
+ assert intptr.deref_pointer() is types.sint
+ assert str(intptr) == '<ffi type (pointer to sint)>'
+ assert types.sint.deref_pointer() is None
+
+ def test_typed_pointer_args(self):
+ """
+ extern int dummy; // defined in test_void_result
+ DLLEXPORT int* get_dummy_ptr(); // defined in test_pointer_args
+ DLLEXPORT void set_val_to_ptr(int* ptr, int val); // ditto
+ """
+ from _ffi import CDLL, types
+
+ libfoo = CDLL(self.libfoo_name)
+ intptr = types.Pointer(types.sint)
+ get_dummy = libfoo.getfunc('get_dummy', [], types.sint)
+ get_dummy_ptr = libfoo.getfunc('get_dummy_ptr', [], intptr)
+ set_val_to_ptr = libfoo.getfunc('set_val_to_ptr', [intptr, types.sint], types.void)
+ assert get_dummy() == 0
+ ptr = get_dummy_ptr()
+ set_val_to_ptr(ptr, 123)
+ assert get_dummy() == 123
+ set_val_to_ptr(ptr, 0)
def test_huge_pointer_args(self):
"""
diff --git a/pypy/module/_ffi/interp_ffi.py b/pypy/module/_ffi/interp_ffi.py
--- a/pypy/module/_ffi/interp_ffi.py
+++ b/pypy/module/_ffi/interp_ffi.py
@@ -14,17 +14,23 @@
from pypy.rlib.rarithmetic import intmask, r_uint
class W_FFIType(Wrappable):
- def __init__(self, name, ffitype, w_datashape=None):
+ def __init__(self, name, ffitype, w_datashape=None, w_pointer_to=None):
self.name = name
self.ffitype = ffitype
self.w_datashape = w_datashape
+ self.w_pointer_to = w_pointer_to
if self.is_struct():
assert w_datashape is not None
- def str(self, space):
+ def descr_deref_pointer(self, space):
+ if self.w_pointer_to is None:
+ return space.w_None
+ return self.w_pointer_to
+
+ def repr(self, space):
return space.wrap(self.__str__())
- def __str__(self):
+ def __repr__(self):
return "<ffi type %s>" % self.name
def is_signed(self):
@@ -42,7 +48,7 @@
self is app_types.ulonglong)
def is_pointer(self):
- return self is app_types.pointer
+ return self.ffitype is libffi.types.pointer
def is_char(self):
return self is app_types.char
@@ -68,7 +74,8 @@
W_FFIType.typedef = TypeDef(
'FFIType',
- __str__ = interp2app(W_FFIType.str),
+ __repr__ = interp2app(W_FFIType.repr),
+ deref_pointer = interp2app(W_FFIType.descr_deref_pointer),
)
@@ -113,10 +120,15 @@
pass
app_types.__dict__ = build_ffi_types()
+def descr_new_pointer(space, w_cls, w_pointer_to):
+ name = '(pointer to %s)' % w_pointer_to.name
+ return W_FFIType(name, libffi.types.pointer, w_pointer_to = w_pointer_to)
+
class W_types(Wrappable):
pass
W_types.typedef = TypeDef(
'types',
+ Pointer = interp2app(descr_new_pointer, as_classmethod=True),
**app_types.__dict__)
@@ -164,7 +176,7 @@
elif w_argtype.is_signed():
argchain.arg(space.int_w(w_arg))
elif w_argtype.is_pointer():
- w_arg = self.convert_pointer_arg_maybe(space, w_arg)
+ w_arg = self.convert_pointer_arg_maybe(space, w_arg, w_argtype)
argchain.arg(intmask(space.uint_w(w_arg)))
elif w_argtype.is_unsigned():
argchain.arg(intmask(space.uint_w(w_arg)))
@@ -187,13 +199,13 @@
assert False, "Argument shape '%s' not supported" % w_argtype
return argchain
- def convert_pointer_arg_maybe(self, space, w_arg):
+ def convert_pointer_arg_maybe(self, space, w_arg, w_argtype):
"""
Try to convert the argument by calling _as_ffi_pointer_()
"""
meth = space.lookup(w_arg, '_as_ffi_pointer_') # this also promotes the type
if meth:
- return space.call_function(meth, w_arg)
+ return space.call_function(meth, w_arg, w_argtype)
else:
return w_arg
More information about the Pypy-commit
mailing list