[pypy-svn] r62682 - in pypy/branch/pyjitpl5/pypy/jit: backend/llgraph metainterp

arigo at codespeak.net arigo at codespeak.net
Sat Mar 7 10:15:33 CET 2009


Author: arigo
Date: Sat Mar  7 10:15:31 2009
New Revision: 62682

Modified:
   pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py
   pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py
   pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py
   pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
Log:
Fix execute(CALL) to also signal an exception via the mechanism of
cpu.get_exception() instead of just raising it.  That turns out to be a
code simplification, too.



Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py	Sat Mar  7 10:15:31 2009
@@ -347,9 +347,8 @@
         """Execute all operations in a loop,
         possibly following to other loops as well.
         """
-        global _last_exception, _last_exception_handled
-        _last_exception = None
-        _last_exception_handled = True
+        global _last_exception
+        assert _last_exception is None, "exception left behind"
         verbose = True
         while True:
             self.opindex += 1
@@ -380,7 +379,6 @@
                                         % (RESTYPE,))
                     self.env[op.result] = x
             except GuardFailed:
-                assert _last_exception_handled
                 if hasattr(op, 'jump_target'):
                     # the guard already failed once, go to the
                     # already-generated code
@@ -499,23 +497,22 @@
             raise GuardFailed    # some other code is already in control
 
     def op_guard_no_exception(self, _):
-        global _last_exception_handled
-        _last_exception_handled = True
         if _last_exception:
             raise GuardFailed
 
     def op_guard_exception(self, _, expected_exception):
-        global _last_exception_handled
-        _last_exception_handled = True
+        global _last_exception
         expected_exception = llmemory.cast_adr_to_ptr(
             cast_int_to_adr(self.memocast, expected_exception),
             rclass.CLASSTYPE)
         assert expected_exception
-        if _last_exception:
-            got = _last_exception.args[0]
+        exc = _last_exception
+        if exc:
+            got = exc.args[0]
             if not rclass.ll_issubclass(got, expected_exception):
                 raise GuardFailed
-            return _last_exception.args[1]
+            _last_exception = None
+            return exc.args[1]
         else:
             raise GuardFailed
 
@@ -565,21 +562,14 @@
             do_setfield_raw_int(struct, fielddescr, newvalue, self.memocast)
 
     def op_call(self, calldescr, func, *args):
-        global _last_exception, _last_exception_handled
         _call_args[:] = args
-        try:
-            res = _do_call_common(func, self.memocast)
-            _last_exception = None
-            return res
-        except LLException, e:
-            _last_exception = e
-            _last_exception_handled = False
-            if calldescr == sys.maxint:
-                return None
-            elif calldescr & 1:
-                return lltype.nullptr(llmemory.GCREF)
-            else:
-                return 0
+        if calldescr == sys.maxint:
+            err_result = None
+        elif calldescr & 1:
+            err_result = lltype.nullptr(llmemory.GCREF.TO)
+        else:
+            err_result = 0
+        return _do_call_common(func, self.memocast, err_result)
 
 # ____________________________________________________________
 
@@ -673,30 +663,31 @@
     frame = _from_opaque(frame)
     return frame.returned_value
 
+_last_exception = None
+
 def get_exception():
-    global _last_exception, _last_exception_handled
-    _last_exception_handled = True
     if _last_exception:
         return llmemory.cast_ptr_to_adr(_last_exception.args[0])
     else:
         return llmemory.NULL
 
 def get_exc_value():
-    global _last_exception, _last_exception_handled
-    _last_exception_handled = True
     if _last_exception:
         return lltype.cast_opaque_ptr(llmemory.GCREF, _last_exception.args[1])
     else:
         return lltype.nullptr(llmemory.GCREF.TO)
 
+def clear_exception():
+    global _last_exception
+    _last_exception = None
+
 def set_overflow_error():
-    global _last_exception, _last_exception_handled
+    global _last_exception
     llframe = _llinterp.frame_class(None, None, _llinterp)
     try:
         llframe.make_llexception(OverflowError())
     except LLException, e:
         _last_exception = e
-        _last_exception_handled = False
     else:
         assert 0, "should have raised"
 
@@ -844,7 +835,9 @@
 def do_call_pushptr(x):
     _call_args.append(x)
 
-def _do_call_common(f, memocast):
+def _do_call_common(f, memocast, err_result=None):
+    global _last_exception
+    assert _last_exception is None, "exception left behind"
     ptr = cast_int_to_adr(memocast, f).ptr
     FUNC = lltype.typeOf(ptr).TO
     ARGS = FUNC.ARGS
@@ -864,20 +857,24 @@
     assert len(ARGS) == len(args)
     if hasattr(ptr._obj, 'graph'):
         llinterp = _llinterp      # it's a global set here by CPU.__init__()
-        result = llinterp.eval_graph(ptr._obj.graph, args)
+        try:
+            result = llinterp.eval_graph(ptr._obj.graph, args)
+        except LLException, e:
+            _last_exception = e
+            result = err_result
     else:
-        result = ptr._obj._callable(*args)
+        result = ptr._obj._callable(*args)  # no exception support in this case
     return result
 
 def do_call_void(f, memocast):
     _do_call_common(f, memocast)
 
 def do_call_int(f, memocast):
-    x = _do_call_common(f, memocast)
+    x = _do_call_common(f, memocast, 0)
     return cast_to_int(x, memocast)
 
 def do_call_ptr(f, memocast):
-    x = _do_call_common(f, memocast)
+    x = _do_call_common(f, memocast, lltype.nullptr(llmemory.GCREF.TO))
     return cast_to_ptr(x)
 
 # ____________________________________________________________
@@ -957,6 +954,7 @@
 
 setannotation(get_exception, annmodel.SomeAddress())
 setannotation(get_exc_value, annmodel.SomePtr(llmemory.GCREF))
+setannotation(clear_exception, annmodel.s_None)
 setannotation(set_overflow_error, annmodel.s_None)
 
 setannotation(new_memo_cast, s_MemoCast)

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py	Sat Mar  7 10:15:31 2009
@@ -178,6 +178,9 @@
     def get_exc_value(self):
         return llimpl.get_exc_value()
 
+    def clear_exception(self):
+        llimpl.clear_exception()
+
     def set_overflow_error(self):
         llimpl.set_overflow_error()
 

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py	Sat Mar  7 10:15:31 2009
@@ -672,7 +672,7 @@
         argtypes = [v.concretetype for v in args]
         resulttype = op.result.concretetype
         calldescr = self.cpu.calldescrof(argtypes[1:], resulttype)
-        self.emit('residual_call_%s' % getkind(resulttype))
+        self.emit('residual_call')
         self.emit(calldescr)
         self.emit_varargs(args)
         self.register_var(op.result)
@@ -716,7 +716,7 @@
         if oopspec_name.endswith('_foldable'):
             opname = 'residual_call_pure'  # XXX not for possibly-raising calls
         else:
-            opname = 'residual_call_%s' % getkind(resulttype)
+            opname = 'residual_call'
         calldescr = self.cpu.calldescrof(argtypes, resulttype)
         self.emit(opname)
         self.emit(calldescr)

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py	Sat Mar  7 10:15:31 2009
@@ -241,7 +241,7 @@
         exec py.code.Source('''
             @arguments("box", "box")
             def opimpl_%s(self, b1, b2):
-                return self.execute_with_exc(rop.%s, [b1, b2], returnsBoxInt)
+                return self.execute_with_exc(rop.%s, [b1, b2])
         ''' % (_opimpl, _opimpl.upper())).compile()
 
     for _opimpl in ['int_is_true', 'int_neg', 'int_invert', 'bool_not',
@@ -257,7 +257,7 @@
         exec py.code.Source('''
             @arguments("box")
             def opimpl_%s(self, b):
-                return self.execute_with_exc(rop.%s, [b], returnsBoxInt)
+                return self.execute_with_exc(rop.%s, [b])
         ''' % (_opimpl, _opimpl.upper())).compile()
 
     @arguments()
@@ -398,19 +398,8 @@
         return True
 
     @arguments("int", "varargs")
-    def opimpl_residual_call_int(self, calldescr, varargs):
-        return self.execute_with_exc(rop.CALL, varargs, returnsBoxInt,
-                                     descr=calldescr)
-
-    @arguments("int", "varargs")
-    def opimpl_residual_call_ptr(self, calldescr, varargs):
-        return self.execute_with_exc(rop.CALL, varargs, returnsBoxPtr,
-                                     descr=calldescr)
-
-    @arguments("int", "varargs")
-    def opimpl_residual_call_void(self, calldescr, varargs):
-        return self.execute_with_exc(rop.CALL, varargs, returnsNone,
-                                     descr=calldescr)
+    def opimpl_residual_call(self, calldescr, varargs):
+        return self.execute_with_exc(rop.CALL, varargs, descr=calldescr)
 
     @arguments("int", "varargs")
     def opimpl_residual_call_pure(self, calldescr, varargs):
@@ -660,33 +649,17 @@
             self.make_result_box(resbox)
     execute._annspecialcase_ = 'specialize:arg(1)'
 
-    def execute_with_exc(self, opnum, argboxes, makeresbox, descr=0):
-        try:
-            resbox = executor.execute(self.metainterp.cpu, opnum, argboxes,
-                                      descr)
-        except Exception, e:
-            if not we_are_translated():
-                if not isinstance(e, LLException):
-                    raise
-                etype, evalue = e.args[:2]
-            else:
-                evalue = cast_instance_to_base_ptr(e)
-                etype = evalue.typeptr
-            resbox = makeresbox()
-        else:
-            if not we_are_translated():
-                self.metainterp._debug_history.append(['call',
+    def execute_with_exc(self, opnum, argboxes, descr=0):
+        cpu = self.metainterp.cpu
+        resbox = executor.execute(cpu, opnum, argboxes, descr)
+        if not we_are_translated():
+            self.metainterp._debug_history.append(['call',
                                                   argboxes[0], argboxes[1:]])
-            etype = lltype.nullptr(rclass.OBJECT_VTABLE)
-            evalue = lltype.nullptr(rclass.OBJECT)
         # record the operation in the history
         self.metainterp.history.record(opnum, argboxes, resbox, descr)
         if resbox is not None:
             self.make_result_box(resbox)
-        type_as_int = self.metainterp.cpu.cast_adr_to_int(
-            llmemory.cast_ptr_to_adr(etype))
-        value_as_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, evalue)
-        return self.metainterp.handle_exception(type_as_int, value_as_gcref)
+        return self.metainterp.handle_exception()
 
 # ____________________________________________________________
 
@@ -822,7 +795,7 @@
         try:
             if guard_failure.guard_op.opnum in (rop.GUARD_EXCEPTION,
                                                 rop.GUARD_NO_EXCEPTION):
-                self.raise_exception_upon_guard_failure()
+                self.handle_exception()
             self.interpret()
             assert False, "should always raise"
         except GenerateMergePoint, gmp:
@@ -956,12 +929,10 @@
         self.rebuild_state_after_failure(guard_op.key, newboxes)
         return boxes_from_frame
 
-    def raise_exception_upon_guard_failure(self):
+    def handle_exception(self):
         etype = self.cpu.get_exception()
         evalue = self.cpu.get_exc_value()
-        self.handle_exception(etype, evalue)
-
-    def handle_exception(self, etype, evalue):
+        self.cpu.clear_exception()
         frame = self.framestack[-1]
         if etype:
             exception_box = ConstInt(etype)
@@ -1020,8 +991,3 @@
 class GenerateMergePoint(Exception):
     def __init__(self, args):
         self.argboxes = args
-
-
-def returnsBoxInt(): return BoxInt()
-def returnsBoxPtr(): return BoxPtr()
-def returnsNone():   return None



More information about the Pypy-commit mailing list