[pypy-svn] r22182 - in pypy/dist/pypy/rpython: . test
arigo at codespeak.net
arigo at codespeak.net
Sat Jan 14 23:00:35 CET 2006
Author: arigo
Date: Sat Jan 14 23:00:32 2006
New Revision: 22182
Modified:
pypy/dist/pypy/rpython/rlist.py
pypy/dist/pypy/rpython/rtyper.py
pypy/dist/pypy/rpython/test/test_llinterp.py
pypy/dist/pypy/rpython/test/test_rlist.py
Log:
The RTyper side of the JIT problem of building real lists from virtual lists
at any time. Now each LIST GcStruct has a list_builder() adt-method that
produces lloperations that create a corresponding list. The ListBuilder class
exists because of some order-of-initialization fun.
Modified: pypy/dist/pypy/rpython/rlist.py
==============================================================================
--- pypy/dist/pypy/rpython/rlist.py (original)
+++ pypy/dist/pypy/rpython/rlist.py Sat Jan 14 23:00:32 2006
@@ -68,8 +68,12 @@
self.external_item_repr, self.item_repr = externalvsinternal(rtyper, item_repr)
self.listitem = listitem
self.list_cache = {}
+ self.list_builder = ListBuilder()
# setup() needs to be called to finish this initialization
-
+
+ def _setup_repr_final(self):
+ self.list_builder.setup(self)
+
def recast(self, llops, v):
return llops.convertvar(v, self.item_repr, self.external_item_repr)
@@ -146,6 +150,46 @@
temp),
rstr.list_str_close_bracket))
+class ListBuilder(object):
+ """Interface to allow lazy list building by the JIT."""
+ # This should not keep a reference to the RTyper, even indirectly via
+ # the list_repr.
+
+ def setup(self, list_repr):
+ # Precompute the c_newitem and c_setitem_nonneg function pointers,
+ # needed below.
+ 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]
+ fnptr = list_repr.rtyper.annotate_helper_fn(LIST.ll_newlist, argtypes)
+ self.c_newlist = inputconst(typeOf(fnptr), fnptr)
+
+ bk = list_repr.rtyper.annotator.bookkeeper
+ argtypes = [bk.immutablevalue(dum_nocheck), LISTPTR, Signed, ITEM]
+ fnptr = list_repr.rtyper.annotate_helper_fn(ll_setitem_nonneg, argtypes)
+ self.c_setitem_nonneg = inputconst(typeOf(fnptr), fnptr)
+
+ def build(self, llop, items_v):
+ """Make the operations that would build a list containing the
+ provided items."""
+ # This is called by the JIT with llop.rtyper == None, so
+ # llop.gendirectcall() doesn't work. Instead, we need to call
+ # directly the c_newitem and c_setitem_nonneg precomputed above.
+ c_list = inputconst(Void, self.LIST)
+ c_len = inputconst(Signed, len(items_v))
+ v_result = llop.genop('direct_call', [self.c_newlist, c_list, c_len],
+ resulttype = self.LISTPTR)
+ for i, v in enumerate(items_v):
+ llop.genop('direct_call', [self.c_setitem_nonneg, v_result,
+ inputconst(Signed, i), v])
+ return v_result
+
class ListRepr(BaseListRepr):
def _setup_repr(self):
@@ -161,6 +205,7 @@
"ll_newlist": ll_newlist,
"ll_length": ll_length,
"ll_items": ll_items,
+ "list_builder": self.list_builder.build,
})
)
@@ -233,6 +278,7 @@
"ll_newlist": ll_fixed_newlist,
"ll_length": ll_fixed_length,
"ll_items": ll_fixed_items,
+ "list_builder": self.list_builder.build,
})
self.LIST.become(ITEMARRAY)
Modified: pypy/dist/pypy/rpython/rtyper.py
==============================================================================
--- pypy/dist/pypy/rpython/rtyper.py (original)
+++ pypy/dist/pypy/rpython/rtyper.py Sat Jan 14 23:00:32 2006
@@ -538,15 +538,31 @@
return self.type_system.getcallable(graph, getconcretetype)
- def annotate_helper(self, ll_function, arglltypes):
- """Annotate the given low-level helper function
- and return it as a function pointer object.
+ def annotate_helper(self, ll_function, argtypes):
+ """Annotate the given low-level helper function and return its graph
"""
- args_s = [annmodel.lltype_to_annotation(T) for T in arglltypes]
+ args_s = []
+ for s in argtypes:
+ # assume 's' is a low-level type, unless it is already an annotation
+ if not isinstance(s, annmodel.SomeObject):
+ s = annmodel.lltype_to_annotation(s)
+ args_s.append(s)
+ # hack for bound methods
+ if hasattr(ll_function, 'im_func'):
+ bk = self.annotator.bookkeeper
+ args_s.insert(0, bk.immutablevalue(ll_function.im_self))
+ ll_function = ll_function.im_func
helper_graph = annotate_lowlevel_helper(self.annotator,
ll_function, args_s)
return helper_graph
+ def annotate_helper_fn(self, ll_function, argtypes):
+ """Annotate the given low-level helper function
+ and return it as a function pointer
+ """
+ graph = self.annotate_helper(ll_function, argtypes)
+ return self.getcallable(graph)
+
def attachRuntimeTypeInfoFunc(self, GCSTRUCT, func, ARG_GCSTRUCT=None,
destrptr=None):
self.call_all_setups() # compute ForwardReferences now
Modified: pypy/dist/pypy/rpython/test/test_llinterp.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_llinterp.py (original)
+++ pypy/dist/pypy/rpython/test/test_llinterp.py Sat Jan 14 23:00:32 2006
@@ -1,7 +1,6 @@
import py
from pypy.rpython.lltypesystem.lltype import typeOf, pyobjectptr, Ptr, PyObject, Void
-from pypy.rpython.rtyper import RPythonTyper
from pypy.rpython.llinterp import LLInterpreter, LLException,log
from pypy.rpython.rmodel import inputconst
from pypy.translator.translator import TranslationContext
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 Jan 14 23:00:32 2006
@@ -1,10 +1,12 @@
import sys
from pypy.rpython.lltypesystem.lltype import *
-from pypy.rpython.rtyper import RPythonTyper
+from pypy.rpython.rtyper import LowLevelOpList
from pypy.rpython.rlist import *
from pypy.rpython.rslice import ll_newslice
from pypy.rpython.rint import signed_repr
from pypy.rpython.test.test_llinterp import interpret, interpret_raises
+from pypy.translator.translator import TranslationContext
+from pypy.objspace.flow.model import Constant, Variable
# undo the specialization parameter
for n1 in 'get set del'.split():
@@ -891,3 +893,37 @@
res = interpret(fn, [2])
assert res == 0
interpret_raises(MemoryError, fn, [sys.maxint])
+
+def test_list_builder():
+ def fixed_size_case():
+ return [42]
+ def variable_size_case():
+ lst = []
+ lst.append(42)
+ return lst
+
+ 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(llop, [v0, v1])
+ assert len(llop) == 3
+ assert llop[0].opname == 'direct_call'
+ 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 op.args[-3] is vr
+ assert op.args[-2].concretetype == Signed
+ assert op.args[-2].value == i
+ assert op.args[-1] is vi
+ assert op.result.concretetype is Void
More information about the Pypy-commit
mailing list