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

arigo at codespeak.net arigo at codespeak.net
Thu Dec 15 13:41:30 CET 2005


Author: arigo
Date: Thu Dec 15 13:41:29 2005
New Revision: 21171

Modified:
   pypy/dist/pypy/rpython/lltypesystem/rpbc.py
   pypy/dist/pypy/rpython/rpbc.py
   pypy/dist/pypy/rpython/test/test_rpbc.py
Log:
More precise function and method calls, to fix the following (now-tested) buggy
case: at the end of annotation, consider_call_site() fills a call table using
the SomePBCs of each call site; later, the RTyper used to try to perform
lookups in this call table by using a less precise SomePBC (the whole call
family).  This lookup can thus fail.


Modified: pypy/dist/pypy/rpython/lltypesystem/rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rpbc.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/rpbc.py	Thu Dec 15 13:41:29 2005
@@ -206,7 +206,10 @@
         mangled_name, r_func = r_class.clsfields[self.methodname]
         assert isinstance(r_func, (FunctionsPBCRepr,
                                    OverriddenFunctionPBCRepr))
-        s_func = r_func.s_pbc
+        # s_func = r_func.s_pbc -- not precise enough, see
+        # test_precise_method_call_1.  Build a more precise one...
+        funcdescs = [desc.funcdesc for desc in hop.args_s[0].descriptions]
+        s_func = annmodel.SomePBC(funcdescs)
         v_im_self = hop.inputarg(self, arg=0)
         v_cls = self.r_im_self.getfield(v_im_self, '__class__', hop.llops)
         v_func = r_class.getclsfield(v_cls, self.methodname, hop.llops)

Modified: pypy/dist/pypy/rpython/rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/rpbc.py	(original)
+++ pypy/dist/pypy/rpython/rpbc.py	Thu Dec 15 13:41:29 2005
@@ -301,7 +301,8 @@
     def call(self, opname, hop):
         bk = self.rtyper.annotator.bookkeeper
         args = bk.build_args(opname, hop.args_s[1:])
-        descs = self.s_pbc.descriptions.keys()
+        s_pbc = hop.args_s[0]   # possibly more precise than self.s_pbc
+        descs = s_pbc.descriptions.keys()
         shape, index = description.FunctionDesc.variant_for_call_site(bk, self.callfamily, descs, args)
         row_of_graphs = self.callfamily.calltables[shape][index]
         anygraph = row_of_graphs.itervalues().next()  # pick any witness

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	Thu Dec 15 13:41:29 2005
@@ -1258,3 +1258,54 @@
     for i in range(5):
         res = interpret(f, [i, 1000])
         assert res == f(i, 1000)
+
+def test_precise_method_call_1():
+    class A(object):
+        def meth(self, x=5):
+            return x+1
+    class B(A):
+        def meth(self, x=5):
+            return x+2
+    class C(A):
+        pass
+    def f(i, n):
+        # call both A.meth and B.meth with an explicit argument
+        if i > 0:
+            x = A()
+        else:
+            x = B()
+        result1 = x.meth(n)
+        # now call A.meth only, using the default argument
+        result2 = C().meth()
+        return result1 * result2
+    for i in [0, 1]:
+        res = interpret(f, [i, 1234])
+        assert res == f(i, 1234)
+
+def test_precise_method_call_2():
+    class A(object):
+        def meth(self, x=5):
+            return x+1
+    class B(A):
+        def meth(self, x=5):
+            return x+2
+    class C(A):
+        def meth(self, x=5):
+            return x+3
+    def f(i, n):
+        # call both A.meth and B.meth with an explicit argument
+        if i > 0:
+            x = A()
+        else:
+            x = B()
+        result1 = x.meth(n)
+        # now call A.meth and C.meth, using the default argument
+        if i > 0:
+            x = C()
+        else:
+            x = A()
+        result2 = x.meth()
+        return result1 * result2
+    for i in [0, 1]:
+        res = interpret(f, [i, 1234])
+        assert res == f(i, 1234)



More information about the Pypy-commit mailing list