[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