[pypy-svn] r25292 - in pypy/dist/pypy/rpython/ootypesystem: . test

nik at codespeak.net nik at codespeak.net
Tue Apr 4 15:31:41 CEST 2006


Author: nik
Date: Tue Apr  4 15:31:39 2006
New Revision: 25292

Modified:
   pypy/dist/pypy/rpython/ootypesystem/exceptiondata.py
   pypy/dist/pypy/rpython/ootypesystem/rlist.py
   pypy/dist/pypy/rpython/ootypesystem/rootype.py
   pypy/dist/pypy/rpython/ootypesystem/test/test_oolist.py
   pypy/dist/pypy/rpython/ootypesystem/test/test_oortype.py
Log:
(pedronis, nik)
tackle exception for ootype in general (all oosends can raise an exception)
and test it for list getitem/setitem in particular.


Modified: pypy/dist/pypy/rpython/ootypesystem/exceptiondata.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/exceptiondata.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/exceptiondata.py	Tue Apr  4 15:31:39 2006
@@ -1,13 +1,17 @@
 from pypy.rpython.exceptiondata import AbstractExceptionData
 from pypy.rpython.ootypesystem import rclass
+from pypy.rpython.ootypesystem import ootype
 from pypy.rpython.annlowlevel import annotate_lowlevel_helper
 from pypy.annotation import model as annmodel
+from pypy.annotation.classdef import FORCE_ATTRIBUTES_INTO_CLASSES
 
 class ExceptionData(AbstractExceptionData):
     """Public information for the code generators to help with exceptions."""
 
     def make_helpers(self, rtyper):
         self.fn_exception_match = self.make_exception_matcher(rtyper)
+        self.fn_pyexcclass2exc = self.make_pyexcclass2exc(rtyper)
+        self.fn_type_of_exc_inst = self.make_type_of_exc_inst(rtyper)
 
     def make_exception_matcher(self, rtyper):
         # ll_exception_matcher(real_exception_meta, match_exception_meta)
@@ -15,3 +19,75 @@
         helper_graph = annotate_lowlevel_helper(
             rtyper.annotator, rclass.ll_issubclass, [s_classtype, s_classtype])
         return rtyper.getcallable(helper_graph)
+
+    def make_type_of_exc_inst(self, rtyper):
+        # ll_type_of_exc_inst(exception_instance) -> exception_vtable
+        s_excinst = annmodel.SomeOOInstance(self.lltype_of_exception_value)
+        helper_graph = annotate_lowlevel_helper(
+            rtyper.annotator, rclass.ll_inst_type, [s_excinst])
+        return rtyper.getcallable(helper_graph)
+
+    def make_pyexcclass2exc(self, rtyper):
+        # ll_pyexcclass2exc(python_exception_class) -> exception_instance
+        table = {}
+        Exception_def = rtyper.annotator.bookkeeper.getuniqueclassdef(Exception)
+        for clsdef in rtyper.class_reprs:
+            if (clsdef and clsdef is not Exception_def
+                and clsdef.issubclass(Exception_def)):
+                if not hasattr(clsdef.classdesc, 'pyobj'):
+                    continue
+                cls = clsdef.classdesc.pyobj
+                if cls in self.standardexceptions and cls not in FORCE_ATTRIBUTES_INTO_CLASSES:
+                    is_standard = True
+                    assert not clsdef.attrs, (
+                        "%r should not have grown attributes" % (cls,))
+                else:
+                    is_standard = (cls.__module__ == 'exceptions'
+                                   and not clsdef.attrs)
+                if is_standard:
+                    r_inst = rclass.getinstancerepr(rtyper, clsdef)
+                    r_inst.setup()
+                    r_class = rclass.getclassrepr(rtyper, clsdef)
+                    r_class.setup()
+                    example = ootype.new(r_inst.lowleveltype)
+                    example = ootype.ooupcast(self.lltype_of_exception_value, example)
+                    example.meta = r_class.get_meta_instance()
+                    table[cls] = example
+        r_inst = rclass.getinstancerepr(rtyper, None)
+        r_inst.setup()
+        r_class = rclass.getclassrepr(rtyper, None)
+        r_class.setup()
+        default_excinst = ootype.new(self.lltype_of_exception_value)
+        default_excinst.meta = r_class.get_meta_instance()
+
+        # build the table in order base classes first, subclasses last
+        sortedtable = []
+        def add_class(cls):
+            if cls in table:
+                for base in cls.__bases__:
+                    add_class(base)
+                sortedtable.append((cls, table[cls]))
+                del table[cls]
+        for cls in table.keys():
+            add_class(cls)
+        assert table == {}
+
+        initial_value_of_i = len(sortedtable) - 1
+        def pyexcclass2exc(python_exception_class):
+            python_exception_class = python_exception_class._obj.value
+            i = initial_value_of_i
+            while i >= 0:
+                if issubclass(python_exception_class, sortedtable[i][0]):
+                    return sortedtable[i][1]
+                i -= 1
+            return default_excinst
+
+        # This function will only be used by the llinterpreter which usually
+        # expects a low-level callable (_meth, _static_meth), so we just
+        # fake it here.
+        FakeCallableType = ootype.OOType()
+        class fake_callable(object):
+            def __init__(self, fn):
+                self._TYPE = FakeCallableType
+                self._callable = fn
+        return fake_callable(pyexcclass2exc)

Modified: pypy/dist/pypy/rpython/ootypesystem/rlist.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/rlist.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/rlist.py	Tue Apr  4 15:31:39 2006
@@ -46,16 +46,11 @@
 class __extend__(pairtype(BaseListRepr, IntegerRepr)):
 
     def rtype_getitem((r_list, r_int), hop):
-        # XXX must handle exceptions
-        #if hop.has_implicit_exception(IndexError):
         # XXX must handle negative indices
         return r_list.send_message(hop, "getitem", can_raise=True)
 
     def rtype_setitem((r_list, r_int), hop):
-        # XXX must handle exceptions
-        #if hop.has_implicit_exception(IndexError):
         # XXX must handle negative indices
-        #if hop.has_implicit_exception(IndexError):
         return r_list.send_message(hop, "setitem", can_raise=True)
 
 def newlist(llops, r_list, items_v):

Modified: pypy/dist/pypy/rpython/ootypesystem/rootype.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/rootype.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/rootype.py	Tue Apr  4 15:31:39 2006
@@ -68,6 +68,7 @@
     def rtype_simple_call(self, hop):
         vlist = hop.inputargs(self, *hop.args_r[1:])
         cname = hop.inputconst(Void, self.name)
+        hop.exception_is_here()
         return hop.genop("oosend", [cname]+vlist,
                          resulttype = hop.r_result.lowleveltype)
         

Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_oolist.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/test/test_oolist.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/test/test_oolist.py	Tue Apr  4 15:31:39 2006
@@ -1,3 +1,4 @@
+import py
 from pypy.rpython.test.test_llinterp import interpret 
 from pypy.rpython.ootypesystem.ootype import *
 
@@ -25,6 +26,12 @@
     l.setitem(0, 3)
     assert l.getitem(0) == 3
 
+def test_setitem_indexerror():
+    LT = List(Signed)
+    l = new(LT)
+    py.test.raises(IndexError, l.getitem, 0)
+    py.test.raises(IndexError, l.setitem, 0, 1)
+
 class TestInterpreted:
 
     def test_append_length(self):

Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_oortype.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/test/test_oortype.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/test/test_oortype.py	Tue Apr  4 15:31:39 2006
@@ -121,7 +121,6 @@
     assert rettype == Unsigned
 
 def test_list_getitem_setitem():
-    # XXX need to test exceptions
     LT = List(Signed)
 
     def oof():
@@ -134,3 +133,16 @@
     rettype = g.getreturnvar().concretetype
     assert rettype == Signed
 
+def test_list_getitem_exceptions():
+    LT = List(Signed)
+
+    def oof():
+        l = new(LT)
+        try:
+            l.getitem(0)
+        except IndexError:
+            return -1
+        return 0
+
+    res = interpret(oof, [], type_system='ootype')
+    assert res is -1



More information about the Pypy-commit mailing list