[pypy-svn] r7546 - in pypy/trunk/src/pypy: interpreter objspace/flow objspace/std

arigo at codespeak.net arigo at codespeak.net
Mon Nov 22 10:56:42 CET 2004


Author: arigo
Date: Mon Nov 22 10:56:41 2004
New Revision: 7546

Modified:
   pypy/trunk/src/pypy/interpreter/pyframe.py
   pypy/trunk/src/pypy/interpreter/pyopcode.py
   pypy/trunk/src/pypy/objspace/flow/specialcase.py
   pypy/trunk/src/pypy/objspace/std/fake.py
Log:
Re-enabled the 3rd (tb) argument of raise statements in RPython code.  (the
flow objspace ignores it, but no longer crashes because of it.)



Modified: pypy/trunk/src/pypy/interpreter/pyframe.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/pyframe.py	(original)
+++ pypy/trunk/src/pypy/interpreter/pyframe.py	Mon Nov 22 10:56:41 2004
@@ -149,8 +149,9 @@
             operationerr = unroller.args[0]
             w_type  = operationerr.w_type
             w_value = operationerr.w_value
-            w_normalized = normalize_exception(frame.space, w_type, w_value)
-            w_type, w_value = frame.space.unpacktuple(w_normalized, 2)
+            w_normalized = normalize_exception(frame.space, w_type, w_value,
+                                               frame.space.w_None)
+            w_type, w_value, w_tb = frame.space.unpacktuple(w_normalized, 3)
             # save the normalized exception back into the OperationError
             # -- in particular it makes sure that sys.exc_info() etc see
             #    normalized exception.
@@ -166,7 +167,7 @@
             return True  # stop unrolling
         return False
 
-def app_normalize_exception(etype, value):
+def app_normalize_exception(etype, value, tb):
     """Normalize an (exc_type, exc_value) pair:
     exc_value will be an exception instance and exc_type its class.
     """
@@ -202,7 +203,7 @@
         if not hasattr(value, '__dict__') and not hasattr(value, '__slots__'):
             raise TypeError("raising built-in objects can be ambiguous, "
                             "use 'raise type, value' instead")
-    return etype, value
+    return etype, value, tb
 normalize_exception = gateway.app2interp(app_normalize_exception)
 
 

Modified: pypy/trunk/src/pypy/interpreter/pyopcode.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/pyopcode.py	(original)
+++ pypy/trunk/src/pypy/interpreter/pyopcode.py	Mon Nov 22 10:56:41 2004
@@ -316,8 +316,9 @@
         if nbargs >= 3: w_traceback = f.valuestack.pop()
         if nbargs >= 2: w_value     = f.valuestack.pop()
         if 1:           w_type      = f.valuestack.pop()
-        w_resulttuple = pyframe.normalize_exception(f.space, w_type, w_value)
-        w_type, w_value = f.space.unpacktuple(w_resulttuple, 2)
+        w_resulttuple = pyframe.normalize_exception(f.space, w_type, w_value,
+                                                    w_traceback)
+        w_type, w_value, w_traceback = f.space.unpacktuple(w_resulttuple, 3)
         tb = f.space.unwrap(w_traceback)
         if tb is not None:
             if not isinstance(tb,pytraceback.PyTraceback):

Modified: pypy/trunk/src/pypy/objspace/flow/specialcase.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/flow/specialcase.py	(original)
+++ pypy/trunk/src/pypy/objspace/flow/specialcase.py	Mon Nov 22 10:56:41 2004
@@ -34,15 +34,24 @@
        - assumes that Arg is the value you want for the exception, and
          that Class is exactly the exception class.  No check or normalization.
     """
-    assert len(args.args_w) == 2 and args.kwds_w == {}
-    w_arg1, w_arg2 = args.args_w
+    assert len(args.args_w) == 3 and args.kwds_w == {}
+    w_arg1, w_arg2, w_tb = args.args_w
+
+    # w_arg3 (the traceback) is ignored and replaced with None
+    # if it is a Variable, because pyopcode.py tries to unwrap it.
+    # It means that we ignore the 'tb' argument of 'raise' in most cases.
+    if not isinstance(w_tb, Constant):
+        w_tb = space.w_None
+
     if w_arg2 != space.w_None:
         # raise Class, Arg: no normalization
-        return (w_arg1, w_arg2)
+        return (w_arg1, w_arg2, w_tb)
+
     etype = getconstclass(space, w_arg1)
     if etype is not None:
         # raise Class
-        return (w_arg1, space.w_None)
+        return (w_arg1, space.w_None, w_tb)
+
     # raise Class(..)?  We need a hack to figure out of which class it is.
     # Normally, Instance should have been created by the previous operation
     # which should be a simple_call(<Class>, ...).
@@ -52,10 +61,11 @@
         if (spaceop.opname == 'simple_call' and
             spaceop.result is w_arg1):
             w_type = spaceop.args[0]
-            return (w_type, w_arg1)
+            return (w_type, w_arg1, w_tb)
+
     # raise Instance.  Fall-back.
     w_type = space.do_operation('type', w_arg1)
-    return (w_type, w_arg1)
+    return (w_type, w_arg1, w_tb)
     # this function returns a real tuple that can be handled
     # by FlowObjSpace.unpacktuple()
 

Modified: pypy/trunk/src/pypy/objspace/std/fake.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/fake.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/fake.py	Mon Nov 22 10:56:41 2004
@@ -18,7 +18,7 @@
 def wrap_exception(space):
     exc, value, tb = sys.exc_info()
     if exc is OperationError:
-        raise exc, value  #, tb   # just re-raise it (tb ignored: not RPython)
+        raise exc, value, tb   # just re-raise it
     name = exc.__name__
     if hasattr(space, 'w_' + name):
         w_exc = getattr(space, 'w_' + name)
@@ -30,7 +30,7 @@
     else:
         w_exc = space.wrap(exc)
         w_value = space.wrap(value)
-    raise OperationError, OperationError(w_exc, w_value)  #, tb not RPython
+    raise OperationError, OperationError(w_exc, w_value), tb
 
 def fake_type(cpy_type):
     assert type(cpy_type) is type



More information about the Pypy-commit mailing list