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

cfbolz at codespeak.net cfbolz at codespeak.net
Tue Feb 14 21:28:38 CET 2006


Author: cfbolz
Date: Tue Feb 14 21:28:34 2006
New Revision: 23344

Modified:
   pypy/branch/genc-gc-refactoring/gc.py
   pypy/branch/genc-gc-refactoring/src/exception.h
   pypy/branch/genc-gc-refactoring/test/test_newgc.py
   pypy/dist/pypy/annotation/unaryop.py
   pypy/dist/pypy/rpython/memory/gctransform.py
   pypy/dist/pypy/rpython/objectmodel.py
   pypy/dist/pypy/rpython/rbuiltin.py
Log:
(arigo, cfbolz):

make the failing test pass:
  * added lots of exception_is_here/exception_cannot_occur/can_only_throw
  * correctly saved and restored the exception around the call to __del__


Modified: pypy/branch/genc-gc-refactoring/gc.py
==============================================================================
--- pypy/branch/genc-gc-refactoring/gc.py	(original)
+++ pypy/branch/genc-gc-refactoring/gc.py	Tue Feb 14 21:28:34 2006
@@ -116,6 +116,17 @@
         args = [funcgen.expr(v) for v in op.args]
         return 'OP_FREE(%s);' % (args[0], )    
 
+    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)
 
 class RefcountingRuntimeTypeInfo_OpaqueNode(ContainerNode):
     nodekind = 'refcnt rtti'

Modified: pypy/branch/genc-gc-refactoring/src/exception.h
==============================================================================
--- pypy/branch/genc-gc-refactoring/src/exception.h	(original)
+++ pypy/branch/genc-gc-refactoring/src/exception.h	Tue Feb 14 21:28:34 2006
@@ -20,16 +20,18 @@
 
 #define RPyExceptionOccurred()	(rpython_exc_type != NULL)
 
-#define RPyRaiseException(etype, evalue)		\
+#define RPyRaiseException(etype, evalue)	do {	\
 		assert(!RPyExceptionOccurred());	\
-		rpython_exc_type = etype;	\
-		rpython_exc_value = evalue
+		rpython_exc_type = etype;		\
+		rpython_exc_value = evalue;		\
+	} while (0)
 
-#define RPyFetchException(etypevar, evaluevar, type_of_evaluevar)       \
+#define RPyFetchException(etypevar, evaluevar, type_of_evaluevar) do {  \
 		etypevar = rpython_exc_type;				\
 		evaluevar = (type_of_evaluevar) rpython_exc_value;	\
 		rpython_exc_type = NULL;				\
-		rpython_exc_value = NULL
+		rpython_exc_value = NULL;				\
+	} while (0)
 
 #define RPyMatchException(etype)	RPYTHON_EXCEPTION_MATCH(rpython_exc_type,  \
 					(RPYTHON_EXCEPTION_VTABLE) etype)
@@ -107,7 +109,7 @@
 
 #define RPyExceptionOccurred()           PyErr_Occurred()
 #define RPyRaiseException(etype, evalue) PyErr_Restore(etype, evalue, NULL)
-#define RPyFetchException(etypevar, evaluevar, ignored)   {	\
+#define RPyFetchException(etypevar, evaluevar, ignored)  do {	\
 		PyObject *__tb;					\
 		PyErr_Fetch(&etypevar, &evaluevar, &__tb);	\
 		if (evaluevar == NULL) {			\
@@ -115,7 +117,7 @@
 			Py_INCREF(Py_None);			\
 		}						\
 		Py_XDECREF(__tb);				\
-	}
+	} while (0)
 #define RPyMatchException(etype)         PyErr_ExceptionMatches(etype)
 #define RPyConvertExceptionFromCPython() /* nothing */
 #define RPyConvertExceptionToCPython(vanishing) vanishing = NULL  

Modified: pypy/branch/genc-gc-refactoring/test/test_newgc.py
==============================================================================
--- pypy/branch/genc-gc-refactoring/test/test_newgc.py	(original)
+++ pypy/branch/genc-gc-refactoring/test/test_newgc.py	Tue Feb 14 21:28:34 2006
@@ -10,6 +10,8 @@
 
 from pypy.rpython.memory.gctransform import GCTransformer
 
+from pypy import conftest
+
 def compile_func(fn, inputtypes):
     t = TranslationContext()
     t.buildannotator().build_types(fn, inputtypes)
@@ -18,6 +20,8 @@
     builder.generate_source()
     skip_missing_compiler(builder.compile)
     builder.import_module()
+    if conftest.option.view:
+        t.view()
     return builder.get_entry_point()
 
 def test_something():
@@ -128,11 +132,8 @@
     assert fn(1) == 4
     assert fn(0) == 5
 
-#________________________________________________________________
-# currently crashing tests
-
 
-def DONTtest_del_catches():
+def test_del_catches():
     import os
     def g():
         pass

Modified: pypy/dist/pypy/annotation/unaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/unaryop.py	(original)
+++ pypy/dist/pypy/annotation/unaryop.py	Tue Feb 14 21:28:34 2006
@@ -563,6 +563,7 @@
         assert s_attr.is_constant(), "getattr on ptr %r with non-constant field-name" % p.ll_ptrtype
         v = getattr(p.ll_ptrtype._example(), s_attr.const)
         return ll_to_annotation(v)
+    getattr.can_only_throw = []
 
     def len(p):
         len(p.ll_ptrtype._example())   # just doing checking
@@ -663,4 +664,4 @@
         assert s_attr.const in lladdress.supported_access_types
         return SomeTypedAddressAccess(
             lladdress.supported_access_types[s_attr.const])
-
+    getattr.can_only_throw = []

Modified: pypy/dist/pypy/rpython/memory/gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctransform.py	(original)
+++ pypy/dist/pypy/rpython/memory/gctransform.py	Tue Feb 14 21:28:34 2006
@@ -379,6 +379,7 @@
         #print_call_chain(self)
         def compute_pop_alive_ll_ops(hop):
             hop.llops.extend(self.pop_alive(hop.args_v[1]))
+            hop.exception_cannot_occur()
             return hop.inputconst(hop.r_result.lowleveltype, hop.s_result.const)
         def pop_alive(var):
             pass
@@ -400,23 +401,32 @@
             return p
 
         if destrptr is not None:
-            body = '\n'.join(_static_deallocator_body_for_type('v', TYPE, 2))
+            body = '\n'.join(_static_deallocator_body_for_type('v', TYPE, 3))
             src = """
 def deallocator(addr):
-    v = cast_adr_to_ptr(addr, PTR_TYPE)
-    gcheader = addr - gc_header_offset
-    # refcount is at zero, temporarily bump it to 1:
-    gcheader.signed[0] = 1
-    destr_v = cast_pointer(DESTR_ARG, v)
+    exc_instance = objectmodel.llop.gc_fetch_exception(EXC_INSTANCE_TYPE)
     try:
-        destrptr(destr_v)
-    except Exception:
-        os.write(2, "a destructor raised an exception, ignoring it\\n")
-    refcount = gcheader.signed[0] - 1
-    gcheader.signed[0] = refcount
-    if refcount == 0:
+        v = cast_adr_to_ptr(addr, PTR_TYPE)
+        gcheader = addr - gc_header_offset
+        # refcount is at zero, temporarily bump it to 1:
+        gcheader.signed[0] = 1
+        destr_v = cast_pointer(DESTR_ARG, v)
+        try:
+            destrptr(destr_v)
+        except:
+            try:
+                os.write(2, "a destructor raised an exception, ignoring it\\n")
+            except:
+                pass
+        refcount = gcheader.signed[0] - 1
+        gcheader.signed[0] = refcount
+        if refcount == 0:
 %s
-        objectmodel.llop.gc_free(lltype.Void, addr)
+            objectmodel.llop.gc_free(lltype.Void, addr)
+    except:
+        pass
+    objectmodel.llop.gc_restore_exception(lltype.Void, exc_instance)
+        
 """ % (body, )
         else:
             call_del = None
@@ -432,6 +442,7 @@
              'cast_pointer': lltype.cast_pointer,
              'PTR_TYPE': lltype.Ptr(TYPE),
              'DESTR_ARG': DESTR_ARG,
+             'EXC_INSTANCE_TYPE': self.translator.rtyper.exceptiondata.lltype_of_exception_value,
              'os': py.std.os}
         exec src in d
         this = d['deallocator']

Modified: pypy/dist/pypy/rpython/objectmodel.py
==============================================================================
--- pypy/dist/pypy/rpython/objectmodel.py	(original)
+++ pypy/dist/pypy/rpython/objectmodel.py	Tue Feb 14 21:28:34 2006
@@ -83,6 +83,7 @@
 
     def specialize(self, hop):
         args_v = [hop.inputarg(r, i+1) for i, r in enumerate(hop.args_r[1:])]
+        hop.exception_is_here()
         return hop.genop(self.opname, args_v, resulttype=hop.r_result.lowleveltype)
 
 class LLOpFactory(object):

Modified: pypy/dist/pypy/rpython/rbuiltin.py
==============================================================================
--- pypy/dist/pypy/rpython/rbuiltin.py	(original)
+++ pypy/dist/pypy/rpython/rbuiltin.py	Tue Feb 14 21:28:34 2006
@@ -292,6 +292,7 @@
     assert hop.args_s[0].is_constant()
     assert isinstance(hop.args_r[1], rptr.PtrRepr)
     v_type, v_input = hop.inputargs(lltype.Void, hop.args_r[1])
+    hop.exception_cannot_occur()
     return hop.genop('cast_pointer', [v_input],    # v_type implicit in r_result
                      resulttype = hop.r_result.lowleveltype)
 
@@ -463,12 +464,14 @@
 def rtype_cast_ptr_to_adr(hop):
     vlist = hop.inputargs(hop.args_r[0])
     assert isinstance(vlist[0].concretetype, lltype.Ptr)
+    hop.exception_cannot_occur()
     return hop.genop('cast_ptr_to_adr', vlist,
                      resulttype = llmemory.Address)
 
 def rtype_cast_adr_to_ptr(hop):
     assert isinstance(hop.args_r[0], raddress.AddressRepr)
     adr, TYPE = hop.inputargs(hop.args_r[0], lltype.Void)
+    hop.exception_cannot_occur()
     return hop.genop('cast_adr_to_ptr', [adr],
                      resulttype = TYPE.value)
 



More information about the Pypy-commit mailing list