[pypy-svn] r31950 - in pypy/dist/pypy: annotation annotation/test rpython rpython/lltypesystem rpython/test
arigo at codespeak.net
arigo at codespeak.net
Sat Sep 2 17:41:49 CEST 2006
Author: arigo
Date: Sat Sep 2 17:41:45 2006
New Revision: 31950
Modified:
pypy/dist/pypy/annotation/policy.py
pypy/dist/pypy/annotation/test/test_annrpython.py
pypy/dist/pypy/rpython/annlowlevel.py
pypy/dist/pypy/rpython/lltypesystem/lltype.py
pypy/dist/pypy/rpython/lltypesystem/rlist.py
pypy/dist/pypy/rpython/rlist.py
pypy/dist/pypy/rpython/test/test_rlist.py
Log:
{arigo, pedronis}
* Allow lambdas in Sig.
* Started the concept of ADTInterface, which describes the signature of
the ADT methods. This is used to ensure that the ADT methods are
always annotated with the most general annotation.
* In the middle of killing ListBuilder...
Modified: pypy/dist/pypy/annotation/policy.py
==============================================================================
--- pypy/dist/pypy/annotation/policy.py (original)
+++ pypy/dist/pypy/annotation/policy.py Sat Sep 2 17:41:45 2006
@@ -6,6 +6,7 @@
# or we create a cycle.
from pypy.annotation import model as annmodel
from pypy.annotation.bookkeeper import getbookkeeper
+import types
class BasicAnnotatorPolicy(object):
@@ -99,10 +100,23 @@
self.argtypes = argtypes
def __call__(self, funcdesc, inputcells):
+ from pypy.rpython.lltypesystem import lltype
args_s = []
- for argtype in self.argtypes:
+ for i, argtype in enumerate(self.argtypes):
+ if isinstance(argtype, (types.FunctionType, types.MethodType)):
+ argtype = argtype(*inputcells)
if isinstance(argtype, annmodel.SomeObject):
args_s.append(argtype)
+ elif isinstance(argtype, lltype.LowLevelType):
+ if argtype is lltype.Void:
+ # XXX the mapping between Void and annotation
+ # is not quite well defined
+ s_input = inputcells[i]
+ assert isinstance(s_input, annmodel.SomePBC)
+ assert s_input.is_constant()
+ args_s.append(s_input)
+ else:
+ args_s.append(annmodel.lltype_to_annotation(argtype))
else:
args_s.append(funcdesc.bookkeeper.valueoftype(argtype))
if len(inputcells) != len(args_s):
Modified: pypy/dist/pypy/annotation/test/test_annrpython.py
==============================================================================
--- pypy/dist/pypy/annotation/test/test_annrpython.py (original)
+++ pypy/dist/pypy/annotation/test/test_annrpython.py Sat Sep 2 17:41:45 2006
@@ -2320,6 +2320,20 @@
assert not s.nonneg
py.test.raises(Exception, a.build_types, fun, [int, int])
+ def test_sig_lambda(self):
+ def fun(x, y):
+ return y
+ s_nonneg = annmodel.SomeInteger(nonneg=True)
+ fun._annenforceargs_ = policy.Sig(lambda s1,s2: s1, lambda s1,s2: s1)
+ # means: the 2nd argument's annotation becomes the 1st argument's
+ # input annotation
+
+ a = self.RPythonAnnotator()
+ s = a.build_types(fun, [int, s_nonneg])
+ assert isinstance(s, annmodel.SomeInteger)
+ assert not s.nonneg
+ py.test.raises(Exception, a.build_types, fun, [s_nonneg, int])
+
def g(n):
return [0,1,2,n]
Modified: pypy/dist/pypy/rpython/annlowlevel.py
==============================================================================
--- pypy/dist/pypy/rpython/annlowlevel.py (original)
+++ pypy/dist/pypy/rpython/annlowlevel.py Sat Sep 2 17:41:45 2006
@@ -5,7 +5,7 @@
import types
from pypy.tool.sourcetools import valid_identifier
from pypy.annotation import model as annmodel
-from pypy.annotation.policy import AnnotatorPolicy
+from pypy.annotation.policy import AnnotatorPolicy, Sig
from pypy.rpython.lltypesystem import lltype
from pypy.rpython import extfunctable, extregistry
from pypy.objspace.flow.model import Constant
@@ -330,5 +330,73 @@
def specialize_call(self, hop):
return hop.args_r[1].get_unique_llfn()
+# ____________________________________________________________
-
+def placeholder_sigarg(s):
+ if s == "self":
+ def expand(s_self, *args_s):
+ assert isinstance(s_self, annmodel.SomePtr)
+ return s_self
+ elif s == "SELF":
+ raise NotImplementedError
+ else:
+ assert s.islower()
+ def expand(s_self, *args_s):
+ assert isinstance(s_self, annmodel.SomePtr)
+ return getattr(s_self.ll_ptrtype.TO, s.upper())
+ return expand
+
+def typemeth_placeholder_sigarg(s):
+ if s == "SELF":
+ def expand(s_TYPE, *args_s):
+ assert isinstance(s_TYPE, annmodel.SomePBC)
+ assert s_TYPE.is_constant()
+ return s_TYPE
+ elif s == "self":
+ def expand(s_TYPE, *args_s):
+ assert isinstance(s_TYPE, annmodel.SomePBC)
+ assert s_TYPE.is_constant()
+ return lltype.Ptr(s_TYPE.const)
+ else:
+ assert s.islower()
+ def expand(s_TYPE, *args_s):
+ assert isinstance(s_TYPE, annmodel.SomePBC)
+ assert s_TYPE.is_constant()
+ return getattr(s_TYPE.const, s.upper())
+ return expand
+
+
+class ADTInterface(object):
+
+ def __init__(self, base, sigtemplates):
+ self.sigtemplates = sigtemplates
+ self.base = base
+ sigs = {}
+ if base is not None:
+ sigs.update(base.sigs)
+ for name, template in sigtemplates.items():
+ args, result = template
+ if args[0] == "self":
+ make_expand = placeholder_sigarg
+ elif args[0] == "SELF":
+ make_expand = typemeth_placeholder_sigarg
+ else:
+ assert False, ("ADTInterface signature should start with"
+ " 'SELF' or 'self'")
+ sigargs = []
+ for arg in args:
+ if isinstance(arg, str):
+ arg = make_expand(arg)
+ sigargs.append(arg)
+ sigs[name] = Sig(*sigargs)
+ self.sigs = sigs
+
+ def __call__(self, adtmeths):
+ for name, sig in self.sigs.items():
+ meth = adtmeths[name]
+ prevsig = getattr(meth, '_annenforceargs_', None)
+ if prevsig:
+ assert prevsig is sig
+ else:
+ meth._annenforceargs_ = sig
+ return adtmeths
Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lltype.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/lltype.py Sat Sep 2 17:41:45 2006
@@ -693,6 +693,14 @@
raise TypeError("don't know how to cast from %r to %r" % (ORIG, TGT))
+def erasedType(T):
+ while isinstance(T, Ptr) and isinstance(T.TO, Struct):
+ first, FIRSTTYPE = T.TO._first_struct()
+ if first is None:
+ break
+ T = Ptr(FIRSTTYPE)
+ return T
+
class InvalidCast(TypeError):
pass
Modified: pypy/dist/pypy/rpython/lltypesystem/rlist.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rlist.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/rlist.py Sat Sep 2 17:41:45 2006
@@ -5,7 +5,7 @@
from pypy.rpython.rmodel import externalvsinternal
from pypy.rpython.rlist import AbstractBaseListRepr, AbstractListRepr, \
AbstractFixedSizeListRepr, AbstractListIteratorRepr, rtype_newlist, \
- rtype_alloc_and_set, ll_setitem_nonneg
+ rtype_alloc_and_set, ll_setitem_nonneg, ADTIList, ADTIFixedList
from pypy.rpython.rlist import dum_nocheck, dum_checkidx
from pypy.rpython.lltypesystem.rslice import SliceRepr
from pypy.rpython.lltypesystem.rslice import startstop_slice_repr, startonly_slice_repr
@@ -49,10 +49,10 @@
self.listitem = listitem
self.list_cache = {}
# setup() needs to be called to finish this initialization
- self.list_builder = ListBuilder(self)
+## self.list_builder = ListBuilder(self)
- def _setup_repr_final(self):
- self.list_builder.setup()
+## def _setup_repr_final(self):
+## self.list_builder.setup()
def null_const(self):
return nullptr(self.LIST)
@@ -81,85 +81,85 @@
temp),
rstr.list_str_close_bracket))
-class ListBuilder(object):
- """Interface to allow lazy list building by the JIT."""
+##class ListBuilder(object):
+## """Interface to allow lazy list building by the JIT."""
- def __init__(self, list_repr):
- # This should not keep a reference to the RTyper, even indirectly via
- # the list_repr. So tmp_list_repr is replaced by None in setup().
- self.tmp_list_repr = list_repr
-
- def setup(self):
- # Precompute the c_newitem and c_setitem_nonneg function pointers,
- # needed below.
- list_repr = self.tmp_list_repr
- if list_repr is None:
- return # already set up
- self.tmp_list_repr = None
- if list_repr.rtyper is None:
- return # only for test_rlist, which doesn't need this anyway
+## def __init__(self, list_repr):
+## # This should not keep a reference to the RTyper, even indirectly via
+## # the list_repr. So tmp_list_repr is replaced by None in setup().
+## self.tmp_list_repr = list_repr
+
+## def setup(self):
+## # Precompute the c_newitem and c_setitem_nonneg function pointers,
+## # needed below.
+## list_repr = self.tmp_list_repr
+## if list_repr is None:
+## return # already set up
+## self.tmp_list_repr = None
+## if list_repr.rtyper is None:
+## return # only for test_rlist, which doesn't need this anyway
- LIST = list_repr.LIST
- LISTPTR = list_repr.lowleveltype
- ITEM = list_repr.item_repr.lowleveltype
- self.LIST = LIST
- self.LISTPTR = LISTPTR
-
- argtypes = [Signed]
- newlist_ptr = list_repr.rtyper.annotate_helper_fn(LIST.ll_newlist,
- argtypes)
-
- bk = list_repr.rtyper.annotator.bookkeeper
- argtypes = [bk.immutablevalue(dum_nocheck), LISTPTR, Signed, ITEM]
- setitem_nonneg_ptr = list_repr.rtyper.annotate_helper_fn(
- ll_setitem_nonneg, argtypes)
- #self.c_dum_nocheck = inputconst(Void, dum_nocheck)
- #self.c_LIST = inputconst(Void, self.LIST)
-
- def build_newlist(llops, length):
- c_newlist = llops.genconst(newlist_ptr)
- c_len = llops.genconst(length)
- c_LIST = llops.genvoidconst(LIST)
- return llops.genop('direct_call',
- [c_newlist, c_LIST, c_len],
- llops.constTYPE(LISTPTR))
-
- def build_setitem(llops, v_list, index, v_item):
- c_setitem_nonneg = llops.genconst(setitem_nonneg_ptr)
- c_i = llops.genconst(index)
- llops.genop('direct_call', [c_setitem_nonneg,
- llops.genvoidconst(dum_nocheck),
- v_list, c_i, v_item])
-
- self.build_newlist = build_newlist
- self.build_setitem = build_setitem
-
- def build(self, llops, items_v):
- """Make the operations that would build a list containing the
- provided items."""
- v_list = self.build_newlist(llops, len(items_v))
- for i, v in enumerate(items_v):
- self.build_setitem(llops, v_list, i, v)
- return v_list
-
- def getlistptr(self):
- list_repr = self.tmp_list_repr
- if list_repr is not None:
- list_repr.setup()
- return list_repr.lowleveltype
- else:
- return self.LISTPTR
-
- def __eq__(self, other):
- if not isinstance(other, ListBuilder):
- return False
- return self.getlistptr() == other.getlistptr()
+## LIST = list_repr.LIST
+## LISTPTR = list_repr.lowleveltype
+## ITEM = list_repr.item_repr.lowleveltype
+## self.LIST = LIST
+## self.LISTPTR = LISTPTR
+
+## argtypes = [Signed]
+## newlist_ptr = list_repr.rtyper.annotate_helper_fn(LIST.ll_newlist,
+## argtypes)
+
+## bk = list_repr.rtyper.annotator.bookkeeper
+## argtypes = [bk.immutablevalue(dum_nocheck), LISTPTR, Signed, ITEM]
+## setitem_nonneg_ptr = list_repr.rtyper.annotate_helper_fn(
+## ll_setitem_nonneg, argtypes)
+## #self.c_dum_nocheck = inputconst(Void, dum_nocheck)
+## #self.c_LIST = inputconst(Void, self.LIST)
+
+## def build_newlist(llops, length):
+## c_newlist = llops.genconst(newlist_ptr)
+## c_len = llops.genconst(length)
+## c_LIST = llops.genvoidconst(LIST)
+## return llops.genop('direct_call',
+## [c_newlist, c_LIST, c_len],
+## llops.constTYPE(LISTPTR))
+
+## def build_setitem(llops, v_list, index, v_item):
+## c_setitem_nonneg = llops.genconst(setitem_nonneg_ptr)
+## c_i = llops.genconst(index)
+## llops.genop('direct_call', [c_setitem_nonneg,
+## llops.genvoidconst(dum_nocheck),
+## v_list, c_i, v_item])
+
+## self.build_newlist = build_newlist
+## self.build_setitem = build_setitem
+
+## def build(self, llops, items_v):
+## """Make the operations that would build a list containing the
+## provided items."""
+## v_list = self.build_newlist(llops, len(items_v))
+## for i, v in enumerate(items_v):
+## self.build_setitem(llops, v_list, i, v)
+## return v_list
+
+## def getlistptr(self):
+## list_repr = self.tmp_list_repr
+## if list_repr is not None:
+## list_repr.setup()
+## return list_repr.lowleveltype
+## else:
+## return self.LISTPTR
+
+## def __eq__(self, other):
+## if not isinstance(other, ListBuilder):
+## return False
+## return self.getlistptr() == other.getlistptr()
- def __ne__(self, other):
- return not (self == other)
+## def __ne__(self, other):
+## return not (self == other)
- def __hash__(self):
- return 1 # bad but not used alone
+## def __hash__(self):
+## return 1 # bad but not used alone
class __extend__(pairtype(BaseListRepr, BaseListRepr)):
@@ -183,18 +183,18 @@
# XXX we might think of turning length stuff into Unsigned
self.LIST.become(GcStruct("list", ("length", Signed),
("items", Ptr(ITEMARRAY)),
- adtmeths = {
+ adtmeths = ADTIList({
"ll_newlist": ll_newlist,
"ll_length": ll_length,
"ll_items": ll_items,
- "list_builder": self.list_builder,
+ ##"list_builder": self.list_builder,
"ITEM": ITEM,
"ll_getitem_fast": ll_getitem_fast,
"ll_setitem_fast": ll_setitem_fast,
"_ll_resize_ge": _ll_list_resize_ge,
"_ll_resize_le": _ll_list_resize_le,
"_ll_resize": _ll_list_resize,
- })
+ }))
)
def compact_repr(self):
@@ -215,15 +215,15 @@
if isinstance(self.LIST, GcForwardReference):
ITEM = self.item_repr.lowleveltype
ITEMARRAY = GcArray(ITEM,
- adtmeths = {
+ adtmeths = ADTIFixedList({
"ll_newlist": ll_fixed_newlist,
"ll_length": ll_fixed_length,
"ll_items": ll_fixed_items,
- "list_builder": self.list_builder,
+ ##"list_builder": self.list_builder,
"ITEM": ITEM,
"ll_getitem_fast": ll_fixed_getitem_fast,
"ll_setitem_fast": ll_fixed_setitem_fast,
- })
+ }))
self.LIST.become(ITEMARRAY)
Modified: pypy/dist/pypy/rpython/rlist.py
==============================================================================
--- pypy/dist/pypy/rpython/rlist.py (original)
+++ pypy/dist/pypy/rpython/rlist.py Sat Sep 2 17:41:45 2006
@@ -7,6 +7,20 @@
from pypy.rpython.lltypesystem.lltype import nullptr, Char, UniChar
from pypy.rpython import robject
from pypy.rpython.objectmodel import malloc_zero_filled
+from pypy.rpython.annlowlevel import ADTInterface
+
+ADTIFixedList = ADTInterface(None, {
+ 'll_newlist': (['SELF', Signed ], 'self'),
+ 'll_length': (['self' ], Signed),
+ 'll_getitem_fast': (['self', Signed ], 'item'),
+ 'll_setitem_fast': (['self', Signed, 'item'], Void),
+})
+ADTIList = ADTInterface(ADTIFixedList, {
+ '_ll_resize_ge': (['self', Signed ], Void),
+ '_ll_resize_le': (['self', Signed ], Void),
+ '_ll_resize': (['self', Signed ], Void),
+})
+
def dum_checkidx(): pass
def dum_nocheck(): pass
Modified: pypy/dist/pypy/rpython/test/test_rlist.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rlist.py (original)
+++ pypy/dist/pypy/rpython/test/test_rlist.py Sat Sep 2 17:41:45 2006
@@ -186,44 +186,44 @@
def _freeze_(self):
return True
-def test_list_builder():
- def fixed_size_case():
- return [42]
- def variable_size_case():
- lst = []
- lst.append(42)
- return lst
-
- from pypy.rpython.rtyper import LowLevelOpList
-
- for fn in [fixed_size_case, variable_size_case]:
- t = TranslationContext()
- t.buildannotator().build_types(fn, [])
- t.buildrtyper().specialize()
- LIST = t.graphs[0].getreturnvar().concretetype.TO
- llop = LowLevelOpList(None)
- v0 = Constant(42)
- v0.concretetype = Signed
- v1 = Variable()
- v1.concretetype = Signed
- vr = LIST.list_builder.build(llop, [v0, v1])
- assert len(llop) == 3
- assert llop[0].opname == 'direct_call'
- assert len(llop[0].args) == 3
- assert llop[0].args[1].concretetype == Void
- assert llop[0].args[1].value == LIST
- assert llop[0].args[2].concretetype == Signed
- assert llop[0].args[2].value == 2
- assert llop[0].result is vr
- for op, i, vi in [(llop[1], 0, v0), (llop[2], 1, v1)]:
- assert op.opname == 'direct_call'
- assert len(op.args) == 5
- assert op.args[1].value is dum_nocheck
- assert op.args[2] is vr
- assert op.args[3].concretetype == Signed
- assert op.args[3].value == i
- assert op.args[4] is vi
- assert op.result.concretetype is Void
+##def test_list_builder():
+## def fixed_size_case():
+## return [42]
+## def variable_size_case():
+## lst = []
+## lst.append(42)
+## return lst
+
+## from pypy.rpython.rtyper import LowLevelOpList
+
+## for fn in [fixed_size_case, variable_size_case]:
+## t = TranslationContext()
+## t.buildannotator().build_types(fn, [])
+## t.buildrtyper().specialize()
+## LIST = t.graphs[0].getreturnvar().concretetype.TO
+## llop = LowLevelOpList(None)
+## v0 = Constant(42)
+## v0.concretetype = Signed
+## v1 = Variable()
+## v1.concretetype = Signed
+## vr = LIST.list_builder.build(llop, [v0, v1])
+## assert len(llop) == 3
+## assert llop[0].opname == 'direct_call'
+## assert len(llop[0].args) == 3
+## assert llop[0].args[1].concretetype == Void
+## assert llop[0].args[1].value == LIST
+## assert llop[0].args[2].concretetype == Signed
+## assert llop[0].args[2].value == 2
+## assert llop[0].result is vr
+## for op, i, vi in [(llop[1], 0, v0), (llop[2], 1, v1)]:
+## assert op.opname == 'direct_call'
+## assert len(op.args) == 5
+## assert op.args[1].value is dum_nocheck
+## assert op.args[2] is vr
+## assert op.args[3].concretetype == Signed
+## assert op.args[3].value == i
+## assert op.args[4] is vi
+## assert op.result.concretetype is Void
More information about the Pypy-commit
mailing list