mirror of https://github.com/python/cpython
gh-102192: Replace PyErr_Fetch/Restore etc by more efficient alternatives (in Python/) (#102193)
This commit is contained in:
parent
85b1fc1fc5
commit
4c87537efb
|
@ -17,7 +17,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()
|
#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
|
||||||
|
|
|
@ -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()
|
#include "pycore_pyerrors.h" // _PyErr_Fetch(), _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
|
||||||
|
@ -105,8 +105,7 @@ static void
|
||||||
dump_stack(_PyInterpreterFrame *frame, PyObject **stack_pointer)
|
dump_stack(_PyInterpreterFrame *frame, PyObject **stack_pointer)
|
||||||
{
|
{
|
||||||
PyObject **stack_base = _PyFrame_Stackbase(frame);
|
PyObject **stack_base = _PyFrame_Stackbase(frame);
|
||||||
PyObject *type, *value, *traceback;
|
PyObject *exc = PyErr_GetRaisedException();
|
||||||
PyErr_Fetch(&type, &value, &traceback);
|
|
||||||
printf(" stack=[");
|
printf(" stack=[");
|
||||||
for (PyObject **ptr = stack_base; ptr < stack_pointer; ptr++) {
|
for (PyObject **ptr = stack_base; ptr < stack_pointer; ptr++) {
|
||||||
if (ptr != stack_base) {
|
if (ptr != stack_base) {
|
||||||
|
@ -120,7 +119,7 @@ dump_stack(_PyInterpreterFrame *frame, PyObject **stack_pointer)
|
||||||
}
|
}
|
||||||
printf("]\n");
|
printf("]\n");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
PyErr_Restore(type, value, traceback);
|
PyErr_SetRaisedException(exc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -157,8 +156,7 @@ lltrace_resume_frame(_PyInterpreterFrame *frame)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PyFunctionObject *f = (PyFunctionObject *)fobj;
|
PyFunctionObject *f = (PyFunctionObject *)fobj;
|
||||||
PyObject *type, *value, *traceback;
|
PyObject *exc = PyErr_GetRaisedException();
|
||||||
PyErr_Fetch(&type, &value, &traceback);
|
|
||||||
PyObject *name = f->func_qualname;
|
PyObject *name = f->func_qualname;
|
||||||
if (name == NULL) {
|
if (name == NULL) {
|
||||||
name = f->func_name;
|
name = f->func_name;
|
||||||
|
@ -178,7 +176,7 @@ lltrace_resume_frame(_PyInterpreterFrame *frame)
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
PyErr_Restore(type, value, traceback);
|
PyErr_SetRaisedException(exc);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
static int call_trace(Py_tracefunc, PyObject *,
|
static int call_trace(Py_tracefunc, PyObject *,
|
||||||
|
@ -1032,7 +1030,6 @@ exception_unwind:
|
||||||
PyObject *v = POP();
|
PyObject *v = POP();
|
||||||
Py_XDECREF(v);
|
Py_XDECREF(v);
|
||||||
}
|
}
|
||||||
PyObject *exc, *val, *tb;
|
|
||||||
if (lasti) {
|
if (lasti) {
|
||||||
int frame_lasti = _PyInterpreterFrame_LASTI(frame);
|
int frame_lasti = _PyInterpreterFrame_LASTI(frame);
|
||||||
PyObject *lasti = PyLong_FromLong(frame_lasti);
|
PyObject *lasti = PyLong_FromLong(frame_lasti);
|
||||||
|
@ -1041,19 +1038,12 @@ exception_unwind:
|
||||||
}
|
}
|
||||||
PUSH(lasti);
|
PUSH(lasti);
|
||||||
}
|
}
|
||||||
_PyErr_Fetch(tstate, &exc, &val, &tb);
|
|
||||||
/* Make the raw exception data
|
/* Make the raw exception data
|
||||||
available to the handler,
|
available to the handler,
|
||||||
so a program can emulate the
|
so a program can emulate the
|
||||||
Python main loop. */
|
Python main loop. */
|
||||||
_PyErr_NormalizeException(tstate, &exc, &val, &tb);
|
PUSH(_PyErr_GetRaisedException(tstate));
|
||||||
if (tb != NULL)
|
|
||||||
PyException_SetTraceback(val, tb);
|
|
||||||
else
|
|
||||||
PyException_SetTraceback(val, Py_None);
|
|
||||||
Py_XDECREF(tb);
|
|
||||||
Py_XDECREF(exc);
|
|
||||||
PUSH(val);
|
|
||||||
JUMPTO(handler);
|
JUMPTO(handler);
|
||||||
/* Resume normal execution */
|
/* Resume normal execution */
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
|
@ -2075,19 +2065,15 @@ call_trace_protected(Py_tracefunc func, PyObject *obj,
|
||||||
PyThreadState *tstate, _PyInterpreterFrame *frame,
|
PyThreadState *tstate, _PyInterpreterFrame *frame,
|
||||||
int what, PyObject *arg)
|
int what, PyObject *arg)
|
||||||
{
|
{
|
||||||
PyObject *type, *value, *traceback;
|
PyObject *exc = _PyErr_GetRaisedException(tstate);
|
||||||
int err;
|
int err = call_trace(func, obj, tstate, frame, what, arg);
|
||||||
_PyErr_Fetch(tstate, &type, &value, &traceback);
|
|
||||||
err = call_trace(func, obj, tstate, frame, what, arg);
|
|
||||||
if (err == 0)
|
if (err == 0)
|
||||||
{
|
{
|
||||||
_PyErr_Restore(tstate, type, value, traceback);
|
_PyErr_SetRaisedException(tstate, exc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Py_XDECREF(type);
|
Py_XDECREF(exc);
|
||||||
Py_XDECREF(value);
|
|
||||||
Py_XDECREF(traceback);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2935,18 +2921,15 @@ format_exc_check_arg(PyThreadState *tstate, PyObject *exc,
|
||||||
|
|
||||||
if (exc == PyExc_NameError) {
|
if (exc == PyExc_NameError) {
|
||||||
// Include the name in the NameError exceptions to offer suggestions later.
|
// Include the name in the NameError exceptions to offer suggestions later.
|
||||||
PyObject *type, *value, *traceback;
|
PyObject *exc = PyErr_GetRaisedException();
|
||||||
PyErr_Fetch(&type, &value, &traceback);
|
if (PyErr_GivenExceptionMatches(exc, PyExc_NameError)) {
|
||||||
PyErr_NormalizeException(&type, &value, &traceback);
|
if (((PyNameErrorObject*)exc)->name == NULL) {
|
||||||
if (PyErr_GivenExceptionMatches(value, PyExc_NameError)) {
|
|
||||||
PyNameErrorObject* exc = (PyNameErrorObject*) value;
|
|
||||||
if (exc->name == NULL) {
|
|
||||||
// We do not care if this fails because we are going to restore the
|
// We do not care if this fails because we are going to restore the
|
||||||
// NameError anyway.
|
// NameError anyway.
|
||||||
(void)PyObject_SetAttr(value, &_Py_ID(name), obj);
|
(void)PyObject_SetAttr(exc, &_Py_ID(name), obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PyErr_Restore(type, value, traceback);
|
PyErr_SetRaisedException(exc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "pycore_atomic.h" // _Py_atomic_int
|
#include "pycore_atomic.h" // _Py_atomic_int
|
||||||
#include "pycore_ceval.h" // _PyEval_SignalReceived()
|
#include "pycore_ceval.h" // _PyEval_SignalReceived()
|
||||||
#include "pycore_pyerrors.h" // _PyErr_Fetch()
|
#include "pycore_pyerrors.h" // _PyErr_GetRaisedException()
|
||||||
#include "pycore_pylifecycle.h" // _PyErr_Print()
|
#include "pycore_pylifecycle.h" // _PyErr_Print()
|
||||||
#include "pycore_initconfig.h" // _PyStatus_OK()
|
#include "pycore_initconfig.h" // _PyStatus_OK()
|
||||||
#include "pycore_interp.h" // _Py_RunGC()
|
#include "pycore_interp.h" // _Py_RunGC()
|
||||||
|
@ -870,10 +870,9 @@ _Py_FinishPendingCalls(PyThreadState *tstate)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (make_pending_calls(tstate->interp) < 0) {
|
if (make_pending_calls(tstate->interp) < 0) {
|
||||||
PyObject *exc, *val, *tb;
|
PyObject *exc = _PyErr_GetRaisedException(tstate);
|
||||||
_PyErr_Fetch(tstate, &exc, &val, &tb);
|
|
||||||
PyErr_BadInternalCall();
|
PyErr_BadInternalCall();
|
||||||
_PyErr_ChainExceptions(exc, val, tb);
|
_PyErr_ChainExceptions1(exc);
|
||||||
_PyErr_Print(tstate);
|
_PyErr_Print(tstate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1633,8 +1633,7 @@ static void
|
||||||
compiler_exit_scope(struct compiler *c)
|
compiler_exit_scope(struct compiler *c)
|
||||||
{
|
{
|
||||||
// Don't call PySequence_DelItem() with an exception raised
|
// Don't call PySequence_DelItem() with an exception raised
|
||||||
PyObject *exc_type, *exc_val, *exc_tb;
|
PyObject *exc = PyErr_GetRaisedException();
|
||||||
PyErr_Fetch(&exc_type, &exc_val, &exc_tb);
|
|
||||||
|
|
||||||
c->c_nestlevel--;
|
c->c_nestlevel--;
|
||||||
compiler_unit_free(c->u);
|
compiler_unit_free(c->u);
|
||||||
|
@ -1655,7 +1654,7 @@ compiler_exit_scope(struct compiler *c)
|
||||||
c->u = NULL;
|
c->u = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyErr_Restore(exc_type, exc_val, exc_tb);
|
PyErr_SetRaisedException(exc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Search if variable annotations are present statically in a block. */
|
/* Search if variable annotations are present statically in a block. */
|
||||||
|
|
|
@ -29,17 +29,14 @@ PyFrameObject *
|
||||||
_PyFrame_MakeAndSetFrameObject(_PyInterpreterFrame *frame)
|
_PyFrame_MakeAndSetFrameObject(_PyInterpreterFrame *frame)
|
||||||
{
|
{
|
||||||
assert(frame->frame_obj == NULL);
|
assert(frame->frame_obj == NULL);
|
||||||
PyObject *error_type, *error_value, *error_traceback;
|
PyObject *exc = PyErr_GetRaisedException();
|
||||||
PyErr_Fetch(&error_type, &error_value, &error_traceback);
|
|
||||||
|
|
||||||
PyFrameObject *f = _PyFrame_New_NoTrack(frame->f_code);
|
PyFrameObject *f = _PyFrame_New_NoTrack(frame->f_code);
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
Py_XDECREF(error_type);
|
Py_XDECREF(exc);
|
||||||
Py_XDECREF(error_value);
|
|
||||||
Py_XDECREF(error_traceback);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
PyErr_Restore(error_type, error_value, error_traceback);
|
PyErr_SetRaisedException(exc);
|
||||||
if (frame->frame_obj) {
|
if (frame->frame_obj) {
|
||||||
// GH-97002: How did we get into this horrible situation? Most likely,
|
// GH-97002: How did we get into this horrible situation? Most likely,
|
||||||
// allocating f triggered a GC collection, which ran some code that
|
// allocating f triggered a GC collection, which ran some code that
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include "pycore_interp.h" // _PyInterpreterState.runtime
|
#include "pycore_interp.h" // _PyInterpreterState.runtime
|
||||||
#include "pycore_long.h" // _PY_LONG_MAX_STR_DIGITS_THRESHOLD
|
#include "pycore_long.h" // _PY_LONG_MAX_STR_DIGITS_THRESHOLD
|
||||||
#include "pycore_pathconfig.h" // _Py_path_config
|
#include "pycore_pathconfig.h" // _Py_path_config
|
||||||
#include "pycore_pyerrors.h" // _PyErr_Fetch()
|
#include "pycore_pyerrors.h" // _PyErr_GetRaisedException()
|
||||||
#include "pycore_pylifecycle.h" // _Py_PreInitializeFromConfig()
|
#include "pycore_pylifecycle.h" // _Py_PreInitializeFromConfig()
|
||||||
#include "pycore_pymem.h" // _PyMem_SetDefaultAllocator()
|
#include "pycore_pymem.h" // _PyMem_SetDefaultAllocator()
|
||||||
#include "pycore_pystate.h" // _PyThreadState_GET()
|
#include "pycore_pystate.h" // _PyThreadState_GET()
|
||||||
|
|
|
@ -93,16 +93,12 @@ static PyObject *do_mkvalue(const char**, va_list *, int);
|
||||||
static void
|
static void
|
||||||
do_ignore(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags)
|
do_ignore(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags)
|
||||||
{
|
{
|
||||||
PyObject *v;
|
|
||||||
Py_ssize_t i;
|
|
||||||
assert(PyErr_Occurred());
|
assert(PyErr_Occurred());
|
||||||
v = PyTuple_New(n);
|
PyObject *v = PyTuple_New(n);
|
||||||
for (i = 0; i < n; i++) {
|
for (Py_ssize_t i = 0; i < n; i++) {
|
||||||
PyObject *exception, *value, *tb, *w;
|
PyObject *exc = PyErr_GetRaisedException();
|
||||||
|
PyObject *w = do_mkvalue(p_format, p_va, flags);
|
||||||
PyErr_Fetch(&exception, &value, &tb);
|
PyErr_SetRaisedException(exc);
|
||||||
w = do_mkvalue(p_format, p_va, flags);
|
|
||||||
PyErr_Restore(exception, value, tb);
|
|
||||||
if (w != NULL) {
|
if (w != NULL) {
|
||||||
if (v != NULL) {
|
if (v != NULL) {
|
||||||
PyTuple_SET_ITEM(v, i, w);
|
PyTuple_SET_ITEM(v, i, w);
|
||||||
|
|
|
@ -23,7 +23,7 @@ Data members:
|
||||||
#include "pycore_namespace.h" // _PyNamespace_New()
|
#include "pycore_namespace.h" // _PyNamespace_New()
|
||||||
#include "pycore_object.h" // _PyObject_IS_GC()
|
#include "pycore_object.h" // _PyObject_IS_GC()
|
||||||
#include "pycore_pathconfig.h" // _PyPathConfig_ComputeSysPath0()
|
#include "pycore_pathconfig.h" // _PyPathConfig_ComputeSysPath0()
|
||||||
#include "pycore_pyerrors.h" // _PyErr_Fetch()
|
#include "pycore_pyerrors.h" // _PyErr_GetRaisedException()
|
||||||
#include "pycore_pylifecycle.h" // _PyErr_WriteUnraisableDefaultHook()
|
#include "pycore_pylifecycle.h" // _PyErr_WriteUnraisableDefaultHook()
|
||||||
#include "pycore_pymath.h" // _PY_SHORT_FLOAT_REPR
|
#include "pycore_pymath.h" // _PY_SHORT_FLOAT_REPR
|
||||||
#include "pycore_pymem.h" // _PyMem_SetDefaultAllocator()
|
#include "pycore_pymem.h" // _PyMem_SetDefaultAllocator()
|
||||||
|
@ -89,12 +89,11 @@ PySys_GetObject(const char *name)
|
||||||
{
|
{
|
||||||
PyThreadState *tstate = _PyThreadState_GET();
|
PyThreadState *tstate = _PyThreadState_GET();
|
||||||
|
|
||||||
PyObject *exc_type, *exc_value, *exc_tb;
|
PyObject *exc = _PyErr_GetRaisedException(tstate);
|
||||||
_PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
|
|
||||||
PyObject *value = _PySys_GetObject(tstate->interp, name);
|
PyObject *value = _PySys_GetObject(tstate->interp, name);
|
||||||
/* XXX Suppress a new exception if it was raised and restore
|
/* XXX Suppress a new exception if it was raised and restore
|
||||||
* the old one. */
|
* the old one. */
|
||||||
_PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
|
_PyErr_SetRaisedException(tstate, exc);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,8 +202,8 @@ sys_audit_tstate(PyThreadState *ts, const char *event,
|
||||||
|
|
||||||
int dtrace = PyDTrace_AUDIT_ENABLED();
|
int dtrace = PyDTrace_AUDIT_ENABLED();
|
||||||
|
|
||||||
PyObject *exc_type, *exc_value, *exc_tb;
|
|
||||||
_PyErr_Fetch(ts, &exc_type, &exc_value, &exc_tb);
|
PyObject *exc = _PyErr_GetRaisedException(ts);
|
||||||
|
|
||||||
/* Initialize event args now */
|
/* Initialize event args now */
|
||||||
if (argFormat && argFormat[0]) {
|
if (argFormat && argFormat[0]) {
|
||||||
|
@ -287,13 +286,11 @@ exit:
|
||||||
Py_XDECREF(eventArgs);
|
Py_XDECREF(eventArgs);
|
||||||
|
|
||||||
if (!res) {
|
if (!res) {
|
||||||
_PyErr_Restore(ts, exc_type, exc_value, exc_tb);
|
_PyErr_SetRaisedException(ts, exc);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert(_PyErr_Occurred(ts));
|
assert(_PyErr_Occurred(ts));
|
||||||
Py_XDECREF(exc_type);
|
Py_XDECREF(exc);
|
||||||
Py_XDECREF(exc_value);
|
|
||||||
Py_XDECREF(exc_tb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
@ -3661,12 +3658,11 @@ static void
|
||||||
sys_write(PyObject *key, FILE *fp, const char *format, va_list va)
|
sys_write(PyObject *key, FILE *fp, const char *format, va_list va)
|
||||||
{
|
{
|
||||||
PyObject *file;
|
PyObject *file;
|
||||||
PyObject *error_type, *error_value, *error_traceback;
|
|
||||||
char buffer[1001];
|
char buffer[1001];
|
||||||
int written;
|
int written;
|
||||||
PyThreadState *tstate = _PyThreadState_GET();
|
PyThreadState *tstate = _PyThreadState_GET();
|
||||||
|
|
||||||
_PyErr_Fetch(tstate, &error_type, &error_value, &error_traceback);
|
PyObject *exc = _PyErr_GetRaisedException(tstate);
|
||||||
file = _PySys_GetAttr(tstate, key);
|
file = _PySys_GetAttr(tstate, key);
|
||||||
written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va);
|
written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va);
|
||||||
if (sys_pyfile_write(buffer, file) != 0) {
|
if (sys_pyfile_write(buffer, file) != 0) {
|
||||||
|
@ -3678,7 +3674,7 @@ sys_write(PyObject *key, FILE *fp, const char *format, va_list va)
|
||||||
if (sys_pyfile_write(truncated, file) != 0)
|
if (sys_pyfile_write(truncated, file) != 0)
|
||||||
fputs(truncated, fp);
|
fputs(truncated, fp);
|
||||||
}
|
}
|
||||||
_PyErr_Restore(tstate, error_type, error_value, error_traceback);
|
_PyErr_SetRaisedException(tstate, exc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -3708,7 +3704,7 @@ sys_format(PyObject *key, FILE *fp, const char *format, va_list va)
|
||||||
const char *utf8;
|
const char *utf8;
|
||||||
PyThreadState *tstate = _PyThreadState_GET();
|
PyThreadState *tstate = _PyThreadState_GET();
|
||||||
|
|
||||||
PyObject *error = _PyErr_GetRaisedException(tstate);
|
PyObject *exc = _PyErr_GetRaisedException(tstate);
|
||||||
file = _PySys_GetAttr(tstate, key);
|
file = _PySys_GetAttr(tstate, key);
|
||||||
message = PyUnicode_FromFormatV(format, va);
|
message = PyUnicode_FromFormatV(format, va);
|
||||||
if (message != NULL) {
|
if (message != NULL) {
|
||||||
|
@ -3720,7 +3716,7 @@ sys_format(PyObject *key, FILE *fp, const char *format, va_list va)
|
||||||
}
|
}
|
||||||
Py_DECREF(message);
|
Py_DECREF(message);
|
||||||
}
|
}
|
||||||
_PyErr_SetRaisedException(tstate, error);
|
_PyErr_SetRaisedException(tstate, exc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Reference in New Issue