Ronan Lamy  committed e78d34c

Turn FSException into a normal object, not an exception.

FSException now unambiguously represents RPython-level exception objects,
and is separate from the internal translator-level exceptions used by
flowspace to implement control flow.

  • Participants
  • Parent commits e675c5b
  • Branches less-stringly-ops

Comments (0)

Files changed (4)

File rpython/flowspace/

     def __init__(self, value):
         self.value = value
-class RaiseImplicit(Exception):
+class Raise(Exception):
     def __init__(self, value):
         self.value = value
+class RaiseImplicit(Raise):
+    pass
 class BytecodeCorruption(Exception):
             link = Link([w_type, w_value], self.graph.exceptblock)
-        except FSException, e:
-            if e.w_type ==
+        except Raise as e:
+            w_exc = e.value
+            if w_exc.w_type ==
                 msg = 'import statement always raises %s' % e
                 raise ImportError(msg)
-            link = Link([e.w_type, e.w_value], self.graph.exceptblock)
+            link = Link([w_exc.w_type, w_exc.w_value], self.graph.exceptblock)
         except StopFlowing:
             return res if res is not None else next_instr
         except RaiseImplicit as e:
             return SImplicitException(e.value).unroll(self)
-        except FSException, operr:
-            return self.handle_operation_error(operr)
-    def handle_operation_error(self, operr):
-        unroller = SApplicationException(operr)
-        return unroller.unroll(self)
+        except Raise as e:
+            return SApplicationException(e.value).unroll(self)
     def getlocalvarname(self, index):
         return self.pycode.co_varnames[index]
         space =
         if nbargs == 0:
             if self.last_exception is not None:
-                raise self.last_exception
+                w_exc = self.last_exception
-                raise const(TypeError(
+                w_exc = const(TypeError(
                     "raise: no active exception to re-raise"))
+            raise Raise(w_exc)
         if nbargs >= 3:
                 operror = w_type
                 operror = space.exc_from_raise(w_type, space.w_None)
-        raise operror
+        raise Raise(operror)
     def IMPORT_NAME(self, nameindex):
         space =
         w_iterator = self.peekvalue()
             w_nextitem =
-        except RaiseImplicit as e:
+        except Raise as e:
             w_exc = e.value
             if not,
             # iterator exhausted
             return target
-        except FSException as e:
-            if not,
-                raise
-            # iterator exhausted
-            self.popvalue()
-            return target
         self.operr = operr
     def nomoreblocks(self):
-        raise self.operr
+        raise Raise(self.operr)
     def state_unpack_variables(self):
         return [self.operr.w_type, self.operr.w_value]

File rpython/flowspace/

             return False
-class FSException(Exception):
+class FSException(object):
     def __init__(self, w_type, w_value):
         assert w_type is not None
         self.w_type = w_type

File rpython/flowspace/

 from rpython.flowspace.bytecode import HostCode
 from rpython.flowspace.operation import op, NOT_REALLY_CONST
 from rpython.flowspace.flowcontext import (FlowSpaceFrame, fixeggblocks,
-    FlowingError)
+    FlowingError, Raise)
 from rpython.flowspace.generator import (tweak_generator_graph,
 from rpython.flowspace.pygraph import PyGraph
             # the only case left here is (inst, None), from a 'raise inst'.
             if not frame.guessbool(self.is_(w_arg2, self.w_None)):
-                raise const(TypeError(
-                    "instance exception may not have a separate value"))
+                exc = TypeError("instance exception may not have a "
+                                "separate value")
+                raise Raise(const(exc))
             w_value = w_arg1
         w_type = self.type(w_value)
         return FSException(w_type, w_value)
             w_len = self.len(w_iterable)
             w_correct = self.eq(w_len, const(expected_length))
             if not self.frame.guessbool(self.bool(w_correct)):
-                e = self.exc_from_raise(self.w_ValueError, self.w_None)
-                raise e
+                w_exc = self.exc_from_raise(self.w_ValueError, self.w_None)
+                raise Raise(w_exc)
             return [self.frame.do_operation('getitem', w_iterable, const(i))
                         for i in range(expected_length)]
             mod = __import__(name, glob, loc, frm, level)
         except ImportError as e:
-            raise const(e)
+            raise Raise(const(e))
         return const(mod)
     def import_from(self, w_module, w_name):
             return const(getattr(w_module.value, w_name.value))
         except AttributeError:
-            raise const(ImportError("cannot import name '%s'" % w_name.value))
+            exc = ImportError("cannot import name '%s'" % w_name.value)
+            raise Raise(const(exc))
     def call_method(self, w_obj, methname, *arg_w):
         w_meth = self.getattr(w_obj, const(methname))

File rpython/flowspace/

                     v, next_unroller = it.step()
                 except IndexError:
-                    raise const(StopIteration())
+                    from rpython.flowspace.flowcontext import Raise
+                    raise Raise(const(StopIteration()))
                     frame.replace_in_stack(it, next_unroller)
                     return const(v)