gh-102192: Replace PyErr_Fetch/Restore etc by more efficient alternatives (#102631)

This commit is contained in:
Irit Katriel 2023-03-13 15:56:24 +00:00 committed by GitHub
parent 9a8b66b58c
commit ca01cae1e9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -13,7 +13,7 @@
#include "pycore_object.h" // _PyObject_GC_TRACK() #include "pycore_object.h" // _PyObject_GC_TRACK()
#include "pycore_moduleobject.h" // PyModuleObject #include "pycore_moduleobject.h" // PyModuleObject
#include "pycore_opcode.h" // EXTRA_CASES #include "pycore_opcode.h" // EXTRA_CASES
#include "pycore_pyerrors.h" // _PyErr_Fetch(), _PyErr_GetRaisedException() #include "pycore_pyerrors.h" // _PyErr_GetRaisedException()
#include "pycore_pymem.h" // _PyMem_IsPtrFreed() #include "pycore_pymem.h" // _PyMem_IsPtrFreed()
#include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_pystate.h" // _PyInterpreterState_GET()
#include "pycore_range.h" // _PyRangeIterObject #include "pycore_range.h" // _PyRangeIterObject
@ -1783,18 +1783,15 @@ do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause)
if (exc == NULL) { if (exc == NULL) {
/* Reraise */ /* Reraise */
_PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate); _PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate);
value = exc_info->exc_value; exc = exc_info->exc_value;
if (Py_IsNone(value) || value == NULL) { if (Py_IsNone(exc) || exc == NULL) {
_PyErr_SetString(tstate, PyExc_RuntimeError, _PyErr_SetString(tstate, PyExc_RuntimeError,
"No active exception to reraise"); "No active exception to reraise");
return 0; return 0;
} }
assert(PyExceptionInstance_Check(value)); Py_INCREF(exc);
type = PyExceptionInstance_Class(value); assert(PyExceptionInstance_Check(exc));
Py_XINCREF(type); _PyErr_SetRaisedException(tstate, exc);
Py_XINCREF(value);
PyObject *tb = PyException_GetTraceback(value); /* new ref */
_PyErr_Restore(tstate, type, value, tb);
return 1; return 1;
} }
@ -2035,28 +2032,27 @@ call_exc_trace(Py_tracefunc func, PyObject *self,
PyThreadState *tstate, PyThreadState *tstate,
_PyInterpreterFrame *f) _PyInterpreterFrame *f)
{ {
PyObject *type, *value, *traceback, *orig_traceback, *arg; PyObject *exc = _PyErr_GetRaisedException(tstate);
int err; assert(exc && PyExceptionInstance_Check(exc));
_PyErr_Fetch(tstate, &type, &value, &orig_traceback); PyObject *type = PyExceptionInstance_Class(exc);
if (value == NULL) { PyObject *traceback = PyException_GetTraceback(exc);
value = Py_NewRef(Py_None); if (traceback == NULL) {
traceback = Py_NewRef(Py_None);
} }
_PyErr_NormalizeException(tstate, &type, &value, &orig_traceback); PyObject *arg = PyTuple_Pack(3, type, exc, traceback);
traceback = (orig_traceback != NULL) ? orig_traceback : Py_None; Py_XDECREF(traceback);
arg = PyTuple_Pack(3, type, value, traceback);
if (arg == NULL) { if (arg == NULL) {
_PyErr_Restore(tstate, type, value, orig_traceback); _PyErr_SetRaisedException(tstate, exc);
return; return;
} }
err = call_trace(func, self, tstate, f, PyTrace_EXCEPTION, arg); int err = call_trace(func, self, tstate, f, PyTrace_EXCEPTION, arg);
Py_DECREF(arg); Py_DECREF(arg);
if (err == 0) { if (err == 0) {
_PyErr_Restore(tstate, type, value, orig_traceback); _PyErr_SetRaisedException(tstate, exc);
} }
else { else {
Py_XDECREF(type); Py_XDECREF(exc);
Py_XDECREF(value);
Py_XDECREF(orig_traceback);
} }
} }