[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