[pypy-commit] pypy py3k: simplify sys_exc_info to return None for a cleared exception and reuse some of

pjenvey pypy.commits at gmail.com
Tue Apr 26 19:08:54 EDT 2016


Author: Philip Jenvey <pjenvey at underboss.org>
Branch: py3k
Changeset: r83929:5c78522a3851
Date: 2016-04-25 17:34 -0700
http://bitbucket.org/pypy/pypy/changeset/5c78522a3851/

Log:	simplify sys_exc_info to return None for a cleared exception and
	reuse some of it in RAISE_VARARGS (grafted from
	c24bc2ff9f5d07e096456bd038b2198ede3558eb)

diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py
--- a/pypy/interpreter/executioncontext.py
+++ b/pypy/interpreter/executioncontext.py
@@ -1,7 +1,6 @@
 import sys
 from pypy.interpreter.error import OperationError, get_cleared_operation_error
 from rpython.rlib.unroll import unrolling_iterable
-from rpython.rlib.objectmodel import specialize
 from rpython.rlib import jit
 
 TICK_COUNTER_STEP = 100
@@ -214,21 +213,18 @@
             self._trace(frame, 'exception', None, operationerr)
         #operationerr.print_detailed_traceback(self.space)
 
-    @staticmethod
-    def last_operr(space, frame):
-        while frame:
-            last = frame.last_exception
-            if (last is not None and
-                (not frame.hide() or
-                 last is get_cleared_operation_error(space))):
-                    return last
-            frame = frame.f_backref()
-        return None
+    @jit.dont_look_inside
+    def sys_exc_info(self):
+        """Implements sys.exc_info().
+        Return an OperationError instance or None.
 
-    def sys_exc_info(self): # attn: the result is not the wrapped sys.exc_info() !!!
-        """Implements sys.exc_info().
-        Return an OperationError instance or None."""
-        return self.last_operr(self.space, self.gettopframe())
+        Ignores exceptions within hidden frames unless for_hidden=True
+        is specified.
+
+        # NOTE: the result is not the wrapped sys.exc_info() !!!
+
+        """
+        return self.gettopframe()._exc_info_unroll(self.space)
 
     def set_sys_exc_info(self, operror):
         frame = self.gettopframe_nohidden()
diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -4,7 +4,7 @@
 from rpython.rlib import jit
 from rpython.rlib.debug import make_sure_not_resized, check_nonneg
 from rpython.rlib.jit import hint
-from rpython.rlib.objectmodel import we_are_translated, instantiate
+from rpython.rlib.objectmodel import instantiate, we_are_translated
 from rpython.rlib.rarithmetic import intmask, r_uint
 from rpython.tool.pairtype import extendabletype
 
@@ -12,7 +12,8 @@
 from pypy.interpreter.argument import Arguments
 from pypy.interpreter.astcompiler import consts
 from pypy.interpreter.baseobjspace import W_Root
-from pypy.interpreter.error import OperationError, oefmt
+from pypy.interpreter.error import (
+    OperationError, get_cleared_operation_error, oefmt)
 from pypy.interpreter.executioncontext import ExecutionContext
 from pypy.interpreter.nestedscope import Cell
 from pypy.tool import stdlib_opcode
@@ -870,6 +871,21 @@
             return space.wrap(self.builtin is not space.builtin)
         return space.w_False
 
+    @jit.unroll_safe
+    def _exc_info_unroll(self, space):
+        """Return the most recent OperationError being handled in the
+        call stack
+        """
+        frame = self
+        while frame:
+            last = frame.last_exception
+            if last is not None:
+                if last is get_cleared_operation_error(self.space):
+                    break
+                if not frame.hide():
+                    return last
+            frame = frame.f_backref()
+        return None
 
 # ____________________________________________________________
 
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -652,24 +652,18 @@
         unroller = SContinueLoop(startofloop)
         return self.unrollstack_and_jump(unroller)
 
-    @jit.unroll_safe
     def RAISE_VARARGS(self, nbargs, next_instr):
         space = self.space
         if nbargs > 2:
             raise BytecodeCorruption("bad RAISE_VARARGS oparg")
         if nbargs == 0:
-            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_RuntimeError,
-                    space.wrap("No active exception to reraise"))
+            last_operr = self._exc_info_unroll(space)
+            if last_operr is None:
+                raise oefmt(space.w_RuntimeError,
+                            "No active exception to reraise")
             # re-raise, no new traceback obj will be attached
-            self.last_exception = operror
-            raise RaiseWithExplicitTraceback(operror)
+            self.last_exception = last_operr
+            raise RaiseWithExplicitTraceback(last_operr)
         if nbargs == 2:
             w_cause = self.popvalue()
             if space.exception_is_valid_obj_as_class_w(w_cause):


More information about the pypy-commit mailing list