[pypy-svn] r25540 - in pypy/dist/pypy/rpython: . lltypesystem memory test

cfbolz at codespeak.net cfbolz at codespeak.net
Sat Apr 8 13:56:16 CEST 2006


Author: cfbolz
Date: Sat Apr  8 13:56:15 2006
New Revision: 25540

Modified:
   pypy/dist/pypy/rpython/lltypesystem/lloperation.py
   pypy/dist/pypy/rpython/lltypesystem/rbuiltin.py
   pypy/dist/pypy/rpython/lltypesystem/rclass.py
   pypy/dist/pypy/rpython/memory/lladdress.py
   pypy/dist/pypy/rpython/normalizecalls.py
   pypy/dist/pypy/rpython/test/test_normalizecalls.py
Log:
(pedronis, cfbolz):

fix the minid, maxid computation so that the ComputedIntSymbolic subclasses
have proper comparisons defined.


Modified: pypy/dist/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lloperation.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/lloperation.py	Sat Apr  8 13:56:15 2006
@@ -78,6 +78,7 @@
 
     'direct_call':          LLOp(canraise=(Exception,)),
     'indirect_call':        LLOp(canraise=(Exception,)),
+    'safe_call':            LLOp(),
 
     # __________ numeric operations __________
 

Modified: pypy/dist/pypy/rpython/lltypesystem/rbuiltin.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rbuiltin.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/rbuiltin.py	Sat Apr  8 13:56:15 2006
@@ -32,7 +32,7 @@
     if isinstance(v_cls, Constant):
         cls = v_cls.value
         # XXX re-implement the following optimization
-        #if cls.subclassrange_max == cls.subclassrange_min + 1:
+        #if cls.subclassrange_max == cls.subclassrange_min:
         #    # a class with no subclass
         #    return hop.gendirectcall(rclass.ll_isinstance_exact, v_obj, v_cls)
         #else:

Modified: pypy/dist/pypy/rpython/lltypesystem/rclass.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rclass.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/rclass.py	Sat Apr  8 13:56:15 2006
@@ -267,7 +267,7 @@
         if isinstance(v_cls2, Constant):
             cls2 = v_cls2.value
             # XXX re-implement the following optimization
-##            if cls2.subclassrange_max == cls2.subclassrange_min + 1:
+##            if cls2.subclassrange_max == cls2.subclassrange_min:
 ##                # a class with no subclass
 ##                return hop.genop('ptr_eq', [v_cls1, v_cls2], resulttype=Bool)
 ##            else:
@@ -708,10 +708,10 @@
     return cast_pointer(OBJECTPTR, obj).typeptr
 
 def ll_issubclass(subcls, cls):
-    return cls.subclassrange_min <= subcls.subclassrange_min < cls.subclassrange_max
+    return cls.subclassrange_min <= subcls.subclassrange_min <= cls.subclassrange_max
 
 def ll_issubclass_const(subcls, minid, maxid):
-    return minid <= subcls.subclassrange_min < maxid
+    return minid <= subcls.subclassrange_min <= maxid
 
 
 def ll_isinstance(obj, cls): # obj should be cast to OBJECT or NONGCOBJECT

Modified: pypy/dist/pypy/rpython/memory/lladdress.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/lladdress.py	(original)
+++ pypy/dist/pypy/rpython/memory/lladdress.py	Sat Apr  8 13:56:15 2006
@@ -4,6 +4,7 @@
 from pypy.rpython.lltypesystem import llmemory
 from pypy.rpython.lltypesystem import lltype
 from pypy.rpython.memory.lltypelayout import convert_offset_to_int
+from pypy.rpython.objectmodel import ComputedIntSymbolic
 
 class address(object):
     #XXX should be _address!
@@ -50,10 +51,12 @@
         return simulator.getstruct(fmt, self.intaddress)
 
     def _store(self, fmt, *values):
-        # XXX annoyance: suddenly an OffsetOf changes into a Signed?!
+        # XXX annoyance: suddenly a Symbolic changes into a Signed?!
         from pypy.rpython.memory.lltypelayout import convert_offset_to_int
         if len(values) == 1 and isinstance(values[0], llmemory.AddressOffset):
             values = [convert_offset_to_int(values[0])]
+        elif len(values) == 1 and isinstance(values[0], ComputedIntSymbolic):
+            values = [values[0].compute_fn()]
         simulator.setstruct(fmt, self.intaddress, *values)
 
     def __nonzero__(self):

Modified: pypy/dist/pypy/rpython/normalizecalls.py
==============================================================================
--- pypy/dist/pypy/rpython/normalizecalls.py	(original)
+++ pypy/dist/pypy/rpython/normalizecalls.py	Sat Apr  8 13:56:15 2006
@@ -275,42 +275,117 @@
 # ____________________________________________________________
 
 class MinIdSymbolic(ComputedIntSymbolic):
-    def __init__(self, classdef):
+    def __init__(self, classdef, rootid):
         self.classdef = classdef
+        if classdef is None:
+            self.parent = None
+        elif classdef.basedef is None:
+            self.parent = rootid
+        else:
+            self.parent = classdef.basedef.minid
+        if self.parent:    
+            self.parent.children.append(self)
+        self.children = []
+        if rootid is None:
+            self.rootid = self
+        else:
+            self.rootid = rootid
+
     def compute_fn(self):
         if self.classdef.minid is self:
             compute_inheritance_ids(self.classdef.bookkeeper)
         return self.classdef.minid
 
+    def __eq__(self, other):
+        if isinstance(other, MinIdSymbolic):
+            return self is other
+        elif isinstance(other, MaxIdSymbolic):
+            return False
+        raise NotImplementedError
+
+    def __ne__(self, other):
+        return not (self == other)
+
+    def __le__(self, other):
+        if isinstance(other, MinIdSymbolic):
+            common_classdef = self.classdef.commonbase(other.classdef)
+            if common_classdef is None:
+                baseid = self.rootid
+            else:
+                baseid = common_classdef.minid
+            if baseid is self:
+                return True
+            if baseid is other:
+                return False
+            current_self = self
+            while current_self.parent is not baseid:
+                current_self = current_self.parent
+            current_other = other
+            while current_other.parent is not baseid:
+                current_other = current_other.parent
+            selfindex = baseid.children.index(current_self)
+            otherindex = baseid.children.index(current_other)
+            return selfindex <= otherindex
+        elif isinstance(other, MaxIdSymbolic):
+            rightmost = other.minid
+            while rightmost.children:
+                rightmost = rightmost.children[-1]
+            return self <= rightmost
+        raise NotImplementedError
+            
+    def compute_inheritance_ids(self, id_=0):
+        if self.classdef is not None:
+            self.classdef.minid = id_
+        maxid = id_
+        for child in self.children:
+            maxid = child.compute_inheritance_ids(maxid + 1)
+        if self.classdef is not None:
+            self.classdef.maxid = maxid
+        return maxid
+
 class MaxIdSymbolic(ComputedIntSymbolic):
-    def __init__(self, classdef):
-        self.classdef = classdef
+    def __init__(self, minid):
+        self.minid = minid
+
     def compute_fn(self):
-        if self.classdef.maxid is self:
-            compute_inheritance_ids(self.classdef.bookkeeper)
-        return self.classdef.maxid
+        if self.minid.classdef.minid is self.minid:
+            compute_inheritance_ids(self.minid.classdef.bookkeeper)
+        return self.minid.classdef.maxid
 
 def compute_inheritance_ids(bookkeeper):
-    def assign_id(classdef, nextid):
-        assert isinstance(classdef.minid, MinIdSymbolic)
-        assert isinstance(classdef.maxid, MaxIdSymbolic)
-        classdef.minid = nextid
-        nextid += 1
-        for subclass in classdef.subdefs:
-            nextid = assign_id(subclass, nextid)
-        classdef.maxid = nextid
-        return classdef.maxid
-    id_ = 0
-    for classdef in bookkeeper.classdefs:
-        if classdef.basedef is None:
-            id_ = assign_id(classdef, id_)
+    bookkeeper.annotator.rootid.compute_inheritance_ids()
+#    def assign_id(classdef, nextid):
+#        assert isinstance(classdef.minid, MinIdSymbolic)
+#        assert isinstance(classdef.maxid, MaxIdSymbolic)
+#        classdef.minid = nextid
+#        nextid += 1
+#        for subclass in classdef.subdefs:
+#            nextid = assign_id(subclass, nextid)
+#        classdef.maxid = nextid
+#        return classdef.maxid
+#    id_ = 0
+#    for classdef in bookkeeper.classdefs:
+#        if classdef.basedef is None:
+#            id_ = assign_id(classdef, id_)
+    
 
 def assign_inheritance_ids(annotator):
-    for classdef in annotator.bookkeeper.classdefs:
+    if hasattr(annotator, 'rootid'):
+        rootid = annotator.rootid
+    else:
+        rootid = MinIdSymbolic(None, None)
+        annotator.rootid = rootid
+    def assign_id(classdef):
         if not hasattr(classdef, 'minid'):
-            classdef.minid = MinIdSymbolic(classdef)
+            classdef.minid = MinIdSymbolic(classdef, rootid)
         if not hasattr(classdef, 'maxid'):
-            classdef.maxid = MaxIdSymbolic(classdef)
+            classdef.maxid = MaxIdSymbolic(classdef.minid)
+        for subclass in classdef.subdefs:
+            assign_id(subclass)
+    for classdef in annotator.bookkeeper.classdefs:
+        
+        if classdef.basedef is None:
+            assign_id(classdef)
 
 # ____________________________________________________________
 

Modified: pypy/dist/pypy/rpython/test/test_normalizecalls.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_normalizecalls.py	(original)
+++ pypy/dist/pypy/rpython/test/test_normalizecalls.py	Sat Apr  8 13:56:15 2006
@@ -164,7 +164,7 @@
 
 class TestNormalizeAfterTheFact(TestNormalize):
 
-    def rtype(self, fn, argtypes, resulttype):
+    def rtype(self, fn, argtypes, resulttype, checkfunction=None):
         t = TranslationContext()
         a = t.buildannotator()
         a.build_types(prefn, [int])
@@ -180,6 +180,10 @@
         graph = annhelper.getgraph(fn, [a.typeannotation(argtype) for argtype in argtypes],
                                    s_result)
         annhelper.finish()
+        t.checkgraphs()
+
+        if checkfunction is not None:
+            checkfunction(t)
 
         # sanity check prefn
         llinterp = LLInterpreter(typer)
@@ -187,8 +191,7 @@
         assert res == 100
         res = llinterp.eval_graph(graphof(t, prefn), [2])
         assert res == 201
-
-        t.checkgraphs()
+        
         return t
 
     def test_mix_after_recursion(self):
@@ -214,6 +217,8 @@
         annhelper.finish()
         
     def test_add_more_subclasses(self):
+        from pypy.rpython import rclass
+        from pypy.rpython.lltypesystem.rclass import ll_issubclass
         class Sub3(PBase):
             def newmethod(self):
                 return 3
@@ -221,7 +226,19 @@
             x = Sub3()
             return x.newmethod()
 
-        translator = self.rtype(dummyfn, [int], int)
+        def checkfunction(translator):
+            # make sure that there is a sensible comparison defined on the
+            # symbolics
+            bk = translator.annotator.bookkeeper
+            rtyper = translator.rtyper
+            base_classdef = bk.getuniqueclassdef(PBase)
+            base_vtable = rclass.getclassrepr(rtyper, base_classdef).getruntime()
+            sub3_classdef = bk.getuniqueclassdef(Sub3)
+            sub3_vtable = rclass.getclassrepr(rtyper, sub3_classdef).getruntime()
+            assert ll_issubclass(sub3_vtable, base_vtable)
+            assert not ll_issubclass(base_vtable, sub3_vtable)
+
+        translator = self.rtype(dummyfn, [int], int, checkfunction)
         base_graph    = graphof(translator, PBase.fn.im_func)
         sub1_graph    = graphof(translator, PSub1.fn.im_func)
         sub2_graph    = graphof(translator, PSub2.fn.im_func)
@@ -232,5 +249,4 @@
         assert sub2_graph.getreturnvar().concretetype == lltype.Signed
         assert sub3_graph.getreturnvar().concretetype == lltype.Signed
         assert dummyfn_graph.getreturnvar().concretetype == lltype.Signed
-
-        
+ 



More information about the Pypy-commit mailing list