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

tismer at codespeak.net tismer at codespeak.net
Fri Jun 17 01:42:16 CEST 2005


Author: tismer
Date: Fri Jun 17 01:42:14 2005
New Revision: 13500

Modified:
   pypy/dist/pypy/rpython/interp.py
   pypy/dist/pypy/rpython/test/test_interp.py
Log:
interp is now working nicely with exceptions.
After all, it was easy.

Modified: pypy/dist/pypy/rpython/interp.py
==============================================================================
--- pypy/dist/pypy/rpython/interp.py	(original)
+++ pypy/dist/pypy/rpython/interp.py	Fri Jun 17 01:42:14 2005
@@ -60,26 +60,32 @@
 
     def eval_graph(self, graph, args=()): 
         nextblock = graph.startblock
+        excblock = graph.exceptblock
         while 1: 
             self.fillvars(nextblock, args) 
-            nextblock, args = self.eval_block(nextblock) 
+            nextblock, args = self.eval_block(nextblock, excblock)
             if nextblock is None: 
                 return args 
 
-    def eval_block(self, block): 
+    def eval_block(self, block, excblock): 
         """ return (nextblock, values) tuple. If nextblock 
             is None, values is the concrete return value. 
         """
         catch_exception = block.exitswitch == Constant(last_exception)
         e = None
 
-        for op in block.operations:
-            try:
+        try:
+            for op in block.operations:
                 self.eval_operation(op)
-            except RPythonError, e:
-                # XXX should only catch exceptions from the last operation
-                # XXX non-caught exceptions should just be allowed to propagate
-                assert catch_exception, 'exception received, but not expected'
+        except RPythonError, e:
+            if not catch_exception:
+                # there is no explicit handler.
+                # we could simply re-raise here, but it is cleaner
+                # to redirect to the provided default exception block
+                block = excblock
+                cls, inst = e.args
+                self.setvar(block.inputargs[0], cls)
+                self.setvar(block.inputargs[1], inst)
 
         # determine nextblock and/or return value 
         if len(block.exits) == 0:
@@ -109,9 +115,9 @@
                     if exdata.ll_exception_match(cls, link.llexitcase):
                         self.setvar(link.last_exception, cls)
                         self.setvar(link.last_exc_value, inst)
-                        return link.target, [cls, inst]
+                        break
                 else:
-                    raise Exception, e # unhandled case, should not happen"
+                    raise Exception, e # unhandled case, should not happen
         else: 
             index = self.getval(block.exitswitch)
             link = block.exits[index]

Modified: pypy/dist/pypy/rpython/test/test_interp.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_interp.py	(original)
+++ pypy/dist/pypy/rpython/test/test_interp.py	Fri Jun 17 01:42:14 2005
@@ -59,10 +59,18 @@
     assert find_exception(info.value) is ValueError
 
 def test_call_raise():
-    res = interpret(call_raise_intercept, [41])
+    res = interpret(call_raise, [41])
     assert res == 41
-    info = raises(RPythonError, interpret, call_raise_intercept, [42])
+    info = raises(RPythonError, interpret, call_raise, [42])
     assert find_exception(info.value) is IndexError
+    info = raises(RPythonError, interpret, call_raise, [43])
+    assert find_exception(info.value) is ValueError
+
+def test_call_raise_intercept():
+    res = interpret(call_raise_intercept, [41])
+    assert res == 41
+    res = interpret(call_raise_intercept, [42])
+    assert res == 42
     info = raises(RPythonError, interpret, call_raise_intercept, [43])
     assert find_exception(info.value) is TypeError
 
@@ -137,9 +145,14 @@
         raise ValueError
     return i
 
+def call_raise(i):
+    return raise_exception(i)
+
 def call_raise_intercept(i):
     try:
         return raise_exception(i)
+    except IndexError:
+        return i
     except ValueError:
         raise TypeError
 #__________________________________________________________________



More information about the Pypy-commit mailing list