Author: Maciej Fijalkowski <fij...@gmail.com>
Branch: optresult
Changeset: r77769:22d1b419809f
Date: 2015-06-02 16:14 +0200
http://bitbucket.org/pypy/pypy/changeset/22d1b419809f/

Log:    an attempt to fix exception handling in the new model

diff --git a/rpython/jit/metainterp/history.py 
b/rpython/jit/metainterp/history.py
--- a/rpython/jit/metainterp/history.py
+++ b/rpython/jit/metainterp/history.py
@@ -684,7 +684,7 @@
     @staticmethod
     def check_consistency_of_branch(operations, seen):
         "NOT_RPYTHON"
-        for op in operations:
+        for num, op in enumerate(operations):
             for i in range(op.numargs()):
                 box = op.getarg(i)
                 if not isinstance(box, Const):
diff --git a/rpython/jit/metainterp/pyjitpl.py 
b/rpython/jit/metainterp/pyjitpl.py
--- a/rpython/jit/metainterp/pyjitpl.py
+++ b/rpython/jit/metainterp/pyjitpl.py
@@ -326,11 +326,11 @@
     @arguments("label")
     def opimpl_catch_exception(self, target):
         """This is a no-op when run normally.  We can check that
-        last_exc_value_box is None; it should have been set to None
+        last_exc_value is a null ptr; it should have been set to None
         by the previous instruction.  If the previous instruction
         raised instead, finishframe_exception() should have been
         called and we would not be there."""
-        assert self.metainterp.last_exc_value_box is None
+        assert not self.metainterp.last_exc_value
 
     @arguments("label")
     def opimpl_goto(self, target):
@@ -1270,10 +1270,10 @@
     @arguments("box", "label")
     def opimpl_goto_if_exception_mismatch(self, vtablebox, next_exc_target):
         metainterp = self.metainterp
-        last_exc_value_box = metainterp.last_exc_value_box
-        assert last_exc_value_box is not None
+        last_exc_value = metainterp.last_exc_value
+        assert last_exc_value
         assert metainterp.class_of_last_exc_is_const
-        if not metainterp.cpu.ts.instanceOf(last_exc_value_box, vtablebox):
+        if not 
metainterp.cpu.ts.instanceOf(ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, 
last_exc_value)), vtablebox):
             self.pc = next_exc_target
 
     @arguments("box", "orgpc")
@@ -1284,29 +1284,30 @@
             self.metainterp.generate_guard(rop.GUARD_CLASS, exc_value_box,
                                            [clsbox], resumepc=orgpc)
         self.metainterp.class_of_last_exc_is_const = True
-        self.metainterp.last_exc_value_box = exc_value_box
+        self.metainterp.last_exc_value = exc_value_box.getref(rclass.OBJECTPTR)
+        self.metainterp.last_exc_box = exc_value_box
         self.metainterp.popframe()
         self.metainterp.finishframe_exception()
 
     @arguments()
     def opimpl_reraise(self):
-        assert self.metainterp.last_exc_value_box is not None
+        assert self.metainterp.last_exc_value
         self.metainterp.popframe()
         self.metainterp.finishframe_exception()
 
     @arguments()
     def opimpl_last_exception(self):
         # Same comment as in opimpl_goto_if_exception_mismatch().
-        exc_value_box = self.metainterp.last_exc_value_box
-        assert exc_value_box is not None
+        exc_value = self.metainterp.last_exc_value
+        assert exc_value
         assert self.metainterp.class_of_last_exc_is_const
-        return self.metainterp.cpu.ts.cls_of_box(exc_value_box)
+        return self.metainterp.cpu.ts.cls_of_box(ConstPtr(exc_value))
 
     @arguments()
     def opimpl_last_exc_value(self):
-        exc_value_box = self.metainterp.last_exc_value_box
-        assert exc_value_box is not None
-        return exc_value_box
+        exc_value = self.metainterp.last_exc_value
+        assert exc_value
+        return ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, exc_value))
 
     @arguments("box")
     def opimpl_debug_fatalerror(self, box):
@@ -1503,7 +1504,7 @@
         self.metainterp.clear_exception()
         op = self.metainterp.execute_and_record_varargs(opnum, argboxes,
                                                             descr=descr)
-        if pure and self.metainterp.last_exc_value_box is None and op:
+        if pure and not self.metainterp.last_exc_value and op:
             op = self.metainterp.record_result_of_call_pure(op)
             exc = exc and not isinstance(op, Const)
         if exc:
@@ -1868,6 +1869,7 @@
     portal_call_depth = 0
     cancel_count = 0
     exported_state = None
+    last_exc_box = None
 
     def __init__(self, staticdata, jitdriver_sd):
         self.staticdata = staticdata
@@ -1878,7 +1880,7 @@
         # during recursion we can also see other jitdrivers.
         self.portal_trace_positions = []
         self.free_frames_list = []
-        self.last_exc_value_box = None
+        self.last_exc_value = lltype.nullptr(rclass.OBJECT)
         self.forced_virtualizable = None
         self.partial_trace = None
         self.retracing_from = -1
@@ -1937,7 +1939,7 @@
 
     def finishframe(self, resultbox):
         # handle a non-exceptional return from the current frame
-        self.last_exc_value_box = None
+        self.last_exc_value = lltype.nullptr(rclass.OBJECT)
         self.popframe()
         if self.framestack:
             if resultbox is not None:
@@ -1963,7 +1965,7 @@
                 assert False
 
     def finishframe_exception(self):
-        excvaluebox = self.last_exc_value_box
+        excvalue = self.last_exc_value
         while self.framestack:
             frame = self.framestack[-1]
             code = frame.bytecode
@@ -1978,10 +1980,10 @@
                     raise ChangeFrame
             self.popframe()
         try:
-            self.compile_exit_frame_with_exception(excvaluebox)
+            self.compile_exit_frame_with_exception(self.last_exc_box)
         except SwitchToBlackhole, stb:
             self.aborted_tracing(stb.reason)
-        raise jitexc.ExitFrameWithExceptionRef(self.cpu, 
excvaluebox.getref_base())
+        raise jitexc.ExitFrameWithExceptionRef(self.cpu, 
lltype.cast_opaque_ptr(llmemory.GCREF, excvalue))
 
     def check_recursion_invariant(self):
         portal_call_depth = -1
@@ -2105,7 +2107,7 @@
     @specialize.argtype(2)
     def _record_helper_nonpure_varargs(self, opnum, resvalue, descr, argboxes):
         if (rop._OVF_FIRST <= opnum <= rop._OVF_LAST and
-            self.last_exc_value_box is None and
+            not self.last_exc_value and
             self._all_constants_varargs(argboxes)):
             return history.newconst(resvalue)
         # record the operation
@@ -2173,22 +2175,17 @@
     def execute_ll_raised(self, llexception, constant=False):
         # Exception handling: when execute.do_call() gets an exception it
         # calls metainterp.execute_raised(), which puts it into
-        # 'self.last_exc_value_box'.  This is used shortly afterwards
+        # 'self.last_exc_value'.  This is used shortly afterwards
         # to generate either GUARD_EXCEPTION or GUARD_NO_EXCEPTION, and also
         # to handle the following opcodes 'goto_if_exception_mismatch'.
-        llexception = self.cpu.ts.cast_to_ref(llexception)
-        if constant:
-            exc_value_box = self.cpu.ts.get_exc_value_const(llexception)
-        else:
-            exc_value_box = self.cpu.ts.get_exc_value_box(llexception)
-        self.last_exc_value_box = exc_value_box
+        self.last_exc_value = llexception
         self.class_of_last_exc_is_const = constant
         # 'class_of_last_exc_is_const' means that the class of the value
         # stored in the exc_value Box can be assumed to be a Const.  This
         # is only True after a GUARD_EXCEPTION or GUARD_CLASS.
 
     def clear_exception(self):
-        self.last_exc_value_box = None
+        self.last_exc_value = lltype.nullptr(rclass.OBJECT)
 
     def aborted_tracing(self, reason):
         self.staticdata.profiler.count(reason)
@@ -2747,28 +2744,30 @@
         self.virtualref_boxes[i+1] = self.cpu.ts.CONST_NULL
 
     def handle_possible_exception(self):
-        if self.last_exc_value_box is not None:
-            exception_box = self.cpu.ts.cls_of_box(self.last_exc_value_box)
+        if self.last_exc_value:
+            exception_box = ConstInt(heaptracker.adr2int(
+                llmemory.cast_ptr_to_adr(self.last_exc_value.typeptr)))
             op = self.generate_guard(rop.GUARD_EXCEPTION,
                                      None, [exception_box])
+            self.last_exc_box = op
+            op.setref_base(lltype.cast_opaque_ptr(llmemory.GCREF,
+                                                  self.last_exc_value))
             assert op is not None
-            op.result = self.last_exc_value_box
             self.class_of_last_exc_is_const = True
             self.finishframe_exception()
         else:
             self.generate_guard(rop.GUARD_NO_EXCEPTION, None, [])
 
     def handle_possible_overflow_error(self):
-        if self.last_exc_value_box is not None:
+        if self.last_exc_value:
             self.generate_guard(rop.GUARD_OVERFLOW, None)
-            assert isinstance(self.last_exc_value_box, Const)
             assert self.class_of_last_exc_is_const
             self.finishframe_exception()
         else:
             self.generate_guard(rop.GUARD_NO_OVERFLOW, None)
 
     def assert_no_exception(self):
-        assert self.last_exc_value_box is None
+        assert self.last_exc_value
 
     def rebuild_state_after_failure(self, resumedescr, deadframe):
         vinfo = self.jitdriver_sd.virtualizable_info
@@ -3046,7 +3045,7 @@
         self.clear_exception()
         executor.execute_varargs(self.cpu, self, rop.CALL_N,
                                           allboxes, descr)
-        if self.last_exc_value_box is not None:
+        if self.last_exc_value:
             # cannot trace this!  it raises, so we have to follow the
             # exception-catching path, but the trace doesn't contain
             # the call at all
@@ -3065,7 +3064,7 @@
         self.reason = reason
         self.raising_exception = raising_exception
         # ^^^ must be set to True if the SwitchToBlackhole is raised at a
-        #     point where the exception on metainterp.last_exc_value_box
+        #     point where the exception on metainterp.last_exc_value
         #     is supposed to be raised.  The default False means that it
         #     should just be copied into the blackhole interp, but not raised.
 
diff --git a/rpython/jit/metainterp/typesystem.py 
b/rpython/jit/metainterp/typesystem.py
--- a/rpython/jit/metainterp/typesystem.py
+++ b/rpython/jit/metainterp/typesystem.py
@@ -79,14 +79,6 @@
     def get_exception_box(self, etype):
         return history.ConstInt(etype)
 
-    def get_exc_value_box(self, evalue):
-        from rpython.jit.metainterp.resoperation import InputArgRef
-        
-        return InputArgRef(evalue)
-
-    def get_exc_value_const(self, evalue):
-        return history.ConstPtr(evalue)
-
     def get_exception_obj(self, evaluebox):
         # only works when translated
         obj = evaluebox.getref(lltype.Ptr(rclass.OBJECT))
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to