[pypy-svn] r77569 - in pypy/branch/jitffi/pypy: jit/metainterp/test rlib

antocuni at codespeak.net antocuni at codespeak.net
Mon Oct 4 15:24:11 CEST 2010


Author: antocuni
Date: Mon Oct  4 15:24:09 2010
New Revision: 77569

Modified:
   pypy/branch/jitffi/pypy/jit/metainterp/test/test_fficall.py
   pypy/branch/jitffi/pypy/rlib/libffi.py
Log:
cast the result to the correct type when calling a function


Modified: pypy/branch/jitffi/pypy/jit/metainterp/test/test_fficall.py
==============================================================================
--- pypy/branch/jitffi/pypy/jit/metainterp/test/test_fficall.py	(original)
+++ pypy/branch/jitffi/pypy/jit/metainterp/test/test_fficall.py	Mon Oct  4 15:24:09 2010
@@ -2,7 +2,7 @@
 import py
 from pypy.rlib.jit import JitDriver, hint
 from pypy.jit.metainterp.test.test_basic import LLJitMixin
-from pypy.rlib.libffi import CDLL, ffi_type_sint, ffi_type_double, ArgChain, Func
+from pypy.rlib.libffi import CDLL, ffi_type_sint, ffi_type_double, ffi_type_uchar, ArgChain, Func
 from pypy.tool.udir import udir
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
 from pypy.translator.platform import platform
@@ -12,7 +12,7 @@
     def setup_class(cls):
         # prepare C code as an example, so we can load it and call
         # it via rlib.libffi
-        c_file = udir.ensure("test_jit_direct_call", dir=1).join("xlib.c")
+        c_file = udir.ensure("test_jit_fficall", dir=1).join("xlib.c")
         c_file.write(py.code.Source('''
         int sum_xy(int x, double y)
         {
@@ -25,8 +25,13 @@
                 return -x;
             return x;
         }
+
+        unsigned char cast_to_uchar(int x)
+        {
+            return 200+(unsigned char)x;
+        }
         '''))
-        eci = ExternalCompilationInfo(export_symbols=['sum_xy'])
+        eci = ExternalCompilationInfo(export_symbols=[])
         cls.lib_name = str(platform.compile([c_file], eci, 'x',
                                             standalone=False))
 
@@ -77,3 +82,23 @@
         assert res == 9
         self.check_loops(call=1)
 
+    def test_cast_result(self):
+        driver = JitDriver(reds = ['n', 'res', 'func'], greens = [])        
+
+        def f(n):
+            cdll = CDLL(self.lib_name)
+            func = cdll.getpointer('cast_to_uchar', [ffi_type_sint],
+                                   ffi_type_uchar)
+            res = 0
+            while n < 10:
+                driver.jit_merge_point(n=n, func=func, res=res)
+                driver.can_enter_jit(n=n, func=func, res=res)
+                func = hint(func, promote=True)
+                argchain = ArgChain()
+                argchain.int(0)
+                res = func.call(argchain, rffi.UCHAR)
+                n += 1
+            return res
+            
+        res = self.meta_interp(f, [0])
+        assert res == 200

Modified: pypy/branch/jitffi/pypy/rlib/libffi.py
==============================================================================
--- pypy/branch/jitffi/pypy/rlib/libffi.py	(original)
+++ pypy/branch/jitffi/pypy/rlib/libffi.py	Mon Oct  4 15:24:09 2010
@@ -15,6 +15,13 @@
 import_types()
 del import_types
 
+def _fits_into_long(TYPE):
+    if not isinstance(TYPE, lltype.Number):
+        return False
+    if TYPE is rffi.FLOAT or TYPE is rffi.DOUBLE:
+        return False
+    sz = rffi.sizeof(TYPE)
+    return sz <= rffi.sizeof(rffi.LONG)
 
 # ----------------------------------------------------------------------
 
@@ -101,12 +108,15 @@
             arg.push(self, ll_args, i)
             i += 1
             arg = arg.next
-        if RESULT is rffi.LONG:
-            return self._do_call_int(self.funcsym, ll_args)
+        #
+        if _fits_into_long(RESULT):
+            res = self._do_call_int(self.funcsym, ll_args)
         elif RESULT is rffi.DOUBLE:
             return self._do_call_float(self.funcsym, ll_args)
         else:
             raise TypeError, 'Unsupported result type: %s' % RESULT
+        #
+        return rffi.cast(RESULT, res)
 
     # END OF THE PUBLIC INTERFACE
     # ------------------------------------------------------------------------
@@ -119,6 +129,7 @@
         ll_args = lltype.malloc(rffi.VOIDPP.TO, len(self.argtypes), flavor='raw')
         return ll_args
 
+
     # _push_* and _do_call_* in theory could be automatically specialize()d by
     # the annotator.  However, specialization doesn't work well with oopspec,
     # so we specialize them by hand



More information about the Pypy-commit mailing list