[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