[pypy-svn] r24534 - in pypy/dist/pypy/rpython/memory: . test

tismer at codespeak.net tismer at codespeak.net
Sat Mar 18 03:23:35 CET 2006


Author: tismer
Date: Sat Mar 18 03:23:13 2006
New Revision: 24534

Modified:
   pypy/dist/pypy/rpython/memory/gctransform.py
   pypy/dist/pypy/rpython/memory/test/test_gctransform.py
Log:
fixed exception filtering to handle protect/unprotect correctly.
Added a test that ensures this.

Modified: pypy/dist/pypy/rpython/memory/gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctransform.py	(original)
+++ pypy/dist/pypy/rpython/memory/gctransform.py	Sat Mar 18 03:23:13 2006
@@ -103,9 +103,9 @@
         # seem to run into all the same problems as the ones we already
         # had to solve there.
         has_exception_handler = block.exitswitch == c_last_exception
-        for i, op in enumerate(block.operations):
+        for i, origop in enumerate(block.operations):
             num_ops_after_exc_raising = 0
-            res = self.replacement_operations(op, livevars)
+            res = self.replacement_operations(origop, livevars)
             try:
                 ops, cleanup_before_exception = res
             except ValueError:
@@ -113,17 +113,16 @@
             if not ops:
                 continue # may happen when we eat gc_protect/gc_unprotect.
             newops.extend(ops)
-            origname = op.opname
             op = ops[-1-num_ops_after_exc_raising]
             # look into the table of all operations to check whether op is
             # expected to raise. if it is not in the table or the last
             # operation in a block with exception catching, we assume it can
             if (op.opname not in LL_OPERATIONS or
-                op.opname not in NEVER_RAISING_OPS or
                 (has_exception_handler and i == len(block.operations) - 1)):
                 can_raise = True
             else:
-                can_raise = bool(LL_OPERATIONS[op.opname].canraise)
+                can_raise = (LL_OPERATIONS[op.opname].canraise and
+                             origop.opname not in NEVER_RAISING_OPS)
             if can_raise:
                 if tuple(livevars) in livevars2cleanup:
                     cleanup_on_exception = livevars2cleanup[tuple(livevars)]

Modified: pypy/dist/pypy/rpython/memory/test/test_gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/test/test_gctransform.py	(original)
+++ pypy/dist/pypy/rpython/memory/test/test_gctransform.py	Sat Mar 18 03:23:13 2006
@@ -217,16 +217,19 @@
             pop_count += 1
     assert push_count == 0 and pop_count == 1
 
-def test_protect_unprotect():
-    def protect(obj): RaiseNameError
-    def unprotect(obj): RaiseNameError
-    def rtype_protect(hop): hop.genop('gc_protect', [hop.inputargs(hop.args_r[0])[0]])
-    def rtype_unprotect(hop): hop.genop('gc_unprotect', [hop.inputargs(hop.args_r[0])[0]])
-    extregistry.register_value(protect,
-        compute_result_annotation=lambda *args: None, specialize_call=rtype_protect)
-    extregistry.register_value(unprotect,
-        compute_result_annotation=lambda *args: None, specialize_call=rtype_unprotect)
+# ____________________________________________________________________
+# testing the protection magic
+
+def protect(obj): RaiseNameError
+def unprotect(obj): RaiseNameError
+def rtype_protect(hop): hop.genop('gc_protect', [hop.inputargs(hop.args_r[0])[0]])
+def rtype_unprotect(hop): hop.genop('gc_unprotect', [hop.inputargs(hop.args_r[0])[0]])
+extregistry.register_value(protect,
+    compute_result_annotation=lambda *args: None, specialize_call=rtype_protect)
+extregistry.register_value(unprotect,
+    compute_result_annotation=lambda *args: None, specialize_call=rtype_unprotect)
 
+def test_protect_unprotect():
     def p():    protect('this is an object')
     def u():    unprotect('this is an object')
 
@@ -239,7 +242,21 @@
         t, transformer = rtype_and_transform(f, [], gc, check=False)
         ops = getops(graphof(t, f))
         assert len(ops.get('direct_call', [])) == ex
-    
+
+def test_protect_unprotect_no_exception_block():
+    def p():    protect('this is an object')
+    def u():    unprotect('this is an object')
+
+    gc = gctransform.RefcountingGCTransformer
+    for f in p, u:
+        t, transformer = rtype_and_transform(f, [], gc, check=False)
+        has_cleanup = False
+        ops = getops(graphof(t, f))
+        for op in ops.get('direct_call', []):
+            assert not op.cleanup
+
+# end of protection tests
+
 def test_except_block():
     S = lltype.GcStruct("S", ('x', lltype.Signed))
     def f(a, n):



More information about the Pypy-commit mailing list