[pypy-svn] r13200 - in pypy/dist/pypy: objspace/flow rpython rpython/test translator/c

arigo at codespeak.net arigo at codespeak.net
Wed Jun 8 22:18:40 CEST 2005


Author: arigo
Date: Wed Jun  8 22:18:36 2005
New Revision: 13200

Modified:
   pypy/dist/pypy/objspace/flow/model.py
   pypy/dist/pypy/rpython/rclass.py
   pypy/dist/pypy/rpython/rtyper.py
   pypy/dist/pypy/rpython/test/test_rpbc.py
   pypy/dist/pypy/translator/c/funcgen.py
Log:
Conversions between an instance of a class and an instance of a subclass and
back.  test_virutal_methods() passes.

Simplification of the varmapping mess, which was provoking strange errors. The
problem is that two variables may have different SomeXxx annotations but the
same low-level type; in this case we cannot really rename one into the other,
because it confuses the rtyper -- which might find the wrong annotation and
representation for the variable.  (It also confuses people staring at flow
graphs quite a lot.)



Modified: pypy/dist/pypy/objspace/flow/model.py
==============================================================================
--- pypy/dist/pypy/objspace/flow/model.py	(original)
+++ pypy/dist/pypy/objspace/flow/model.py	Wed Jun  8 22:18:36 2005
@@ -171,6 +171,7 @@
         for op in self.operations:
             op.args = [mapping.get(a, a) for a in op.args]
             op.result = mapping.get(op.result, op.result)
+        self.exitswitch = mapping.get(self.exitswitch, self.exitswitch)
         for link in self.exits:
             link.args = [mapping.get(a, a) for a in link.args]
 

Modified: pypy/dist/pypy/rpython/rclass.py
==============================================================================
--- pypy/dist/pypy/rpython/rclass.py	(original)
+++ pypy/dist/pypy/rpython/rclass.py	Wed Jun  8 22:18:36 2005
@@ -411,6 +411,35 @@
         self.setfield(vinst, attr, vvalue, hop.llops)
 
 
+class __extend__(pairtype(InstanceRepr, InstanceRepr)):
+    def convert_from_to((r_ins1, r_ins2), v, llops):
+        # which is a subclass of which?
+        if r_ins1.classdef is None or r_ins2.classdef is None:
+            return NotImplemented
+        basedef = r_ins1.classdef.commonbase(r_ins2.classdef)
+        if basedef == r_ins2.classdef:
+            # r_ins1 is an instance of the subclass: converting to parent
+            while r_ins1 != r_ins2:
+                v = r_ins1.parentpart(v, llops)
+                r_ins1 = r_ins1.rbase
+            return v
+        elif basedef == r_ins1.classdef:
+            # r_ins2 is an instance of the subclass: potentially unsafe
+            # casting, but we do it anyway (e.g. the annotator produces
+            # such casts after a successful isinstance() check)
+            cast_chain = []
+            while r_ins2 != r_ins1:
+                cast_chain.append(r_ins2)
+                r_ins2 = r_ins2.rbase
+            cast_chain.reverse()
+            for r in cast_chain:
+                ctype = inputconst(Void, r.lowleveltype)
+                v = llops.genop('cast_parent', [ctype, v],
+                                resulttype = r.lowleveltype)
+            return v
+        else:
+            return NotImplemented
+
 # ____________________________________________________________
 
 def rtype_new_instance(cls, hop):

Modified: pypy/dist/pypy/rpython/rtyper.py
==============================================================================
--- pypy/dist/pypy/rpython/rtyper.py	(original)
+++ pypy/dist/pypy/rpython/rtyper.py	Wed Jun  8 22:18:36 2005
@@ -119,6 +119,9 @@
             return
         newops = LowLevelOpList(self)
         varmapping = {}
+        for v in block.getvariables():
+            varmapping[v] = v    # records existing Variables
+
         for op in block.operations:
             try:
                 hop = HighLevelOp(self, op, newops)
@@ -128,15 +131,6 @@
                 return  # cannot continue this block: no op.result.concretetype
 
         block.operations[:] = newops
-        # multiple renamings (v1->v2->v3->...) are possible
-        while True:
-            done = True
-            for v1, v2 in varmapping.items():
-                if v2 in varmapping:
-                    varmapping[v1] = varmapping[v2]
-                    done = False
-            if done:
-                break
         block.renamevariables(varmapping)
         self.insert_link_conversions(block)
 
@@ -202,9 +196,15 @@
                                  "but rtype* says %r" % (
                     op.opname, hop.s_result,
                     op.result.concretetype, resulttype))
-            while resultvar in varmapping:
-                resultvar = varmapping[resultvar]
-            varmapping[resultvar] = op.result
+            # figure out if the resultvar is a completely fresh Variable or not
+            if (resultvar not in self.annotator.bindings and
+                resultvar not in varmapping):
+                # fresh Variable: rename it to the previously existing op.result
+                varmapping[resultvar] = op.result
+            else:
+                # renaming unsafe.  Insert a 'same_as' operation...
+                hop.llops.append(SpaceOperation('same_as', [resultvar],
+                                                op.result))
         else:
             # translate_meth() returned a Constant
             assert isinstance(resultvar, Constant)

Modified: pypy/dist/pypy/rpython/test/test_rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rpbc.py	(original)
+++ pypy/dist/pypy/rpython/test/test_rpbc.py	Wed Jun  8 22:18:36 2005
@@ -48,7 +48,7 @@
         return obj.m(b)
     rtype(f, [int, int])
 
-def PROGRESSING_ON_test_virtual_method_call():
+def test_virtual_method_call():
     def f(a, b):
         if a > 0:
             obj = MyBase()
@@ -56,4 +56,4 @@
             obj = MySubclass()
         obj.z = a
         return obj.m(b)
-    rtype(f, [int, int]).view()
+    rtype(f, [int, int])

Modified: pypy/dist/pypy/translator/c/funcgen.py
==============================================================================
--- pypy/dist/pypy/translator/c/funcgen.py	(original)
+++ pypy/dist/pypy/translator/c/funcgen.py	Wed Jun  8 22:18:36 2005
@@ -389,6 +389,14 @@
                   ]
         return '\t'.join(result)
 
+    def OP_SAME_AS(self, op, err):
+        result = ['%s = %s;' % (self.expr(op.result),
+                                self.expr(op.args[0]))]
+        line = self.cincref(op.result)
+        if line:
+            result.append(line)
+        return '\t'.join(result)
+
     def cincref(self, v):
         T = self.lltypemap[v]
         return self.db.cincrefstmt(v.name, T)



More information about the Pypy-commit mailing list