[pypy-svn] pypy default: (armin, alex, fijal): Don't escape the frame when re-raising an exception.

alex_gaynor commits-noreply at bitbucket.org
Tue Mar 8 20:14:56 CET 2011


Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: 
Changeset: r42481:eb44d135f334
Date: 2011-03-08 11:14 -0800
http://bitbucket.org/pypy/pypy/changeset/eb44d135f334/

Log:	(armin, alex, fijal): Don't escape the frame when re-raising an
	exception.

diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -538,11 +538,17 @@
         unroller = SContinueLoop(startofloop)
         return self.unrollstack_and_jump(unroller)
 
+    @jit.unroll_safe
     def RAISE_VARARGS(self, nbargs, next_instr):
         space = self.space
         if nbargs == 0:
-            operror = space.getexecutioncontext().sys_exc_info()
-            if operror is None:
+            frame = self
+            while frame:
+                if frame.last_exception is not None:
+                    operror = frame.last_exception
+                    break
+                frame = frame.f_backref()
+            else:
                 raise OperationError(space.w_TypeError,
                     space.wrap("raise: no active exception to re-raise"))
             # re-raise, no new traceback obj will be attached

diff --git a/pypy/module/pypyjit/test_pypy_c/test_pypy_c_new.py b/pypy/module/pypyjit/test_pypy_c/test_pypy_c_new.py
--- a/pypy/module/pypyjit/test_pypy_c/test_pypy_c_new.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_pypy_c_new.py
@@ -123,3 +123,20 @@
         loop, = log.loops_by_id("except")
         ops = list(loop.ops_by_id("except", opcode="COMPARE_OP"))
         assert ops == []
+
+    def test_reraise(self):
+        def f(n):
+            i = 0
+            while i < n:
+                try:
+                    try:
+                        raise KeyError
+                    except KeyError:
+                        raise
+                except KeyError:
+                    i += 1
+            return i
+
+        log = self.run(f, [100000])
+        assert log.result == 100000
+        loop, = log.loops_by_filename(self.filepath)


More information about the Pypy-commit mailing list