[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