Move exc state to generator. Fixes bpo-25612 (#1773)

Move exception state information from frame objects to coroutine (generator/thread) object where it belongs.
This commit is contained in:
Mark Shannon 2017-10-22 22:41:51 +01:00 committed by Antoine Pitrou
parent 91dc64ba3f
commit ae3087c638
13 changed files with 188 additions and 164 deletions

View file

@ -53,6 +53,18 @@ PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback)
Py_XDECREF(oldtraceback);
}
_PyErr_StackItem *
_PyErr_GetTopmostException(PyThreadState *tstate)
{
_PyErr_StackItem *exc_info = tstate->exc_info;
while ((exc_info->exc_type == NULL || exc_info->exc_type == Py_None) &&
exc_info->previous_item != NULL)
{
exc_info = exc_info->previous_item;
}
return exc_info;
}
static PyObject*
_PyErr_CreateException(PyObject *exception, PyObject *value)
{
@ -83,7 +95,7 @@ PyErr_SetObject(PyObject *exception, PyObject *value)
}
Py_XINCREF(value);
exc_value = tstate->exc_value;
exc_value = _PyErr_GetTopmostException(tstate)->exc_value;
if (exc_value != NULL && exc_value != Py_None) {
/* Implicit exception chaining */
Py_INCREF(exc_value);
@ -335,9 +347,11 @@ PyErr_GetExcInfo(PyObject **p_type, PyObject **p_value, PyObject **p_traceback)
{
PyThreadState *tstate = PyThreadState_GET();
*p_type = tstate->exc_type;
*p_value = tstate->exc_value;
*p_traceback = tstate->exc_traceback;
_PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate);
*p_type = exc_info->exc_type;
*p_value = exc_info->exc_value;
*p_traceback = exc_info->exc_traceback;
Py_XINCREF(*p_type);
Py_XINCREF(*p_value);
@ -350,13 +364,13 @@ PyErr_SetExcInfo(PyObject *p_type, PyObject *p_value, PyObject *p_traceback)
PyObject *oldtype, *oldvalue, *oldtraceback;
PyThreadState *tstate = PyThreadState_GET();
oldtype = tstate->exc_type;
oldvalue = tstate->exc_value;
oldtraceback = tstate->exc_traceback;
oldtype = tstate->exc_info->exc_type;
oldvalue = tstate->exc_info->exc_value;
oldtraceback = tstate->exc_info->exc_traceback;
tstate->exc_type = p_type;
tstate->exc_value = p_value;
tstate->exc_traceback = p_traceback;
tstate->exc_info->exc_type = p_type;
tstate->exc_info->exc_value = p_value;
tstate->exc_info->exc_traceback = p_traceback;
Py_XDECREF(oldtype);
Py_XDECREF(oldvalue);