[pypy-svn] r77489 - in pypy/branch/jitffi/pypy/jit/backend: llgraph test

antocuni at codespeak.net antocuni at codespeak.net
Thu Sep 30 14:17:26 CEST 2010


Author: antocuni
Date: Thu Sep 30 14:17:25 2010
New Revision: 77489

Modified:
   pypy/branch/jitffi/pypy/jit/backend/llgraph/llimpl.py
   pypy/branch/jitffi/pypy/jit/backend/llgraph/runner.py
   pypy/branch/jitffi/pypy/jit/backend/test/runner_test.py
Log:
teach the llgraph backend how to CALL c functions. This makes test_direct_call.py passing for the first time :-)


Modified: pypy/branch/jitffi/pypy/jit/backend/llgraph/llimpl.py
==============================================================================
--- pypy/branch/jitffi/pypy/jit/backend/llgraph/llimpl.py	(original)
+++ pypy/branch/jitffi/pypy/jit/backend/llgraph/llimpl.py	Thu Sep 30 14:17:25 2010
@@ -10,7 +10,7 @@
                                          BoxInt, BoxPtr, BoxObj, BoxFloat,
                                          REF, INT, FLOAT)
 from pypy.jit.codewriter import heaptracker
-from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rstr
+from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rstr, rffi
 from pypy.rpython.ootypesystem import ootype
 from pypy.rpython.module.support import LLSupport, OOSupport
 from pypy.rpython.llinterp import LLException
@@ -305,12 +305,12 @@
     loop = _from_opaque(loop)
     loop.operations.append(Operation(opnum))
 
-def compile_add_descr(loop, ofs, type):
+def compile_add_descr(loop, ofs, type, arg_types):
     from pypy.jit.backend.llgraph.runner import Descr
     loop = _from_opaque(loop)
     op = loop.operations[-1]
     assert isinstance(type, str) and len(type) == 1
-    op.descr = Descr(ofs, type)
+    op.descr = Descr(ofs, type, arg_types=arg_types)
 
 def compile_add_loop_token(loop, descr):
     if we_are_translated():
@@ -801,7 +801,7 @@
             else:
                 raise TypeError(x)
         try:
-            return _do_call_common(func, args_in_order)
+            return _do_call_common(func, args_in_order, calldescr)
         except LLException, lle:
             _last_exception = lle
             d = {'v': None,
@@ -1397,10 +1397,26 @@
 def do_call_pushfloat(x):
     _call_args_f.append(x)
 
-def _do_call_common(f, args_in_order=None):
+kind2TYPE = {
+    'i': lltype.Signed,
+    'f': lltype.Float,
+    'r': rffi.VOIDP, # XXX this is probably wrong
+    }
+
+def _do_call_common(f, args_in_order=None, calldescr=None):
     ptr = llmemory.cast_int_to_adr(f).ptr
-    FUNC = lltype.typeOf(ptr).TO
-    ARGS = FUNC.ARGS
+    PTR = lltype.typeOf(ptr)
+    if PTR == rffi.VOIDP:
+        # it's a pointer to a C function, so we don't have a precise
+        # signature: create one from the descr
+        ARGS = map(kind2TYPE.get, calldescr.arg_types)
+        RESULT = kind2TYPE[calldescr.typeinfo]
+        FUNC = lltype.FuncType(ARGS, RESULT)
+        func_to_call = rffi.cast(lltype.Ptr(FUNC), ptr)
+    else:
+        FUNC = PTR.TO
+        ARGS = FUNC.ARGS
+        func_to_call = ptr._obj._callable
     args = cast_call_args(ARGS, _call_args_i, _call_args_r, _call_args_f,
                           args_in_order)
     del _call_args_i[:]
@@ -1412,7 +1428,7 @@
         result = llinterp.eval_graph(ptr._obj.graph, args)
         # ^^^ may raise, in which case we get an LLException
     else:
-        result = ptr._obj._callable(*args)
+        result = func_to_call(*args)
     return result
 
 def do_call_void(f):

Modified: pypy/branch/jitffi/pypy/jit/backend/llgraph/runner.py
==============================================================================
--- pypy/branch/jitffi/pypy/jit/backend/llgraph/runner.py	(original)
+++ pypy/branch/jitffi/pypy/jit/backend/llgraph/runner.py	Thu Sep 30 14:17:25 2010
@@ -154,7 +154,7 @@
             llimpl.compile_add(c, op.getopnum())
             descr = op.getdescr()
             if isinstance(descr, Descr):
-                llimpl.compile_add_descr(c, descr.ofs, descr.typeinfo)
+                llimpl.compile_add_descr(c, descr.ofs, descr.typeinfo, descr.arg_types)
             if isinstance(descr, history.LoopToken) and op.getopnum() != rop.JUMP:
                 llimpl.compile_add_loop_token(c, descr)
             if self.is_oo and isinstance(descr, (OODescr, MethDescr)):

Modified: pypy/branch/jitffi/pypy/jit/backend/test/runner_test.py
==============================================================================
--- pypy/branch/jitffi/pypy/jit/backend/test/runner_test.py	(original)
+++ pypy/branch/jitffi/pypy/jit/backend/test/runner_test.py	Thu Sep 30 14:17:25 2010
@@ -516,6 +516,23 @@
                                          'int', descr=calldescr)
             assert res.value == func_ints(*args)
 
+    def test_call_to_c_function(self):
+        from pypy.rlib.libffi import CDLL, ffi_type_uchar, ffi_type_sint
+        libc = CDLL('libc.so.6')
+        c_tolower = libc.getpointer('tolower', [ffi_type_uchar], ffi_type_sint)
+        c_tolower.push_arg('A')
+        assert c_tolower.call(lltype.Signed) == ord('a')
+
+        func_adr = llmemory.cast_ptr_to_adr(c_tolower.funcsym)
+        funcbox = ConstInt(heaptracker.adr2int(func_adr))
+        calldescr = self.cpu.calldescrof_dynamic([ffi_type_uchar], ffi_type_sint)
+        res = self.execute_operation(rop.CALL,
+                                     [funcbox, BoxInt(ord('A'))],
+                                     'int',
+                                     descr=calldescr)
+        assert res.value == ord('a')
+
+
     def test_field_basic(self):
         t_box, T_box = self.alloc_instance(self.T)
         fielddescr = self.cpu.fielddescrof(self.S, 'value')



More information about the Pypy-commit mailing list