[pypy-svn] r77683 - in pypy/branch/jitffi/pypy: module/_ffi module/_ffi/test rlib

antocuni at codespeak.net antocuni at codespeak.net
Thu Oct 7 16:44:38 CEST 2010


Author: antocuni
Date: Thu Oct  7 16:44:37 2010
New Revision: 77683

Modified:
   pypy/branch/jitffi/pypy/module/_ffi/__init__.py
   pypy/branch/jitffi/pypy/module/_ffi/interp_ffi.py
   pypy/branch/jitffi/pypy/module/_ffi/test/test__ffi.py
   pypy/branch/jitffi/pypy/rlib/libffi.py
Log:
app-level call of an ffi function works :-)
(modulo tons of details left)


Modified: pypy/branch/jitffi/pypy/module/_ffi/__init__.py
==============================================================================
--- pypy/branch/jitffi/pypy/module/_ffi/__init__.py	(original)
+++ pypy/branch/jitffi/pypy/module/_ffi/__init__.py	Thu Oct  7 16:44:37 2010
@@ -5,7 +5,6 @@
 
     interpleveldefs = {
         'CDLL'               : 'interp_ffi.W_CDLL',
-#        'FuncPtr'            : 'interp_ffi.W_FuncPtr',
         'types':             'interp_ffi.W_types',
     }
 

Modified: pypy/branch/jitffi/pypy/module/_ffi/interp_ffi.py
==============================================================================
--- pypy/branch/jitffi/pypy/module/_ffi/interp_ffi.py	(original)
+++ pypy/branch/jitffi/pypy/module/_ffi/interp_ffi.py	Thu Oct  7 16:44:37 2010
@@ -1,10 +1,12 @@
 import sys
 from pypy.interpreter.baseobjspace import W_Root, ObjSpace, Wrappable, Arguments
 from pypy.interpreter.error import OperationError, wrap_oserror, operationerrfmt
-from pypy.interpreter.gateway import interp2app, NoneNotWrapped
+from pypy.interpreter.gateway import interp2app, NoneNotWrapped, unwrap_spec
 from pypy.interpreter.typedef import TypeDef, GetSetProperty
-
-from pypy.rlib.libffi import CDLL, types
+#
+from pypy.rpython.lltypesystem import lltype, rffi
+#
+from pypy.rlib import libffi
 from pypy.rlib.rdynload import DLOpenError
 
 class W_FFIType(Wrappable):
@@ -12,9 +14,10 @@
         self.name = name
         self.ffitype = ffitype
 
+    @unwrap_spec('self', ObjSpace)
     def str(self, space):
         return space.wrap('<ffi type %s>' % self.name)
-    str.unwrap_spec = ['self', ObjSpace]
+
 
 
 W_FFIType.typedef = TypeDef(
@@ -27,10 +30,12 @@
     pass
 
 def build_ffi_types():
+    from pypy.rlib.clibffi import FFI_TYPE_P
     tdict = {}
-    for key, value in types.__dict__.iteritems():
-        if key.startswith('__'):
+    for key, value in libffi.types.__dict__.iteritems():
+        if key == 'getkind' or key.startswith('__'):
             continue
+        assert lltype.typeOf(value) == FFI_TYPE_P
         tdict[key] = W_FFIType(key, value)
     return tdict
     
@@ -40,24 +45,72 @@
 
 # ========================================================================
 
+class W_FuncPtr(Wrappable):
+    def __init__(self, func):
+        self.func = func
+
+    @unwrap_spec('self', ObjSpace, 'args_w')
+    def call(self, space, args_w):
+        assert len(args_w) == len(self.func.argtypes) # XXX: raise OperationError
+        argchain = libffi.ArgChain()
+        for i in range(len(args_w)):
+            argtype = self.func.argtypes[i]
+            w_arg = args_w[i]
+            kind = libffi.types.getkind(argtype)
+            if kind == 'i':
+                assert False
+                #argchain.arg(space.int_w(w_arg))
+            elif kind == 'f':
+                argchain.arg(space.float_w(w_arg))
+            else:
+                assert False # XXX
+        #
+        reskind = libffi.types.getkind(self.func.restype)
+        if reskind == 'f':
+            floatres = self.func.call(argchain, rffi.DOUBLE)
+            return space.wrap(floatres)
+        else:
+            assert False
+
+W_FuncPtr.typedef = TypeDef(
+    'FuncPtr',
+    __call__ = interp2app(W_FuncPtr.call)
+    )
+
+
+
+# ========================================================================
+
 class W_CDLL(Wrappable):
     def __init__(self, space, name):
         try:
-            self.cdll = CDLL(name)
+            self.cdll = libffi.CDLL(name)
         except DLOpenError, e:
             raise operationerrfmt(space.w_OSError, '%s: %s', name,
                                   e.msg or 'unspecified error')
         self.name = name
         self.space = space
 
+    def ffitype(self, w_argtype):
+        return self.space.interp_w(W_FFIType, w_argtype).ffitype
+
+    @unwrap_spec('self', ObjSpace, str, W_Root, W_Root)
+    def getfunc(self, space, name, w_argtypes, w_restype):
+        argtypes = [self.ffitype(w_argtype) for w_argtype in space.listview(w_argtypes)]
+        restype = self.ffitype(w_restype)
+        func = self.cdll.getpointer(name, argtypes, restype)
+        return W_FuncPtr(func)
 
+
+ at unwrap_spec(ObjSpace, W_Root, str)
 def descr_new_cdll(space, w_type, name):
     return space.wrap(W_CDLL(space, name))
-descr_new_cdll.unwrap_spec = [ObjSpace, W_Root, str]
+
 
 W_CDLL.typedef = TypeDef(
     'CDLL',
     __new__     = interp2app(descr_new_cdll),
+    getfunc     = interp2app(W_CDLL.getfunc),
     )
 
 # ========================================================================

Modified: pypy/branch/jitffi/pypy/module/_ffi/test/test__ffi.py
==============================================================================
--- pypy/branch/jitffi/pypy/module/_ffi/test/test__ffi.py	(original)
+++ pypy/branch/jitffi/pypy/module/_ffi/test/test__ffi.py	Thu Oct  7 16:44:37 2010
@@ -38,7 +38,7 @@
         cls.space = space
         cls.w_libfoo_name = space.wrap(cls.prepare_c_example())
         cls.w_libc_name = space.wrap(get_libc_name())
-        cls.w_libc_name = space.wrap(get_libm_name(sys.platform))
+        cls.w_libm_name = space.wrap(get_libm_name(sys.platform))
 
     def test_libload(self):
         import _ffi
@@ -53,3 +53,9 @@
         assert str(types.sint) == '<ffi type sint>'
         assert str(types.uint) == '<ffi type uint>'
         
+    def test_callfunc(self):
+        from _ffi import CDLL, types
+        libm = CDLL(self.libm_name)
+        pow = libm.getfunc('pow', [types.double, types.double], types.double)
+        assert pow(2, 3) == 8
+        

Modified: pypy/branch/jitffi/pypy/rlib/libffi.py
==============================================================================
--- pypy/branch/jitffi/pypy/rlib/libffi.py	(original)
+++ pypy/branch/jitffi/pypy/rlib/libffi.py	Thu Oct  7 16:44:37 2010
@@ -32,6 +32,13 @@
         cls.ulong = clibffi.cast_type_to_ffitype(rffi.ULONG)
         del cls._import
 
+    @classmethod
+    def getkind(cls, ffitype):
+        # XXX: move this function outside the jit
+        from pypy.jit.backend.llsupport.ffisupport import get_ffi_type_kind
+        return get_ffi_type_kind(ffitype)
+
+
 types._import()
 
 @specialize.arg(0)



More information about the Pypy-commit mailing list