[pypy-svn] r18838 - in pypy/dist/pypy: annotation rpython rpython/lltypesystem rpython/test translator

pedronis at codespeak.net pedronis at codespeak.net
Sat Oct 22 23:11:09 CEST 2005


Author: pedronis
Date: Sat Oct 22 23:11:04 2005
New Revision: 18838

Modified:
   pypy/dist/pypy/annotation/bookkeeper.py
   pypy/dist/pypy/annotation/model.py
   pypy/dist/pypy/annotation/unaryop.py
   pypy/dist/pypy/rpython/lltypesystem/lltype.py
   pypy/dist/pypy/rpython/rdict.py
   pypy/dist/pypy/rpython/rlist.py
   pypy/dist/pypy/rpython/rptr.py
   pypy/dist/pypy/rpython/rtyper.py
   pypy/dist/pypy/rpython/test/test_lltype.py
   pypy/dist/pypy/rpython/test/test_rdict.py
   pypy/dist/pypy/rpython/test/test_rlist.py
   pypy/dist/pypy/rpython/test/test_rptr.py
   pypy/dist/pypy/translator/transform.py
Log:

* type erasure for lists

* doing that discovered a bug in the rtyper logic for splitting a llops block when the operation
that can raise an exception is in the middle

* support for attaching methods (ADT meths) to ll container types, should make the code for
supporting fixed size list in the rtyper reasonable: if l is some kind of list it should
be now  possible to express generalized access to items or length as l.ll_items() and l.ll_length(),
this get trasforment into normal ll function calls

(doing the latter it has become clear that the call logic in bookkeeper need some refactoring, not
clear when we can get to it)



Modified: pypy/dist/pypy/annotation/bookkeeper.py
==============================================================================
--- pypy/dist/pypy/annotation/bookkeeper.py	(original)
+++ pypy/dist/pypy/annotation/bookkeeper.py	Sat Oct 22 23:11:04 2005
@@ -487,6 +487,8 @@
                 
         return s_result
 
+    # xxx refactor
+
     def consider_pbc_call(self, pbc, shape, spaceop=None, implicit_init=None): # computation done at fix-point
         if not isinstance(pbc, SomePBC):
             return
@@ -602,22 +604,27 @@
             else:
                 s_obj, init_classdef = implicit_init
 
-            assert isinstance(s_obj, SomePBC)
-            if len(s_obj.prebuiltinstances) > 1: # no specialization expected
-                return s_obj, False
-
             argsvars = spaceop.args[1:]
             args_s = [self.annotator.binding(v) for v in argsvars]
             args = self.build_args(spaceop.opname, args_s)
 
-            func, classdef = s_obj.prebuiltinstances.items()[0]
+            if isinstance(s_obj, SomePBC):
+                if len(s_obj.prebuiltinstances) > 1: # no specialization expected
+                    return s_obj, False
+
+                func, classdef = s_obj.prebuiltinstances.items()[0]
+
+                if init_classdef:
+                    args = args.prepend(SomeInstance(init_classdef))
+                elif isclassdef(classdef): 
+                    s_self = SomeInstance(classdef)
+                    args = args.prepend(s_self)
+            elif isinstance(s_obj, SomeLLADTMeth):
+                func = s_obj.func
+                args = args.prepend(SomePtr(s_obj.ll_ptrtype))
+            else:
+                assert False, "unexpected callable %r for query_spaceop_callable" % s_obj
 
-            if init_classdef:
-                args = args.prepend(SomeInstance(init_classdef))
-            elif isclassdef(classdef): 
-                s_self = SomeInstance(classdef)
-                args = args.prepend(s_self)
-            
             func, key = decide_callable(self, spaceop, func, args, mono=True)
 
             if key is None:
@@ -626,7 +633,10 @@
             if func is None: # specialisation computes annotation direclty
                 return s_obj, True
 
-            return SomePBC({func: classdef}), False
+            if isinstance(s_obj, SomePBC):
+                return SomePBC({func: classdef}), False
+            else:
+                return SomeLLADTMeth(s_obj.ll_ptrtype, func), False
         finally:
             self.leave()
 

Modified: pypy/dist/pypy/annotation/model.py
==============================================================================
--- pypy/dist/pypy/annotation/model.py	(original)
+++ pypy/dist/pypy/annotation/model.py	Sat Oct 22 23:11:04 2005
@@ -431,6 +431,14 @@
     def can_be_none(self):
         return False
 
+class SomeLLADTMeth(SomeObject):
+    def __init__(self, ll_ptrtype, func):
+        self.ll_ptrtype = ll_ptrtype
+        self.func = func 
+
+    def can_be_none(self):
+        return False
+
 class SomeOOClass(SomeObject):
     def __init__(self, ootype):
         self.ootype = ootype
@@ -495,6 +503,10 @@
         # functions
         from bookkeeper import getbookkeeper
         return getbookkeeper().immutablevalue(None)
+    if isinstance(v, MethodType):
+        ll_ptrtype = lltype.typeOf(v.im_self)
+        assert isinstance(ll_ptrtype, lltype.Ptr)
+        return SomeLLADTMeth(ll_ptrtype, v.im_func)
     return lltype_to_annotation(lltype.typeOf(v))
     
 # ____________________________________________________________

Modified: pypy/dist/pypy/annotation/unaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/unaryop.py	(original)
+++ pypy/dist/pypy/annotation/unaryop.py	Sat Oct 22 23:11:04 2005
@@ -566,7 +566,8 @@
 
 
 # annotation of low-level types
-from pypy.annotation.model import SomePtr, SomeOOInstance, SomeOOBoundMeth, SomeOOStaticMeth
+from pypy.annotation.model import SomePtr, SomeLLADTMeth 
+from pypy.annotation.model import SomeOOInstance, SomeOOBoundMeth, SomeOOStaticMeth
 from pypy.annotation.model import ll_to_annotation, annotation_to_lltype
 
 class __extend__(SomePtr):
@@ -594,6 +595,12 @@
     def is_true(p):
         return SomeBool()
 
+class __extend__(SomeLLADTMeth):
+
+    def call(adtmeth, args):
+        bookkeeper = getbookkeeper()
+        return bookkeeper.pycall(adtmeth.func, args.prepend(SomePtr(adtmeth.ll_ptrtype)), mono=True)
+
 from pypy.rpython.ootypesystem import ootype
 class __extend__(SomeOOInstance):
     def getattr(r, s_attr):

Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lltype.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/lltype.py	Sat Oct 22 23:11:04 2005
@@ -116,17 +116,32 @@
     def _is_varsize(self):
         return False
 
+NFOUND = object()
 
 class ContainerType(LowLevelType):
+    _adtmeths = {}
+
     def _gcstatus(self):
         return isinstance(self, GC_CONTAINER)
 
     def _inline_is_varsize(self, last):
         raise TypeError, "%r cannot be inlined in structure" % self
 
+    def _install_adtmeths(self, adtmeths={}):
+        self._adtmeths = frozendict(adtmeths)
+
+    def __getattr__(self, name):
+        adtmeth = self._adtmeths.get(name, NFOUND)
+        if adtmeth is not NFOUND:
+            return adtmeth
+        self._nofield(name)
+
+    def _nofield(self, name):
+        raise AttributeError("no field %r" % name)
+        
 
 class Struct(ContainerType):
-    def __init__(self, name, *fields):
+    def __init__(self, name, *fields, **kwds):
         self._name = self.__name__ = name
         flds = {}
         names = []
@@ -157,6 +172,8 @@
         self._flds = frozendict(flds)
         self._names = tuple(names)
 
+        self._install_adtmeths(**kwds)
+
     def _first_struct(self):
         if self._names:
             first = self._names[0]
@@ -184,8 +201,12 @@
         try:
             return self._flds[name]
         except KeyError:
-            raise AttributeError, 'struct %s has no field %r' % (self._name,
-                                                                 name)
+            return ContainerType.__getattr__(self, name)
+
+
+    def _nofield(self, name):
+        raise AttributeError, 'struct %s has no field %r' % (self._name,
+                                                             name)
 
     def _names_without_voids(self):
         names_without_voids = [name for name in self._names if self._flds[name] is not Void]
@@ -243,7 +264,7 @@
     __name__ = 'array'
     _anonym_struct = False
     
-    def __init__(self, *fields):
+    def __init__(self, *fields, **kwds):
         if len(fields) == 1 and isinstance(fields[0], LowLevelType):
             self.OF = fields[0]
         else:
@@ -253,6 +274,8 @@
             raise TypeError("cannot have a GC structure as array item type")
         self.OF._inline_is_varsize(False)
 
+        self._install_adtmeths(**kwds)
+
     def _inline_is_varsize(self, last):
         if not last:
             raise TypeError("cannot inline an array in another container"
@@ -611,6 +634,10 @@
             if field_name in self._T._flds:
                 o = getattr(self._obj, field_name)
                 return _expose(o)
+        if isinstance(self._T, ContainerType):
+            adtmeth = self._T._adtmeths.get(field_name)
+            if adtmeth is not None:
+                return adtmeth.__get__(self)
         raise AttributeError("%r instance has no field %r" % (self._T,
                                                               field_name))
 

Modified: pypy/dist/pypy/rpython/rdict.py
==============================================================================
--- pypy/dist/pypy/rpython/rdict.py	(original)
+++ pypy/dist/pypy/rpython/rdict.py	Sat Oct 22 23:11:04 2005
@@ -593,9 +593,15 @@
                 r.item1 = entry.value
                 items[p] = r
             elif func is dum_keys:
-                items[p] = entry.key
+                k = entry.key
+                if isinstance(LISTPTR.TO.items.TO.OF, lltype.Ptr):
+                    k = lltype.cast_pointer(LISTPTR.TO.items.TO.OF, k)
+                items[p] = k
             elif func is dum_values:
-                items[p] = entry.value
+                val = entry.value
+                if isinstance(LISTPTR.TO.items.TO.OF, lltype.Ptr):
+                    val = lltype.cast_pointer(LISTPTR.TO.items.TO.OF, val)
+                items[p] = val
             p += 1
         i += 1
     return res

Modified: pypy/dist/pypy/rpython/rlist.py
==============================================================================
--- pypy/dist/pypy/rpython/rlist.py	(original)
+++ pypy/dist/pypy/rpython/rlist.py	Sat Oct 22 23:11:04 2005
@@ -37,7 +37,7 @@
         else:
             # cannot do the rtyper.getrepr() call immediately, for the case
             # of recursive structures -- i.e. if the listdef contains itself
-            return ListRepr(lambda: rtyper.getrepr(listitem.s_value),
+            return ListRepr(rtyper, lambda: rtyper.getrepr(listitem.s_value),
                             listitem)
 
     def rtyper_makekey(self):
@@ -46,21 +46,33 @@
 
 class ListRepr(Repr):
 
-    def __init__(self, item_repr, listitem=None):
+    def __init__(self, rtyper, item_repr, listitem=None):
+        self.rtyper = rtyper
         self.LIST = GcForwardReference()
         self.lowleveltype = Ptr(self.LIST)
         if not isinstance(item_repr, Repr):  # not computed yet, done by setup()
             assert callable(item_repr)
             self._item_repr_computer = item_repr
         else:
-            self.item_repr = item_repr
+            self.set_item_repr(item_repr)
         self.listitem = listitem
         self.list_cache = {}
         # setup() needs to be called to finish this initialization
 
+    def set_item_repr(self, item_repr):
+        from pypy.rpython import rclass
+        if isinstance(item_repr, rclass.AbstractInstanceRepr):
+            self.item_repr = rclass.getinstancerepr(self.rtyper, None)
+            self.external_item_repr = item_repr
+        else:
+            self.item_repr = self.external_item_repr = item_repr
+        
+    def recast(self, llops, v):
+        return llops.convertvar(v, self.item_repr, self.external_item_repr)
+
     def _setup_repr(self):
         if 'item_repr' not in self.__dict__:
-            self.item_repr = self._item_repr_computer()
+            self.set_item_repr(self._item_repr_computer())
         if isinstance(self.LIST, GcForwardReference):
             ITEM = self.item_repr.lowleveltype
             ITEMARRAY = GcArray(ITEM)
@@ -164,7 +176,8 @@
             args = hop.inputargs(self)
             llfn = ll_pop_default
         hop.exception_is_here()
-        return hop.gendirectcall(llfn, v_func, *args)
+        v_res = hop.gendirectcall(llfn, v_func, *args)
+        return self.recast(hop.llops, v_res)
 
     def make_iterator_repr(self):
         return ListIteratorRepr(self)
@@ -209,7 +222,8 @@
         else:
             llfn = ll_getitem
         hop.exception_is_here()
-        return hop.gendirectcall(llfn, v_func, v_lst, v_index)
+        v_res = hop.gendirectcall(llfn, v_func, v_lst, v_index)
+        return r_lst.recast(hop.llops, v_res)
 
     def rtype_setitem((r_lst, r_int), hop):
         if hop.has_implicit_exception(IndexError):
@@ -843,7 +857,8 @@
         v_iter, = hop.inputargs(self)
         hop.has_implicit_exception(StopIteration) # record that we know about it
         hop.exception_is_here()
-        return hop.gendirectcall(ll_listnext, v_iter)
+        v_res = hop.gendirectcall(ll_listnext, v_iter)
+        return self.r_list.recast(hop.llops, v_res)
 
 def ll_listiter(ITERPTR, lst):
     iter = malloc(ITERPTR.TO)

Modified: pypy/dist/pypy/rpython/rptr.py
==============================================================================
--- pypy/dist/pypy/rpython/rptr.py	(original)
+++ pypy/dist/pypy/rpython/rptr.py	Sat Oct 22 23:11:04 2005
@@ -1,7 +1,8 @@
 from pypy.annotation.pairtype import pairtype
 from pypy.annotation import model as annmodel
+from pypy.objspace.flow import model as flowmodel
 from pypy.rpython.lltype import Ptr, _ptr
-from pypy.rpython.lltype import ContainerType, Void, Signed, Bool, FuncType
+from pypy.rpython.lltype import ContainerType, Void, Signed, Bool, FuncType, typeOf
 from pypy.rpython.rmodel import Repr, TyperError, IntegerRepr, inputconst
 
 
@@ -26,6 +27,8 @@
 
     def rtype_getattr(self, hop):
         attr = hop.args_s[1].const
+        if isinstance(hop.s_result, annmodel.SomeLLADTMeth):
+            return hop.inputarg(hop.r_result, arg=0)
         FIELD_TYPE = getattr(self.lowleveltype.TO, attr)
         if isinstance(FIELD_TYPE, ContainerType):
             newopname = 'getsubstruct'
@@ -121,3 +124,35 @@
     def rtype_ne((r_any, r_ptr), hop):
         vlist = hop.inputargs(r_ptr, r_ptr)
         return hop.genop('ptr_ne', vlist, resulttype=Bool)
+
+# ________________________________________________________________
+# ADT  methods
+
+class __extend__(annmodel.SomeLLADTMeth):
+    def rtyper_makerepr(self, rtyper):
+        return LLADTMethRepr(self)
+    def rtyper_makekey(self):
+        return self.__class__, self.ll_ptrtype, self.func
+
+class LLADTMethRepr(Repr):
+
+    def __init__(self, adtmeth):
+        self.adtmeth = adtmeth
+        self.lowleveltype = adtmeth.ll_ptrtype
+
+    def rtype_hardwired_simple_call(self, hop):
+        hop2 = hop.copy()
+        hop2.swap_fst_snd_args()
+        r_func, s_func = hop2.r_s_popfirstarg()
+        fptr = hop2.rtyper.getcallable(s_func.const)
+        hop2.v_s_insertfirstarg(flowmodel.Constant(fptr), annmodel.SomePtr(typeOf(fptr)))
+        return hop2.dispatch(opname='simple_call')
+
+class __extend__(pairtype(PtrRepr, LLADTMethRepr)):
+
+    def convert_from_to((r_from, r_to), v, llops):
+        if r_from.lowleveltype == r_to.lowleveltype:
+            return v
+        return NotImplemented
+
+    

Modified: pypy/dist/pypy/rpython/rtyper.py
==============================================================================
--- pypy/dist/pypy/rpython/rtyper.py	(original)
+++ pypy/dist/pypy/rpython/rtyper.py	Sat Oct 22 23:11:04 2005
@@ -156,6 +156,11 @@
             self.exceptiondata.make_helpers(self)
             self.specialize_more_blocks()   # for the helpers just made
 
+        #
+        from pypy.annotation import listdef
+        ldef = listdef.ListDef(None, annmodel.SomeString())
+        self.list_of_str_repr = self.getrepr(annmodel.SomeList(ldef))
+
     def specialize_more_blocks(self):
         while True:
             # look for blocks not specialized yet
@@ -300,6 +305,7 @@
         block.operations[:] = newops
         block.renamevariables(varmapping)
 
+        extrablock = None
         pos = newops.llop_raising_exceptions
         if (pos is not None and pos != len(newops)-1):
             # this is for the case where the llop that raises the exceptions
@@ -322,16 +328,24 @@
                 assert 0 <= pos < len(newops) - 1
                 extraops = block.operations[pos+1:]
                 del block.operations[pos+1:]
-                insert_empty_block(self.annotator.translator,
-                                   noexclink,
-                                   newops = extraops)
+                extrablock = insert_empty_block(self.annotator.translator,
+                                                noexclink,
+                                                newops = extraops)
 
-        self.insert_link_conversions(block)
+        if extrablock is None:
+            self.insert_link_conversions(block)
+        else:
+            # skip the extrablock as a link target, its link doesn't need conversions
+            # by construction, OTOH some of involved vars have no annotation
+            # so proceeding with it would kill information
+            self.insert_link_conversions(block, skip=1)
+            # consider it as a link source instead
+            self.insert_link_conversions(extrablock)
 
-    def insert_link_conversions(self, block):
+    def insert_link_conversions(self, block, skip=0):
         # insert the needed conversions on the links
         can_insert_here = block.exitswitch is None and len(block.exits) == 1
-        for link in block.exits:
+        for link in block.exits[skip:]:
             if link.exitcase is not None:
                 if isinstance(block.exitswitch, Variable):
                     r_case = self.bindingrepr(block.exitswitch)

Modified: pypy/dist/pypy/rpython/test/test_lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_lltype.py	(original)
+++ pypy/dist/pypy/rpython/test/test_lltype.py	Sat Oct 22 23:11:04 2005
@@ -424,3 +424,32 @@
     assert Q._is_atomic() is False
     assert O._is_atomic() is False
     assert F._is_atomic() is False
+
+def test_adtmeths():
+    def h_newstruct():
+        return malloc(S)
+    
+    S = GcStruct('s', ('x', Signed), 
+                 adtmeths={"h_newstruct": h_newstruct})
+
+    s = S.h_newstruct()
+
+    assert typeOf(s) == Ptr(S)
+
+    def h_alloc(n):
+        return malloc(A, n)
+
+    def h_length(a):
+        return len(a)
+
+    A = GcArray(Signed,
+                adtmeths={"h_alloc": h_alloc,
+                          "h_length": h_length})
+
+    a = A.h_alloc(10)
+
+    assert typeOf(a) == Ptr(A)
+    assert len(a) == 10
+
+    assert a.h_length() == 10
+    

Modified: pypy/dist/pypy/rpython/test/test_rdict.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rdict.py	(original)
+++ pypy/dist/pypy/rpython/test/test_rdict.py	Sat Oct 22 23:11:04 2005
@@ -271,6 +271,16 @@
     res = interpret(func, ())#, view=True)
     assert res == 14
 
+def test_dict_inst_keys():
+    class A:
+        pass
+    def func():
+        dic = {A(): 1, A(): 2}
+        keys = dic.keys()
+        return (isinstance(keys[1], A))*2+(isinstance(keys[0],A))
+    res = interpret(func, [])
+    assert res == 3
+
 def test_dict_values():
     def func():
         dic = {' 4':1000, ' 8':200}
@@ -279,6 +289,17 @@
     res = interpret(func, ())
     assert res == 1202
 
+def test_dict_inst_value():
+    class A:
+        pass
+    def func():
+        dic = {1: A(), 2: A()}
+        vals = dic.values()
+        return (isinstance(vals[1], A))*2+(isinstance(vals[0],A))
+    res = interpret(func, [])
+    assert res == 3
+
+
 def test_dict_items():
     def func():
         dic = {' 4':1000, ' 8':200}

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 Oct 22 23:11:04 2005
@@ -19,7 +19,7 @@
 del n1, n2, name
 
 def sample_list():    # [42, 43, 44, 45]
-    rlist = ListRepr(signed_repr)
+    rlist = ListRepr(None, signed_repr)
     rlist.setup()
     l = ll_newlist(rlist.lowleveltype, 3)
     ll_setitem(l, 0, 42)
@@ -204,6 +204,19 @@
     res = interpret(dummyfn, ())#, view=True)
     assert res == 42
 
+def test_inst_pop():
+    class A:
+        pass
+    l = [A(), A()]
+    def f(idx):
+        try:
+            return l.pop(idx)
+        except IndexError:
+            return None
+    res = interpret(f, [1])
+    assert ''.join(res.super.typeptr.name) == 'A\00'
+        
+
 def test_reverse():
     def dummyfn():
         l = [5, 3, 2]
@@ -375,6 +388,23 @@
     res = interpret(fn, [2])
     assert res == 1
 
+def test_inst_list():
+    def fn():
+        l = [None]
+        l[0] = Foo()
+        l.append(Bar())
+        l2 = [l[1], l[0], l[0]]
+        l.extend(l2)
+        for x in l2:
+            l.append(x)
+        x = l.pop()
+        x = l.pop()
+        x = l.pop()
+        x = l2.pop()
+        return str(x)+";"+str(l)
+    res = interpret(fn, [])
+    assert ''.join(res.chars) == '<Foo object>;[<Foo object>, <Bar object>, <Bar object>, <Foo object>, <Foo object>]'
+
 def test_list_slice_minusone():
     def fn(i):
         lst = [i, i+1, i+2]

Modified: pypy/dist/pypy/rpython/test/test_rptr.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rptr.py	(original)
+++ pypy/dist/pypy/rpython/test/test_rptr.py	Sat Oct 22 23:11:04 2005
@@ -1,5 +1,5 @@
 from pypy.translator.annrpython import RPythonAnnotator
-from pypy.rpython.annlowlevel import annotate_lowlevel_helper
+from pypy.rpython.annlowlevel import annotate_lowlevel_helper, LowLevelAnnotatorPolicy
 from pypy.rpython.lltype import *
 from pypy.rpython.rtyper import RPythonTyper
 from pypy.annotation import model as annmodel
@@ -43,3 +43,52 @@
     s, t = ll_rtype(ll_example, [annmodel.SomePtr(Ptr(S))])
     assert s == annmodel.SomeTuple([annmodel.SomePtr(Ptr(RuntimeTypeInfo)),
                                     annmodel.SomeBool()])
+
+from pypy.rpython.test.test_llinterp import interpret, gengraph
+
+def test_adtmeths():
+    policy = LowLevelAnnotatorPolicy()
+
+    def h_newstruct():
+        return malloc(S)
+    
+    S = GcStruct('s', ('x', Signed), 
+                 adtmeths={"h_newstruct": h_newstruct})
+
+    def f():
+        return S.h_newstruct()
+
+    s = interpret(f, [], policy=policy)
+
+    assert typeOf(s) == Ptr(S)
+
+    def h_alloc(n):
+        return malloc(A, n)
+    def h_length(a):
+        return len(a)
+
+    A = GcArray(Signed,
+                adtmeths={"h_alloc": h_alloc,
+                          "h_length": h_length,
+                          'flag': True})
+
+    def f():
+        return A.h_alloc(10)
+
+    a = interpret(f, [], policy=policy)
+
+    assert typeOf(a) == Ptr(A)
+    assert len(a) == 10
+    
+
+    def f():
+        a = A.h_alloc(10)
+        return a.h_length()
+
+    res = interpret(f, [], policy=policy)
+    assert res == 10
+
+    def f():
+        return A.flag
+    res = interpret(f, [], policy=policy)
+    assert res

Modified: pypy/dist/pypy/translator/transform.py
==============================================================================
--- pypy/dist/pypy/translator/transform.py	(original)
+++ pypy/dist/pypy/translator/transform.py	Sat Oct 22 23:11:04 2005
@@ -186,6 +186,12 @@
                                     op.args[0] = Constant(memo_table)
                                 else:
                                     op.opname = intern('call_specialcase')
+                elif isinstance(callb, annmodel.SomeLLADTMeth):
+                    specialized_callb, specialcase = self.bookkeeper.query_spaceop_callable(op)
+                    assert not specialcase
+                    assert not isinstance(op.args[0], Constant) and not callb.is_constant()
+                    op.opname = intern('hardwired_'+op.opname)
+                    op.args.insert(1, Constant(specialized_callb.func))
 
 def insert_stackcheck(ann):
     from pypy.tool.algo.graphlib import Edge, make_edge_dict, break_cycles



More information about the Pypy-commit mailing list