[pypy-svn] r47509 - in pypy/dist/pypy/module/_ffi: . test
fijal at codespeak.net
fijal at codespeak.net
Wed Oct 17 12:33:51 CEST 2007
Author: fijal
Date: Wed Oct 17 12:33:50 2007
New Revision: 47509
Modified:
pypy/dist/pypy/module/_ffi/TODO
pypy/dist/pypy/module/_ffi/__init__.py
pypy/dist/pypy/module/_ffi/app_ffi.py
pypy/dist/pypy/module/_ffi/interp_ffi.py
pypy/dist/pypy/module/_ffi/structure.py
pypy/dist/pypy/module/_ffi/test/test__ffi.py
Log:
Add arrays, working almost out of the box.
Modified: pypy/dist/pypy/module/_ffi/TODO
==============================================================================
--- pypy/dist/pypy/module/_ffi/TODO (original)
+++ pypy/dist/pypy/module/_ffi/TODO Wed Oct 17 12:33:50 2007
@@ -2,6 +2,6 @@
* long support with all messy corners (when to create long integer and
such), also short overflowing
-* add arrays
-
+* add faulty parameters checking (they end up with fatal rpython error KeyErro
+ or sth like that by now)
Modified: pypy/dist/pypy/module/_ffi/__init__.py
==============================================================================
--- pypy/dist/pypy/module/_ffi/__init__.py (original)
+++ pypy/dist/pypy/module/_ffi/__init__.py Wed Oct 17 12:33:50 2007
@@ -12,10 +12,12 @@
interpleveldefs = {
'CDLL' : 'interp_ffi.W_CDLL',
'FuncPtr' : 'interp_ffi.W_FuncPtr',
- 'StructureInstance' : 'structure.W_StructureInstance',
+ 'StructureInstance' : 'structure.W_StructureInstance',
+ 'ArrayInstance' : 'array.W_ArrayInstance',
}
appleveldefs = {
'Structure' : 'app_ffi.Structure',
+ 'Array' : 'app_ffi.Array',
#'StructureInstance' : 'app_ffi.StructureInstance',
}
Modified: pypy/dist/pypy/module/_ffi/app_ffi.py
==============================================================================
--- pypy/dist/pypy/module/_ffi/app_ffi.py (original)
+++ pypy/dist/pypy/module/_ffi/app_ffi.py Wed Oct 17 12:33:50 2007
@@ -13,3 +13,11 @@
raise TypeError("Keyword arguments not allowed when passing address argument")
return StructureInstance(self, args[0], None)
return StructureInstance(self, None, kwds)
+
+class Array(object):
+ def __init__(self, of):
+ self.of = of
+
+ def __call__(self, size):
+ from _ffi import ArrayInstance
+ return ArrayInstance(self.of, size)
Modified: pypy/dist/pypy/module/_ffi/interp_ffi.py
==============================================================================
--- pypy/dist/pypy/module/_ffi/interp_ffi.py (original)
+++ pypy/dist/pypy/module/_ffi/interp_ffi.py Wed Oct 17 12:33:50 2007
@@ -141,7 +141,9 @@
else:
mod = space.getbuiltinmodule('_ffi')
w_StructureInstance = space.getattr(mod, w('StructureInstance'))
- if space.is_true(space.isinstance(w_arg, w_StructureInstance)):
+ w_ArrayInstance = space.getattr(mod, w('ArrayInstance'))
+ if space.is_true(space.isinstance(w_arg, w_StructureInstance)) or\
+ space.is_true(space.isinstance(w_arg, w_ArrayInstance)):
ptr = rffi.cast(rffi.VOIDP, space.int_w(space.getattr(w_arg, w('buffer'))))
push_func(add_arg, argdesc, ptr)
else:
@@ -162,33 +164,37 @@
ll_typemap_iter = unrolling_iterable(LL_TYPEMAP.items())
-def wrap_result(space, restype, arg, func):
+def wrap_result(space, restype, arg, argdesc, func):
for c, ll_type in ll_typemap_iter:
if restype == c:
if c == 's':
- ptr = func(arg, rffi.CCHARP)
+ ptr = func(arg, argdesc, rffi.CCHARP)
if not ptr:
return space.w_None
return space.wrap(rffi.charp2str(ptr))
elif c == 'P':
- res = func(arg, rffi.VOIDP)
+ res = func(arg, argdesc, rffi.VOIDP)
+ if not res:
+ return space.w_None
return space.wrap(rffi.cast(rffi.INT, res))
#elif c == 'q' or c == 'Q' or c == 'L':
# return space.newlong(func(arg, ll_type))
elif c == 'f' or c == 'd':
- return space.wrap(float(func(arg, ll_type)))
+ return space.wrap(float(func(arg, argdesc, ll_type)))
elif c == 'c' or c == 'b' or c == 'B':
- return space.wrap(chr(rffi.cast(rffi.INT, func(arg, ll_type))))
+ return space.wrap(chr(rffi.cast(rffi.INT, func(arg, argdesc,
+ ll_type))))
elif c == 'h' or c == 'H':
- return space.wrap(rffi.cast(rffi.INT, func(arg, ll_type)))
+ return space.wrap(rffi.cast(rffi.INT, func(arg, argdesc,
+ ll_type)))
else:
- return space.wrap(intmask(func(arg, ll_type)))
+ return space.wrap(intmask(func(arg, argdesc, ll_type)))
return space.w_None
wrap_result._annspecialcase_ = 'specialize:arg(3)'
-def ptr_call(ptr, ll_type):
+def ptr_call(ptr, some_arg, ll_type):
return ptr.call(ll_type)
-ptr_call._annspecialcase_ = 'specialize:arg(1)'
+ptr_call._annspecialcase_ = 'specialize:arg(2)'
def push(ptr, argdesc, value):
ptr.push_arg(value)
@@ -214,7 +220,7 @@
unwrap_arg(space, push, self.ptr, i, argtype, w_arg, to_free)
i += 1
try:
- return wrap_result(space, self.restype, self.ptr, ptr_call)
+ return wrap_result(space, self.restype, self.ptr, None, ptr_call)
finally:
for elem in to_free:
lltype.free(elem, flavor='raw')
Modified: pypy/dist/pypy/module/_ffi/structure.py
==============================================================================
--- pypy/dist/pypy/module/_ffi/structure.py (original)
+++ pypy/dist/pypy/module/_ffi/structure.py Wed Oct 17 12:33:50 2007
@@ -50,12 +50,11 @@
rffi.cast(T, ptr)[0] = value
push_field._annspecialcase_ = 'specialize:argtype(2)'
-def cast_pos(self, ll_t):
- i = self.next_pos
+def cast_pos(self, i, ll_t):
pos = rffi.ptradd(self.ll_buffer, self.ll_positions[i])
TP = lltype.Ptr(rffi.CArray(ll_t))
return rffi.cast(TP, pos)[0]
-cast_pos._annspecialcase_ = 'specialize:arg(1)'
+cast_pos._annspecialcase_ = 'specialize:arg(2)'
class W_StructureInstance(Wrappable):
def __init__(self, space, w_shape, w_address, w_fieldinits):
@@ -71,7 +70,6 @@
self.ll_buffer = lltype.malloc(rffi.VOIDP.TO, size, flavor='raw',
zero=True)
self.ll_positions = pos
- self.next_pos = 0
if space.is_true(w_fieldinits):
for w_field in space.unpackiterable(w_fieldinits):
w_value = space.getitem(w_fieldinits, w_field)
@@ -83,9 +81,7 @@
for i in range(len(self.fields)):
name, c = self.fields[i]
if name == attr:
- # XXX RPython-trick for passing lambda around
- self.next_pos = i
- return wrap_result(space, c, self, cast_pos)
+ return wrap_result(space, c, self, i, cast_pos)
raise OperationError(space.w_AttributeError, space.wrap(
"C Structure has no attribute %s" % attr))
getattr.unwrap_spec = ['self', ObjSpace, str]
Modified: pypy/dist/pypy/module/_ffi/test/test__ffi.py
==============================================================================
--- pypy/dist/pypy/module/_ffi/test/test__ffi.py (original)
+++ pypy/dist/pypy/module/_ffi/test/test__ffi.py Wed Oct 17 12:33:50 2007
@@ -59,6 +59,16 @@
return static_str;
return NULL;
}
+
+ int get_array_elem(int* stuff, int num)
+ {
+ return stuff[num];
+ }
+
+ struct x* get_array_elem_s(struct x** array, int num)
+ {
+ return array[num];
+ }
'''))
compile_c_module([c_file], 'x')
return str(udir.join('x.so'))
@@ -188,6 +198,34 @@
x = create_double_struct()
assert X(X(x).next).x2 == 3
+ def test_array(self):
+ import _ffi
+ lib = _ffi.CDLL(self.lib_name)
+ A = _ffi.Array('i')
+ get_array_elem = lib.ptr('get_array_elem', ['P', 'i'], 'i')
+ a = A(10)
+ a[8] = 3
+ a[7] = 1
+ a[6] = 2
+ assert get_array_elem(a, 9) == 0
+ assert get_array_elem(a, 8) == 3
+ assert get_array_elem(a, 7) == 1
+ assert get_array_elem(a, 6) == 2
+ assert a[3] == 0
+
+ def test_array_of_structure(self):
+ import _ffi
+ lib = _ffi.CDLL(self.lib_name)
+ A = _ffi.Array('P')
+ X = _ffi.Structure([('x1', 'i'), ('x2', 'h'), ('x3', 'c'), ('next', 'P')])
+ x = X(x2=3)
+ a = A(3)
+ a[1] = x
+ get_array_elem_s = lib.ptr('get_array_elem_s', ['P', 'i'], 'P')
+ ptr1 = get_array_elem_s(a, 0)
+ assert ptr1 is None
+ assert X(get_array_elem_s(a, 1)).x2 == 3
+
def test_implicit_structure(self):
skip("Does not work yet")
import _ffi
More information about the Pypy-commit
mailing list