[pypy-svn] r12257 - pypy/dist/pypy/rpython
arigo at codespeak.net
arigo at codespeak.net
Sat May 14 11:59:09 CEST 2005
Author: arigo
Date: Sat May 14 11:59:09 2005
New Revision: 12257
Modified:
pypy/dist/pypy/rpython/rlist.py
pypy/dist/pypy/rpython/typer.py
Log:
Slightly saner approach to building and registering list operations.
Modified: pypy/dist/pypy/rpython/rlist.py
==============================================================================
--- pypy/dist/pypy/rpython/rlist.py (original)
+++ pypy/dist/pypy/rpython/rlist.py Sat May 14 11:59:09 2005
@@ -4,66 +4,61 @@
from pypy.tool.template import compile_template
+class ListType:
+
+ def __init__(self, s_list):
+ assert isinstance(s_list, SomeList)
+ self.s_list = s_list
+ self.s_item = s_list.listdef.listitem.s_value
+ self.LIST = ForwardReference()
+ self.LISTPTR = GcPtr(self.LIST)
+ #self.ITEM = ... see below
+
+ def define(self, typer):
+ self.ITEM = typer.annotation2concretetype(self.s_item)
+ self.LIST.become(Struct("list",
+ ("items", GcPtr(Array(('item', self.ITEM))))))
+
+ def getitem(l, i):
+ return l.items[i].item
+
+ typer['getitem', self.s_list, SomeInteger()] = (
+ getitem, self.LISTPTR, Signed, self.ITEM)
+
+ ## def append(l, newitem):
+ ## length = len(l.items)
+ ## newitems = malloc(List_typ.items.TO, length+1)
+ ## i = 0
+ ## while i<length:
+ ## newitems[i].item = l.items[i].item
+ ## i += 1
+ ## newitems[length].item = newitem
+ ## l.items = newitems
+
+ ## Registry['getattr', ...
+
+
+
def substitute_newlist(typer, op):
+ # Make an implementation of newlist(x1,..,xn) which allocates
+ # a list with nbargs elements and initialize them.
s_result = typer.annotator.binding(op.result)
- LIST = getlisttype(typer, s_result)
- T = getlistitemtype(typer, s_result)
- n = len(op.args)
- inputsignature = (T,) * n
- try:
- newlist = typer.newlistcache[LIST, n]
- except KeyError:
- # Make an implementation of newlist(x1,..,xn) which allocates
- # a list with n elements and initialize them.
- List_typ = LIST.TO
-
- def template():
- args = ', '.join(['arg%d' % i for i in range(n)])
- yield 'def newlist(%s):' % args
- yield ' l = malloc(List_typ)'
- yield ' l.items = malloc(List_typ.items.TO, %d)' % n
- for i in range(n):
- yield ' l.items[%d].item = arg%d' % (i, i)
- yield ' return l'
-
- newlist = compile_template(template(), 'newlist')
- typer.newlistcache[LIST, n] = newlist
- return typer.substitute_op(op, (newlist,) + inputsignature + (LIST,))
-
-def getlisttype(typer, s_list):
- assert isinstance(s_list, SomeList)
- listdef = s_list.listdef
- try:
- return typer.listtypecache[listdef]
- except KeyError:
- List_typ = ForwardReference()
- result = typer.listtypecache[listdef] = GcPtr(List_typ)
- define_list(typer, s_list, List_typ)
- return result
-
-def getlistitemtype(typer, s_list):
- return typer.annotation2concretetype(s_list.listdef.listitem.s_value)
-
-
-def define_list(typer, s_list, List_typ):
- T = getlistitemtype(typer, s_list)
- List_typ.become(Struct("list",
- ("items", GcPtr(Array(('item',T))))))
-
- def getitem(l, i):
- return l.items[i].item
-
- typer['getitem', s_list, SomeInteger()] = (
- getitem, GcPtr(List_typ), Signed, T)
-
-## def append(l, newitem):
-## length = len(l.items)
-## newitems = malloc(List_typ.items.TO, length+1)
-## i = 0
-## while i<length:
-## newitems[i].item = l.items[i].item
-## i += 1
-## newitems[length].item = newitem
-## l.items = newitems
-
-## Registry['getattr', ...
+ listtype = typer.maketype(ListType, s_result)
+ LIST = listtype.LIST
+ nbargs = len(op.args)
+
+ def template():
+ args = ', '.join(['arg%d' % i for i in range(nbargs)])
+ yield 'def newlist(%s):' % args
+ yield ' l = malloc(LIST)'
+ yield ' l.items = malloc(LIST.items.TO, %d)' % nbargs
+ for i in range(nbargs):
+ yield ' l.items[%d].item = arg%d' % (i, i)
+ yield ' return l'
+
+ newlist = compile_template(template(), 'newlist')
+
+ pattern = ('newlist',) + (listtype.s_item,)*nbargs
+ substitution = (newlist,) + (listtype.ITEM,)*nbargs + (listtype.LISTPTR,)
+ typer[pattern] = substitution
+ raise typer.Retry # the new pattern should match now
Modified: pypy/dist/pypy/rpython/typer.py
==============================================================================
--- pypy/dist/pypy/rpython/typer.py (original)
+++ pypy/dist/pypy/rpython/typer.py Sat May 14 11:59:09 2005
@@ -3,13 +3,19 @@
from pypy.annotation.model import *
from pypy.objspace.flow.model import Variable, Constant, SpaceOperation
from pypy.translator.typer import Specializer, flatten_ops, TyperError
-from pypy.rpython.rlist import substitute_newlist, getlisttype
+from pypy.rpython.rlist import ListType, substitute_newlist
PyObjPtr = GcPtr(PyObject)
+class Retry(Exception):
+ """Raised by substitute_*() after they have inserted new patterns
+ in the typer's registry. This asks the typer to try again from
+ scratch to specialize the current operation."""
+
class RPythonTyper(Specializer):
+ Retry = Retry
def __init__(self, annotator):
# initialization
@@ -17,6 +23,7 @@
typematches = [], specializationtable = [],
)
self.registry = {}
+ self.typecache = {}
SINT = SomeInteger()
self['add', SINT, SINT] = 'int_add', Signed, Signed, Signed
#self['add', UINT, UINT] = 'int_add', Unsigned, Unsigned, Unsigned
@@ -25,8 +32,6 @@
self['simple_call', s_malloc, ...] = substitute_malloc
# ____________________ lists ____________________
- self.listtypecache = {}
- self.newlistcache = {}
self['newlist', ...] = substitute_newlist
# ____________________ conversions ____________________
@@ -37,14 +42,24 @@
def __setitem__(self, pattern, substitution):
patternlist = self.registry.setdefault(pattern[0], [])
- patternlist.append((pattern[1:], substitution))
+ # items inserted last have higher priority
+ patternlist.insert(0, (pattern[1:], substitution))
+
+ def maketype(self, cls, s_annotation):
+ try:
+ return self.typecache[cls, s_annotation]
+ except KeyError:
+ newtype = cls(s_annotation)
+ self.typecache[cls, s_annotation] = newtype
+ newtype.define(self)
+ return newtype
def annotation2concretetype(self, s_value):
try:
return annotation_to_lltype(s_value)
except ValueError:
if isinstance(s_value, SomeList):
- return getlisttype(self, s_value)
+ return self.maketype(ListType, s_value).LISTPTR
return PyObjPtr
def convertvar(self, v, concretetype):
@@ -125,7 +140,11 @@
break
else:
# match!
- return self.substitute_op(op, substitution)
+ try:
+ return self.substitute_op(op, substitution)
+ except Retry:
+ return self.specialized_op(op, bindings)
+
# specialization not found
argtypes = [self.defaultconcretetype] * len(op.args)
return self.typed_op(op, argtypes, self.defaultconcretetype)
More information about the Pypy-commit
mailing list