[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