[pypy-svn] r19650 - in pypy/branch/somepbc-refactoring/pypy: annotation translator translator/test
arigo at codespeak.net
arigo at codespeak.net
Tue Nov 8 17:14:07 CET 2005
Author: arigo
Date: Tue Nov 8 17:14:04 2005
New Revision: 19650
Modified:
pypy/branch/somepbc-refactoring/pypy/annotation/binaryop.py
pypy/branch/somepbc-refactoring/pypy/annotation/bookkeeper.py
pypy/branch/somepbc-refactoring/pypy/annotation/classdef.py
pypy/branch/somepbc-refactoring/pypy/annotation/desc.py
pypy/branch/somepbc-refactoring/pypy/annotation/model.py
pypy/branch/somepbc-refactoring/pypy/annotation/unaryop.py
pypy/branch/somepbc-refactoring/pypy/translator/annrpython.py
pypy/branch/somepbc-refactoring/pypy/translator/test/test_annrpython.py
pypy/branch/somepbc-refactoring/pypy/translator/transform.py
Log:
(mwh, pedronis, arigo)
Intermediate check-in.
Progressing slowly on the branch. The Desc classes look nice so far,
probably because they don't worry about specialization yet :-/
(But Samuele is optimistic)
Modified: pypy/branch/somepbc-refactoring/pypy/annotation/binaryop.py
==============================================================================
--- pypy/branch/somepbc-refactoring/pypy/annotation/binaryop.py (original)
+++ pypy/branch/somepbc-refactoring/pypy/annotation/binaryop.py Tue Nov 8 17:14:04 2005
@@ -15,7 +15,6 @@
from pypy.annotation.model import unionof, UnionError, set, missing_operation, TLS
from pypy.annotation.model import add_knowntypedata, merge_knowntypedata
from pypy.annotation.bookkeeper import getbookkeeper
-from pypy.annotation.classdef import isclassdef
from pypy.objspace.flow.model import Variable
# convenience only!
@@ -555,8 +554,8 @@
class __extend__(pairtype(SomePBC, SomePBC)):
def union((pbc1, pbc2)):
- d = pbc1.prebuiltinstances.copy()
- d.update(pbc2.prebuiltinstances)
+ d = pbc1.descriptions.copy()
+ d.update(pbc2.descriptions)
return SomePBC(d, can_be_None = pbc1.can_be_None or pbc2.can_be_None)
class __extend__(pairtype(SomeImpossibleValue, SomeObject)):
Modified: pypy/branch/somepbc-refactoring/pypy/annotation/bookkeeper.py
==============================================================================
--- pypy/branch/somepbc-refactoring/pypy/annotation/bookkeeper.py (original)
+++ pypy/branch/somepbc-refactoring/pypy/annotation/bookkeeper.py Tue Nov 8 17:14:04 2005
@@ -12,9 +12,10 @@
SomeUnicodeCodePoint, SomeOOStaticMeth, s_None, \
SomeLLADTMeth, SomeBool, SomeTuple, SomeOOClass, SomeImpossibleValue, \
SomeList, SomeObject
-from pypy.annotation.classdef import ClassDef, isclassdef
+from pypy.annotation.classdef import ClassDef
from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF
from pypy.annotation.dictdef import DictDef, MOST_GENERAL_DICTDEF
+from pypy.annotation import desc
from pypy.interpreter.pycode import cpython_code_signature
from pypy.interpreter.argument import Arguments, ArgErr
from pypy.rpython.rarithmetic import r_uint
@@ -26,27 +27,6 @@
from pypy.annotation.specialize import decide_callable
-class PBCAccessSet:
- def __init__(self, obj):
- self.objects = { obj: True }
- self.read_locations = {}
- self.attrs = {}
- self.values = {} # used in the typer
-
- def update(self, other):
- self.objects.update(other.objects)
- self.read_locations.update(other.read_locations)
- self.attrs.update(other.attrs)
-
-class PBCCallFamily:
- def __init__(self, obj):
- self.objects = { obj: True }
- self.patterns = {}
-
- def update(self, other):
- self.objects.update(other.objects)
- self.patterns.update(other.patterns)
-
class Stats:
def __init__(self, bookkeeper):
@@ -191,12 +171,8 @@
# mapping position -> key, prev_result for specializations
self.spec_callsite_keys_results = {}
- self.pbc_maximal_access_sets = UnionFind(PBCAccessSet)
- # can be precisely computed only at fix-point, see
- # compute_at_fixpoint
- self.pbc_maximal_call_families = None
- self.pbc_callables = None
-
+ self.pbc_maximal_access_sets = UnionFind(desc.AttrFamily)
+ self.pbc_maximal_call_families = UnionFind(desc.CallFamily)
self.pbc_call_sites = {}
self.emulated_pbc_calls = {}
@@ -225,21 +201,21 @@
del self.position_key
def compute_at_fixpoint(self):
- if self.pbc_maximal_call_families is None:
- self.pbc_maximal_call_families = UnionFind(PBCCallFamily)
- if self.pbc_callables is None:
- self.pbc_callables = {}
-
- for (fn, block, i), shape in self.pbc_call_sites.iteritems():
- spaceop = block.operations[i]
- assert spaceop.opname in ('call_args', 'simple_call')
- pbc = self.annotator.binding(spaceop.args[0], extquery=True)
- self.consider_pbc_call(pbc, shape, spaceop)
- self.pbc_call_sites = {}
-
- for pbc, shape in self.emulated_pbc_calls.itervalues():
- self.consider_pbc_call(pbc, shape)
- self.emulated_pbc_calls = {}
+## if self.pbc_maximal_call_families is None:
+## ...
+## if self.pbc_callables is None:
+## self.pbc_callables = {}
+
+## for (fn, block, i), shape in self.pbc_call_sites.iteritems():
+## spaceop = block.operations[i]
+## assert spaceop.opname in ('call_args', 'simple_call')
+## pbc = self.annotator.binding(spaceop.args[0], extquery=True)
+## self.consider_pbc_call(pbc, shape, spaceop)
+## self.pbc_call_sites = {}
+
+## for pbc, shape in self.emulated_pbc_calls.itervalues():
+## self.consider_pbc_call(pbc, shape)
+## self.emulated_pbc_calls = {}
for cls in self.needs_hash_support.keys():
for cls2 in self.needs_hash_support:
@@ -377,9 +353,7 @@
if frozen:
result = SomePBC([self.getdesc(x)])
else:
- clsdef = self.getclassdef(x.__class__)
- if x.__class__.__dict__.get('_annspecialcase_', '').endswith('ctr_location'):
- raise Exception, "encountered a pre-built mutable instance of a class needing specialization: %s" % x.__class__.__name__
+ clsdef = self.getuniqueclassdef(x.__class__)
if x not in self.seen_mutable: # avoid circular reflowing,
# see for example test_circular_mutable_getattr
self.seen_mutable[x] = True
@@ -405,17 +379,16 @@
try:
return self.descs[pyobj]
except KeyError:
- from pypy.annotation import desc
if isinstance(pyobj, types.FunctionType):
- result = desc.FunctionDesc(pyobj)
- elif isintance(pyobj, (type, types.ClassType)):
- result = desc.ClassDesc(pyobj)
+ result = desc.FunctionDesc(self, pyobj)
+ elif isinstance(pyobj, (type, types.ClassType)):
+ result = desc.ClassDesc(self, pyobj)
elif isinstance(pyobj, types.MethodType):
if pyobj.im_self is None: # unbound
- result = desc.FunctionDesc(pyobj.im_func)
+ result = desc.FunctionDesc(self, pyobj.im_func)
elif (hasattr(pyobj.im_self, '_freeze_') and
pyobj.im_self._freeze_()): # method of frozen
- result = desc.MethodOfFrozenDesc(
+ result = desc.MethodOfFrozenDesc(self,
self.getdesc(pyobj.im_func), # funcdesc
self.getdesc(pyobj.im_self)) # frozendesc
else: # regular method
@@ -425,7 +398,7 @@
else:
# must be a frozen pre-built constant, but let's check
assert pyobj._freeze_()
- result = desc.FrozenDesc(pyobj)
+ result = desc.FrozenDesc(self, pyobj)
cls = result.knowntype
if cls not in self.pbctypes:
self.pbctypes[cls] = True
@@ -439,8 +412,7 @@
try:
return self.methoddescs[funcdesc, classdef]
except KeyError:
- from pypy.annotation import desc
- result = desc.MethodDesc(funcdesc, classdef)
+ result = desc.MethodDesc(self, funcdesc, classdef)
self.methoddescs[funcdesc, classdef] = result
return result
@@ -468,7 +440,7 @@
elif t in EXTERNAL_TYPE_ANALYZERS:
return SomeExternalObject(t)
elif t.__module__ != '__builtin__' and t not in self.pbctypes:
- classdef = self.getclassdef(t)
+ classdef = self.getuniqueclassdef(t)
return SomeInstance(classdef)
else:
o = SomeObject()
@@ -480,29 +452,25 @@
assert s_attr.is_constant()
attr = s_attr.const
- access_sets = self.pbc_maximal_access_sets
- descs = pbc.prebuiltinstances.keys()
+ descs = pbc.descriptions.keys()
if not descs:
return SomeImpossibleValue()
first = descs[0]
-
- change, rep, access = access_sets.find(first)
- for desc in descs:
- change1, rep, access = access_sets.union(rep, desc)
- change = change or change1
+ change = first.mergeattrfamilies(*descs[1:])
+ attrfamily = first.getattrfamily()
position = self.position_key
- access.read_locations[position] = True
+ attrfamily.read_locations[position] = True
actuals = []
- for desc in access.objects:
+ for desc in attrfamily.descs:
actuals.append(desc.s_read_attribute(attr))
s_result = unionof(*actuals)
- access.attrs[attr] = s_result
+ attrfamily.attrs[attr] = s_result
if change:
- for position in access.read_locations:
+ for position in attrfamily.read_locations:
self.annotator.reflowfromposition(position)
return s_result
@@ -551,8 +519,29 @@
dontcare, rep, callfamily = call_families.union(rep, obj)
callfamily.patterns.update({shape: True})
-
- def pbc_call(self, pbc, args, implicit_init=False, emulated=None):
+
+ def pbc_call(self, pbc, args):
+ """Analyse a call to a SomePBC() with the given args (list of
+ annotations).
+ """
+ descs = pbc.descriptions.keys()
+ if not descs:
+ return SomeImpossibleValue()
+ first = descs[0]
+ first.mergecallfamilies(*descs[1:])
+ callfamily = first.getcallfamily()
+
+ def schedule(graph, inputcells):
+ whence = self.position_key
+ return self.annotator.recursivecall(graph, whence, inputcells)
+
+ results = []
+ for desc in descs:
+ results.append(desc.pycall(schedule, args))
+ s_result = unionof(*results)
+ return s_result
+
+ def DISABLED_pbc_call(self, pbc, args, implicit_init=False, emulated=None):
if not implicit_init and not emulated:
fn, block, i = self.position_key
assert block.operations[i].opname in ('call_args', 'simple_call')
@@ -765,8 +754,9 @@
return r
- def ondegenerated(self, what, s_value, where=None, called_from=None):
- self.annotator.ondegenerated(what, s_value, where=where, called_from=called_from)
+ def ondegenerated(self, what, s_value, where=None, called_from_graph=None):
+ self.annotator.ondegenerated(what, s_value, where=where,
+ called_from_graph=called_from_graph)
def whereami(self):
return self.annotator.whereami(self.position_key)
Modified: pypy/branch/somepbc-refactoring/pypy/annotation/classdef.py
==============================================================================
--- pypy/branch/somepbc-refactoring/pypy/annotation/classdef.py (original)
+++ pypy/branch/somepbc-refactoring/pypy/annotation/classdef.py Tue Nov 8 17:14:04 2005
@@ -6,6 +6,7 @@
from types import FunctionType
from pypy.annotation.model import SomeImpossibleValue, SomePBC, unionof
from pypy.annotation.model import SomeInteger, isdegenerated
+from pypy.annotation.desc import MethodDesc
# The main purpose of a ClassDef is to collect information about class/instance
@@ -119,8 +120,8 @@
if isinstance(s_newvalue, SomePBC):
attr = self.name
meth = False
- for func, classdef in s_newvalue.prebuiltinstances.items():
- if isclassdef(classdef):
+ for desc in s_newvalue.descriptions:
+ if isinstance(desc, MethodDesc):
meth = True
break
if meth and getattr(homedef.cls, attr, None) is None:
@@ -167,7 +168,7 @@
base = b1
mixeddict.update(cls.__dict__)
- self.basedef = bookkeeper.getclassdef(base)
+ self.basedef = bookkeeper.getuniqueclassdef(base)
if self.basedef:
self.basedef.subdefs[cls] = self
@@ -417,9 +418,6 @@
else:
return False
-def isclassdef(x):
- return isinstance(x, ClassDef)
-
# ____________________________________________________________
FORCE_ATTRIBUTES_INTO_CLASSES = {
Modified: pypy/branch/somepbc-refactoring/pypy/annotation/desc.py
==============================================================================
--- pypy/branch/somepbc-refactoring/pypy/annotation/desc.py (original)
+++ pypy/branch/somepbc-refactoring/pypy/annotation/desc.py Tue Nov 8 17:14:04 2005
@@ -1,11 +1,40 @@
import types
from pypy.interpreter.pycode import cpython_code_signature
-from pypy.annotation.classdef import ClassDef
-from pypy.annotation import model as annmodel
+from pypy.interpreter.argument import ArgErr
+class CallFamily:
+ """A family of Desc objects that could be called from common call sites.
+ """
+ def __init__(self, desc):
+ self.descs = { desc: True }
+ self.patterns = {} # set of "call shapes" in the sense of
+ # pypy.interpreter.argument.Argument
+
+ def update(self, other):
+ self.descs.update(other.descs)
+ self.patterns.update(other.patterns)
+
+class AttrFamily:
+ """A family of Desc objects that have common 'getattr' sites.
+ """
+ def __init__(self, desc):
+ self.descs = { desc: True }
+ self.read_locations = {} # set of position_keys
+ self.attrs = {} # { attr: s_value }
+
+ def update(self, other):
+ self.descs.update(other.descs)
+ self.read_locations.update(other.read_locations)
+ self.attrs.update(other.attrs)
+
+# ____________________________________________________________
+
class Desc(object):
- pyobj = None # non-None if there is an associated underlying Python obj
+ def __init__(self, bookkeeper, pyobj=None):
+ self.bookkeeper = bookkeeper
+ # 'pyobj' is non-None if there is an associated underlying Python obj
+ self.pyobj = pyobj
def __repr__(self):
pyobj = self.pyobj
@@ -13,23 +42,89 @@
return object.__repr__(self)
return '<%s for %r>' % (self.__class__.__name__, pyobj)
+ def getcallfamily(self):
+ """Get the CallFamily object."""
+ call_families = self.bookkeeper.pbc_maximal_call_families
+ _, _, callfamily = call_families.find(self)
+ return callfamily
+
+ def mergecallfamilies(self, *others):
+ """Merge the call families of the given Descs into one."""
+ call_families = self.bookkeeper.pbc_maximal_call_families
+ changed, rep, callfamily = call_families.find(self)
+ for desc in others:
+ changed1, rep, callfamily = call_families.union(rep, desc)
+ changed = changed or changed1
+ return changed
+
+ def getattrfamily(self):
+ """Get the AttrFamily object."""
+ access_sets = self.bookkeeper.pbc_maximal_access_sets
+ _, _, attrfamily = access_sets.find(self)
+ return attrfamily
+
+ def mergeattrfamilies(self, *others):
+ """Merge the attr families of the given Descs into one."""
+ access_sets = self.bookkeeper.pbc_maximal_access_sets
+ changed, rep, attrfamily = access_sets.find(self)
+ for desc in others:
+ changed1, rep, attrfamily = access_sets.union(rep, desc)
+ changed = changed or changed1
+ return changed
+
+ def bind(self, classdef):
+ return self
+
class FunctionDesc(Desc):
knowntype = types.FunctionType
- def __init__(self, pyobj=None, signature=None):
- self.pyobj = pyobj
+ def __init__(self, bookkeeper, pyobj=None,
+ name=None, signature=None, defaults=None, graph=None):
+ super(FunctionDesc, self).__init__(bookkeeper, pyobj)
+ if name is None:
+ name = pyobj.func_name
if signature is None:
signature = cpython_code_signature(pyobj.func_code)
+ if defaults is None:
+ defaults = pyobj.func_defaults
+ self.name = name
self.signature = signature
+ self.defaults = defaults or ()
+ self._graph = graph
+
+ def getgraph(self): # for now
+ if self._graph is None:
+ translator = self.bookkeeper.annotator.translator
+ self._graph = translator.buildflowgraph(self.pyobj)
+ return self._graph
+
+ def parse_arguments(self, args):
+ defs_s = []
+ for x in self.defaults:
+ defs_s.append(self.bookkeeper.immutablevalue(x))
+ try:
+ inputcells = args.match_signature(self.signature, defs_s)
+ except ArgErr, e:
+ raise TypeError, "signature mismatch: %s" % e.getmsg(args, self.name)
+ return inputcells
+
+ def pycall(self, schedule, args):
+ inputcells = self.parse_arguments(args)
+ graph = self.getgraph()
+ s_result = schedule(graph, inputcells)
+ return s_result
+
+ def bind(self, classdef):
+ # XXX static methods
+ return self.bookkeeper.getmethoddesc(self, classdef)
class ClassDesc(Desc):
knowntype = type
def __init__(self, bookkeeper, pyobj, specialize=None):
- self.bookkeeper = bookkeeper
- self.pyobj = pyobj
+ super(ClassDesc, self).__init__(bookkeeper, pyobj)
self.name = pyobj.__module__ + '.' + pyobj.__name__
if specialize is None:
tag = pyobj.__dict__.get('_annspecialcase_', '')
@@ -42,17 +137,37 @@
raise Exception("not supported on class %r because it needs "
"specialization" % (self.name,))
if self._classdef is None:
+ from pypy.annotation.classdef import ClassDef
classdef = ClassDef(self.pyobj, self.bookkeeper)
self.bookkeeper.classdefs.append(classdef)
self._classdef = classdef
classdef.setup()
return self._classdef
+ def pycall(self, schedule, args):
+ from pypy.annotation.model import SomeInstance
+ classdef = self.getuniqueclassdef()
+ s_instance = SomeInstance(classdef)
+ init = getattr(self.pyobj, '__init__', None) # xxx
+ if init is not None and init != object.__init__:
+ # call the constructor
+ s_init = self.bookkeeper.immutablevalue(init)
+ args = args.prepend(s_instance)
+ s_init.call(args)
+ else:
+ try:
+ args.fixedunpack(0)
+ except ValueError:
+ raise Exception("default __init__ takes no argument"
+ " (class %s)" % (self.name,))
+ return s_instance
+
class MethodDesc(Desc):
knowntype = types.MethodType
- def __init__(self, funcdesc, classdef):
+ def __init__(self, bookkeeper, funcdesc, classdef):
+ super(MethodDesc, self).__init__(bookkeeper)
self.funcdesc = funcdesc
self.classdef = classdef
@@ -60,6 +175,16 @@
return '<MethodDesc %r of %r>' % (self.funcdesc,
self.classdef)
+ def pycall(self, schedule, args):
+ from pypy.annotation.model import SomeInstance
+ s_instance = SomeInstance(self.classdef)
+ args = args.prepend(s_instance)
+ return self.funcdesc.pycall(schedule, args)
+
+ def bind(self, classdef):
+ self.bookkeeper.warning("rebinding an already bound %r" % (self,))
+ return self.funcdesc.bind(classdef)
+
def new_or_old_class(c):
if hasattr(c, '__class__'):
@@ -67,12 +192,10 @@
else:
return type(c)
-
class FrozenDesc(Desc):
def __init__(self, bookkeeper, pyobj):
- self.bookkeeper = bookkeeper
- self.pyobj = pyobj
+ super(FrozenDesc, self).__init__(bookkeeper, pyobj)
self.attributes = self.pyobj.__dict__.copy()
self.knowntype = new_or_old_class(pyobj)
@@ -80,13 +203,15 @@
if attr in self.attributes:
return self.bookkeeper.immutablevalue(self.attributes[attr])
else:
- return annmodel.SomeImpossibleValue()
+ from pypy.annotation.model import s_ImpossibleValue
+ return s_ImpossibleValue
class MethodOfFrozenDesc(Desc):
knowntype = types.MethodType
- def __init__(self, funcdesc, frozendesc):
+ def __init__(self, bookkeeper, funcdesc, frozendesc):
+ super(MethodOfFrozenDesc, self).__init__(bookkeeper)
self.funcdesc = funcdesc
self.frozendesc = frozendesc
Modified: pypy/branch/somepbc-refactoring/pypy/annotation/model.py
==============================================================================
--- pypy/branch/somepbc-refactoring/pypy/annotation/model.py (original)
+++ pypy/branch/somepbc-refactoring/pypy/annotation/model.py Tue Nov 8 17:14:04 2005
@@ -297,10 +297,10 @@
class SomePBC(SomeObject):
"""Stands for a global user instance, built prior to the analysis,
or a set of such instances."""
- def __init__(self, prebuiltinstances, can_be_None=False):
- # prebuiltinstances is a set of Desc instances.
- prebuiltinstances = dict.fromkeys(prebuiltinstances)
- self.prebuiltinstances = prebuiltinstances
+ def __init__(self, descriptions, can_be_None=False):
+ # descriptions is a set of Desc instances.
+ descriptions = dict.fromkeys(descriptions)
+ self.descriptions = descriptions
self.can_be_None = can_be_None
self.check()
if self.isNone():
@@ -308,31 +308,31 @@
self.const = None
else:
knowntype = reduce(commonbase,
- [x.knowntype for x in prebuiltinstances])
+ [x.knowntype for x in descriptions])
if knowntype == type(Exception):
knowntype = type
if knowntype != object:
self.knowntype = knowntype
- if len(prebuiltinstances) == 1:
- desc, = prebuiltinstances
+ if len(descriptions) == 1:
+ # hack for the convenience of direct callers to SomePBC():
+ # only if there is a single object in descriptions
+ desc, = descriptions
if desc.pyobj is not None:
- # hack for the convenience of direct callers to SomePBC():
- # only if there is a single object in prebuiltinstances
self.const = desc.pyobj
def check(self):
# We check that the set only contains a single kind of Desc instance
kinds = {}
- for x in self.prebuiltinstances:
+ for x in self.descriptions:
assert type(x).__name__.endswith('Desc') # avoid import nightmares
kinds[x.__class__] = True
assert len(kinds) <= 1, (
"mixing several kinds of PBCs: %r" % (kinds.keys(),))
- assert self.prebuiltinstances or self.can_be_None, (
+ assert self.descriptions or self.can_be_None, (
"use s_ImpossibleValue")
def isNone(self):
- return len(self.prebuiltinstances) == 0
+ return len(self.descriptions) == 0
def can_be_none(self):
return self.can_be_None
@@ -341,9 +341,9 @@
if self.isNone():
return s_ImpossibleValue
else:
- return SomePBC(self.prebuiltinstances, can_be_None=False)
+ return SomePBC(self.descriptions, can_be_None=False)
- def fmt_prebuiltinstances(self, pbis):
+ def fmt_descriptions(self, pbis):
if hasattr(self, 'const'):
return None
else:
Modified: pypy/branch/somepbc-refactoring/pypy/annotation/unaryop.py
==============================================================================
--- pypy/branch/somepbc-refactoring/pypy/annotation/unaryop.py (original)
+++ pypy/branch/somepbc-refactoring/pypy/annotation/unaryop.py Tue Nov 8 17:14:04 2005
@@ -10,7 +10,6 @@
SomeExternalObject, SomeTypedAddressAccess, SomeAddress, \
unionof, set, missing_operation, add_knowntypedata
from pypy.annotation.bookkeeper import getbookkeeper
-from pypy.annotation.classdef import isclassdef
from pypy.annotation import builtin
from pypy.annotation.binaryop import _clone ## XXX where to put this?
@@ -502,39 +501,19 @@
def setattr(pbc, s_attr, s_value):
getbookkeeper().warning("setattr not wanted on %r" % (pbc,))
- def call(pbc, args, implicit_init=False):
+ def call(pbc, args):
bookkeeper = getbookkeeper()
- return bookkeeper.pbc_call(pbc, args, implicit_init=implicit_init)
-
- #bookkeeper = getbookkeeper()
- #results = []
- #for func, classdef in pbc.prebuiltinstances.items():
- # if isclassdef(classdef):
- # s_self = SomeInstance(classdef)
- # args1 = args.prepend(s_self)
- # else:
- # args1 = args
- # results.append(bookkeeper.pycall(func, args1))
- #return unionof(*results)
+ return bookkeeper.pbc_call(pbc, args)
def bindcallables(pbc, classdef):
""" turn the callables in the given SomeCallable 'cal'
into bound versions.
"""
- d = {}
- for func, value in pbc.prebuiltinstances.items():
- if isinstance(func, FunctionType):
- if isclassdef(value):
- getbookkeeper().warning("rebinding an already bound "
- "method %r with %r" % (func, value))
- d[func] = classdef
- elif isinstance(func, staticmethod):
- d[func.__get__(43)] = value
- else:
- d[func] = value
+ d = [desc.bind(classdef) for desc in pbc.descriptions]
return SomePBC(d)
def is_true_behavior(pbc):
+ FIXME_BY_THE_WAY
outcome = None
for c in pbc.prebuiltinstances:
if c is not None and not bool(c):
Modified: pypy/branch/somepbc-refactoring/pypy/translator/annrpython.py
==============================================================================
--- pypy/branch/somepbc-refactoring/pypy/translator/annrpython.py (original)
+++ pypy/branch/somepbc-refactoring/pypy/translator/annrpython.py Tue Nov 8 17:14:04 2005
@@ -116,21 +116,9 @@
raise TypeError, ("Variable or Constant instance expected, "
"got %r" % (variable,))
- def getuserclasses(self):
- """Return a set of known user classes."""
- return self.bookkeeper.userclasses
-
def getuserclassdefinitions(self):
"""Return a list of ClassDefs."""
- return self.bookkeeper.userclasseslist
-
- def getuserattributes(self, cls):
- """Enumerate the attributes of the given user class, as Variable()s."""
- clsdef = self.bookkeeper.userclasses[cls]
- for attr, s_value in clsdef.attrs.items():
- v = Variable(name=attr)
- self.bindings[v] = s_value
- yield v
+ return self.bookkeeper.classdefs
def getpbcaccesssets(self):
"""Return mapping const obj -> PBCAccessSet"""
@@ -188,11 +176,10 @@
# make sure that the return variables of all graphs is annotated
if self.translator is not None:
if self.added_blocks is not None:
- newgraphs = [self.translator.flowgraphs[self.annotated[block]]
- for block in self.added_blocks]
+ newgraphs = [self.annotated[block] for block in self.added_blocks]
newgraphs = dict.fromkeys(newgraphs)
else:
- newgraphs = self.translator.flowgraphs.itervalues() #all of them
+ newgraphs = self.translator.graphs #all of them
for graph in newgraphs:
v = graph.getreturnvar()
if v not in self.bindings:
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 Tue Nov 8 17:14:04 2005
@@ -33,6 +33,14 @@
def somedict(s_key=annmodel.SomeObject(), s_value=annmodel.SomeObject()):
return annmodel.SomeDict(DictDef(None, s_key, s_value))
+def graphof(a, func):
+ result = []
+ for graph in a.translator.graphs:
+ if getattr(graph, 'func', None) is func:
+ result.append(graph)
+ assert len(result) == 1
+ return result[0]
+
class TestAnnotateTestCase:
def setup_class(cls):
@@ -223,11 +231,11 @@
a = self.RPythonAnnotator()
a.build_types(snippet._methodcall1, [int])
# the user classes should have the following attributes:
- classes = a.bookkeeper.userclasses
- assert classes[snippet.F].attrs.keys() == ['m']
- assert classes[snippet.G].attrs.keys() == ['m2']
- assert classes[snippet.H].attrs.keys() == ['attr']
- assert classes[snippet.H].about_attribute('attr') == (
+ getcdef = a.bookkeeper.getuniqueclassdef
+ assert getcdef(snippet.F).attrs.keys() == ['m']
+ assert getcdef(snippet.G).attrs.keys() == ['m2']
+ assert getcdef(snippet.H).attrs.keys() == ['attr']
+ assert getcdef(snippet.H).about_attribute('attr') == (
a.bookkeeper.immutablevalue(1))
def DISABLED_test_knownkeysdict(self):
@@ -259,13 +267,13 @@
a = self.RPythonAnnotator()
s = a.build_types(snippet.with_more_init, [int, bool])
# the user classes should have the following attributes:
- classes = a.bookkeeper.userclasses
+ getcdef = a.bookkeeper.getuniqueclassdef
# XXX on which class should the attribute 'a' appear? We only
# ever flow WithInit.__init__ with a self which is an instance
# of WithMoreInit, so currently it appears on WithMoreInit.
- assert classes[snippet.WithMoreInit].about_attribute('a') == (
+ assert getcdef(snippet.WithMoreInit).about_attribute('a') == (
annmodel.SomeInteger())
- assert classes[snippet.WithMoreInit].about_attribute('b') == (
+ assert getcdef(snippet.WithMoreInit).about_attribute('b') == (
annmodel.SomeBool())
def test_global_instance(self):
@@ -293,21 +301,16 @@
#a.translator.simplify()
# must return "yadda"
assert s == a.bookkeeper.immutablevalue("yadda")
- keys = a.translator.flowgraphs.keys()
- keys.sort()
- expected = [snippet.constant_result,
- snippet.forty_two,
- # and not snippet.never_called
- ]
- expected.sort()
- assert keys == expected
+ graphs = a.translator.graphs
+ assert len(graphs) == 2
+ assert graphs[0].func is snippet.constant_result
+ assert graphs[1].func is snippet.forty_two
a.simplify()
#a.translator.view()
def test_flow_type_info(self):
a = self.RPythonAnnotator()
s = a.build_types(snippet.flow_type_info, [object])
- a.translator.simplify()
a.simplify()
#a.translator.view()
assert s.knowntype == int
@@ -335,7 +338,6 @@
def test_flow_identity_info(self):
a = self.RPythonAnnotator()
s = a.build_types(snippet.flow_identity_info, [object, object])
- a.translator.simplify()
a.simplify()
#a.translator.view()
assert s == a.bookkeeper.immutablevalue((None, None))
@@ -377,7 +379,7 @@
def test_isinstance_and_knowntype_data(self):
a = self.RPythonAnnotator()
- x = annmodel.SomePBC({snippet.apbc: True})
+ x = a.bookkeeper.immutablevalue(snippet.apbc)
s = a.build_types(snippet.isinstance_and_knowntype, [x])
#a.simplify()
#a.translator.view()
@@ -409,14 +411,13 @@
def test_simple_slicing0(self):
a = self.RPythonAnnotator()
- s = a.build_types(snippet.simple_slice, [list])
- g = a.translator.getflowgraph(snippet.simple_slice)
- for thing in flatten(g):
- if isinstance(thing, Block):
- for op in thing.operations:
- if op.opname == "newslice":
- assert isinstance(a.binding(op.result),
- annmodel.SomeSlice)
+ a.build_types(snippet.simple_slice, [list])
+ g = graphof(a, snippet.simple_slice)
+ for block in g.iterblocks():
+ for op in block.operations:
+ if op.opname == "newslice":
+ assert isinstance(a.binding(op.result),
+ annmodel.SomeSlice)
def test_simple_slicing(self):
a = self.RPythonAnnotator()
@@ -540,8 +541,8 @@
def test_bltin_code_frame_confusion(self):
a = self.RPythonAnnotator()
a.build_types(snippet.bltin_code_frame_confusion,[])
- f_flowgraph = a.translator.getflowgraph(snippet.bltin_code_frame_f)
- g_flowgraph = a.translator.getflowgraph(snippet.bltin_code_frame_g)
+ f_flowgraph = graphof(a, snippet.bltin_code_frame_f)
+ g_flowgraph = graphof(a, snippet.bltin_code_frame_g)
# annotator confused by original bltin code/frame setup, we just get SomeObject here
assert a.binding(f_flowgraph.getreturnvar()).__class__ is annmodel.SomeObject
assert a.binding(g_flowgraph.getreturnvar()).__class__ is annmodel.SomeObject
@@ -549,8 +550,8 @@
def test_bltin_code_frame_reorg(self):
a = self.RPythonAnnotator()
a.build_types(snippet.bltin_code_frame_reorg,[])
- f_flowgraph = a.translator.getflowgraph(snippet.bltin_code_frame_f)
- g_flowgraph = a.translator.getflowgraph(snippet.bltin_code_frame_g)
+ f_flowgraph = graphof(a, snippet.bltin_code_frame_f)
+ g_flowgraph = graphof(a, snippet.bltin_code_frame_g)
assert isinstance(a.binding(f_flowgraph.getreturnvar()),
annmodel.SomeInteger)
assert isinstance(a.binding(g_flowgraph.getreturnvar()),
@@ -565,7 +566,7 @@
a = self.RPythonAnnotator()
s = a.build_types(snippet.make_r, [int])
assert s.knowntype == snippet.R
- Rdef = a.getuserclasses()[snippet.R]
+ Rdef = a.bookkeeper.getuniqueclassdef(snippet.R)
assert Rdef.attrs['r'].s_value.knowntype == snippet.R
assert Rdef.attrs['n'].s_value.knowntype == int
assert Rdef.attrs['m'].s_value.knowntype == int
@@ -575,8 +576,8 @@
a = self.RPythonAnnotator()
s = a.build_types(snippet.make_eo, [int])
assert s.knowntype == snippet.B
- Even_def = a.getuserclasses()[snippet.Even]
- Odd_def = a.getuserclasses()[snippet.Odd]
+ Even_def = a.bookkeeper.getuniqueclassdef(snippet.Even)
+ Odd_def = a.bookkeeper.getuniqueclassdef(snippet.Odd)
assert listitem(Even_def.attrs['x'].s_value).knowntype == snippet.Odd
assert listitem(Even_def.attrs['y'].s_value).knowntype == snippet.Even
assert listitem(Odd_def.attrs['x'].s_value).knowntype == snippet.Even
@@ -591,11 +592,11 @@
def test_methodcall_is_precise(self):
a = self.RPythonAnnotator()
s = a.build_types(snippet.methodcall_is_precise, [bool])
- classes = a.bookkeeper.userclasses
- assert 'x' not in classes[snippet.CBase].attrs
- assert (classes[snippet.CSub1].attrs['x'].s_value ==
+ getcdef = a.bookkeeper.getuniqueclassdef
+ assert 'x' not in getcdef(snippet.CBase).attrs
+ assert (getcdef(snippet.CSub1).attrs['x'].s_value ==
a.bookkeeper.immutablevalue(42))
- assert (classes[snippet.CSub2].attrs['x'].s_value ==
+ assert (getcdef(snippet.CSub2).attrs['x'].s_value ==
a.bookkeeper.immutablevalue('world'))
assert s == a.bookkeeper.immutablevalue(42)
@@ -896,7 +897,7 @@
callables = a.getpbccallables()
call_families = a.getpbccallfamilies()
- clsdef = lambda cls: a.getuserclasses()[cls]
+ clsdef = a.bookkeeper.getuniqueclassdef
fc = lambda x: {(None, x): True}
mc = lambda x: {(clsdef(x.im_class), x.im_func): True}
@@ -974,9 +975,9 @@
spec_alloc = spec_alloc.const
assert spec_alloc in callb
assert callb[spec_alloc] == {(None, spec_alloc): True}
- assert (a.binding(a.translator.getflowgraph(spec_alloc).getreturnvar()).knowntype
+ assert (a.binding(graphof(a, spec_alloc).getreturnvar()).knowntype
== spaceop.args[1].value)
- traverse(visit, a.translator.getflowgraph(f))
+ traverse(visit, graphof(a, f))
def test_assert_list_doesnt_lose_info(self):
class T(object):
@@ -1085,7 +1086,7 @@
raise
a = self.RPythonAnnotator()
a.build_types(f, [dict])
- fg = a.translator.getflowgraph(f)
+ fg = graphof(a, f)
et, ev = fg.exceptblock.inputargs
t = annmodel.SomeObject()
t.knowntype = type
@@ -1102,7 +1103,7 @@
raise
a = self.RPythonAnnotator()
a.build_types(f, [dict])
- fg = a.translator.getflowgraph(f)
+ fg = graphof(a, f)
et, ev = fg.exceptblock.inputargs
t = annmodel.SomeObject()
t.knowntype = type
@@ -1138,7 +1139,7 @@
h()
a = self.RPythonAnnotator()
a.build_types(f, [int, list])
- fg = a.translator.getflowgraph(f)
+ fg = graphof(a, f)
et, ev = fg.exceptblock.inputargs
t = annmodel.SomeObject()
t.knowntype = type
@@ -1161,7 +1162,7 @@
h()
a = self.RPythonAnnotator()
a.build_types(f, [])
- fg = a.translator.getflowgraph(f)
+ fg = graphof(a, f)
et, ev = fg.exceptblock.inputargs
t = annmodel.SomeObject()
t.knowntype = type
@@ -1294,8 +1295,8 @@
witness2(x)
a = self.RPythonAnnotator()
s = a.build_types(f, [annmodel.SomeInteger(unsigned=True)])
- wg1 = a.translator.getflowgraph(witness1)
- wg2 = a.translator.getflowgraph(witness2)
+ wg1 = graphof(a, witness1)
+ wg2 = graphof(a, witness2)
assert a.binding(wg1.getargs()[0]).unsigned is True
assert a.binding(wg2.getargs()[0]).unsigned is True
@@ -1445,7 +1446,7 @@
mutr(k, x, i)
a = self.RPythonAnnotator()
a.build_types(f, [bool, K, int, int])
- g = a.translator.getflowgraph(witness)
+ g = graphof(a, witness)
assert a.binding(g.getargs()[0]).knowntype == int
# check RPython static semantics of isinstance(x,bool|int) as needed for wrap
Modified: pypy/branch/somepbc-refactoring/pypy/translator/transform.py
==============================================================================
--- pypy/branch/somepbc-refactoring/pypy/translator/transform.py (original)
+++ pypy/branch/somepbc-refactoring/pypy/translator/transform.py Tue Nov 8 17:14:04 2005
@@ -18,8 +18,7 @@
def checkgraphs(self, blocks):
seen = {}
for block in blocks:
- fn = self.annotated[block]
- graph = self.translator.flowgraphs[fn]
+ graph = self.annotated[block]
if graph not in seen:
checkgraph(graph)
seen[graph] = True
More information about the Pypy-commit
mailing list