[pypy-svn] r74107 - in pypy/branch/blackhole-improvement/pypy/jit/codewriter: . test
arigo at codespeak.net
arigo at codespeak.net
Tue Apr 27 13:19:55 CEST 2010
Author: arigo
Date: Tue Apr 27 13:19:54 2010
New Revision: 74107
Modified:
pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py
Log:
Finish the bytecode format for exceptions (it was missing
'last_exception' and 'last_exc_value' support).
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py Tue Apr 27 13:19:54 2010
@@ -127,6 +127,17 @@
self.insert_renamings(link)
self.make_bytecode_block(link.target)
+ def make_exception_link(self, link):
+ # Like make_link(), but also introduces the 'last_exception' and
+ # 'last_exc_value' as variables if needed
+ assert link.last_exception is not None
+ assert link.last_exc_value is not None
+ if link.last_exception in link.args:
+ self.emitline("last_exception", self.getcolor(link.last_exception))
+ if link.last_exc_value in link.args:
+ self.emitline("last_exc_value", self.getcolor(link.last_exc_value))
+ self.make_link(link)
+
def insert_exits(self, block):
if len(block.exits) == 1:
# A single link, fall-through
@@ -168,22 +179,29 @@
# exc_2 case
# reraise
assert block.exits[0].exitcase is None # is this always True?
- self.emitline('goto_if_exception', TLabel(block.exits[0]))
+ self.emitline('catch', TLabel(block.exits[0]))
self.make_link(block.exits[0])
self.emitline(Label(block.exits[0]))
for link in block.exits[1:]:
- if (link.exitcase is Exception and link.target.operations == ()
- and len(link.target.inputargs) == 2):
- # default exit-by-exception block, if the link is going
- # directly to the except block.
- self.emitline("reraise")
- else:
- self.emitline('goto_if_exception_mismatch',
- Constant(link.llexitcase,
- lltype.typeOf(link.llexitcase)),
- TLabel(link))
- self.make_link(link)
- self.emitline(Label(link))
+ if link.exitcase is Exception:
+ # this link captures all exceptions
+ if (link.target.operations == ()
+ and len(link.target.inputargs) == 2):
+ # the link is going directly to the except block
+ self.emitline("reraise")
+ else:
+ self.make_exception_link(link)
+ break
+ self.emitline('goto_if_exception_mismatch',
+ Constant(link.llexitcase,
+ lltype.typeOf(link.llexitcase)),
+ TLabel(link))
+ self.make_exception_link(link)
+ self.emitline(Label(link))
+ else:
+ # no link captures all exceptions, so we have to put a reraise
+ # for the other exceptions
+ self.emitline("reraise")
else:
# A switch.
#
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py Tue Apr 27 13:19:54 2010
@@ -21,6 +21,16 @@
self.num_colors += 1
return self.seen[v]
+class FakeDescr(AbstractDescr):
+ def __repr__(self):
+ return '<Descr>'
+
+class FakeCPU:
+ def calldescrof(self, FUNC, ARGS, RESULT):
+ return FakeDescr()
+ def fielddescrof(self, STRUCT, name):
+ return FakeDescr()
+
def fake_regallocs():
return {'int': FakeRegAlloc(),
'ref': FakeRegAlloc(),
@@ -48,7 +58,7 @@
def encoding_test(self, func, args, expected, transform=False):
graphs = self.make_graphs(func, args)
if transform:
- transform_graph(graphs[0])
+ transform_graph(graphs[0], FakeCPU())
ssarepr = flatten_graph(graphs[0], fake_regallocs())
self.assert_format(ssarepr, expected)
@@ -234,7 +244,7 @@
self.encoding_test(f, [65], """
direct_call $<* fn g>, %i0
- goto_if_exception L1
+ catch L1
int_return $3
L1:
goto_if_exception_mismatch $<* struct object_vtable>, L2
@@ -245,3 +255,33 @@
L3:
reraise
""")
+
+ def test_exc_exitswitch_2(self):
+ class FooError(Exception):
+ pass
+ def g(i):
+ FooError().num = 1
+ FooError().num = 2
+ def f(i):
+ try:
+ g(i)
+ except FooError, e:
+ return e.num
+ except Exception:
+ return 3
+ else:
+ return 4
+
+ self.encoding_test(f, [65], """
+ residual_call_ir_v $<* fn g>, <Descr>, I[%i0], R[]
+ catch L1
+ int_return $4
+ L1:
+ goto_if_exception_mismatch $<* struct object_vtable>, L2
+ last_exc_value %r0
+ ref_copy %r0, %r1
+ getfield_gc_i %r1, <Descr>, %i1
+ int_return %i1
+ L2:
+ int_return $3
+ """, transform=True)
More information about the Pypy-commit
mailing list