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

arigo at codespeak.net arigo at codespeak.net
Sat Sep 2 17:41:49 CEST 2006


Author: arigo
Date: Sat Sep  2 17:41:45 2006
New Revision: 31950

Modified:
   pypy/dist/pypy/annotation/policy.py
   pypy/dist/pypy/annotation/test/test_annrpython.py
   pypy/dist/pypy/rpython/annlowlevel.py
   pypy/dist/pypy/rpython/lltypesystem/lltype.py
   pypy/dist/pypy/rpython/lltypesystem/rlist.py
   pypy/dist/pypy/rpython/rlist.py
   pypy/dist/pypy/rpython/test/test_rlist.py
Log:
{arigo, pedronis}

* Allow lambdas in Sig.

* Started the concept of ADTInterface, which describes the signature of
  the ADT methods.  This is used to ensure that the ADT methods are
  always annotated with the most general annotation.

* In the middle of killing ListBuilder...



Modified: pypy/dist/pypy/annotation/policy.py
==============================================================================
--- pypy/dist/pypy/annotation/policy.py	(original)
+++ pypy/dist/pypy/annotation/policy.py	Sat Sep  2 17:41:45 2006
@@ -6,6 +6,7 @@
 # or we create a cycle.
 from pypy.annotation import model as annmodel
 from pypy.annotation.bookkeeper import getbookkeeper
+import types
 
 
 class BasicAnnotatorPolicy(object):
@@ -99,10 +100,23 @@
         self.argtypes = argtypes
         
     def __call__(self, funcdesc, inputcells):
+        from pypy.rpython.lltypesystem import lltype
         args_s = []
-        for argtype in self.argtypes:
+        for i, argtype in enumerate(self.argtypes):
+            if isinstance(argtype, (types.FunctionType, types.MethodType)):
+                argtype = argtype(*inputcells)
             if isinstance(argtype, annmodel.SomeObject):
                 args_s.append(argtype)
+            elif isinstance(argtype, lltype.LowLevelType):
+                if argtype is lltype.Void:
+                    # XXX the mapping between Void and annotation
+                    # is not quite well defined
+                    s_input = inputcells[i]
+                    assert isinstance(s_input, annmodel.SomePBC)
+                    assert s_input.is_constant()
+                    args_s.append(s_input)
+                else:
+                    args_s.append(annmodel.lltype_to_annotation(argtype))
             else:
                 args_s.append(funcdesc.bookkeeper.valueoftype(argtype))
         if len(inputcells) != len(args_s):

Modified: pypy/dist/pypy/annotation/test/test_annrpython.py
==============================================================================
--- pypy/dist/pypy/annotation/test/test_annrpython.py	(original)
+++ pypy/dist/pypy/annotation/test/test_annrpython.py	Sat Sep  2 17:41:45 2006
@@ -2320,6 +2320,20 @@
         assert not s.nonneg
         py.test.raises(Exception, a.build_types, fun, [int, int])
 
+    def test_sig_lambda(self):
+        def fun(x, y):
+            return y
+        s_nonneg = annmodel.SomeInteger(nonneg=True)
+        fun._annenforceargs_ = policy.Sig(lambda s1,s2: s1, lambda s1,s2: s1)
+        # means: the 2nd argument's annotation becomes the 1st argument's
+        #        input annotation
+
+        a = self.RPythonAnnotator()
+        s = a.build_types(fun, [int, s_nonneg])
+        assert isinstance(s, annmodel.SomeInteger)
+        assert not s.nonneg
+        py.test.raises(Exception, a.build_types, fun, [s_nonneg, int])
+
 def g(n):
     return [0,1,2,n]
 

Modified: pypy/dist/pypy/rpython/annlowlevel.py
==============================================================================
--- pypy/dist/pypy/rpython/annlowlevel.py	(original)
+++ pypy/dist/pypy/rpython/annlowlevel.py	Sat Sep  2 17:41:45 2006
@@ -5,7 +5,7 @@
 import types
 from pypy.tool.sourcetools import valid_identifier
 from pypy.annotation import model as annmodel
-from pypy.annotation.policy import AnnotatorPolicy
+from pypy.annotation.policy import AnnotatorPolicy, Sig
 from pypy.rpython.lltypesystem import lltype
 from pypy.rpython import extfunctable, extregistry
 from pypy.objspace.flow.model import Constant
@@ -330,5 +330,73 @@
     def specialize_call(self, hop):
         return hop.args_r[1].get_unique_llfn()
         
+# ____________________________________________________________
 
-    
+def placeholder_sigarg(s):
+    if s == "self":
+        def expand(s_self, *args_s):
+            assert isinstance(s_self, annmodel.SomePtr)
+            return s_self
+    elif s == "SELF":
+        raise NotImplementedError
+    else:
+        assert s.islower()
+        def expand(s_self, *args_s):
+            assert isinstance(s_self, annmodel.SomePtr)
+            return getattr(s_self.ll_ptrtype.TO, s.upper()) 
+    return expand
+
+def typemeth_placeholder_sigarg(s):
+    if s == "SELF":
+        def expand(s_TYPE, *args_s):
+            assert isinstance(s_TYPE, annmodel.SomePBC)
+            assert s_TYPE.is_constant()
+            return s_TYPE
+    elif s == "self":
+        def expand(s_TYPE, *args_s):
+            assert isinstance(s_TYPE, annmodel.SomePBC)
+            assert s_TYPE.is_constant()
+            return lltype.Ptr(s_TYPE.const)
+    else:
+        assert s.islower()
+        def expand(s_TYPE, *args_s):
+            assert isinstance(s_TYPE, annmodel.SomePBC)
+            assert s_TYPE.is_constant()
+            return getattr(s_TYPE.const, s.upper()) 
+    return expand
+
+            
+class ADTInterface(object):
+
+    def __init__(self, base, sigtemplates):
+        self.sigtemplates = sigtemplates
+        self.base = base
+        sigs = {}
+        if base is not None:
+            sigs.update(base.sigs)
+        for name, template in sigtemplates.items():
+            args, result = template
+            if args[0] == "self":
+                make_expand = placeholder_sigarg
+            elif args[0] == "SELF":
+                make_expand = typemeth_placeholder_sigarg
+            else:
+                assert False, ("ADTInterface signature should start with"
+                               " 'SELF' or 'self'")
+            sigargs = []
+            for arg in args:
+                if isinstance(arg, str):
+                    arg = make_expand(arg)
+                sigargs.append(arg)
+            sigs[name] = Sig(*sigargs)
+        self.sigs = sigs
+
+    def __call__(self, adtmeths):
+        for name, sig in self.sigs.items():
+            meth = adtmeths[name]
+            prevsig = getattr(meth, '_annenforceargs_', None)
+            if prevsig:
+                assert prevsig is sig
+            else:
+                meth._annenforceargs_ = sig
+        return adtmeths

Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lltype.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/lltype.py	Sat Sep  2 17:41:45 2006
@@ -693,6 +693,14 @@
     raise TypeError("don't know how to cast from %r to %r" % (ORIG, TGT))
 
 
+def erasedType(T):
+    while isinstance(T, Ptr) and isinstance(T.TO, Struct):
+        first, FIRSTTYPE = T.TO._first_struct()
+        if first is None:
+            break
+        T = Ptr(FIRSTTYPE)
+    return T
+
 class InvalidCast(TypeError):
     pass
 

Modified: pypy/dist/pypy/rpython/lltypesystem/rlist.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rlist.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/rlist.py	Sat Sep  2 17:41:45 2006
@@ -5,7 +5,7 @@
 from pypy.rpython.rmodel import externalvsinternal
 from pypy.rpython.rlist import AbstractBaseListRepr, AbstractListRepr, \
         AbstractFixedSizeListRepr, AbstractListIteratorRepr, rtype_newlist, \
-        rtype_alloc_and_set, ll_setitem_nonneg
+        rtype_alloc_and_set, ll_setitem_nonneg, ADTIList, ADTIFixedList
 from pypy.rpython.rlist import dum_nocheck, dum_checkidx
 from pypy.rpython.lltypesystem.rslice import SliceRepr
 from pypy.rpython.lltypesystem.rslice import startstop_slice_repr, startonly_slice_repr
@@ -49,10 +49,10 @@
         self.listitem = listitem
         self.list_cache = {}
         # setup() needs to be called to finish this initialization
-        self.list_builder = ListBuilder(self)
+##        self.list_builder = ListBuilder(self)
 
-    def _setup_repr_final(self):
-        self.list_builder.setup()
+##    def _setup_repr_final(self):
+##        self.list_builder.setup()
 
     def null_const(self):
         return nullptr(self.LIST)
@@ -81,85 +81,85 @@
                                            temp),
                               rstr.list_str_close_bracket))
 
-class ListBuilder(object):
-    """Interface to allow lazy list building by the JIT."""
+##class ListBuilder(object):
+##    """Interface to allow lazy list building by the JIT."""
 
-    def __init__(self, list_repr):
-        # This should not keep a reference to the RTyper, even indirectly via
-        # the list_repr.  So tmp_list_repr is replaced by None in setup().
-        self.tmp_list_repr = list_repr
-
-    def setup(self):
-        # Precompute the c_newitem and c_setitem_nonneg function pointers,
-        # needed below.
-        list_repr = self.tmp_list_repr
-        if list_repr is None:
-            return     # already set up
-        self.tmp_list_repr = None
-        if list_repr.rtyper is None:
-            return     # only for test_rlist, which doesn't need this anyway
+##    def __init__(self, list_repr):
+##        # This should not keep a reference to the RTyper, even indirectly via
+##        # the list_repr.  So tmp_list_repr is replaced by None in setup().
+##        self.tmp_list_repr = list_repr
+
+##    def setup(self):
+##        # Precompute the c_newitem and c_setitem_nonneg function pointers,
+##        # needed below.
+##        list_repr = self.tmp_list_repr
+##        if list_repr is None:
+##            return     # already set up
+##        self.tmp_list_repr = None
+##        if list_repr.rtyper is None:
+##            return     # only for test_rlist, which doesn't need this anyway
         
-        LIST = list_repr.LIST
-        LISTPTR = list_repr.lowleveltype
-        ITEM = list_repr.item_repr.lowleveltype
-        self.LIST = LIST
-        self.LISTPTR = LISTPTR
-
-        argtypes = [Signed]
-        newlist_ptr = list_repr.rtyper.annotate_helper_fn(LIST.ll_newlist,
-                                                          argtypes)
-
-        bk = list_repr.rtyper.annotator.bookkeeper
-        argtypes = [bk.immutablevalue(dum_nocheck), LISTPTR, Signed, ITEM]
-        setitem_nonneg_ptr = list_repr.rtyper.annotate_helper_fn(
-            ll_setitem_nonneg, argtypes)
-        #self.c_dum_nocheck = inputconst(Void, dum_nocheck)
-        #self.c_LIST = inputconst(Void, self.LIST)
-
-        def build_newlist(llops, length):
-            c_newlist = llops.genconst(newlist_ptr)
-            c_len     = llops.genconst(length)
-            c_LIST    = llops.genvoidconst(LIST)
-            return llops.genop('direct_call',
-                               [c_newlist, c_LIST, c_len],
-                               llops.constTYPE(LISTPTR))
-
-        def build_setitem(llops, v_list, index, v_item):
-            c_setitem_nonneg = llops.genconst(setitem_nonneg_ptr)
-            c_i = llops.genconst(index)
-            llops.genop('direct_call', [c_setitem_nonneg,
-                                        llops.genvoidconst(dum_nocheck),
-                                        v_list, c_i, v_item])
-
-        self.build_newlist = build_newlist
-        self.build_setitem = build_setitem
-
-    def build(self, llops, items_v):
-        """Make the operations that would build a list containing the
-        provided items."""
-        v_list = self.build_newlist(llops, len(items_v))
-        for i, v in enumerate(items_v):
-            self.build_setitem(llops, v_list, i, v)
-        return v_list
-
-    def getlistptr(self):
-        list_repr = self.tmp_list_repr
-        if list_repr is not None:
-            list_repr.setup()
-            return list_repr.lowleveltype
-        else:
-            return self.LISTPTR
-
-    def __eq__(self, other):
-        if not isinstance(other, ListBuilder):
-            return False
-        return self.getlistptr() == other.getlistptr()
+##        LIST = list_repr.LIST
+##        LISTPTR = list_repr.lowleveltype
+##        ITEM = list_repr.item_repr.lowleveltype
+##        self.LIST = LIST
+##        self.LISTPTR = LISTPTR
+
+##        argtypes = [Signed]
+##        newlist_ptr = list_repr.rtyper.annotate_helper_fn(LIST.ll_newlist,
+##                                                          argtypes)
+
+##        bk = list_repr.rtyper.annotator.bookkeeper
+##        argtypes = [bk.immutablevalue(dum_nocheck), LISTPTR, Signed, ITEM]
+##        setitem_nonneg_ptr = list_repr.rtyper.annotate_helper_fn(
+##            ll_setitem_nonneg, argtypes)
+##        #self.c_dum_nocheck = inputconst(Void, dum_nocheck)
+##        #self.c_LIST = inputconst(Void, self.LIST)
+
+##        def build_newlist(llops, length):
+##            c_newlist = llops.genconst(newlist_ptr)
+##            c_len     = llops.genconst(length)
+##            c_LIST    = llops.genvoidconst(LIST)
+##            return llops.genop('direct_call',
+##                               [c_newlist, c_LIST, c_len],
+##                               llops.constTYPE(LISTPTR))
+
+##        def build_setitem(llops, v_list, index, v_item):
+##            c_setitem_nonneg = llops.genconst(setitem_nonneg_ptr)
+##            c_i = llops.genconst(index)
+##            llops.genop('direct_call', [c_setitem_nonneg,
+##                                        llops.genvoidconst(dum_nocheck),
+##                                        v_list, c_i, v_item])
+
+##        self.build_newlist = build_newlist
+##        self.build_setitem = build_setitem
+
+##    def build(self, llops, items_v):
+##        """Make the operations that would build a list containing the
+##        provided items."""
+##        v_list = self.build_newlist(llops, len(items_v))
+##        for i, v in enumerate(items_v):
+##            self.build_setitem(llops, v_list, i, v)
+##        return v_list
+
+##    def getlistptr(self):
+##        list_repr = self.tmp_list_repr
+##        if list_repr is not None:
+##            list_repr.setup()
+##            return list_repr.lowleveltype
+##        else:
+##            return self.LISTPTR
+
+##    def __eq__(self, other):
+##        if not isinstance(other, ListBuilder):
+##            return False
+##        return self.getlistptr() == other.getlistptr()
 
-    def __ne__(self, other):
-        return not (self == other)
+##    def __ne__(self, other):
+##        return not (self == other)
 
-    def __hash__(self):
-        return 1 # bad but not used alone
+##    def __hash__(self):
+##        return 1 # bad but not used alone
 
 
 class __extend__(pairtype(BaseListRepr, BaseListRepr)):
@@ -183,18 +183,18 @@
             # XXX we might think of turning length stuff into Unsigned
             self.LIST.become(GcStruct("list", ("length", Signed),
                                               ("items", Ptr(ITEMARRAY)),
-                                      adtmeths = {
+                                      adtmeths = ADTIList({
                                           "ll_newlist": ll_newlist,
                                           "ll_length": ll_length,
                                           "ll_items": ll_items,
-                                          "list_builder": self.list_builder,
+                                          ##"list_builder": self.list_builder,
                                           "ITEM": ITEM,
                                           "ll_getitem_fast": ll_getitem_fast,
                                           "ll_setitem_fast": ll_setitem_fast,
                                           "_ll_resize_ge": _ll_list_resize_ge,
                                           "_ll_resize_le": _ll_list_resize_le,
                                           "_ll_resize": _ll_list_resize,
-                                      })
+                                      }))
                              )
 
     def compact_repr(self):
@@ -215,15 +215,15 @@
         if isinstance(self.LIST, GcForwardReference):
             ITEM = self.item_repr.lowleveltype
             ITEMARRAY = GcArray(ITEM,
-                                adtmeths = {
+                                adtmeths = ADTIFixedList({
                                      "ll_newlist": ll_fixed_newlist,
                                      "ll_length": ll_fixed_length,
                                      "ll_items": ll_fixed_items,
-                                     "list_builder": self.list_builder,
+                                     ##"list_builder": self.list_builder,
                                      "ITEM": ITEM,
                                      "ll_getitem_fast": ll_fixed_getitem_fast,
                                      "ll_setitem_fast": ll_fixed_setitem_fast,
-                                })
+                                }))
 
             self.LIST.become(ITEMARRAY)
 

Modified: pypy/dist/pypy/rpython/rlist.py
==============================================================================
--- pypy/dist/pypy/rpython/rlist.py	(original)
+++ pypy/dist/pypy/rpython/rlist.py	Sat Sep  2 17:41:45 2006
@@ -7,6 +7,20 @@
 from pypy.rpython.lltypesystem.lltype import nullptr, Char, UniChar
 from pypy.rpython import robject
 from pypy.rpython.objectmodel import malloc_zero_filled
+from pypy.rpython.annlowlevel import ADTInterface
+
+ADTIFixedList = ADTInterface(None, {
+    'll_newlist':      (['SELF', Signed        ], 'self'),
+    'll_length':       (['self'                ], Signed),
+    'll_getitem_fast': (['self', Signed        ], 'item'),
+    'll_setitem_fast': (['self', Signed, 'item'], Void),
+})
+ADTIList = ADTInterface(ADTIFixedList, {
+    '_ll_resize_ge':   (['self', Signed        ], Void),
+    '_ll_resize_le':   (['self', Signed        ], Void),
+    '_ll_resize':      (['self', Signed        ], Void),
+})
+
 
 def dum_checkidx(): pass
 def dum_nocheck(): pass

Modified: pypy/dist/pypy/rpython/test/test_rlist.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rlist.py	(original)
+++ pypy/dist/pypy/rpython/test/test_rlist.py	Sat Sep  2 17:41:45 2006
@@ -186,44 +186,44 @@
     def _freeze_(self):
         return True
 
-def test_list_builder():
-    def fixed_size_case():
-        return [42]
-    def variable_size_case():
-        lst = []
-        lst.append(42)
-        return lst
-
-    from pypy.rpython.rtyper import LowLevelOpList
-
-    for fn in [fixed_size_case, variable_size_case]:
-        t = TranslationContext()
-        t.buildannotator().build_types(fn, [])
-        t.buildrtyper().specialize()
-        LIST = t.graphs[0].getreturnvar().concretetype.TO
-        llop = LowLevelOpList(None)
-        v0 = Constant(42)
-        v0.concretetype = Signed
-        v1 = Variable()
-        v1.concretetype = Signed
-        vr = LIST.list_builder.build(llop, [v0, v1])
-        assert len(llop) == 3
-        assert llop[0].opname == 'direct_call'
-        assert len(llop[0].args) == 3
-        assert llop[0].args[1].concretetype == Void
-        assert llop[0].args[1].value == LIST
-        assert llop[0].args[2].concretetype == Signed
-        assert llop[0].args[2].value == 2
-        assert llop[0].result is vr
-        for op, i, vi in [(llop[1], 0, v0), (llop[2], 1, v1)]:
-            assert op.opname == 'direct_call'
-            assert len(op.args) == 5
-            assert op.args[1].value is dum_nocheck
-            assert op.args[2] is vr
-            assert op.args[3].concretetype == Signed
-            assert op.args[3].value == i
-            assert op.args[4] is vi
-            assert op.result.concretetype is Void
+##def test_list_builder():
+##    def fixed_size_case():
+##        return [42]
+##    def variable_size_case():
+##        lst = []
+##        lst.append(42)
+##        return lst
+
+##    from pypy.rpython.rtyper import LowLevelOpList
+
+##    for fn in [fixed_size_case, variable_size_case]:
+##        t = TranslationContext()
+##        t.buildannotator().build_types(fn, [])
+##        t.buildrtyper().specialize()
+##        LIST = t.graphs[0].getreturnvar().concretetype.TO
+##        llop = LowLevelOpList(None)
+##        v0 = Constant(42)
+##        v0.concretetype = Signed
+##        v1 = Variable()
+##        v1.concretetype = Signed
+##        vr = LIST.list_builder.build(llop, [v0, v1])
+##        assert len(llop) == 3
+##        assert llop[0].opname == 'direct_call'
+##        assert len(llop[0].args) == 3
+##        assert llop[0].args[1].concretetype == Void
+##        assert llop[0].args[1].value == LIST
+##        assert llop[0].args[2].concretetype == Signed
+##        assert llop[0].args[2].value == 2
+##        assert llop[0].result is vr
+##        for op, i, vi in [(llop[1], 0, v0), (llop[2], 1, v1)]:
+##            assert op.opname == 'direct_call'
+##            assert len(op.args) == 5
+##            assert op.args[1].value is dum_nocheck
+##            assert op.args[2] is vr
+##            assert op.args[3].concretetype == Signed
+##            assert op.args[3].value == i
+##            assert op.args[4] is vi
+##            assert op.result.concretetype is Void
 
 
 



More information about the Pypy-commit mailing list