[pypy-commit] pypy py3k: we cannot push frame.last_exception directly to the valuestack: instead, we wrap it inside a tiny operation error wrapper

antocuni noreply at buildbot.pypy.org
Fri Mar 2 14:03:12 CET 2012


Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: py3k
Changeset: r53108:1466c3172b9b
Date: 2012-03-02 14:02 +0100
http://bitbucket.org/pypy/pypy/changeset/1466c3172b9b/

Log:	we cannot push frame.last_exception directly to the valuestack:
	instead, we wrap it inside a tiny operation error wrapper

diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py
--- a/pypy/interpreter/error.py
+++ b/pypy/interpreter/error.py
@@ -469,3 +469,14 @@
 def typed_unwrap_error_msg(space, expected, w_obj):
     type_name = space.type(w_obj).getname(space)
     return space.wrap("expected %s, got %s object" % (expected, type_name))
+
+
+from pypy.interpreter.baseobjspace import Wrappable
+
+class W_OperationError(Wrappable):
+    """
+    Tiny applevel wrapper around an OperationError.
+    """
+
+    def __init__(self, operr):
+        self.operr = operr
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -529,10 +529,16 @@
             self.setdictscope(w_locals)
 
     def POP_EXCEPT(self, oparg, next_instr):
+        from pypy.interpreter.error import W_OperationError
         assert self.space.py3k
         # on CPython, POP_EXCEPT also pops the block. Here, the block is
         # automatically popped by unrollstack()
-        self.last_exception = self.popvalue()
+        w_last_exception = self.popvalue()
+        if not isinstance(w_last_exception, W_OperationError):
+            msg = "expected an OperationError, got %s" % (
+                self.space.str_w(w_last_exception))
+            raise BytecodeCorruption(msg)
+        self.last_exception = w_last_exception.operr
 
     def POP_BLOCK(self, oparg, next_instr):
         block = self.pop_block()
@@ -1277,8 +1283,11 @@
         # instead of the traceback, we store the unroller object,
         # wrapped.
         if frame.space.py3k:
+            from pypy.interpreter.error import W_OperationError
             # this is popped by POP_EXCEPT, which is present only in py3k
-            frame.pushvalue(frame.last_exception)
+            w_last_exception = W_OperationError(frame.last_exception)
+            w_last_exception = frame.space.wrap(w_last_exception)
+            frame.pushvalue(w_last_exception)
         frame.pushvalue(frame.space.wrap(unroller))
         frame.pushvalue(operationerr.get_w_value(frame.space))
         frame.pushvalue(operationerr.w_type)
diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py
--- a/pypy/interpreter/typedef.py
+++ b/pypy/interpreter/typedef.py
@@ -6,7 +6,7 @@
 from pypy.interpreter.gateway import interp2app, BuiltinCode
 from pypy.interpreter.argument import Arguments
 from pypy.interpreter.baseobjspace import Wrappable, DescrMismatch
-from pypy.interpreter.error import OperationError, operationerrfmt
+from pypy.interpreter.error import OperationError, operationerrfmt, W_OperationError
 from pypy.tool.sourcetools import compile2, func_with_new_name
 from pypy.rlib.objectmodel import instantiate, compute_identity_hash, specialize
 from pypy.rlib.jit import promote
@@ -940,3 +940,5 @@
 
 SuspendedUnroller.typedef = TypeDef("SuspendedUnroller")
 SuspendedUnroller.typedef.acceptable_as_base_class = False
+
+W_OperationError.typedef = TypeDef("OperationError")


More information about the pypy-commit mailing list