[pypy-svn] r49020 - in pypy/branch/remove-extcompiler-rctypes/pypy/translator/c: . test
cfbolz at codespeak.net
cfbolz at codespeak.net
Sat Nov 24 11:38:52 CET 2007
Author: cfbolz
Date: Sat Nov 24 11:38:49 2007
New Revision: 49020
Added:
pypy/branch/remove-extcompiler-rctypes/pypy/translator/c/test/test_wrapper.py (contents, props changed)
Modified:
pypy/branch/remove-extcompiler-rctypes/pypy/translator/c/wrapper.py
Log:
(pedronis, cfbolz): create a new wrapper generator that does not do all the
argument parsing of the old one.
Added: pypy/branch/remove-extcompiler-rctypes/pypy/translator/c/test/test_wrapper.py
==============================================================================
--- (empty file)
+++ pypy/branch/remove-extcompiler-rctypes/pypy/translator/c/test/test_wrapper.py Sat Nov 24 11:38:49 2007
@@ -0,0 +1,56 @@
+import py
+from pypy import conftest
+from pypy.translator.translator import TranslationContext
+from pypy.translator.c.wrapper import new_wrapper
+from pypy.rpython.rmodel import PyObjPtr
+from pypy.rpython.llinterp import LLInterpreter, LLException, log
+from pypy.rpython.lltypesystem import lltype
+
+
+class TestMakeWrapper:
+
+ def getgraph(self, func, argtypes=None):
+ from pypy.config.pypyoption import get_pypy_config
+ config = get_pypy_config(translating=True)
+ config.translation.gc = "ref"
+ config.translation.simplifying = True
+ t = TranslationContext(config=config)
+ if argtypes is None:
+ argtypes = []
+ a = t.buildannotator()
+ a.build_types(func, argtypes)
+ a.simplify()
+ t.buildrtyper().specialize()
+ wrapperptr = new_wrapper(func, t)
+ wrappergraph = wrapperptr._obj.graph
+ for inputarg in wrappergraph.startblock.inputargs:
+ assert inputarg.concretetype == PyObjPtr
+ assert wrappergraph.getreturnvar().concretetype == PyObjPtr
+ return t.graphs[0], wrappergraph, t
+
+ def interpret(self, t, graph, *args):
+ interp = LLInterpreter(t.rtyper)
+ result = interp.eval_graph(graph, [lltype.pyobjectptr(arg)
+ for arg in args])
+ return result._obj.value
+
+ def test_simple(self):
+ def f(x):
+ return x * 3
+ graph, wrappergraph, t = self.getgraph(f, [int])
+ res = self.interpret(t, wrappergraph, 3)
+ assert res == 9
+
+ def test_manyargs(self):
+ def f(x, y, z):
+ return x * y + z
+ graph, wrappergraph, t = self.getgraph(f, [int, int, int])
+ res = self.interpret(t, wrappergraph, 3, 4, 5)
+ assert res == 3 * 4 + 5
+
+ def test_returnnone(self):
+ def f():
+ pass
+ graph, wrappergraph, t = self.getgraph(f)
+ res = self.interpret(t, wrappergraph)
+ assert res is None
Modified: pypy/branch/remove-extcompiler-rctypes/pypy/translator/c/wrapper.py
==============================================================================
--- pypy/branch/remove-extcompiler-rctypes/pypy/translator/c/wrapper.py (original)
+++ pypy/branch/remove-extcompiler-rctypes/pypy/translator/c/wrapper.py Sat Nov 24 11:38:49 2007
@@ -195,3 +195,74 @@
if ALWAYS_INLINE:
simple_inline_function(translator, graph, newgraph)
return newgraph
+
+
+
+def new_wrapper(func, translator, newname=None):
+ # The basic idea is to produce a flow graph from scratch, using the
+ # help of the rtyper for the conversion of the arguments after they
+ # have been decoded.
+
+ bk = translator.annotator.bookkeeper
+ graph = bk.getdesc(func).getuniquegraph()
+
+ f = getfunctionptr(graph)
+ FUNCTYPE = typeOf(f).TO
+
+ newops = LowLevelOpList(translator.rtyper)
+
+ varguments = []
+ for var in graph.startblock.inputargs:
+ v = Variable(var)
+ v.concretetype = PyObjPtr
+ varguments.append(v)
+
+ wrapper_inputargs = varguments[:]
+ # use the rtyper to produce the conversions
+ inputargs = f._obj.graph.getargs()
+ for i in range(len(varguments)):
+ if FUNCTYPE.ARGS[i] != PyObjPtr:
+ rtyper = translator.rtyper
+ r_arg = rtyper.bindingrepr(inputargs[i])
+ # give the rtyper a chance to know which function we are wrapping
+ rtyper.set_wrapper_context(func)
+ varguments[i] = newops.convertvar(varguments[i],
+ r_from = pyobj_repr,
+ r_to = r_arg)
+ rtyper.set_wrapper_context(None)
+
+ vlist = [inputconst(typeOf(f), f)] + varguments
+ vresult = newops.genop('direct_call', vlist, resulttype=FUNCTYPE.RESULT)
+
+ if FUNCTYPE.RESULT != PyObjPtr:
+ # convert "result" back to a PyObject
+ rtyper = translator.rtyper
+ assert rtyper is not None, (
+ "needs the rtyper to perform function result conversions")
+ r_result = rtyper.bindingrepr(f._obj.graph.getreturnvar())
+ vresult = newops.convertvar(vresult,
+ r_from = r_result,
+ r_to = pyobj_repr)
+
+ # "return result"
+ block = Block(wrapper_inputargs)
+ wgraph = FunctionGraph('pyfn_' + (newname or func.func_name), block)
+ translator.update_call_graph(wgraph, graph, object())
+ translator.graphs.append(wgraph)
+ block.operations[:] = newops
+ block.closeblock(Link([vresult], wgraph.returnblock))
+ wgraph.getreturnvar().concretetype = PyObjPtr
+ checkgraph(wgraph)
+
+ # the above convertvar()s may have created and annotated new helpers
+ # that need to be specialized now
+ translator.rtyper.specialize_more_blocks()
+
+ return functionptr(FuncType([PyObjPtr,
+ PyObjPtr,
+ PyObjPtr],
+ PyObjPtr),
+ wgraph.name,
+ graph = wgraph,
+ exception_policy = "CPython")
+
More information about the Pypy-commit
mailing list