[pypy-svn] r7445 - in pypy/trunk/src/pypy/translator: . test

arigo at codespeak.net arigo at codespeak.net
Fri Nov 19 15:48:55 CET 2004


Author: arigo
Date: Fri Nov 19 15:48:55 2004
New Revision: 7445

Modified:
   pypy/trunk/src/pypy/translator/genc.py
   pypy/trunk/src/pypy/translator/test/snippet.py
   pypy/trunk/src/pypy/translator/test/test_ctrans.py
Log:
Support def(*args) in the generated C functions.
Added a test for it.



Modified: pypy/trunk/src/pypy/translator/genc.py
==============================================================================
--- pypy/trunk/src/pypy/translator/genc.py	(original)
+++ pypy/trunk/src/pypy/translator/genc.py	Fri Nov 19 15:48:55 2004
@@ -8,6 +8,7 @@
 from pypy.objspace.flow.model import FunctionGraph, Block, Link, last_exception
 from pypy.objspace.flow.model import traverse, uniqueitems, checkgraph
 from pypy.translator.simplify import remove_direct_loops
+from pypy.interpreter.pycode import CO_VARARGS
 from types import FunctionType
 
 from pypy.objspace.std.restricted_int import r_int, r_uint
@@ -395,14 +396,45 @@
         print >> f
 
         # argument unpacking
-        lst = ['args',
-               '"%s"' % func.__name__,
-               '%d' % len(graph.getargs()),
-               '%d' % len(graph.getargs()),
-               ]
-        lst += ['&' + a.name for a in graph.getargs()]
-        print >> f, '\tif (!PyArg_UnpackTuple(%s))' % ', '.join(lst)
-        print >> f, '\t\treturn NULL;'
+        if func.func_code.co_flags & CO_VARARGS:
+            vararg = graph.getargs()[-1]
+            positional_args = graph.getargs()[:-1]
+            print >> f, '\t%s = PyTuple_GetSlice(args, %d, INT_MAX);' % (
+                vararg, len(positional_args))
+            print >> f, '\tif (%s == NULL)' % vararg
+            print >> f, '\t\treturn NULL;'
+            print >> f, '\targs = PyTuple_GetSlice(args, 0, %d);' % (
+                len(positional_args),)
+            print >> f, '\tif (args == NULL) {'
+            print >> f, '\t\tPy_DECREF(%s);' % vararg
+            print >> f, '\t\treturn NULL;'
+            print >> f, '\t}'
+            lst = ['args',
+                   '"%s"' % func.__name__,
+                   '%d' % len(positional_args),
+                   '%d' % len(positional_args),
+                   ]
+            lst += ['&' + a.name for a in positional_args]
+            print >> f, '\tif (!PyArg_UnpackTuple(%s)) {' % ', '.join(lst)
+            print >> f, '\t\tPy_DECREF(args);'
+            print >> f, '\t\tPy_DECREF(%s);' % vararg
+            print >> f, '\t\treturn NULL;'
+            print >> f, '\t}'
+            print >> f, '\tPy_DECREF(args);'
+        else:
+            positional_args = graph.getargs()
+            lst = ['args',
+                   '"%s"' % func.__name__,
+                   '%d' % len(positional_args),
+                   '%d' % len(positional_args),
+                   ]
+            lst += ['&' + a.name for a in positional_args]
+            print >> f, '\tif (!PyArg_UnpackTuple(%s))' % ', '.join(lst)
+            print >> f, '\t\treturn NULL;'
+
+        # generate an incref for each input argument
+        for v in positional_args:
+            print >> f, '\tPy_INCREF(%s);' % v.name
 
         # print the body
         for line in body:
@@ -463,10 +495,6 @@
                 blocknum[block] = len(blocknum)
         traverse(visit, graph)
 
-        # generate an incref for each input argument
-        for v in graph.getargs():
-            yield 'Py_INCREF(%s);' % v.name
-
         # generate the body of each block
         for block in allblocks:
             yield ''

Modified: pypy/trunk/src/pypy/translator/test/snippet.py
==============================================================================
--- pypy/trunk/src/pypy/translator/test/snippet.py	(original)
+++ pypy/trunk/src/pypy/translator/test/snippet.py	Fri Nov 19 15:48:55 2004
@@ -474,6 +474,12 @@
         else:
             return (None, None)
 
+def star_args(x, y, *args):
+    return x + args[0]
+
+def call_star_args(z):
+    return star_args(z, 5, 10, 15, 20)
+
 def powerset(setsize=int):
     """Powerset
 

Modified: pypy/trunk/src/pypy/translator/test/test_ctrans.py
==============================================================================
--- pypy/trunk/src/pypy/translator/test/test_ctrans.py	(original)
+++ pypy/trunk/src/pypy/translator/test/test_ctrans.py	Fri Nov 19 15:48:55 2004
@@ -126,6 +126,10 @@
         multiple_inheritance = self.build_cfunc(snippet.multiple_inheritance)
         self.assertEquals(multiple_inheritance(), 1+2+3+4)
 
+    def test_call_star_args(self):
+        call_star_args = self.build_cfunc(snippet.call_star_args)
+        self.assertEquals(call_star_args(42), 52)
+
 class TypedTestCase(testit.IntTestCase):
 
     def getcompiled(self, func):



More information about the Pypy-commit mailing list