[pypy-svn] r77069 - in pypy/branch/better-map-instances/pypy/rlib: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Tue Sep 14 17:54:29 CEST 2010


Author: cfbolz
Date: Tue Sep 14 17:54:27 2010
New Revision: 77069

Modified:
   pypy/branch/better-map-instances/pypy/rlib/rerased.py
   pypy/branch/better-map-instances/pypy/rlib/test/test_rerased.py
Log:
whack whack whack, until erasing fixed-size lists of instances works


Modified: pypy/branch/better-map-instances/pypy/rlib/rerased.py
==============================================================================
--- pypy/branch/better-map-instances/pypy/rlib/rerased.py	(original)
+++ pypy/branch/better-map-instances/pypy/rlib/rerased.py	Tue Sep 14 17:54:27 2010
@@ -23,8 +23,15 @@
         res = 2 * x + 1
         if res > sys.maxint or res < -sys.maxint - 1:
             raise OverflowError
+    assert not isinstance(x, list)
     return Erased(x)
 
+def erase_fixedsizelist(l, type):
+    assert isinstance(l, list)
+    result = Erased(l)
+    result._list_item_type = type
+    return result
+
 def unerase(y, type):
     """Turn an erased object back into an object of type 'type'."""
     if y._x is None:
@@ -32,6 +39,14 @@
     assert isinstance(y._x, type)
     return y._x
 
+def unerase_fixedsizelist(y, type):
+    if y._x is None:
+        return None
+    assert isinstance(y._x, list)
+    if y._x:
+        assert isinstance(y._x[0], type)
+    return y._x
+
 def is_integer(e):
     """Gives information whether the erased argument is a tagged integer or not."""
     return isinstance(e._x, int)
@@ -40,6 +55,7 @@
 # ---------- implementation-specific ----------
 
 class Erased(object):
+    _list_item_type = None
     def __init__(self, x):
         self._x = x
     def __repr__(self):
@@ -55,6 +71,18 @@
         return hop.r_result.specialize_call(hop)
 
 class Entry(ExtRegistryEntry):
+    _about_ = erase_fixedsizelist
+
+    def compute_result_annotation(self, s_arg, s_type):
+        # s_type ignored: only for prebuilt erased lists
+        assert isinstance(s_arg, annmodel.SomeList)
+        s_arg.listdef.never_resize()
+        return SomeErased()
+
+    def specialize_call(self, hop):
+        return hop.r_result.specialize_call(hop)
+
+class Entry(ExtRegistryEntry):
     _about_ = unerase
 
     def compute_result_annotation(self, s_obj, s_type):
@@ -75,6 +103,21 @@
         return hop.genop('cast_opaque_ptr', [v], resulttype = hop.r_result)
 
 class Entry(ExtRegistryEntry):
+    _about_ = unerase_fixedsizelist
+
+    def compute_result_annotation(self, s_obj, s_type):
+        assert isinstance(s_type, annmodel.SomePBC)
+        assert len(s_type.descriptions) == 1
+        clsdef = s_type.descriptions.keys()[0].getuniqueclassdef()
+        s_item = annmodel.SomeInstance(clsdef)
+        return self.bookkeeper.newlist(s_item)
+
+    def specialize_call(self, hop):
+        v, t = hop.inputargs(hop.args_r[0], lltype.Void)
+        return hop.genop('cast_opaque_ptr', [v], resulttype = hop.r_result)
+
+
+class Entry(ExtRegistryEntry):
     _about_ = is_integer
 
     def compute_result_annotation(self, s_obj):
@@ -92,16 +135,21 @@
     _type_ = Erased
 
     def compute_annotation(self):
-        from pypy.rlib import _jit_vref
         s_obj = self.bookkeeper.immutablevalue(self.instance._x)
+        if self.instance._list_item_type is not None:
+            # only non-resizable lists of instances for now
+            clsdef = self.bookkeeper.getuniqueclassdef(self.instance._list_item_type)
+            s_item = annmodel.SomeInstance(clsdef)
+            s_obj.listdef.generalize(s_item)
+            self.instance._s_list = s_obj
         return SomeErased()
 
-# annotation and rtyping support 
+# annotation and rtyping support
 
 class SomeErased(annmodel.SomeObject):
 
-    def __init__(self):
-        pass
+    def __init__(self, s_obj=None):
+        self.s_obj = s_obj # only non-None for constants
 
     def can_be_none(self):
         return False # cannot be None, but can contain a None
@@ -124,7 +172,7 @@
         self.rtyper = rtyper
 
     def specialize_call(self, hop):
-        s_arg, = hop.args_s
+        s_arg = hop.args_s[0]
         r_generic_object = getinstancerepr(hop.rtyper, None)
         if (isinstance(s_arg, annmodel.SomeInstance) or
                 (s_arg.is_constant() and s_arg.const is None)):
@@ -133,6 +181,13 @@
             v = hop.genop('cast_opaque_ptr', [v_instance],
                           resulttype=self.lowleveltype)
             return v
+        elif isinstance(s_arg, annmodel.SomeList):
+            hop.exception_cannot_occur()
+            r_list = self.rtyper.getrepr(s_arg)
+            v_list = hop.inputarg(r_list, 0)
+            v = hop.genop('cast_opaque_ptr', [v_list],
+                          resulttype=self.lowleveltype)
+            return v
         else:
             assert isinstance(s_arg, annmodel.SomeInteger)
             v_value = hop.inputarg(lltype.Signed, arg=0)
@@ -152,6 +207,10 @@
     def convert_const(self, value):
         if isinstance(value._x, int):
             return lltype.cast_int_to_ptr(self.lowleveltype, value._x * 2 + 1)
+        if isinstance(value._x, list):
+            r_list = self.rtyper.getrepr(value._s_list)
+            v = r_list.convert_const(value._x)
+            return lltype.cast_opaque_ptr(self.lowleveltype, v)
         else:
             r_generic_object = getinstancerepr(self.rtyper, None)
             v = r_generic_object.convert_const(value._x)

Modified: pypy/branch/better-map-instances/pypy/rlib/test/test_rerased.py
==============================================================================
--- pypy/branch/better-map-instances/pypy/rlib/test/test_rerased.py	(original)
+++ pypy/branch/better-map-instances/pypy/rlib/test/test_rerased.py	Tue Sep 14 17:54:27 2010
@@ -1,6 +1,6 @@
 import py
 import sys
-from pypy.rlib.rerased import erase, unerase, is_integer, SomeErased
+from pypy.rlib.rerased import *
 from pypy.annotation import model as annmodel
 from pypy.annotation.annrpython import RPythonAnnotator
 from pypy.rpython.test.test_llinterp import interpret
@@ -39,6 +39,12 @@
     py.test.raises(OverflowError, erase, -sys.maxint)
     py.test.raises(OverflowError, erase, -sys.maxint-1)
 
+def test_list():
+    l = [X()]
+    e = erase_fixedsizelist(l, X)
+    assert is_integer(e) is False
+    assert unerase_fixedsizelist(e, X) is l
+
 def test_annotate_1():
     def f():
         return erase(X())
@@ -133,3 +139,23 @@
     s_e2 = SomeErased()
     s_e2.const = 3
     assert not annmodel.pair(s_e1, s_e2).union().is_constant()
+
+
+def test_rtype_list():
+    prebuilt_l = [X()]
+    prebuilt_e = erase_fixedsizelist(prebuilt_l, X)
+    def l(flag):
+        if flag == 1:
+            l = [X()]
+            e = erase_fixedsizelist(l, X)
+        elif flag == 2:
+            l = prebuilt_l
+            e = erase_fixedsizelist(l, X)
+        else:
+            l = prebuilt_l
+            e = prebuilt_e
+        assert is_integer(e) is False
+        assert unerase_fixedsizelist(e, X) is l
+    interpret(l, [0])
+    interpret(l, [1])
+    interpret(l, [2])



More information about the Pypy-commit mailing list