[pypy-svn] r20247 - in pypy/branch/somepbc-refactoring/pypy: annotation rpython/test tool translator/test
arigo at codespeak.net
arigo at codespeak.net
Fri Nov 25 18:21:03 CET 2005
Author: arigo
Date: Fri Nov 25 18:21:01 2005
New Revision: 20247
Modified:
pypy/branch/somepbc-refactoring/pypy/annotation/policy.py
pypy/branch/somepbc-refactoring/pypy/annotation/specialize.py
pypy/branch/somepbc-refactoring/pypy/rpython/test/test_rpbc.py
pypy/branch/somepbc-refactoring/pypy/tool/cache.py
pypy/branch/somepbc-refactoring/pypy/translator/test/test_annrpython.py
Log:
(mwh, arigo, pedronis)
RTemoved support for memo functions with two pbcs args, it did
not solve the case we are interested in: Cache.getorbuild.
Introduced instead a new specialisation methodmemo, it does
memoisation wrt both of the 2 supported and expected
arguments and specialises wrt the type of the first argument.
test_call_memoized_cache passes now.
Modified: pypy/branch/somepbc-refactoring/pypy/annotation/policy.py
==============================================================================
--- pypy/branch/somepbc-refactoring/pypy/annotation/policy.py (original)
+++ pypy/branch/somepbc-refactoring/pypy/annotation/policy.py Fri Nov 25 18:21:01 2005
@@ -1,6 +1,7 @@
# base annotation policy for overrides and specialization
-from pypy.annotation.specialize import memo, default_specialize as default
+from pypy.annotation.specialize import default_specialize as default
from pypy.annotation.specialize import argtype, argvalue
+from pypy.annotation.specialize import memo, methodmemo
# for some reason, model must be imported first,
# or we create a cycle.
from pypy.annotation import model as annmodel
@@ -50,6 +51,7 @@
default_specialize = staticmethod(default)
specialize__memo = staticmethod(memo)
+ specialize__methodmemo = staticmethod(methodmemo)
specialize__arg0 = staticmethod(argvalue(0))
specialize__argtype0 = staticmethod(argtype(0))
specialize__arg1 = staticmethod(argvalue(1))
Modified: pypy/branch/somepbc-refactoring/pypy/annotation/specialize.py
==============================================================================
--- pypy/branch/somepbc-refactoring/pypy/annotation/specialize.py (original)
+++ pypy/branch/somepbc-refactoring/pypy/annotation/specialize.py Fri Nov 25 18:21:01 2005
@@ -64,15 +64,10 @@
return s # we will probably get more possible args later
raise Exception("memo call: argument must be a class or a frozen "
"PBC, got %r" % (s,))
- if len(arglist_s) == 1:
- return memo_one_argument(funcdesc, *arglist_s)
- elif len(arglist_s) == 2:
- return memo_two_arguments(funcdesc, *arglist_s)
- else:
- raise Exception("memo call: only 1 or 2 arguments functions supported"
+ if len(arglist_s) != 1:
+ raise Exception("memo call: only 1 argument functions supported"
" at the moment (%r)" % (funcdesc,))
-
-def memo_one_argument(funcdesc, s):
+ s, = arglist_s
from pypy.annotation.model import SomeImpossibleValue
func = funcdesc.pyobj
if func is None:
@@ -98,22 +93,39 @@
return funcdesc.cachedgraph('memo1', alt_name='memo_%s' % funcdesc.name,
builder=builder)
-def memo_two_arguments(funcdesc, s1, s2):
+def methodmemo(funcdesc, arglist_s):
+ """NOT_RPYTHON"""
+ from pypy.annotation.model import SomePBC, SomeImpossibleValue
+ # call the function now, and collect possible results
+ for s in arglist_s:
+ if not isinstance(s, SomePBC):
+ if isinstance(s, SomeImpossibleValue):
+ return s # we will probably get more possible args later
+ raise Exception("method-memo call: argument must be a class or"
+ " a frozen PBC, got %r" % (s,))
+ if len(arglist_s) != 2:
+ raise Exception("method-memo call: expected 2 arguments function"
+ " at the moment (%r)" % (funcdesc,))
from pypy.annotation.model import SomeImpossibleValue
from pypy.annotation.description import FrozenDesc
func = funcdesc.pyobj
if func is None:
- raise Exception("memo call: no Python function object to call (%r)" %
- (funcdesc,))
+ raise Exception("method-memo call: no Python function object to call"
+ " (%r)" % (funcdesc,))
# compute the concrete results and store them directly on the descs,
# using a strange attribute name. The goal is to store in the pbcs of
# 's1' under the common 'attrname' a reader function; each reader function
# will read a field 'attrname2' from the pbcs of 's2', where 'attrname2'
- # differs for each pbc of 's1'.
- attrname = '$memoreader%d_%s' % (uid(funcdesc), funcdesc.name)
+ # differs for each pbc of 's1'. This is all specialized also
+ # considering the type of s1 to support return value
+ # polymorphism.
+ s1, s2 = arglist_s
+ s1_type = s1.knowntype
+ memosig = "%d_%d_%s" % (uid(funcdesc), uid(s1_type), funcdesc.name)
+
+ attrname = '$memoreader%s' % memosig
for desc1 in s1.descriptions:
- attrname2 = '$memofield%d_%d_%s' % (uid(funcdesc), uid(desc1),
- funcdesc.name)
+ attrname2 = '$memofield%d_%s' % (uid(desc1), memosig)
s_reader = desc1.s_read_attribute(attrname)
if isinstance(s_reader, SomeImpossibleValue):
# first time we see this 'desc1': sanity-check 'desc1' and
@@ -121,7 +133,8 @@
assert isinstance(desc1, FrozenDesc), (
"XXX not implemented: memo call with a class as first arg")
if desc1.pyobj is None:
- raise Exception("memo call with a class or PBC that has no "
+ raise Exception("method-memo call with a class or PBC"
+ " that has no "
"corresponding Python object (%r)" % (desc1,))
def reader(y, attrname2=attrname2):
return getattr(y, attrname2)
@@ -131,7 +144,8 @@
if isinstance(s_result, SomeImpossibleValue):
# first time we see this 'desc1+desc2' combination
if desc2.pyobj is None:
- raise Exception("memo call with a class or PBC that has no "
+ raise Exception("method-memo call with a class or PBC"
+ " that has no "
"corresponding Python object (%r)" % (desc2,))
# concrete call, to get the concrete result
result = func(desc1.pyobj, desc2.pyobj)
@@ -146,7 +160,7 @@
return reader_fn(y)
def builder(translator, func):
return translator.buildflowgraph(memoized) # instead of 'func'
- return funcdesc.cachedgraph('memo2', alt_name='memo_%s' % funcdesc.name,
+ return funcdesc.cachedgraph(s1_type, alt_name='memo_%s' % funcdesc.name,
builder=builder)
def argvalue(i):
Modified: pypy/branch/somepbc-refactoring/pypy/rpython/test/test_rpbc.py
==============================================================================
--- pypy/branch/somepbc-refactoring/pypy/rpython/test/test_rpbc.py (original)
+++ pypy/branch/somepbc-refactoring/pypy/rpython/test/test_rpbc.py Fri Nov 25 18:21:01 2005
@@ -260,36 +260,6 @@
res = interpret(f1, [1])
assert res == 3
-def test_call_memoized_function_2():
- fr1 = Freezing()
- fr2 = Freezing()
- br1 = Freezing(); br1.value = 'a'
- br2 = Freezing(); br2.value = 'b'
- def getorbuild(key1, key2):
- a = 1
- b = 100
- if key1 is fr1:
- result = eval("%s+2" % key2.value)
- else:
- result = eval("%s+6" % key2.value)
- return result
- getorbuild._annspecialcase_ = "specialize:memo"
-
- def f1(i):
- if i > 0:
- fr = fr1
- else:
- fr = fr2
- if i % 2 == 0:
- br = br1
- else:
- br = br2
- return getorbuild(fr, br)
-
- for check in [-1, 0, 1, 2]:
- res = interpret(f1, [check])
- assert res == f1(check)
-
def test_call_memoized_cache():
# this test checks that we add a separate field
Modified: pypy/branch/somepbc-refactoring/pypy/tool/cache.py
==============================================================================
--- pypy/branch/somepbc-refactoring/pypy/tool/cache.py (original)
+++ pypy/branch/somepbc-refactoring/pypy/tool/cache.py Fri Nov 25 18:21:01 2005
@@ -37,7 +37,7 @@
result = self._build(key)
self.content[key] = result
return result
- getorbuild._annspecialcase_ = "specialize:memo"
+ getorbuild._annspecialcase_ = "specialize:methodmemo"
def _freeze_(self):
# needs to be SomePBC, but otherwise we can't really freeze the
Modified: pypy/branch/somepbc-refactoring/pypy/translator/test/test_annrpython.py
==============================================================================
--- pypy/branch/somepbc-refactoring/pypy/translator/test/test_annrpython.py (original)
+++ pypy/branch/somepbc-refactoring/pypy/translator/test/test_annrpython.py Fri Nov 25 18:21:01 2005
@@ -1780,36 +1780,6 @@
s = a.build_types(f1, [int])
assert s.knowntype == int
- def test_call_memoized_function_2(self):
- fr1 = Freezing()
- fr2 = Freezing()
- br1 = Freezing(); br1.value = 'a'
- br2 = Freezing(); br2.value = 'b'
- def getorbuild(key1, key2):
- a = 1
- b = 100
- if key1 is fr1:
- result = eval("%s+2" % key2.value)
- else:
- result = eval("%s+6" % key2.value)
- return result
- getorbuild._annspecialcase_ = "specialize:memo"
-
- def f1(i):
- if i > 0:
- fr = fr1
- else:
- fr = fr2
- if i % 2 == 0:
- br = br1
- else:
- br = br2
- return getorbuild(fr, br)
-
- a = self.RPythonAnnotator()
- s = a.build_types(f1, [int])
- assert s.knowntype == int
-
def g(n):
return [0,1,2,n]
More information about the Pypy-commit
mailing list