[pypy-svn] r46755 - in pypy/dist/pypy: annotation rpython rpython/test

arigo at codespeak.net arigo at codespeak.net
Thu Sep 20 12:22:06 CEST 2007


Author: arigo
Date: Thu Sep 20 12:22:04 2007
New Revision: 46755

Modified:
   pypy/dist/pypy/annotation/specialize.py
   pypy/dist/pypy/rpython/annlowlevel.py
   pypy/dist/pypy/rpython/test/test_llann.py
Log:
Allow *args in low-level helpers, by making it compatible with
specialize:ll.  Based on a small refactoring which should allow other
specializations to be easily combined with *args.  I think I ran the
relevant tests but I'll take the blame if not.



Modified: pypy/dist/pypy/annotation/specialize.py
==============================================================================
--- pypy/dist/pypy/annotation/specialize.py	(original)
+++ pypy/dist/pypy/annotation/specialize.py	Thu Sep 20 12:22:04 2007
@@ -8,7 +8,7 @@
 from pypy.objspace.flow.model import Constant, checkgraph
 from pypy.annotation import model as annmodel
 
-def default_specialize(funcdesc, args_s):
+def flatten_star_args(funcdesc, args_s):
     argnames, vararg, kwarg = funcdesc.signature
     assert not kwarg, "functions with ** arguments are not supported"
     if vararg:
@@ -49,26 +49,29 @@
             checkgraph(graph)
             return graph
 
-        key, name_suffix = access_direct_key(nb_extra_args, flattened_s)
-        return funcdesc.cachedgraph(key,
-                                    alt_name='%s_star%d%s' % (funcdesc.name,
-                                                              nb_extra_args,
-                                                              name_suffix),
-                                    builder=builder)
+        key = nb_extra_args
+        name_suffix = '_star%d' % (nb_extra_args,)
+        return flattened_s, key, name_suffix, builder
+
     else:
-        key, name_suffix = access_direct_key(None, args_s)
-        if name_suffix:
-            alt_name = '%s%s' % (funcdesc.name, name_suffix)
-        else:
-            alt_name = None
-        return funcdesc.cachedgraph(key, alt_name=alt_name)
+        return args_s, None, '', None
 
-def access_direct_key(key, args_s):
+def default_specialize(funcdesc, args_s):
+    # first flatten the *args
+    args_s, key, name_suffix, builder = flatten_star_args(funcdesc, args_s)
+    # two versions: a regular one and one for instances with 'access_directly'
     for s_obj in args_s:
         if (isinstance(s_obj, annmodel.SomeInstance) and
             'access_directly' in s_obj.flags):
-            return (AccessDirect, key), '_AccessDirect'
-    return key, ''
+            key = (AccessDirect, key)
+            name_suffix += '_AccessDirect'
+            break
+    # done
+    if name_suffix:
+        alt_name = '%s%s' % (funcdesc.name, name_suffix)
+    else:
+        alt_name = None
+    return funcdesc.cachedgraph(key, alt_name=alt_name, builder=builder)
 
 class AccessDirect(object):
     """marker for specialization: set when any arguments is a SomeInstance

Modified: pypy/dist/pypy/rpython/annlowlevel.py
==============================================================================
--- pypy/dist/pypy/rpython/annlowlevel.py	(original)
+++ pypy/dist/pypy/rpython/annlowlevel.py	Thu Sep 20 12:22:04 2007
@@ -6,6 +6,7 @@
 from pypy.tool.sourcetools import valid_identifier
 from pypy.annotation import model as annmodel
 from pypy.annotation.policy import AnnotatorPolicy, Sig
+from pypy.annotation.specialize import flatten_star_args
 from pypy.rpython.lltypesystem import lltype
 from pypy.rpython import extfunctable, extregistry
 from pypy.objspace.flow.model import Constant
@@ -39,7 +40,8 @@
         pol.rtyper = rtyper
 
     def lowlevelspecialize(funcdesc, args_s, key_for_args):
-        key = []
+        args_s, key, ignored, builder = flatten_star_args(funcdesc, args_s)
+        key = [key]
         new_args_s = []
         for i, s_obj in enumerate(args_s):
             if i in key_for_args:
@@ -57,7 +59,7 @@
                     # passing non-low-level types to a ll_* function is allowed
                     # for module/ll_*
                     key.append(s_obj.__class__)
-        flowgraph = funcdesc.cachedgraph(tuple(key))
+        flowgraph = funcdesc.cachedgraph(tuple(key), builder=builder)
         args_s[:] = new_args_s
         return flowgraph
     lowlevelspecialize = staticmethod(lowlevelspecialize)

Modified: pypy/dist/pypy/rpython/test/test_llann.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_llann.py	(original)
+++ pypy/dist/pypy/rpython/test/test_llann.py	Thu Sep 20 12:22:04 2007
@@ -10,6 +10,7 @@
 from pypy.rpython.llinterp import LLInterpreter
 from pypy.rpython.test.test_llinterp import interpret
 from pypy.objspace.flow import FlowObjSpace 
+from pypy.conftest import option
 
 # helpers
 
@@ -34,6 +35,8 @@
     def annotate(self, ll_function, argtypes):
         self.a = self.RPythonAnnotator()
         graph = annotate_lowlevel_helper(self.a, ll_function, argtypes)
+        if option.view:
+            self.a.translator.view()
         return self.a.binding(graph.getreturnvar())
 
     def test_simple(self):
@@ -286,6 +289,38 @@
 
         return a, vTs # reused by a test in test_rtyper
 
+    def test_ll_stararg(self):
+        A = GcArray(Float)
+        B = GcArray(Signed)
+        def ll_sum(*args):
+            result = 0
+            if len(args) > 0:
+                result += args[0]
+            if len(args) > 1:
+                result += args[1]
+            if len(args) > 2:
+                result += args[2]
+            if len(args) > 3:
+                result += args[3]
+            return result
+        def llf():
+            a = ll_sum()
+            b = ll_sum(4, 5)
+            c = ll_sum(2.5)
+            d = ll_sum(4, 5.25)
+            e = ll_sum(1000, 200, 30, 4)
+            f = ll_sum(1000, 200, 30, 5)
+            return a, b, c, d, e, f
+        s = self.annotate(llf, [])
+        assert isinstance(s, annmodel.SomeTuple)
+        assert s.items[0].knowntype is int
+        assert s.items[0].const == 0
+        assert s.items[1].knowntype is int
+        assert s.items[2].knowntype is float
+        assert s.items[3].knowntype is float
+        assert s.items[4].knowntype is int
+        assert s.items[5].knowntype is int
+
     def test_getRuntimeTypeInfo(self):
         S = GcStruct('s', ('x', Signed))
         attachRuntimeTypeInfo(S)



More information about the Pypy-commit mailing list