[pypy-svn] r23363 - in pypy: branch/genc-gc-refactoring branch/genc-gc-refactoring/test dist/pypy/rpython/memory

mwh at codespeak.net mwh at codespeak.net
Wed Feb 15 15:44:53 CET 2006


Author: mwh
Date: Wed Feb 15 15:44:51 2006
New Revision: 23363

Modified:
   pypy/branch/genc-gc-refactoring/gc.py
   pypy/branch/genc-gc-refactoring/test/test_boehm.py
   pypy/dist/pypy/rpython/memory/gctransform.py
Log:
(a) some efforts to make sure the test_boehm __del__ tests actually test
    something
(b) a version of the test_del_raises test from test_newgc
(c) code to make (b) pass.  it's a bit spammy, maybe we'll fix that soon...



Modified: pypy/branch/genc-gc-refactoring/gc.py
==============================================================================
--- pypy/branch/genc-gc-refactoring/gc.py	(original)
+++ pypy/branch/genc-gc-refactoring/gc.py	Wed Feb 15 15:44:51 2006
@@ -128,6 +128,10 @@
         # see src/exception.h
         return 'if (%s != NULL) RPyRaiseException(%s->o_typeptr, %s);' % (argh, argh, argh)
 
+    def OP_GC__COLLECT(self, funcgen, op, err):
+        return ''
+
+
 class RefcountingRuntimeTypeInfo_OpaqueNode(ContainerNode):
     nodekind = 'refcnt rtti'
     globalcontainer = True
@@ -217,6 +221,22 @@
         yield 'GC_init();'
 
 
+    def OP_GC_FETCH_EXCEPTION(self, funcgen, op, err):
+        result = funcgen.expr(op.result)
+        return ('%s = rpython_exc_value;\n'
+                'rpython_exc_type = NULL;\n'
+                'rpython_exc_value = NULL;') % (result, )
+
+    def OP_GC_RESTORE_EXCEPTION(self, funcgen, op, err):
+        argh = funcgen.expr(op.args[0])
+        # XXX uses officially bad fishing
+        # see src/exception.h
+        return 'if (%s != NULL) RPyRaiseException(%s->o_typeptr, %s);' % (argh, argh, argh)
+
+    def OP_GC__COLLECT(self, funcgen, op, err):
+        return 'GC_gcollect(); GC_invoke_finalizers();'
+
+
 class BoehmGcRuntimeTypeInfo_OpaqueNode(ContainerNode):
     nodekind = 'boehm rtti'
     globalcontainer = True

Modified: pypy/branch/genc-gc-refactoring/test/test_boehm.py
==============================================================================
--- pypy/branch/genc-gc-refactoring/test/test_boehm.py	(original)
+++ pypy/branch/genc-gc-refactoring/test/test_boehm.py	Wed Feb 15 15:44:51 2006
@@ -54,6 +54,8 @@
         fn()
 
     def test__del__(self):
+        from pypy.rpython import objectmodel
+        from pypy.rpython.lltypesystem import lltype
         class State:
             pass
         s = State()
@@ -74,10 +76,46 @@
             A()
             B()
             C()
+            objectmodel.llop.gc__collect(lltype.Void)
             return s.a_dels * 10 + s.b_dels
         fn = self.getcompiled(f)
-        res = f()
-        assert res == 42
-        res = fn() #does not crash
-        res = fn() #does not crash
-        assert 0 <= res <= 42 # 42 cannot be guaranteed
+        # we can't demand that boehm has collected all of the objects,
+        # even with the gc__collect call.  calling the compiled
+        # function twice seems to help, though.
+        res = 0
+        res += fn()
+        res += fn()
+        # if res is still 0, then we haven't tested anything so fail.
+        # it might be the test's fault though.
+        assert 0 < res <= 84
+
+    def test_del_raises(self):
+        from pypy.rpython import objectmodel
+        from pypy.rpython.lltypesystem import lltype
+        import os
+        class A(object):
+            def __del__(self):
+                s.dels += 1
+                raise Exception
+        class State:
+            pass
+        s = State()
+        s.dels = 0
+        def g():
+            a = A()            
+        def f():
+            s.dels = 0
+            for i in range(10):
+                g()
+            objectmodel.llop.gc__collect(lltype.Void)
+            return s.dels
+        fn = self.getcompiled(f)
+        # we can't demand that boehm has collected all of the objects,
+        # even with the gc__collect call.  calling the compiled
+        # function twice seems to help, though.
+        res = 0
+        res += fn()
+        res += fn()
+        # if res is still 0, then we haven't tested anything so fail.
+        # it might be the test's fault though.
+        assert res > 0

Modified: pypy/dist/pypy/rpython/memory/gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctransform.py	(original)
+++ pypy/dist/pypy/rpython/memory/gctransform.py	Wed Feb 15 15:44:51 2006
@@ -7,7 +7,7 @@
 from pypy.annotation import model as annmodel
 from pypy.rpython import rmodel, objectmodel, rptr
 from pypy.rpython.memory import gc
-import sets
+import sets, os
 
 """
 thought experiments
@@ -600,15 +600,20 @@
             exec src in d
             g = self.annotate_helper(d['finalizer'], [llmemory.Address])
         elif destrptr:
-            d = {'PTR_TYPE':DESTR_ARG,
-                 'cast_adr_to_ptr':objectmodel.cast_adr_to_ptr,
-                 'destrptr':destrptr}
-            # XXX swallow __del__ exceptions, preserve preexisting ones in case!
-            src = ("def finalizer(addr):\n"
-                   "    v = cast_adr_to_ptr(addr, PTR_TYPE)\n"
-                   "    destrptr(v)\n")
-            exec src in d
-            g = self.annotate_helper(d['finalizer'], [llmemory.Address])
+            EXC_INSTANCE_TYPE = self.translator.rtyper.exceptiondata.lltype_of_exception_value
+            def finalizer(addr):
+                exc_instance = objectmodel.llop.gc_fetch_exception(
+                    EXC_INSTANCE_TYPE)
+                try:
+                    v = objectmodel.cast_adr_to_ptr(addr, DESTR_ARG)
+                    destrptr(v)
+                except:
+                    try:
+                        os.write(2, "a destructor raised an exception, ignoring it\n")
+                    except:
+                        pass
+                objectmodel.llop.gc_restore_exception(lltype.Void, exc_instance)
+            g = self.annotate_helper(finalizer, [llmemory.Address])
         else:
             g = None
 



More information about the Pypy-commit mailing list