[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