[pypy-svn] r24946 - in pypy/branch/explicit-exceptions/translator/c: . src

mwh at codespeak.net mwh at codespeak.net
Fri Mar 24 12:17:22 CET 2006


Author: mwh
Date: Fri Mar 24 12:17:17 2006
New Revision: 24946

Modified:
   pypy/branch/explicit-exceptions/translator/c/exceptiontransform.py
   pypy/branch/explicit-exceptions/translator/c/extfunc.py
   pypy/branch/explicit-exceptions/translator/c/funcgen.py
   pypy/branch/explicit-exceptions/translator/c/gc.py
   pypy/branch/explicit-exceptions/translator/c/src/exception.h
   pypy/branch/explicit-exceptions/translator/c/src/ll_stackless.h
   pypy/branch/explicit-exceptions/translator/c/src/main.h
   pypy/branch/explicit-exceptions/translator/c/src/mem.h
Log:
implement all the RPyExceptionOccurred(), etc functions in RPython so that
instead of having to special case exceptions all over the place, the existing
machinery can do it for us, and in fact this reduces the overall number of
special cases somewhat.

this status of the branch is that one test fails in test_backendoptimized
(test_del_inheritance, a bit of a mystery), test_boehm, test_standalone and
test_exceptiontransform pass, test_stackless crashes and the others i haven't
run recently.  not too bad :)


Modified: pypy/branch/explicit-exceptions/translator/c/exceptiontransform.py
==============================================================================
--- pypy/branch/explicit-exceptions/translator/c/exceptiontransform.py	(original)
+++ pypy/branch/explicit-exceptions/translator/c/exceptiontransform.py	Fri Mar 24 12:17:17 2006
@@ -7,6 +7,8 @@
 from pypy.rpython.memory.lladdress import NULL
 from pypy.rpython import rclass
 from pypy.rpython.rarithmetic import r_uint, r_longlong, r_ulonglong
+from pypy.annotation import model as annmodel
+from pypy.rpython.annlowlevel import MixLevelHelperAnnotator
 
 PrimitiveErrorValue = {lltype.Signed: -1,
                        lltype.Unsigned: r_uint(-1),
@@ -25,63 +27,88 @@
         return Constant(lltype.nullptr(T.TO), T)
     assert 0, "not implemented yet"
 
-# dummy functions to make the resulting graphs runnable on the llinterpreter
-
-class ExcData(object):
-    exc_type = None
-    exc_value = None
-
-def rpyexc_occured():
-    return ExcData.exc_type is not None
-
-def rpyexc_fetch_type():
-    return ExcData.exc_type
-
-def rpyexc_fetch_value():
-    return ExcData.exc_value
-
-def rpyexc_clear():
-    ExcData.exc_type = None
-    ExcData.exc_value = None
-
-def rpyexc_raise(etype, evalue):
-    ExcData.exc_type = etype
-    ExcData.exc_value = evalue
-
 class ExceptionTransformer(object):
     def __init__(self, translator):
         self.translator = translator
         self.raise_analyzer = canraise.RaiseAnalyzer(translator)
         self.exc_data = translator.rtyper.getexceptiondata()
+        mixlevelannotator = MixLevelHelperAnnotator(translator.rtyper)
+        l2a = annmodel.lltype_to_annotation
+
+        class ExcData(object):
+            pass
+            #exc_type = lltype.nullptr(self.exc_data.lltype_of_exception_type.TO)
+            #exc_value = lltype.nullptr(self.exc_data.lltype_of_exception_value.TO)
+
+        exc_data = ExcData()
+        null_type = lltype.nullptr(self.exc_data.lltype_of_exception_type.TO)
+        null_value = lltype.nullptr(self.exc_data.lltype_of_exception_value.TO)
+        
+        def rpyexc_occured():
+            return exc_data.exc_type is not null_type
+
+        def rpyexc_fetch_type():
+            return exc_data.exc_type
+
+        def rpyexc_fetch_value():
+            return exc_data.exc_value
+
+        def rpyexc_clear():
+            exc_data.exc_type = null_type
+            exc_data.exc_value = null_value
+
+        def rpyexc_raise(etype, evalue):
+            # assert(!RPyExceptionOccurred());
+            exc_data.exc_type = etype
+            exc_data.exc_value = evalue
+        
         RPYEXC_OCCURED_TYPE = lltype.FuncType([], lltype.Bool)
+        rpyexc_occured_graph = mixlevelannotator.getgraph(
+            rpyexc_occured, [], l2a(lltype.Bool))
         self.rpyexc_occured_ptr = Constant(lltype.functionptr(
-            RPYEXC_OCCURED_TYPE, "RPyExceptionOccurred", external="C",
-            neverrraises=True, _callable=rpyexc_occured),
+            RPYEXC_OCCURED_TYPE, "RPyExceptionOccurred",
+            graph=rpyexc_occured_graph),
             lltype.Ptr(RPYEXC_OCCURED_TYPE))
+        
         RPYEXC_FETCH_TYPE_TYPE = lltype.FuncType([], self.exc_data.lltype_of_exception_type)
+        rpyexc_fetch_type_graph = mixlevelannotator.getgraph(
+            rpyexc_fetch_type, [],
+            l2a(self.exc_data.lltype_of_exception_type))
         self.rpyexc_fetch_type_ptr = Constant(lltype.functionptr(
-            RPYEXC_FETCH_TYPE_TYPE, "RPyFetchExceptionType", external="C",
-            neverraises=True, _callable=rpyexc_fetch_type),
+            RPYEXC_FETCH_TYPE_TYPE, "RPyFetchExceptionType",
+            graph=rpyexc_fetch_type_graph),
             lltype.Ptr(RPYEXC_FETCH_TYPE_TYPE))
+        
         RPYEXC_FETCH_VALUE_TYPE = lltype.FuncType([], self.exc_data.lltype_of_exception_value)
+        rpyexc_fetch_value_graph = mixlevelannotator.getgraph(
+            rpyexc_fetch_value, [],
+            l2a(self.exc_data.lltype_of_exception_value))
         self.rpyexc_fetch_value_ptr = Constant(lltype.functionptr(
-            RPYEXC_FETCH_VALUE_TYPE, "RPyFetchExceptionValue", external="C",
-            neverraises=True, _callable=rpyexc_fetch_value),
+            RPYEXC_FETCH_VALUE_TYPE, "RPyFetchExceptionValue",
+            graph=rpyexc_fetch_value_graph),
             lltype.Ptr(RPYEXC_FETCH_VALUE_TYPE))
+
         RPYEXC_CLEAR = lltype.FuncType([], lltype.Void)
+        rpyexc_clear_graph = mixlevelannotator.getgraph(
+            rpyexc_clear, [], l2a(lltype.Void))
         self.rpyexc_clear_ptr = Constant(lltype.functionptr(
-            RPYEXC_CLEAR, "RPyClearException", external="C",
-            neverraises=True, _callable=rpyexc_clear),
+            RPYEXC_CLEAR, "RPyClearException",
+            graph=rpyexc_clear_graph),
             lltype.Ptr(RPYEXC_CLEAR))
+
         RPYEXC_RAISE = lltype.FuncType([self.exc_data.lltype_of_exception_type,
                                         self.exc_data.lltype_of_exception_value],
                                         lltype.Void)
-        # XXX cannot really be called as a normal function, it wants to steal
-        # the argument references away, so those should not be pop_alive (decrefed)
+        rpyexc_raise_graph = mixlevelannotator.getgraph(
+            rpyexc_raise, [l2a(self.exc_data.lltype_of_exception_type),
+                           l2a(self.exc_data.lltype_of_exception_value)],
+            l2a(lltype.Void))
         self.rpyexc_raise_ptr = Constant(lltype.functionptr(
-            RPYEXC_RAISE, "RPyRaiseException", external="C",
-            neverraises=True, _callable=rpyexc_raise),
+            RPYEXC_RAISE, "RPyRaiseException",
+            graph=rpyexc_raise_graph),
             lltype.Ptr(RPYEXC_RAISE))
+
+        mixlevelannotator.finish()
     
     def transform_completely(self):
         for graph in self.translator.graphs:

Modified: pypy/branch/explicit-exceptions/translator/c/extfunc.py
==============================================================================
--- pypy/branch/explicit-exceptions/translator/c/extfunc.py	(original)
+++ pypy/branch/explicit-exceptions/translator/c/extfunc.py	Fri Mar 24 12:17:17 2006
@@ -226,6 +226,7 @@
 def predeclare_exception_data(db, rtyper, optimize=True):
     # Exception-related types and constants
     exceptiondata = rtyper.getexceptiondata()
+    exctransformer = db.exctransformer
 
     yield ('RPYTHON_EXCEPTION_VTABLE', exceptiondata.lltype_of_exception_type)
     yield ('RPYTHON_EXCEPTION',        exceptiondata.lltype_of_exception_value)
@@ -236,6 +237,12 @@
     if not db.standalone:
         yield ('RPYTHON_PYEXCCLASS2EXC', exceptiondata.fn_pyexcclass2exc)
 
+    yield ('RPyExceptionOccurred',     exctransformer.rpyexc_occured_ptr.value)
+    yield ('RPyFetchExceptionType',    exctransformer.rpyexc_fetch_type_ptr.value)
+    yield ('RPyFetchExceptionValue',   exctransformer.rpyexc_fetch_value_ptr.value)
+    yield ('RPyClearException',        exctransformer.rpyexc_clear_ptr.value)
+    yield ('RPyRaiseException',        exctransformer.rpyexc_raise_ptr.value)
+
     for pyexccls in exceptiondata.standardexceptions:
         exc_llvalue = exceptiondata.fn_pyexcclass2exc(
             lltype.pyobjectptr(pyexccls))

Modified: pypy/branch/explicit-exceptions/translator/c/funcgen.py
==============================================================================
--- pypy/branch/explicit-exceptions/translator/c/funcgen.py	(original)
+++ pypy/branch/explicit-exceptions/translator/c/funcgen.py	Fri Mar 24 12:17:17 2006
@@ -189,10 +189,9 @@
                 assert len(block.inputargs) == 1
                 # regular return block
                 if self.cpython_exc:
-                    # XXX leaks!
                     assert self.lltypemap(self.graph.getreturnvar()) == PyObjPtr
                     yield 'if (RPyExceptionOccurred()) {'
-                    yield '\tRPyConvertExceptionToCPython(rpython_exc_value);'
+                    yield '\tRPyConvertExceptionToCPython();'
                     yield '\treturn NULL;'
                     yield '}'
                 retval = self.expr(block.inputargs[0])

Modified: pypy/branch/explicit-exceptions/translator/c/gc.py
==============================================================================
--- pypy/branch/explicit-exceptions/translator/c/gc.py	(original)
+++ pypy/branch/explicit-exceptions/translator/c/gc.py	Fri Mar 24 12:17:17 2006
@@ -118,15 +118,12 @@
 
     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, )
+        return ('%s = RPyFetchExceptionValue();\n'
+                'RPyClearException();') % (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)
+        return 'if (%s != NULL) RPyRaiseException(RPYTHON_TYPE_OF_EXC_INST(%s), %s);' % (argh, argh, argh)
 
     def OP_GC__COLLECT(self, funcgen, op, err):
         return ''
@@ -223,15 +220,12 @@
 
     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, )
+        return ('%s = RPyFetchExceptionValue();\n'
+                'RPyClearException();') % (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)
+        return 'if (%s != NULL) RPyRaiseException(RPYTHON_TYPE_OF_EXC_INST(%s), %s);' % (argh, argh, argh)
 
     def OP_GC__COLLECT(self, funcgen, op, err):
         return 'GC_gcollect(); GC_invoke_finalizers();'

Modified: pypy/branch/explicit-exceptions/translator/c/src/exception.h
==============================================================================
--- pypy/branch/explicit-exceptions/translator/c/src/exception.h	(original)
+++ pypy/branch/explicit-exceptions/translator/c/src/exception.h	Fri Mar 24 12:17:17 2006
@@ -10,44 +10,12 @@
 #ifdef HAVE_RTYPER               /* RPython version of exceptions */
 /******************************************************************/
 
-#ifdef PYPY_NOT_MAIN_FILE
-extern RPYTHON_EXCEPTION_VTABLE	rpython_exc_type;
-extern RPYTHON_EXCEPTION	rpython_exc_value;
-#else
-RPYTHON_EXCEPTION_VTABLE	rpython_exc_type = NULL;
-RPYTHON_EXCEPTION		rpython_exc_value = NULL;
-#endif
-
-#define RPyExceptionOccurred()	(rpython_exc_type != NULL)
-
-#define RPyRaiseException(etype, evalue)	do {	\
-		assert(!RPyExceptionOccurred());	\
-		rpython_exc_type = etype;		\
-		rpython_exc_value = evalue;		\
-	} while (0)
-
 #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;				\
-	} while (0)
-
-#define RPyFetchExceptionValue() rpython_exc_value
-
-#define RPyFetchExceptionType() rpython_exc_type
-
-#define RPyClearException() do {                                        \
-		rpython_exc_type = NULL;				\
-		rpython_exc_value = NULL;				\
+		etypevar = RPyFetchExceptionType();			\
+		evaluevar = (type_of_evaluevar)RPyFetchExceptionValue(); \
+		RPyClearException();					\
 	} while (0)
 
-                
-
-#define RPyMatchException(etype)	RPYTHON_EXCEPTION_MATCH(rpython_exc_type,  \
-					(RPYTHON_EXCEPTION_VTABLE) etype)
-
-
 /* prototypes */
 
 #define RPyRaiseSimpleException(exc, msg)   _RPyRaiseSimpleException(R##exc)
@@ -55,26 +23,17 @@
 
 #ifndef PYPY_STANDALONE
 void RPyConvertExceptionFromCPython(void);
-void _RPyConvertExceptionToCPython(void);
-#define RPyConvertExceptionToCPython(vanishing)    \
-	_RPyConvertExceptionToCPython();		\
-	vanishing = rpython_exc_value;		\
-	rpython_exc_type = NULL;		\
-	rpython_exc_value = NULL
+void RPyConvertExceptionToCPython(void);
 #endif
 
-
 /* implementations */
 
 #ifndef PYPY_NOT_MAIN_FILE
 
 void _RPyRaiseSimpleException(RPYTHON_EXCEPTION rexc)
 {
-	/* XXX 1. uses officially bad fishing */
-	/* XXX 2. msg is ignored */
-	rpython_exc_type = rexc->o_typeptr;
-	rpython_exc_value = rexc;
-	PUSH_ALIVE(rpython_exc_value);
+	/* XXX msg is ignored */
+	RPyRaiseException(RPYTHON_TYPE_OF_EXC_INST(rexc), rexc);
 }
 
 #ifndef PYPY_STANDALONE
@@ -82,15 +41,18 @@
 {
 	/* convert the CPython exception to an RPython one */
 	PyObject *exc_type, *exc_value, *exc_tb;
+	RPYTHON_EXCEPTION rexc;
+
 	assert(PyErr_Occurred());
 	assert(!RPyExceptionOccurred());
 	PyErr_Fetch(&exc_type, &exc_value, &exc_tb);
-	/* XXX loosing the error message here */
-	rpython_exc_value = RPYTHON_PYEXCCLASS2EXC(exc_type);
-	rpython_exc_type = RPYTHON_TYPE_OF_EXC_INST(rpython_exc_value);
+
+	/* XXX losing the error message here */	
+	rexc = RPYTHON_PYEXCCLASS2EXC(exc_type);
+	RPyRaiseException(RPYTHON_TYPE_OF_EXC_INST(rexc), rexc);
 }
 
-void _RPyConvertExceptionToCPython(void)
+void RPyConvertExceptionToCPython(void)
 {
 	/* XXX 1. uses officially bad fishing */
 	/* XXX 2. looks for exception classes by name, fragile */
@@ -98,7 +60,7 @@
 	PyObject* pycls;
 	assert(RPyExceptionOccurred());
 	assert(!PyErr_Occurred());
-	clsname = rpython_exc_type->ov_name->items;
+	clsname = RPyFetchExceptionType()->ov_name->items;
 	pycls = PyDict_GetItemString(PyEval_GetBuiltins(), clsname);
 	if (pycls != NULL && PyClass_Check(pycls) &&
 	    PyClass_IsSubclass(pycls, PyExc_Exception)) {
@@ -107,6 +69,7 @@
 	else {
 		PyErr_SetString(RPythonError, clsname);
 	}
+	RPyClearException();
 }
 #endif   /* !PYPY_STANDALONE */
 
@@ -129,7 +92,6 @@
 		}						\
 		Py_XDECREF(__tb);				\
 	} while (0)
-#define RPyMatchException(etype)         PyErr_ExceptionMatches(etype)
 #define RPyConvertExceptionFromCPython() /* nothing */
 #define RPyConvertExceptionToCPython(vanishing) vanishing = NULL  
 

Modified: pypy/branch/explicit-exceptions/translator/c/src/ll_stackless.h
==============================================================================
--- pypy/branch/explicit-exceptions/translator/c/src/ll_stackless.h	(original)
+++ pypy/branch/explicit-exceptions/translator/c/src/ll_stackless.h	Fri Mar 24 12:17:17 2006
@@ -17,6 +17,7 @@
 
 #undef USE_OPTIMIZED_STACKLESS_UNWIND
 /* XXX we seem to be missing something */
+/* XXX also now very broken because exceptions have changed */
 
 #ifdef USE_OPTIMIZED_STACKLESS_UNWIND
 

Modified: pypy/branch/explicit-exceptions/translator/c/src/main.h
==============================================================================
--- pypy/branch/explicit-exceptions/translator/c/src/main.h	(original)
+++ pypy/branch/explicit-exceptions/translator/c/src/main.h	Fri Mar 24 12:17:17 2006
@@ -35,7 +35,7 @@
     if (RPyExceptionOccurred()) {
         /* fish for the exception type, at least */
         fprintf(stderr, "Fatal PyPy error: %s\n",
-                rpython_exc_type->ov_name->items);
+                RPyFetchExceptionType()->ov_name->items);
         exitcode = 1;
     }
     return exitcode;

Modified: pypy/branch/explicit-exceptions/translator/c/src/mem.h
==============================================================================
--- pypy/branch/explicit-exceptions/translator/c/src/mem.h	(original)
+++ pypy/branch/explicit-exceptions/translator/c/src/mem.h	Fri Mar 24 12:17:17 2006
@@ -29,9 +29,6 @@
 
 #define OP_FREE(p)	{ PyObject_Free(p); COUNT_FREE; }
 
-/* XXX uses officially bad fishing */
-#define PUSH_ALIVE(obj) obj->refcount++
-
 /*------------------------------------------------------------*/
 #ifndef COUNT_OP_MALLOCS
 /*------------------------------------------------------------*/
@@ -82,9 +79,6 @@
 */
 #define OP_CALL_BOEHM_GC_ALLOC(size, r, err) OP_BOEHM_ZERO_MALLOC(size, r, 0, 0, err)
 
-#undef PUSH_ALIVE
-#define PUSH_ALIVE(obj)
-
 #endif /* USING_BOEHM_GC */
 
 /* for no GC */



More information about the Pypy-commit mailing list