[pypy-svn] r53125 - in pypy/dist/pypy/module/_rawffi: . test

fijal at codespeak.net fijal at codespeak.net
Sun Mar 30 04:46:04 CEST 2008


Author: fijal
Date: Sun Mar 30 04:46:01 2008
New Revision: 53125

Modified:
   pypy/dist/pypy/module/_rawffi/interp_rawffi.py
   pypy/dist/pypy/module/_rawffi/test/test__rawffi.py
Log:
Allow creation of raw callable pointers.


Modified: pypy/dist/pypy/module/_rawffi/interp_rawffi.py
==============================================================================
--- pypy/dist/pypy/module/_rawffi/interp_rawffi.py	(original)
+++ pypy/dist/pypy/module/_rawffi/interp_rawffi.py	Sun Mar 30 04:46:01 2008
@@ -124,6 +124,26 @@
         size, alignment = resshape._size_alignment()
         return ('V', length*size, alignment) # value object
 
+def unpack_resshape(space, w_restype):
+    if space.is_w(w_restype, space.w_None):
+        resshape = None
+        ffi_restype = ffi_type_void
+    else:
+        tp_letter, ffi_restype, resshape = unpack_to_ffi_type(space,
+                                                    w_restype,
+                                                    allow_void=True,
+                                                    shape=True)
+    return ffi_restype, resshape
+
+def unpack_argshapes(space, w_argtypes):
+    argletters = []
+    ffi_argtypes = []
+    for w_arg in space.unpackiterable(w_argtypes):
+        argletter, ffi_argtype, _ = unpack_to_ffi_type(space, w_arg)
+        argletters.append(argletter)
+        ffi_argtypes.append(ffi_argtype)
+    return ffi_argtypes, argletters
+
 class W_CDLL(Wrappable):
     def __init__(self, space, name):
         self.cdll = CDLL(name)
@@ -135,15 +155,7 @@
         """ Get a pointer for function name with provided argtypes
         and restype
         """
-        # xxx refactor
-        if space.is_w(w_restype, space.w_None):
-            resshape = None
-            ffi_restype = ffi_type_void
-        else:
-            tp_letter, ffi_restype, resshape = unpack_to_ffi_type(space,
-                                                        w_restype,
-                                                        allow_void=True,
-                                                        shape=True)
+        ffi_restype, resshape = unpack_resshape(space, w_restype)
         w = space.wrap
         argtypes_w = space.unpackiterable(w_argtypes)
         w_argtypes = space.newtuple(argtypes_w)
@@ -155,13 +167,7 @@
                 pass
             else:
                 raise
-        argletters = []
-        ffi_argtypes = []
-        for w_arg in argtypes_w:
-            argletter, ffi_argtype, _ = unpack_to_ffi_type(space, w_arg)
-            argletters.append(argletter)
-            ffi_argtypes.append(ffi_argtype)
-
+        ffi_argtypes, argletters = unpack_argshapes(space, w_argtypes)
         try:
             ptr = self.cdll.getrawpointer(name, ffi_argtypes, ffi_restype)
             w_funcptr = W_FuncPtr(space, ptr, argletters, resshape)
@@ -397,10 +403,19 @@
             return space.w_None
     call.unwrap_spec = ['self', ObjSpace, 'args_w']
 
+def descr_new_funcptr(space, w_tp, addr, w_args, w_res):
+    ffi_args, args = unpack_argshapes(space, w_args)
+    ffi_res, res = unpack_resshape(space, w_res)
+    ptr = RawFuncPtr('???', ffi_args, ffi_res, rffi.cast(rffi.VOIDP, addr))
+    return space.wrap(W_FuncPtr(space, ptr, args, res))
+descr_new_funcptr.unwrap_spec = [ObjSpace, W_Root, r_uint, W_Root, W_Root]
+
 W_FuncPtr.typedef = TypeDef(
     'FuncPtr',
+    __new__  = interp2app(descr_new_funcptr),
     __call__ = interp2app(W_FuncPtr.call)
 )
+W_FuncPtr.typedef.acceptable_as_base_class = False
 
 def _create_new_accessor(func_name, name):
     def accessor(space, tp_letter):

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	Sun Mar 30 04:46:01 2008
@@ -63,6 +63,11 @@
            return one + two;
         }
 
+        void* get_raw_pointer()
+        {
+           return (void*)add_shorts;
+        }
+
         char get_char(char* s, unsigned short num)
         {
            return s[num];
@@ -215,6 +220,22 @@
         arg1.free()
         arg2.free()
 
+    def test_raw_callable(self):
+        import _rawffi
+        lib = _rawffi.CDLL(self.lib_name)
+        get_raw_pointer = lib.ptr('get_raw_pointer', [], 'P')
+        ptr = get_raw_pointer()
+        rawcall = _rawffi.FuncPtr(ptr[0], ['h', 'h'], 'H')
+        A = _rawffi.Array('h')
+        arg1 = A(1)
+        arg2 = A(1)
+        arg1[0] = 1
+        arg2[0] = 2
+        res = rawcall(arg1, arg2)
+        assert res[0] == 3
+        arg1.free()
+        arg2.free()
+
     def test_short_addition(self):
         import _rawffi
         lib = _rawffi.CDLL(self.lib_name)
@@ -700,7 +721,6 @@
         assert a[3] == 'z'
         assert a[4] == 't'
 
-
 class AppTestAutoFree:
     def setup_class(cls):
         space = gettestobjspace(usemodules=('_rawffi', 'struct'))



More information about the Pypy-commit mailing list