[pypy-commit] pypy default: A corner case test, and fix

arigo noreply at buildbot.pypy.org
Sat May 3 11:37:04 CEST 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r71223:305c557e4bc3
Date: 2014-05-03 11:36 +0200
http://bitbucket.org/pypy/pypy/changeset/305c557e4bc3/

Log:	A corner case test, and fix

diff --git a/rpython/jit/codewriter/jtransform.py b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -24,9 +24,31 @@
     """Transform a control flow graph to make it suitable for
     being flattened in a JitCode.
     """
+    constant_fold_ll_issubclass(graph, cpu)
     t = Transformer(cpu, callcontrol, portal_jd)
     t.transform(graph)
 
+def constant_fold_ll_issubclass(graph, cpu):
+    # ll_issubclass can be inserted by the inliner to check exception types.
+    # See corner case metainterp.test.test_exception:test_catch_different_class
+    if cpu is None:
+        return
+    excmatch = cpu.rtyper.exceptiondata.fn_exception_match
+    for block in list(graph.iterblocks()):
+        for i, op in enumerate(block.operations):
+            if (op.opname == 'direct_call' and
+                    all(isinstance(a, Constant) for a in op.args) and
+                    op.args[0].value._obj is excmatch._obj):
+                constant_result = excmatch(*[a.value for a in op.args[1:]])
+                block.operations[i] = SpaceOperation(
+                    'same_as',
+                    [Constant(constant_result, lltype.Bool)],
+                    op.result)
+                if block.exitswitch is op.result:
+                    block.exitswitch = None
+                    block.recloseblock(*[link for link in block.exits
+                                         if link.exitcase == constant_result])
+
 def integer_bounds(size, unsigned):
     if unsigned:
         return 0, 1 << (8 * size)
diff --git a/rpython/jit/metainterp/test/test_exception.py b/rpython/jit/metainterp/test/test_exception.py
--- a/rpython/jit/metainterp/test/test_exception.py
+++ b/rpython/jit/metainterp/test/test_exception.py
@@ -611,6 +611,20 @@
         res = self.meta_interp(f, [0], inline=True)
         assert res == 30
 
+    def test_catch_different_class(self):
+        def g(i):
+            if i < 0:
+                raise KeyError
+            return i
+        def f(i):
+            MyError(i)
+            try:
+                return g(i)
+            except MyError as e:
+                return e.n
+        res = self.interp_operations(f, [5], backendopt=True)
+        assert res == 5
+
 
 class MyError(Exception):
     def __init__(self, n):


More information about the pypy-commit mailing list