[pypy-svn] r50829 - in pypy/dist/pypy/module/_rawffi: . test
fijal at codespeak.net
fijal at codespeak.net
Mon Jan 21 13:17:07 CET 2008
Author: fijal
Date: Mon Jan 21 13:17:07 2008
New Revision: 50829
Modified:
pypy/dist/pypy/module/_rawffi/__init__.py
pypy/dist/pypy/module/_rawffi/callback.py
pypy/dist/pypy/module/_rawffi/test/test__rawffi.py
Log:
Support for _rawffi callbacks (not sure how keepalive stuff will
look like, for now it's a bit crappy)
Modified: pypy/dist/pypy/module/_rawffi/__init__.py
==============================================================================
--- pypy/dist/pypy/module/_rawffi/__init__.py (original)
+++ pypy/dist/pypy/module/_rawffi/__init__.py Mon Jan 21 13:17:07 2008
@@ -19,7 +19,7 @@
'sizeof' : 'interp_rawffi.sizeof',
'alignment' : 'interp_rawffi.alignment',
'charp2string' : 'interp_rawffi.charp2string',
- #'CallbackPtr' : 'callback.W_CallbackPtr',
+ 'CallbackPtr' : 'callback.W_CallbackPtr',
}
appleveldefs = {
Modified: pypy/dist/pypy/module/_rawffi/callback.py
==============================================================================
--- pypy/dist/pypy/module/_rawffi/callback.py (original)
+++ pypy/dist/pypy/module/_rawffi/callback.py Mon Jan 21 13:17:07 2008
@@ -5,27 +5,62 @@
from pypy.interpreter.typedef import TypeDef, GetSetProperty
from pypy.rpython.lltypesystem import lltype, rffi
from pypy.module._rawffi.structure import unpack_fields
+from pypy.module._rawffi.array import get_elem
+from pypy.module._rawffi.interp_rawffi import W_DataInstance, _get_type_,\
+ wrap_value, unwrap_value, unwrap_truncate_int
+from pypy.rlib.libffi import USERDATA_P, CallbackFuncPtr
-def stuff(a, b):
- print "comparing"
- return int(a > b)
+def callback(ll_args, ll_res, ll_userdata):
+ userdata = rffi.cast(USERDATA_P, ll_userdata)
+ callback_ptr = W_CallbackPtr.CallbackPtr_by_number[userdata.addarg]
+ w_callable = callback_ptr.w_callable
+ res = rffi.cast(rffi.VOIDPP, ll_res)
+ argtypes = callback_ptr.args
+ space = callback_ptr.space
+ w_args = space.newlist([wrap_value(space, get_elem, ll_args[i], 0,
+ (argtypes[i], None, None))
+ for i in range(len(argtypes))])
+ w_res = space.call(w_callable, w_args)
+ if space.is_w(w_res, space.w_None):
+ res[0] = lltype.nullptr(rffi.VOIDP.TO)
+ else:
+ instance = space.interpclass_w(w_res)
+ if isinstance(instance, W_DataInstance):
+ res[0] = instance.ll_buffer
+ else:
+ res[0] = unwrap_truncate_int(rffi.VOIDP, space, w_res)
-class W_CallbackPtr(Wrappable):
+class W_CallbackPtr(W_DataInstance):
+ # XXX some weird hackery to be able to recover W_CallbackPtr object
+ # out of number
+ CallbackPtr_by_number = {}
+ CallbackPtr_id = 0
+
def __init__(self, space, w_callable, w_args, w_result):
+ number = self.CallbackPtr_id
+ self.CallbackPtr_id += 1
+ self.CallbackPtr_by_number[number] = self
+ self.space = space
self.w_callable = w_callable
+ self.number = number
self.args = [space.str_w(w_arg) for w_arg in space.unpackiterable(
w_args)]
+ self.result = space.str_w(w_result)
+ ffiargs = [_get_type_(space, arg) for arg in self.args]
+ ffiresult = _get_type_(space, self.result)
+ # necessary to keep stuff alive
+ self.ll_callback = CallbackFuncPtr(ffiargs, ffiresult,
+ callback, number)
+ self.ll_buffer = self.ll_callback.ll_closure
- def getllfuncptr(space, self):
- TP = lltype.FuncType([lltype.Signed, lltype.Signed], lltype.Signed)
- ptr = lltype.functionptr(TP, stuff)
- return space.wrap(rffi.cast(rffi.Unsigned, ptr))
+ def __del__(self):
+ del self.CallbackPtr_by_number[self.number]
def descr_new_callbackptr(space, w_type, w_callable, w_args, w_result):
return W_CallbackPtr(space, w_callable, w_args, w_result)
W_CallbackPtr.typedef = TypeDef(
'CallbackPtr',
- buffer = GetSetProperty(W_CallbackPtr.getllfuncptr),
__new__ = interp2app(descr_new_callbackptr),
+ byptr = interp2app(W_CallbackPtr.byptr),
)
Modified: pypy/dist/pypy/module/_rawffi/test/test__rawffi.py
==============================================================================
--- pypy/dist/pypy/module/_rawffi/test/test__rawffi.py (original)
+++ pypy/dist/pypy/module/_rawffi/test/test__rawffi.py Mon Jan 21 13:17:07 2008
@@ -359,18 +359,32 @@
arg1.free()
def test_callback(self):
- skip("Not working")
import _rawffi
+ import struct
libc = _rawffi.CDLL('libc.so.6')
- to_sort = "kljhgfa"
- ll_to_sort = _rawffi.Array('c')(to_sort)
+ ll_to_sort = _rawffi.Array('i')(4)
+ for i in range(4):
+ ll_to_sort[i] = 4-i
qsort = libc.ptr('qsort', ['P', 'i', 'i', 'P'], None)
+ resarray = _rawffi.Array('i')(1)
def compare(a, b):
- return a < b
- qsort(ll_to_sort, len(to_sort), 1,
- _rawffi.CallbackPtr(compare, ['i', 'i'], 'i'))
- res = [ll_to_sort[i] for i in range(len(to_sort))]
- assert res == sorted(to_sort)
+ a1 = _rawffi.Array('i').fromaddress(a, 1)
+ a2 = _rawffi.Array('i').fromaddress(b, 1)
+ if a1[0] > a2[0]:
+ res = 1
+ res = -1
+ resarray[0] = res
+ return resarray
+ a1 = ll_to_sort.byptr()
+ a2 = _rawffi.Array('i')(1)
+ a2[0] = len(ll_to_sort)
+ a3 = _rawffi.Array('i')(1)
+ a3[0] = struct.calcsize('i')
+ cb = _rawffi.CallbackPtr(compare, ['P', 'P'], 'i')
+ a4 = cb.byptr()
+ qsort(a1, a2, a3, a4)
+ res = [ll_to_sort[i] for i in range(len(ll_to_sort))]
+ assert res == [1,2,3,4]
def test_setattr_struct(self):
import _rawffi
More information about the Pypy-commit
mailing list