[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