[Python-checkins] r46384 - in python/branches/tim-exc_sanity: Doc/api/exceptions.tex Python/ceval.c Python/errors.c

tim.peters python-checkins at python.org
Fri May 26 20:33:10 CEST 2006


Author: tim.peters
Date: Fri May 26 20:33:09 2006
New Revision: 46384

Modified:
   python/branches/tim-exc_sanity/Doc/api/exceptions.tex
   python/branches/tim-exc_sanity/Python/ceval.c
   python/branches/tim-exc_sanity/Python/errors.c
Log:
Part way there, but code still blows up.


Modified: python/branches/tim-exc_sanity/Doc/api/exceptions.tex
==============================================================================
--- python/branches/tim-exc_sanity/Doc/api/exceptions.tex	(original)
+++ python/branches/tim-exc_sanity/Doc/api/exceptions.tex	Fri May 26 20:33:09 2006
@@ -124,7 +124,9 @@
 \begin{cfuncdesc}{void}{PyErr_SetObject}{PyObject *type, PyObject *value}
   This function is similar to \cfunction{PyErr_SetString()} but lets
   you specify an arbitrary Python object for the ``value'' of the
-  exception.
+  exception.  Passing \NULL{} for \var{value} is treated as
+  if \cdata{Py_None} were passed instead.
+  \versionchanged[Treating \NULL{} as \cdata{Py_None} was added]{2.5}
 \end{cfuncdesc}
 
 \begin{cfuncdesc}{PyObject*}{PyErr_Format}{PyObject *exception,

Modified: python/branches/tim-exc_sanity/Python/ceval.c
==============================================================================
--- python/branches/tim-exc_sanity/Python/ceval.c	(original)
+++ python/branches/tim-exc_sanity/Python/ceval.c	Fri May 26 20:33:09 2006
@@ -24,7 +24,7 @@
 #pragma optimize("agtw", on)
 #endif
 
-#ifndef WITH_TSC 
+#ifndef WITH_TSC
 
 #define READ_TIMESTAMP(var)
 
@@ -49,7 +49,7 @@
 	asm volatile ("mftbu %0" : "=r" (tbu2));
 	if (__builtin_expect(tbu != tbu2, 0)) goto loop;
 
-	/* The slightly peculiar way of writing the next lines is 
+	/* The slightly peculiar way of writing the next lines is
 	   compiled better by GCC than any other way I tried. */
 	((long*)(v))[0] = tbu;
 	((long*)(v))[1] = tb;
@@ -62,7 +62,7 @@
 
 #endif
 
-void dump_tsc(int opcode, int ticked, uint64 inst0, uint64 inst1, 
+void dump_tsc(int opcode, int ticked, uint64 inst0, uint64 inst1,
 	      uint64 loop0, uint64 loop1, uint64 intr0, uint64 intr1)
 {
 	uint64 intr, inst, loop;
@@ -567,7 +567,7 @@
    inst0 -- beginning of switch statement for opcode dispatch
    inst1 -- end of switch statement (may be skipped)
    loop0 -- the top of the mainloop
-   loop1 -- place where control returns again to top of mainloop 
+   loop1 -- place where control returns again to top of mainloop
             (may be skipped)
    intr1 -- beginning of long interruption
    intr2 -- end of long interruption
@@ -768,7 +768,7 @@
 		why = WHY_EXCEPTION;
 		goto on_error;
 	}
-		
+
 	for (;;) {
 #ifdef WITH_TSC
 		if (inst1 == 0) {
@@ -2218,7 +2218,7 @@
 			   re-raising the exception.  (But non-local gotos
 			   should still be resumed.)
 			*/
-			
+
 			x = TOP();
 			u = SECOND();
 			if (PyInt_Check(u) || u == Py_None) {
@@ -2581,7 +2581,12 @@
 		}
 	}
 
-	reset_exc_info(tstate);
+	if (tstate->frame->f_exc_type != NULL)
+		reset_exc_info(tstate);
+	else {
+		assert(tstate->frame->f_exc_value == NULL);
+		assert(tstate->frame->f_exc_traceback == NULL);
+	}
 
 	/* pop frame */
     exit_eval_frame:
@@ -2900,29 +2905,34 @@
 set_exc_info(PyThreadState *tstate,
 	     PyObject *type, PyObject *value, PyObject *tb)
 {
-	PyFrameObject *frame;
+	PyFrameObject *frame = tstate->frame;
 	PyObject *tmp_type, *tmp_value, *tmp_tb;
 
-	frame = tstate->frame;
+	assert(type != NULL);
+	assert(value != NULL);
+	assert(tb != NULL);
+
 	if (frame->f_exc_type == NULL) {
-		/* This frame didn't catch an exception before */
-		/* Save previous exception of this thread in this frame */
-		if (tstate->exc_type == NULL) {
-			Py_INCREF(Py_None);
-			tstate->exc_type = Py_None;
-		}
-		tmp_value = frame->f_exc_value;
-		tmp_tb = frame->f_exc_traceback;
-		Py_XINCREF(tstate->exc_type);
-		Py_XINCREF(tstate->exc_value);
-		Py_XINCREF(tstate->exc_traceback);
-		frame->f_exc_type = tstate->exc_type;
-		frame->f_exc_value = tstate->exc_value;
-		frame->f_exc_traceback = tstate->exc_traceback;
-		Py_XDECREF(tmp_value);
-		Py_XDECREF(tmp_tb);
+		/* This frame didn't catch an exception before. */
+		assert(frame->f_exc_value == NULL);
+		assert(frame->f_exc_traceback == NULL);
+		/* Save previous exception of this thread in this frame. */
+		if (tstate->exc_type != NULL) {
+			assert(tstate->exc_value != NULL);
+			assert(tstate->exc_traceback != NULL);
+			Py_INCREF(tstate->exc_type);
+			Py_INCREF(tstate->exc_value);
+			Py_INCREF(tstate->exc_traceback);
+			frame->f_exc_type = tstate->exc_type;
+			frame->f_exc_value = tstate->exc_value;
+			frame->f_exc_traceback = tstate->exc_traceback;
+		}
+		else {
+			assert(tstate->exc_value == NULL);
+			assert(tstate->exc_traceback == NULL);
+		}
 	}
-	/* Set new exception for this thread */
+	/* Set new exception for this thread. */
 	tmp_type = tstate->exc_type;
 	tmp_value = tstate->exc_value;
 	tmp_tb = tstate->exc_traceback;
@@ -2935,6 +2945,7 @@
 	Py_XDECREF(tmp_type);
 	Py_XDECREF(tmp_value);
 	Py_XDECREF(tmp_tb);
+
 	/* For b/w compatibility */
 	PySys_SetObject("exc_type", type);
 	PySys_SetObject("exc_value", value);
@@ -2944,37 +2955,43 @@
 Py_LOCAL(void)
 reset_exc_info(PyThreadState *tstate)
 {
-	PyFrameObject *frame;
+	PyFrameObject *frame = tstate->frame;
 	PyObject *tmp_type, *tmp_value, *tmp_tb;
-	frame = tstate->frame;
-	if (frame->f_exc_type != NULL) {
-		/* This frame caught an exception */
-		tmp_type = tstate->exc_type;
-		tmp_value = tstate->exc_value;
-		tmp_tb = tstate->exc_traceback;
-		Py_INCREF(frame->f_exc_type);
-		Py_XINCREF(frame->f_exc_value);
-		Py_XINCREF(frame->f_exc_traceback);
-		tstate->exc_type = frame->f_exc_type;
-		tstate->exc_value = frame->f_exc_value;
-		tstate->exc_traceback = frame->f_exc_traceback;
-		Py_XDECREF(tmp_type);
-		Py_XDECREF(tmp_value);
-		Py_XDECREF(tmp_tb);
-		/* For b/w compatibility */
-		PySys_SetObject("exc_type", frame->f_exc_type);
-		PySys_SetObject("exc_value", frame->f_exc_value);
-		PySys_SetObject("exc_traceback", frame->f_exc_traceback);
-	}
+
+	/* That this frame caught an exception is a precondition. */
+	assert(frame->f_exc_type != NULL);
+	assert(frame->f_exc_value != NULL);
+	assert(frame->f_exc_traceback != NULL);
+
+	/* Copy exception info back into the thread state. */
+	tmp_type = tstate->exc_type;
+	tmp_value = tstate->exc_value;
+	tmp_tb = tstate->exc_traceback;
+	Py_INCREF(frame->f_exc_type);
+	Py_INCREF(frame->f_exc_value);
+	Py_INCREF(frame->f_exc_traceback);
+	tstate->exc_type = frame->f_exc_type;
+	tstate->exc_value = frame->f_exc_value;
+	tstate->exc_traceback = frame->f_exc_traceback;
+	Py_XDECREF(tmp_type);
+	Py_XDECREF(tmp_value);
+	Py_XDECREF(tmp_tb);
+
+	/* For b/w compatibility. */
+	PySys_SetObject("exc_type", frame->f_exc_type);
+	PySys_SetObject("exc_value", frame->f_exc_value);
+	PySys_SetObject("exc_traceback", frame->f_exc_traceback);
+
+	/* Clear the frame's exception info. */
 	tmp_type = frame->f_exc_type;
 	tmp_value = frame->f_exc_value;
 	tmp_tb = frame->f_exc_traceback;
 	frame->f_exc_type = NULL;
 	frame->f_exc_value = NULL;
 	frame->f_exc_traceback = NULL;
-	Py_XDECREF(tmp_type);
-	Py_XDECREF(tmp_value);
-	Py_XDECREF(tmp_tb);
+	Py_DECREF(tmp_type);
+	Py_DECREF(tmp_value);
+	Py_DECREF(tmp_tb);
 }
 
 /* Logic for the raise statement (too complicated for inlining).
@@ -3846,7 +3863,7 @@
 		Py_ssize_t x;
 		if (PyInt_Check(v)) {
 			x = PyInt_AsSsize_t(v);
-		} 
+		}
 		else if (v->ob_type->tp_as_number &&
 			 PyType_HasFeature(v->ob_type, Py_TPFLAGS_HAVE_INDEX)
 			 && v->ob_type->tp_as_number->nb_index) {
@@ -4064,7 +4081,7 @@
 	result = PyObject_CallFunctionObjArgs(metaclass, name, bases, methods, NULL);
 	Py_DECREF(metaclass);
 	if (result == NULL && PyErr_ExceptionMatches(PyExc_TypeError)) {
-		/* A type error here likely means that the user passed 
+		/* A type error here likely means that the user passed
 		   in a base that was not a class (such the random module
 		   instead of the random.random type).  Help them out with
 		   by augmenting the error message with more information.*/
@@ -4204,7 +4221,7 @@
 {
 	/* This function implements 'variable += expr' when both arguments
 	   are strings. */
-	
+
 	if (v->ob_refcnt == 2) {
 		/* In the common case, there are 2 references to the value
 		 * stored in 'variable' when the += is performed: one on the

Modified: python/branches/tim-exc_sanity/Python/errors.c
==============================================================================
--- python/branches/tim-exc_sanity/Python/errors.c	(original)
+++ python/branches/tim-exc_sanity/Python/errors.c	Fri May 26 20:33:09 2006
@@ -52,8 +52,13 @@
 void
 PyErr_SetObject(PyObject *exception, PyObject *value)
 {
+	/* ho ho ho!  blows up _while_ initializing exceptions
+	   assert(exception != NULL); */
+	if (value == NULL)
+		value = Py_None;
+	/* Py_INCREF(exception); */
 	Py_XINCREF(exception);
-	Py_XINCREF(value);
+	Py_INCREF(value);
 	PyErr_Restore(exception, value, (PyObject *)NULL);
 }
 
@@ -138,13 +143,11 @@
 		return;
 	}
 
-	/* If PyErr_SetNone() was used, the value will have been actually
-	   set to NULL.
+	assert(value != NULL);
+	assert(tb != NULL);
+	/* XXX this triggers
+	assert(*tb != NULL);
 	*/
-	if (!value) {
-		value = Py_None;
-		Py_INCREF(value);
-	}
 
 	if (PyExceptionInstance_Check(value))
 		inclass = PyExceptionInstance_Class(value);


More information about the Python-checkins mailing list