From 438a12dd9d85f463c0bb7bf1505cd87b98b98170 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 24 May 2019 17:01:38 +0200 Subject: bpo-36710: Add tstate parameter in ceval.c (GH-13547) * Fix a possible reference leak in _PyErr_Print() if exception is NULL. * PyErr_BadInternalCall(): replace PyErr_Format() with _PyErr_SetString(). * Add pycore_pyerrors.h header file. * New functions: * _PyErr_Clear() * _PyErr_Fetch() * _PyErr_Print() * _PyErr_Restore() * _PyErr_SetObject() * _PyErr_SetString() * Add 'tstate' parameter to _PyEval_AddPendingCall(). --- Include/internal/pycore_ceval.h | 1 + Include/internal/pycore_pyerrors.h | 62 +++ Include/internal/pycore_pylifecycle.h | 2 + Include/internal/pycore_pymem.h | 6 +- Makefile.pre.in | 1 + Modules/signalmodule.c | 5 +- PCbuild/pythoncore.vcxproj | 1 + PCbuild/pythoncore.vcxproj.filters | 3 + Python/ceval.c | 732 ++++++++++++++++++---------------- Python/errors.c | 92 +++-- Python/pythonrun.c | 61 ++- 11 files changed, 563 insertions(+), 403 deletions(-) create mode 100644 Include/internal/pycore_pyerrors.h diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 7a3166e..37170ed 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -19,6 +19,7 @@ PyAPI_FUNC(void) _PyEval_FiniThreads( PyAPI_FUNC(void) _PyEval_SignalReceived( struct _ceval_runtime_state *ceval); PyAPI_FUNC(int) _PyEval_AddPendingCall( + PyThreadState *tstate, struct _ceval_runtime_state *ceval, int (*func)(void *), void *arg); diff --git a/Include/internal/pycore_pyerrors.h b/Include/internal/pycore_pyerrors.h new file mode 100644 index 0000000..23327ef --- /dev/null +++ b/Include/internal/pycore_pyerrors.h @@ -0,0 +1,62 @@ +#ifndef Py_INTERNAL_PYERRORS_H +#define Py_INTERNAL_PYERRORS_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +static inline PyObject* _PyErr_Occurred(PyThreadState *tstate) +{ + return tstate == NULL ? NULL : tstate->curexc_type; +} + + +PyAPI_FUNC(void) _PyErr_Fetch( + PyThreadState *tstate, + PyObject **type, + PyObject **value, + PyObject **traceback); + +PyAPI_FUNC(int) _PyErr_ExceptionMatches( + PyThreadState *tstate, + PyObject *exc); + +PyAPI_FUNC(void) _PyErr_Restore( + PyThreadState *tstate, + PyObject *type, + PyObject *value, + PyObject *traceback); + +PyAPI_FUNC(void) _PyErr_SetObject( + PyThreadState *tstate, + PyObject *type, + PyObject *value); + +PyAPI_FUNC(void) _PyErr_Clear(PyThreadState *tstate); + +PyAPI_FUNC(void) _PyErr_SetNone(PyThreadState *tstate, PyObject *exception); + +PyAPI_FUNC(void) _PyErr_SetString( + PyThreadState *tstate, + PyObject *exception, + const char *string); + +PyAPI_FUNC(PyObject *) _PyErr_Format( + PyThreadState *tstate, + PyObject *exception, + const char *format, + ...); + +PyAPI_FUNC(void) _PyErr_NormalizeException( + PyThreadState *tstate, + PyObject **exc, + PyObject **val, + PyObject **tb); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_PYERRORS_H */ diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index 07cf815..13a31c2 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -106,6 +106,8 @@ PyAPI_FUNC(int) _Py_HandleSystemExit(int *exitcode_p); PyAPI_FUNC(PyObject*) _PyErr_WriteUnraisableDefaultHook(PyObject *unraisable); +PyAPI_FUNC(void) _PyErr_Print(PyThreadState *tstate); + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_pymem.h b/Include/internal/pycore_pymem.h index dcc492a..22677d3 100644 --- a/Include/internal/pycore_pymem.h +++ b/Include/internal/pycore_pymem.h @@ -1,5 +1,5 @@ -#ifndef Py_INTERNAL_MEM_H -#define Py_INTERNAL_MEM_H +#ifndef Py_INTERNAL_PYMEM_H +#define Py_INTERNAL_PYMEM_H #ifdef __cplusplus extern "C" { #endif @@ -191,4 +191,4 @@ PyAPI_FUNC(int) _PyMem_SetupAllocators(PyMemAllocatorName allocator); #ifdef __cplusplus } #endif -#endif /* !Py_INTERNAL_MEM_H */ +#endif /* !Py_INTERNAL_PYMEM_H */ diff --git a/Makefile.pre.in b/Makefile.pre.in index 12891e9..a149fde 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1077,6 +1077,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/internal/pycore_hamt.h \ $(srcdir)/Include/internal/pycore_object.h \ $(srcdir)/Include/internal/pycore_pathconfig.h \ + $(srcdir)/Include/internal/pycore_pyerrors.h \ $(srcdir)/Include/internal/pycore_pyhash.h \ $(srcdir)/Include/internal/pycore_pylifecycle.h \ $(srcdir)/Include/internal/pycore_pymem.h \ diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index ed3852d..7698984 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -258,6 +258,7 @@ trip_signal(int sig_num) /* Notify ceval.c */ _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); _PyEval_SignalReceived(&runtime->ceval); /* And then write to the wakeup fd *after* setting all the globals and @@ -298,7 +299,7 @@ trip_signal(int sig_num) { /* Py_AddPendingCall() isn't signal-safe, but we still use it for this exceptional case. */ - _PyEval_AddPendingCall(&runtime->ceval, + _PyEval_AddPendingCall(tstate, &runtime->ceval, report_wakeup_send_error, (void *)(intptr_t) last_error); } @@ -317,7 +318,7 @@ trip_signal(int sig_num) { /* Py_AddPendingCall() isn't signal-safe, but we still use it for this exceptional case. */ - _PyEval_AddPendingCall(&runtime->ceval, + _PyEval_AddPendingCall(tstate, &runtime->ceval, report_wakeup_write_error, (void *)(intptr_t)errno); } diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 681c4db..10f51dd 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -168,6 +168,7 @@ + diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index 32964c0..396d146 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -207,6 +207,9 @@ Include + + Include + Include diff --git a/Python/ceval.c b/Python/ceval.c index 781b10d..cb5a4be 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -12,6 +12,8 @@ #include "Python.h" #include "pycore_ceval.h" #include "pycore_object.h" +#include "pycore_pyerrors.h" +#include "pycore_pylifecycle.h" #include "pycore_pystate.h" #include "pycore_tupleobject.h" @@ -50,7 +52,7 @@ static PyObject * do_call_core( #ifdef LLTRACE static int lltrace; -static int prtrace(PyObject *, const char *); +static int prtrace(PyThreadState *, PyObject *, const char *); #endif static int call_trace(Py_tracefunc, PyObject *, PyThreadState *, PyFrameObject *, @@ -67,19 +69,19 @@ static void maybe_dtrace_line(PyFrameObject *, int *, int *, int *); static void dtrace_function_entry(PyFrameObject *); static void dtrace_function_return(PyFrameObject *); -static PyObject * cmp_outcome(int, PyObject *, PyObject *); -static PyObject * import_name(PyFrameObject *, PyObject *, PyObject *, - PyObject *); -static PyObject * import_from(PyObject *, PyObject *); -static int import_all_from(PyObject *, PyObject *); -static void format_exc_check_arg(PyObject *, const char *, PyObject *); -static void format_exc_unbound(PyCodeObject *co, int oparg); -static PyObject * unicode_concatenate(PyObject *, PyObject *, +static PyObject * cmp_outcome(PyThreadState *, int, PyObject *, PyObject *); +static PyObject * import_name(PyThreadState *, PyFrameObject *, + PyObject *, PyObject *, PyObject *); +static PyObject * import_from(PyThreadState *, PyObject *, PyObject *); +static int import_all_from(PyThreadState *, PyObject *, PyObject *); +static void format_exc_check_arg(PyThreadState *, PyObject *, const char *, PyObject *); +static void format_exc_unbound(PyThreadState *tstate, PyCodeObject *co, int oparg); +static PyObject * unicode_concatenate(PyThreadState *, PyObject *, PyObject *, PyFrameObject *, const _Py_CODEUNIT *); -static PyObject * special_lookup(PyObject *, _Py_Identifier *); -static int check_args_iterable(PyObject *func, PyObject *vararg); -static void format_kwargs_error(PyObject *func, PyObject *kwargs); -static void format_awaitable_error(PyTypeObject *, int); +static PyObject * special_lookup(PyThreadState *, PyObject *, _Py_Identifier *); +static int check_args_iterable(PyThreadState *, PyObject *func, PyObject *vararg); +static void format_kwargs_error(PyThreadState *, PyObject *func, PyObject *kwargs); +static void format_awaitable_error(PyThreadState *, PyTypeObject *, int); #define NAME_ERROR_MSG \ "name '%.200s' is not defined" @@ -420,7 +422,8 @@ _pop_pending_call(struct _pending_calls *pending, */ int -_PyEval_AddPendingCall(struct _ceval_runtime_state *ceval, +_PyEval_AddPendingCall(PyThreadState *tstate, + struct _ceval_runtime_state *ceval, int (*func)(void *), void *arg) { struct _pending_calls *pending = &ceval->pending; @@ -430,12 +433,12 @@ _PyEval_AddPendingCall(struct _ceval_runtime_state *ceval, PyThread_release_lock(pending->lock); PyObject *exc, *val, *tb; - PyErr_Fetch(&exc, &val, &tb); - PyErr_SetString(PyExc_SystemError, + _PyErr_Fetch(tstate, &exc, &val, &tb); + _PyErr_SetString(tstate, PyExc_SystemError, "Py_AddPendingCall: cannot add pending calls " "(Python shutting down)"); - PyErr_Print(); - PyErr_Restore(exc, val, tb); + _PyErr_Print(tstate); + _PyErr_Restore(tstate, exc, val, tb); return -1; } int result = _push_pending_call(pending, func, arg); @@ -449,7 +452,9 @@ _PyEval_AddPendingCall(struct _ceval_runtime_state *ceval, int Py_AddPendingCall(int (*func)(void *), void *arg) { - return _PyEval_AddPendingCall(&_PyRuntime.ceval, func, arg); + _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + return _PyEval_AddPendingCall(tstate, &runtime->ceval, func, arg); } static int @@ -535,6 +540,7 @@ _Py_FinishPendingCalls(_PyRuntimeState *runtime) { assert(PyGILState_Check()); + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); struct _pending_calls *pending = &runtime->ceval.pending; PyThread_acquire_lock(pending->lock, WAIT_LOCK); @@ -547,10 +553,10 @@ _Py_FinishPendingCalls(_PyRuntimeState *runtime) if (make_pending_calls(runtime) < 0) { PyObject *exc, *val, *tb; - PyErr_Fetch(&exc, &val, &tb); + _PyErr_Fetch(tstate, &exc, &val, &tb); PyErr_BadInternalCall(); _PyErr_ChainExceptions(exc, val, tb); - PyErr_Print(); + _PyErr_Print(tstate); } } @@ -623,7 +629,7 @@ _Py_CheckRecursiveCall(const char *where) tstate->stackcheck_counter = 0; if (PyOS_CheckStack()) { --tstate->recursion_depth; - PyErr_SetString(PyExc_MemoryError, "Stack overflow"); + _PyErr_SetString(tstate, PyExc_MemoryError, "Stack overflow"); return -1; } /* Needed for ABI backwards-compatibility (see bpo-31857) */ @@ -642,16 +648,16 @@ _Py_CheckRecursiveCall(const char *where) if (tstate->recursion_depth > recursion_limit) { --tstate->recursion_depth; tstate->overflowed = 1; - PyErr_Format(PyExc_RecursionError, - "maximum recursion depth exceeded%s", - where); + _PyErr_Format(tstate, PyExc_RecursionError, + "maximum recursion depth exceeded%s", + where); return -1; } return 0; } static int do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause); -static int unpack_iterable(PyObject *, int, int, PyObject **); +static int unpack_iterable(PyThreadState *, PyObject *, int, int, PyObject **); #define _Py_TracingPossible(ceval) ((ceval)->tracing_possible) @@ -908,24 +914,24 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) #ifdef LLTRACE #define PUSH(v) { (void)(BASIC_PUSH(v), \ - lltrace && prtrace(TOP(), "push")); \ + lltrace && prtrace(tstate, TOP(), "push")); \ assert(STACK_LEVEL() <= co->co_stacksize); } -#define POP() ((void)(lltrace && prtrace(TOP(), "pop")), \ +#define POP() ((void)(lltrace && prtrace(tstate, TOP(), "pop")), \ BASIC_POP()) #define STACK_GROW(n) do { \ assert(n >= 0); \ (void)(BASIC_STACKADJ(n), \ - lltrace && prtrace(TOP(), "stackadj")); \ + lltrace && prtrace(tstate, TOP(), "stackadj")); \ assert(STACK_LEVEL() <= co->co_stacksize); \ } while (0) #define STACK_SHRINK(n) do { \ assert(n >= 0); \ - (void)(lltrace && prtrace(TOP(), "stackadj")); \ + (void)(lltrace && prtrace(tstate, TOP(), "stackadj")); \ (void)(BASIC_STACKADJ(-n)); \ assert(STACK_LEVEL() <= co->co_stacksize); \ } while (0) #define EXT_POP(STACK_POINTER) ((void)(lltrace && \ - prtrace((STACK_POINTER)[-1], "ext_pop")), \ + prtrace(tstate, (STACK_POINTER)[-1], "ext_pop")), \ *--(STACK_POINTER)) #else #define PUSH(v) BASIC_PUSH(v) @@ -1070,14 +1076,14 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) /* PyEval_EvalFrameEx() must not be called with an exception set, because it can clear it (directly or indirectly) and so the caller loses its exception */ - assert(!PyErr_Occurred()); + assert(!_PyErr_Occurred(tstate)); #endif main_loop: for (;;) { assert(stack_pointer >= f->f_valuestack); /* else underflow */ assert(STACK_LEVEL() <= co->co_stacksize); /* else overflow */ - assert(!PyErr_Occurred()); + assert(!_PyErr_Occurred(tstate)); /* Do periodic things. Doing this every time through the loop would add too much overhead, so we do it @@ -1146,7 +1152,7 @@ main_loop: PyObject *exc = tstate->async_exc; tstate->async_exc = NULL; UNSIGNAL_ASYNC_EXC(ceval); - PyErr_SetNone(exc); + _PyErr_SetNone(tstate, exc); Py_DECREF(exc); goto error; } @@ -1222,7 +1228,7 @@ main_loop: case TARGET(LOAD_FAST): { PyObject *value = GETLOCAL(oparg); if (value == NULL) { - format_exc_check_arg(PyExc_UnboundLocalError, + format_exc_check_arg(tstate, PyExc_UnboundLocalError, UNBOUNDLOCAL_ERROR_MSG, PyTuple_GetItem(co->co_varnames, oparg)); goto error; @@ -1441,7 +1447,7 @@ main_loop: speedup on microbenchmarks. */ if (PyUnicode_CheckExact(left) && PyUnicode_CheckExact(right)) { - sum = unicode_concatenate(left, right, f, next_instr); + sum = unicode_concatenate(tstate, left, right, f, next_instr); /* unicode_concatenate consumed the ref to left */ } else { @@ -1640,7 +1646,7 @@ main_loop: PyObject *left = TOP(); PyObject *sum; if (PyUnicode_CheckExact(left) && PyUnicode_CheckExact(right)) { - sum = unicode_concatenate(left, right, f, next_instr); + sum = unicode_concatenate(tstate, left, right, f, next_instr); /* unicode_concatenate consumed the ref to left */ } else { @@ -1762,8 +1768,8 @@ main_loop: PyObject *hook = _PySys_GetObjectId(&PyId_displayhook); PyObject *res; if (hook == NULL) { - PyErr_SetString(PyExc_RuntimeError, - "lost sys.displayhook"); + _PyErr_SetString(tstate, PyExc_RuntimeError, + "lost sys.displayhook"); Py_DECREF(value); goto error; } @@ -1790,8 +1796,8 @@ main_loop: } break; default: - PyErr_SetString(PyExc_SystemError, - "bad RAISE_VARARGS oparg"); + _PyErr_SetString(tstate, PyExc_SystemError, + "bad RAISE_VARARGS oparg"); break; } goto error; @@ -1823,11 +1829,10 @@ main_loop: } else { SET_TOP(NULL); - PyErr_Format( - PyExc_TypeError, - "'async for' requires an object with " - "__aiter__ method, got %.100s", - type->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "'async for' requires an object with " + "__aiter__ method, got %.100s", + type->tp_name); Py_DECREF(obj); goto error; } @@ -1836,11 +1841,10 @@ main_loop: Py_TYPE(iter)->tp_as_async->am_anext == NULL) { SET_TOP(NULL); - PyErr_Format( - PyExc_TypeError, - "'async for' received an object from __aiter__ " - "that does not implement __anext__: %.100s", - Py_TYPE(iter)->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "'async for' received an object from __aiter__ " + "that does not implement __anext__: %.100s", + Py_TYPE(iter)->tp_name); Py_DECREF(iter); goto error; } @@ -1873,11 +1877,10 @@ main_loop: } } else { - PyErr_Format( - PyExc_TypeError, - "'async for' requires an iterator with " - "__anext__ method, got %.100s", - type->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "'async for' requires an iterator with " + "__anext__ method, got %.100s", + type->tp_name); goto error; } @@ -1907,7 +1910,7 @@ main_loop: PyObject *iter = _PyCoro_GetAwaitableIter(iterable); if (iter == NULL) { - format_awaitable_error(Py_TYPE(iterable), + format_awaitable_error(tstate, Py_TYPE(iterable), _Py_OPCODE(next_instr[-2])); } @@ -1921,9 +1924,8 @@ main_loop: being awaited on. */ Py_DECREF(yf); Py_CLEAR(iter); - PyErr_SetString( - PyExc_RuntimeError, - "coroutine is being awaited already"); + _PyErr_SetString(tstate, PyExc_RuntimeError, + "coroutine is being awaited already"); /* The code below jumps to `error` if `iter` is NULL. */ } } @@ -1955,7 +1957,7 @@ main_loop: if (retval == NULL) { PyObject *val; if (tstate->c_tracefunc != NULL - && PyErr_ExceptionMatches(PyExc_StopIteration)) + && _PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, f); err = _PyGen_FetchStopIterationValue(&val); if (err < 0) @@ -1994,8 +1996,8 @@ main_loop: _PyErr_StackItem *exc_info; PyTryBlock *b = PyFrame_BlockPop(f); if (b->b_type != EXCEPT_HANDLER) { - PyErr_SetString(PyExc_SystemError, - "popped block is not an except handler"); + _PyErr_SetString(tstate, PyExc_SystemError, + "popped block is not an except handler"); goto error; } assert(STACK_LEVEL() >= (b)->b_level + 3 && @@ -2047,8 +2049,8 @@ main_loop: _PyErr_StackItem *exc_info; PyTryBlock *b = PyFrame_BlockPop(f); if (b->b_type != EXCEPT_HANDLER) { - PyErr_SetString(PyExc_SystemError, - "popped block is not an except handler"); + _PyErr_SetString(tstate, PyExc_SystemError, + "popped block is not an except handler"); Py_XDECREF(res); goto error; } @@ -2104,7 +2106,7 @@ main_loop: else if (PyLong_CheckExact(exc)) { int ret = _PyLong_AsInt(exc); Py_DECREF(exc); - if (ret == -1 && PyErr_Occurred()) { + if (ret == -1 && _PyErr_Occurred(tstate)) { goto error; } JUMPTO(ret); @@ -2114,7 +2116,7 @@ main_loop: assert(PyExceptionClass_Check(exc)); PyObject *val = POP(); PyObject *tb = POP(); - PyErr_Restore(exc, val, tb); + _PyErr_Restore(tstate, exc, val, tb); goto exception_unwind; } } @@ -2134,7 +2136,7 @@ main_loop: else { PyObject *val = POP(); PyObject *tb = POP(); - PyErr_Restore(exc, val, tb); + _PyErr_Restore(tstate, exc, val, tb); goto exception_unwind; } } @@ -2146,9 +2148,9 @@ main_loop: if (PyDict_CheckExact(f->f_builtins)) { bc = _PyDict_GetItemIdWithError(f->f_builtins, &PyId___build_class__); if (bc == NULL) { - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_NameError, - "__build_class__ not found"); + if (!_PyErr_Occurred(tstate)) { + _PyErr_SetString(tstate, PyExc_NameError, + "__build_class__ not found"); } goto error; } @@ -2160,9 +2162,9 @@ main_loop: goto error; bc = PyObject_GetItem(f->f_builtins, build_class_str); if (bc == NULL) { - if (PyErr_ExceptionMatches(PyExc_KeyError)) - PyErr_SetString(PyExc_NameError, - "__build_class__ not found"); + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) + _PyErr_SetString(tstate, PyExc_NameError, + "__build_class__ not found"); goto error; } } @@ -2176,8 +2178,8 @@ main_loop: PyObject *ns = f->f_locals; int err; if (ns == NULL) { - PyErr_Format(PyExc_SystemError, - "no locals found when storing %R", name); + _PyErr_Format(tstate, PyExc_SystemError, + "no locals found when storing %R", name); Py_DECREF(v); goto error; } @@ -2196,13 +2198,13 @@ main_loop: PyObject *ns = f->f_locals; int err; if (ns == NULL) { - PyErr_Format(PyExc_SystemError, - "no locals when deleting %R", name); + _PyErr_Format(tstate, PyExc_SystemError, + "no locals when deleting %R", name); goto error; } err = PyObject_DelItem(ns, name); if (err != 0) { - format_exc_check_arg(PyExc_NameError, + format_exc_check_arg(tstate, PyExc_NameError, NAME_ERROR_MSG, name); goto error; @@ -2229,7 +2231,7 @@ main_loop: Py_INCREF(item); PUSH(item); } - } else if (unpack_iterable(seq, oparg, -1, + } else if (unpack_iterable(tstate, seq, oparg, -1, stack_pointer + oparg)) { STACK_GROW(oparg); } else { @@ -2245,7 +2247,7 @@ main_loop: int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8); PyObject *seq = POP(); - if (unpack_iterable(seq, oparg & 0xFF, oparg >> 8, + if (unpack_iterable(tstate, seq, oparg & 0xFF, oparg >> 8, stack_pointer + totalargs)) { stack_pointer += totalargs; } else { @@ -2297,9 +2299,9 @@ main_loop: int err; err = PyDict_DelItem(f->f_globals, name); if (err != 0) { - if (PyErr_ExceptionMatches(PyExc_KeyError)) { - format_exc_check_arg( - PyExc_NameError, NAME_ERROR_MSG, name); + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + format_exc_check_arg(tstate, PyExc_NameError, + NAME_ERROR_MSG, name); } goto error; } @@ -2311,8 +2313,8 @@ main_loop: PyObject *locals = f->f_locals; PyObject *v; if (locals == NULL) { - PyErr_Format(PyExc_SystemError, - "no locals when loading %R", name); + _PyErr_Format(tstate, PyExc_SystemError, + "no locals when loading %R", name); goto error; } if (PyDict_CheckExact(locals)) { @@ -2320,16 +2322,16 @@ main_loop: if (v != NULL) { Py_INCREF(v); } - else if (PyErr_Occurred()) { + else if (_PyErr_Occurred(tstate)) { goto error; } } else { v = PyObject_GetItem(locals, name); if (v == NULL) { - if (!PyErr_ExceptionMatches(PyExc_KeyError)) + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) goto error; - PyErr_Clear(); + _PyErr_Clear(tstate); } } if (v == NULL) { @@ -2337,16 +2339,16 @@ main_loop: if (v != NULL) { Py_INCREF(v); } - else if (PyErr_Occurred()) { + else if (_PyErr_Occurred(tstate)) { goto error; } else { if (PyDict_CheckExact(f->f_builtins)) { v = PyDict_GetItemWithError(f->f_builtins, name); if (v == NULL) { - if (!PyErr_Occurred()) { + if (!_PyErr_Occurred(tstate)) { format_exc_check_arg( - PyExc_NameError, + tstate, PyExc_NameError, NAME_ERROR_MSG, name); } goto error; @@ -2356,10 +2358,11 @@ main_loop: else { v = PyObject_GetItem(f->f_builtins, name); if (v == NULL) { - if (PyErr_ExceptionMatches(PyExc_KeyError)) + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { format_exc_check_arg( - PyExc_NameError, + tstate, PyExc_NameError, NAME_ERROR_MSG, name); + } goto error; } } @@ -2382,7 +2385,7 @@ main_loop: if (!_PyErr_OCCURRED()) { /* _PyDict_LoadGlobal() returns NULL without raising * an exception if the key doesn't exist */ - format_exc_check_arg(PyExc_NameError, + format_exc_check_arg(tstate, PyExc_NameError, NAME_ERROR_MSG, name); } goto error; @@ -2395,17 +2398,19 @@ main_loop: /* namespace 1: globals */ v = PyObject_GetItem(f->f_globals, name); if (v == NULL) { - if (!PyErr_ExceptionMatches(PyExc_KeyError)) + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { goto error; - PyErr_Clear(); + } + _PyErr_Clear(tstate); /* namespace 2: builtins */ v = PyObject_GetItem(f->f_builtins, name); if (v == NULL) { - if (PyErr_ExceptionMatches(PyExc_KeyError)) + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { format_exc_check_arg( - PyExc_NameError, + tstate, PyExc_NameError, NAME_ERROR_MSG, name); + } goto error; } } @@ -2421,7 +2426,7 @@ main_loop: DISPATCH(); } format_exc_check_arg( - PyExc_UnboundLocalError, + tstate, PyExc_UnboundLocalError, UNBOUNDLOCAL_ERROR_MSG, PyTuple_GetItem(co->co_varnames, oparg) ); @@ -2436,7 +2441,7 @@ main_loop: Py_DECREF(oldobj); DISPATCH(); } - format_exc_unbound(co, oparg); + format_exc_unbound(tstate, co, oparg); goto error; } @@ -2460,23 +2465,24 @@ main_loop: if (value != NULL) { Py_INCREF(value); } - else if (PyErr_Occurred()) { + else if (_PyErr_Occurred(tstate)) { goto error; } } else { value = PyObject_GetItem(locals, name); if (value == NULL) { - if (!PyErr_ExceptionMatches(PyExc_KeyError)) + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { goto error; - PyErr_Clear(); + } + _PyErr_Clear(tstate); } } if (!value) { PyObject *cell = freevars[oparg]; value = PyCell_GET(cell); if (value == NULL) { - format_exc_unbound(co, oparg); + format_exc_unbound(tstate, co, oparg); goto error; } Py_INCREF(value); @@ -2489,7 +2495,7 @@ main_loop: PyObject *cell = freevars[oparg]; PyObject *value = PyCell_GET(cell); if (value == NULL) { - format_exc_unbound(co, oparg); + format_exc_unbound(tstate, co, oparg); goto error; } Py_INCREF(value); @@ -2565,9 +2571,9 @@ main_loop: none_val = _PyList_Extend((PyListObject *)sum, PEEK(i)); if (none_val == NULL) { if (opcode == BUILD_TUPLE_UNPACK_WITH_CALL && - PyErr_ExceptionMatches(PyExc_TypeError)) + _PyErr_ExceptionMatches(tstate, PyExc_TypeError)) { - check_args_iterable(PEEK(1 + oparg), PEEK(i)); + check_args_iterable(tstate, PEEK(1 + oparg), PEEK(i)); } Py_DECREF(sum); goto error; @@ -2660,8 +2666,8 @@ main_loop: int err; PyObject *ann_dict; if (f->f_locals == NULL) { - PyErr_Format(PyExc_SystemError, - "no locals found when setting up annotations"); + _PyErr_Format(tstate, PyExc_SystemError, + "no locals found when setting up annotations"); goto error; } /* check if __annotations__ in locals()... */ @@ -2669,7 +2675,7 @@ main_loop: ann_dict = _PyDict_GetItemIdWithError(f->f_locals, &PyId___annotations__); if (ann_dict == NULL) { - if (PyErr_Occurred()) { + if (_PyErr_Occurred(tstate)) { goto error; } /* ...if not, create a new one */ @@ -2693,10 +2699,10 @@ main_loop: } ann_dict = PyObject_GetItem(f->f_locals, ann_str); if (ann_dict == NULL) { - if (!PyErr_ExceptionMatches(PyExc_KeyError)) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { goto error; } - PyErr_Clear(); + _PyErr_Clear(tstate); ann_dict = PyDict_New(); if (ann_dict == NULL) { goto error; @@ -2720,8 +2726,8 @@ main_loop: PyObject *keys = TOP(); if (!PyTuple_CheckExact(keys) || PyTuple_GET_SIZE(keys) != (Py_ssize_t)oparg) { - PyErr_SetString(PyExc_SystemError, - "bad BUILD_CONST_KEY_MAP keys argument"); + _PyErr_SetString(tstate, PyExc_SystemError, + "bad BUILD_CONST_KEY_MAP keys argument"); goto error; } map = _PyDict_NewPresized((Py_ssize_t)oparg); @@ -2756,10 +2762,10 @@ main_loop: for (i = oparg; i > 0; i--) { PyObject *arg = PEEK(i); if (PyDict_Update(sum, arg) < 0) { - if (PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Format(PyExc_TypeError, - "'%.200s' object is not a mapping", - arg->ob_type->tp_name); + if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object is not a mapping", + arg->ob_type->tp_name); } Py_DECREF(sum); goto error; @@ -2782,7 +2788,7 @@ main_loop: PyObject *arg = PEEK(i); if (_PyDict_MergeEx(sum, arg, 2) < 0) { Py_DECREF(sum); - format_kwargs_error(PEEK(2 + oparg), arg); + format_kwargs_error(tstate, PEEK(2 + oparg), arg); goto error; } } @@ -2824,7 +2830,7 @@ main_loop: case TARGET(COMPARE_OP): { PyObject *right = POP(); PyObject *left = TOP(); - PyObject *res = cmp_outcome(oparg, left, right); + PyObject *res = cmp_outcome(tstate, oparg, left, right); Py_DECREF(left); Py_DECREF(right); SET_TOP(res); @@ -2840,7 +2846,7 @@ main_loop: PyObject *fromlist = POP(); PyObject *level = TOP(); PyObject *res; - res = import_name(f, name, fromlist, level); + res = import_name(tstate, f, name, fromlist, level); Py_DECREF(level); Py_DECREF(fromlist); SET_TOP(res); @@ -2859,12 +2865,12 @@ main_loop: locals = f->f_locals; if (locals == NULL) { - PyErr_SetString(PyExc_SystemError, - "no locals found during 'import *'"); + _PyErr_SetString(tstate, PyExc_SystemError, + "no locals found during 'import *'"); Py_DECREF(from); goto error; } - err = import_all_from(locals, from); + err = import_all_from(tstate, locals, from); PyFrame_LocalsToFast(f, 0); Py_DECREF(from); if (err != 0) @@ -2876,7 +2882,7 @@ main_loop: PyObject *name = GETITEM(names, oparg); PyObject *from = TOP(); PyObject *res; - res = import_from(from, name); + res = import_from(tstate, from, name); PUSH(res); if (res == NULL) goto error; @@ -3027,9 +3033,9 @@ main_loop: regular generator. */ Py_DECREF(iterable); SET_TOP(NULL); - PyErr_SetString(PyExc_TypeError, - "cannot 'yield from' a coroutine object " - "in a non-coroutine generator"); + _PyErr_SetString(tstate, PyExc_TypeError, + "cannot 'yield from' a coroutine object " + "in a non-coroutine generator"); goto error; } } @@ -3056,12 +3062,14 @@ main_loop: PREDICT(UNPACK_SEQUENCE); DISPATCH(); } - if (PyErr_Occurred()) { - if (!PyErr_ExceptionMatches(PyExc_StopIteration)) + if (_PyErr_Occurred(tstate)) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) { goto error; - else if (tstate->c_tracefunc != NULL) + } + else if (tstate->c_tracefunc != NULL) { call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, f); - PyErr_Clear(); + } + _PyErr_Clear(tstate); } /* iterator ended normally */ STACK_SHRINK(1); @@ -3087,13 +3095,13 @@ main_loop: _Py_IDENTIFIER(__aenter__); PyObject *mgr = TOP(); - PyObject *exit = special_lookup(mgr, &PyId___aexit__), + PyObject *exit = special_lookup(tstate, mgr, &PyId___aexit__), *enter; PyObject *res; if (exit == NULL) goto error; SET_TOP(exit); - enter = special_lookup(mgr, &PyId___aenter__); + enter = special_lookup(tstate, mgr, &PyId___aenter__); Py_DECREF(mgr); if (enter == NULL) goto error; @@ -3120,11 +3128,12 @@ main_loop: _Py_IDENTIFIER(__exit__); _Py_IDENTIFIER(__enter__); PyObject *mgr = TOP(); - PyObject *enter = special_lookup(mgr, &PyId___enter__), *exit; + PyObject *enter = special_lookup(tstate, mgr, &PyId___enter__); PyObject *res; - if (enter == NULL) + if (enter == NULL) { goto error; - exit = special_lookup(mgr, &PyId___exit__); + } + PyObject *exit = special_lookup(tstate, mgr, &PyId___exit__); if (exit == NULL) { Py_DECREF(enter); goto error; @@ -3380,7 +3389,7 @@ main_loop: goto error; if (_PyDict_MergeEx(d, kwargs, 2) < 0) { Py_DECREF(d); - format_kwargs_error(SECOND(), kwargs); + format_kwargs_error(tstate, SECOND(), kwargs); Py_DECREF(kwargs); goto error; } @@ -3392,7 +3401,7 @@ main_loop: callargs = POP(); func = TOP(); if (!PyTuple_CheckExact(callargs)) { - if (check_args_iterable(func, callargs) < 0) { + if (check_args_iterable(tstate, func, callargs) < 0) { Py_DECREF(callargs); goto error; } @@ -3485,9 +3494,9 @@ main_loop: case FVC_REPR: conv_fn = PyObject_Repr; break; case FVC_ASCII: conv_fn = PyObject_ASCII; break; default: - PyErr_Format(PyExc_SystemError, - "unexpected conversion flag %d", - which_conversion); + _PyErr_Format(tstate, PyExc_SystemError, + "unexpected conversion flag %d", + which_conversion); goto error; } @@ -3542,7 +3551,7 @@ main_loop: "XXX lineno: %d, opcode: %d\n", PyFrame_GetLineNumber(f), opcode); - PyErr_SetString(PyExc_SystemError, "unknown opcode"); + _PyErr_SetString(tstate, PyExc_SystemError, "unknown opcode"); goto error; } /* switch */ @@ -3554,11 +3563,12 @@ main_loop: error: /* Double-check exception status. */ #ifdef NDEBUG - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_SystemError, - "error return without exception set"); + if (!_PyErr_Occurred(tstate)) { + _PyErr_SetString(tstate, PyExc_SystemError, + "error return without exception set"); + } #else - assert(PyErr_Occurred()); + assert(_PyErr_Occurred(tstate)); #endif /* Log traceback info. */ @@ -3594,13 +3604,12 @@ exception_unwind: Py_INCREF(Py_None); PUSH(Py_None); } - PyErr_Fetch(&exc, &val, &tb); + _PyErr_Fetch(tstate, &exc, &val, &tb); /* Make the raw exception data available to the handler, so a program can emulate the Python main loop. */ - PyErr_NormalizeException( - &exc, &val, &tb); + _PyErr_NormalizeException(tstate, &exc, &val, &tb); if (tb != NULL) PyException_SetTraceback(val, tb); else @@ -3627,7 +3636,7 @@ exception_unwind: } /* main loop */ assert(retval == NULL); - assert(PyErr_Occurred()); + assert(_PyErr_Occurred(tstate)); exit_returning: @@ -3665,7 +3674,8 @@ exit_eval_frame: } static void -format_missing(const char *kind, PyCodeObject *co, PyObject *names) +format_missing(PyThreadState *tstate, const char *kind, + PyCodeObject *co, PyObject *names) { int err; Py_ssize_t len = PyList_GET_SIZE(names); @@ -3716,18 +3726,19 @@ format_missing(const char *kind, PyCodeObject *co, PyObject *names) } if (name_str == NULL) return; - PyErr_Format(PyExc_TypeError, - "%U() missing %i required %s argument%s: %U", - co->co_name, - len, - kind, - len == 1 ? "" : "s", - name_str); + _PyErr_Format(tstate, PyExc_TypeError, + "%U() missing %i required %s argument%s: %U", + co->co_name, + len, + kind, + len == 1 ? "" : "s", + name_str); Py_DECREF(name_str); } static void -missing_arguments(PyCodeObject *co, Py_ssize_t missing, Py_ssize_t defcount, +missing_arguments(PyThreadState *tstate, PyCodeObject *co, + Py_ssize_t missing, Py_ssize_t defcount, PyObject **fastlocals) { Py_ssize_t i, j = 0; @@ -3760,12 +3771,13 @@ missing_arguments(PyCodeObject *co, Py_ssize_t missing, Py_ssize_t defcount, } } assert(j == missing); - format_missing(kind, co, missing_names); + format_missing(tstate, kind, co, missing_names); Py_DECREF(missing_names); } static void -too_many_positional(PyCodeObject *co, Py_ssize_t given, Py_ssize_t defcount, +too_many_positional(PyThreadState *tstate, PyCodeObject *co, + Py_ssize_t given, Py_ssize_t defcount, PyObject **fastlocals) { int plural; @@ -3810,21 +3822,21 @@ too_many_positional(PyCodeObject *co, Py_ssize_t given, Py_ssize_t defcount, kwonly_sig = PyUnicode_FromString(""); assert(kwonly_sig != NULL); } - PyErr_Format(PyExc_TypeError, - "%U() takes %U positional argument%s but %zd%U %s given", - co->co_name, - sig, - plural ? "s" : "", - given, - kwonly_sig, - given == 1 && !kwonly_given ? "was" : "were"); + _PyErr_Format(tstate, PyExc_TypeError, + "%U() takes %U positional argument%s but %zd%U %s given", + co->co_name, + sig, + plural ? "s" : "", + given, + kwonly_sig, + given == 1 && !kwonly_given ? "was" : "were"); Py_DECREF(sig); Py_DECREF(kwonly_sig); } static int -positional_only_passed_as_keyword(PyCodeObject *co, Py_ssize_t kwcount, - PyObject* const* kwnames) +positional_only_passed_as_keyword(PyThreadState *tstate, PyCodeObject *co, + Py_ssize_t kwcount, PyObject* const* kwnames) { int posonly_conflicts = 0; PyObject* posonly_names = PyList_New(0); @@ -3866,10 +3878,10 @@ positional_only_passed_as_keyword(PyCodeObject *co, Py_ssize_t kwcount, if (error_names == NULL) { goto fail; } - PyErr_Format(PyExc_TypeError, - "%U() got some positional-only arguments passed" - " as keyword arguments: '%U'", - co->co_name, error_names); + _PyErr_Format(tstate, PyExc_TypeError, + "%U() got some positional-only arguments passed" + " as keyword arguments: '%U'", + co->co_name, error_names); Py_DECREF(error_names); goto fail; } @@ -3905,15 +3917,16 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, Py_ssize_t i, j, n; PyObject *kwdict; + PyThreadState *tstate = _PyThreadState_GET(); + assert(tstate != NULL); + if (globals == NULL) { - PyErr_SetString(PyExc_SystemError, - "PyEval_EvalCodeEx: NULL globals"); + _PyErr_SetString(tstate, PyExc_SystemError, + "PyEval_EvalCodeEx: NULL globals"); return NULL; } /* Create the frame */ - PyThreadState *tstate = _PyThreadState_GET(); - assert(tstate != NULL); f = _PyFrame_New_NoTrack(tstate, co, globals, locals); if (f == NULL) { return NULL; @@ -3981,9 +3994,9 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, Py_ssize_t j; if (keyword == NULL || !PyUnicode_Check(keyword)) { - PyErr_Format(PyExc_TypeError, - "%U() keywords must be strings", - co->co_name); + _PyErr_Format(tstate, PyExc_TypeError, + "%U() keywords must be strings", + co->co_name); goto fail; } @@ -4012,13 +4025,16 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, assert(j >= total_args); if (kwdict == NULL) { - if (co->co_posonlyargcount && positional_only_passed_as_keyword(co, kwcount, kwnames)) { + if (co->co_posonlyargcount + && positional_only_passed_as_keyword(tstate, co, + kwcount, kwnames)) + { goto fail; } - PyErr_Format(PyExc_TypeError, - "%U() got an unexpected keyword argument '%S'", - co->co_name, keyword); + _PyErr_Format(tstate, PyExc_TypeError, + "%U() got an unexpected keyword argument '%S'", + co->co_name, keyword); goto fail; } @@ -4029,9 +4045,9 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, kw_found: if (GETLOCAL(j) != NULL) { - PyErr_Format(PyExc_TypeError, - "%U() got multiple values for argument '%S'", - co->co_name, keyword); + _PyErr_Format(tstate, PyExc_TypeError, + "%U() got multiple values for argument '%S'", + co->co_name, keyword); goto fail; } Py_INCREF(value); @@ -4040,7 +4056,7 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, /* Check the number of positional arguments */ if ((argcount > co->co_argcount + co->co_posonlyargcount) && !(co->co_flags & CO_VARARGS)) { - too_many_positional(co, argcount, defcount, fastlocals); + too_many_positional(tstate, co, argcount, defcount, fastlocals); goto fail; } @@ -4054,7 +4070,7 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, } } if (missing) { - missing_arguments(co, missing, defcount, fastlocals); + missing_arguments(tstate, co, missing, defcount, fastlocals); goto fail; } if (n > m) @@ -4085,14 +4101,14 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, SETLOCAL(i, def); continue; } - else if (PyErr_Occurred()) { + else if (_PyErr_Occurred(tstate)) { goto fail; } } missing++; } if (missing) { - missing_arguments(co, missing, -1, fastlocals); + missing_arguments(tstate, co, missing, -1, fastlocals); goto fail; } } @@ -4132,11 +4148,11 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, if (is_coro && tstate->in_coroutine_wrapper) { assert(coro_wrapper != NULL); - PyErr_Format(PyExc_RuntimeError, - "coroutine wrapper %.200R attempted " - "to recursively wrap %.200R", - coro_wrapper, - co); + _PyErr_Format(tstate, PyExc_RuntimeError, + "coroutine wrapper %.200R attempted " + "to recursively wrap %.200R", + coro_wrapper, + co); goto fail; } @@ -4209,12 +4225,12 @@ PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals, } static PyObject * -special_lookup(PyObject *o, _Py_Identifier *id) +special_lookup(PyThreadState *tstate, PyObject *o, _Py_Identifier *id) { PyObject *res; res = _PyObject_LookupSpecial(o, id); - if (res == NULL && !PyErr_Occurred()) { - PyErr_SetObject(PyExc_AttributeError, id->object); + if (res == NULL && !_PyErr_Occurred(tstate)) { + _PyErr_SetObject(tstate, PyExc_AttributeError, id->object); return NULL; } return res; @@ -4236,14 +4252,14 @@ do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause) value = exc_info->exc_value; tb = exc_info->exc_traceback; if (type == Py_None || type == NULL) { - PyErr_SetString(PyExc_RuntimeError, - "No active exception to reraise"); + _PyErr_SetString(tstate, PyExc_RuntimeError, + "No active exception to reraise"); return 0; } Py_XINCREF(type); Py_XINCREF(value); Py_XINCREF(tb); - PyErr_Restore(type, value, tb); + _PyErr_Restore(tstate, type, value, tb); return 1; } @@ -4258,11 +4274,11 @@ do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause) if (value == NULL) goto raise_error; if (!PyExceptionInstance_Check(value)) { - PyErr_Format(PyExc_TypeError, - "calling %R should have returned an instance of " - "BaseException, not %R", - type, Py_TYPE(value)); - goto raise_error; + _PyErr_Format(tstate, PyExc_TypeError, + "calling %R should have returned an instance of " + "BaseException, not %R", + type, Py_TYPE(value)); + goto raise_error; } } else if (PyExceptionInstance_Check(exc)) { @@ -4274,8 +4290,8 @@ do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause) /* Not something you can raise. You get an exception anyway, just not what you specified :-) */ Py_DECREF(exc); - PyErr_SetString(PyExc_TypeError, - "exceptions must derive from BaseException"); + _PyErr_SetString(tstate, PyExc_TypeError, + "exceptions must derive from BaseException"); goto raise_error; } @@ -4298,15 +4314,15 @@ do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause) fixed_cause = NULL; } else { - PyErr_SetString(PyExc_TypeError, - "exception causes must derive from " - "BaseException"); + _PyErr_SetString(tstate, PyExc_TypeError, + "exception causes must derive from " + "BaseException"); goto raise_error; } PyException_SetCause(value, fixed_cause); } - PyErr_SetObject(type, value); + _PyErr_SetObject(tstate, type, value); /* PyErr_SetObject incref's its arguments */ Py_DECREF(value); Py_DECREF(type); @@ -4327,7 +4343,8 @@ raise_error: */ static int -unpack_iterable(PyObject *v, int argcnt, int argcntafter, PyObject **sp) +unpack_iterable(PyThreadState *tstate, PyObject *v, + int argcnt, int argcntafter, PyObject **sp) { int i = 0, j = 0; Py_ssize_t ll = 0; @@ -4339,12 +4356,12 @@ unpack_iterable(PyObject *v, int argcnt, int argcntafter, PyObject **sp) it = PyObject_GetIter(v); if (it == NULL) { - if (PyErr_ExceptionMatches(PyExc_TypeError) && + if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) && v->ob_type->tp_iter == NULL && !PySequence_Check(v)) { - PyErr_Format(PyExc_TypeError, - "cannot unpack non-iterable %.200s object", - v->ob_type->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "cannot unpack non-iterable %.200s object", + v->ob_type->tp_name); } return 0; } @@ -4353,17 +4370,18 @@ unpack_iterable(PyObject *v, int argcnt, int argcntafter, PyObject **sp) w = PyIter_Next(it); if (w == NULL) { /* Iterator done, via error or exhaustion. */ - if (!PyErr_Occurred()) { + if (!_PyErr_Occurred(tstate)) { if (argcntafter == -1) { - PyErr_Format(PyExc_ValueError, - "not enough values to unpack (expected %d, got %d)", - argcnt, i); + _PyErr_Format(tstate, PyExc_ValueError, + "not enough values to unpack " + "(expected %d, got %d)", + argcnt, i); } else { - PyErr_Format(PyExc_ValueError, - "not enough values to unpack " - "(expected at least %d, got %d)", - argcnt + argcntafter, i); + _PyErr_Format(tstate, PyExc_ValueError, + "not enough values to unpack " + "(expected at least %d, got %d)", + argcnt + argcntafter, i); } } goto Error; @@ -4375,15 +4393,15 @@ unpack_iterable(PyObject *v, int argcnt, int argcntafter, PyObject **sp) /* We better have exhausted the iterator now. */ w = PyIter_Next(it); if (w == NULL) { - if (PyErr_Occurred()) + if (_PyErr_Occurred(tstate)) goto Error; Py_DECREF(it); return 1; } Py_DECREF(w); - PyErr_Format(PyExc_ValueError, - "too many values to unpack (expected %d)", - argcnt); + _PyErr_Format(tstate, PyExc_ValueError, + "too many values to unpack (expected %d)", + argcnt); goto Error; } @@ -4395,7 +4413,7 @@ unpack_iterable(PyObject *v, int argcnt, int argcntafter, PyObject **sp) ll = PyList_GET_SIZE(l); if (ll < argcntafter) { - PyErr_Format(PyExc_ValueError, + _PyErr_Format(tstate, PyExc_ValueError, "not enough values to unpack (expected at least %d, got %zd)", argcnt + argcntafter, argcnt + ll); goto Error; @@ -4420,11 +4438,13 @@ Error: #ifdef LLTRACE static int -prtrace(PyObject *v, const char *str) +prtrace(PyThreadState *tstate, PyObject *v, const char *str) { printf("%s ", str); - if (PyObject_Print(v, stdout, 0) != 0) - PyErr_Clear(); /* Don't know what else to do */ + if (PyObject_Print(v, stdout, 0) != 0) { + /* Don't know what else to do */ + _PyErr_Clear(tstate); + } printf("\n"); return 1; } @@ -4436,22 +4456,23 @@ call_exc_trace(Py_tracefunc func, PyObject *self, { PyObject *type, *value, *traceback, *orig_traceback, *arg; int err; - PyErr_Fetch(&type, &value, &orig_traceback); + _PyErr_Fetch(tstate, &type, &value, &orig_traceback); if (value == NULL) { value = Py_None; Py_INCREF(value); } - PyErr_NormalizeException(&type, &value, &orig_traceback); + _PyErr_NormalizeException(tstate, &type, &value, &orig_traceback); traceback = (orig_traceback != NULL) ? orig_traceback : Py_None; arg = PyTuple_Pack(3, type, value, traceback); if (arg == NULL) { - PyErr_Restore(type, value, orig_traceback); + _PyErr_Restore(tstate, type, value, orig_traceback); return; } err = call_trace(func, self, tstate, f, PyTrace_EXCEPTION, arg); Py_DECREF(arg); - if (err == 0) - PyErr_Restore(type, value, orig_traceback); + if (err == 0) { + _PyErr_Restore(tstate, type, value, orig_traceback); + } else { Py_XDECREF(type); Py_XDECREF(value); @@ -4466,11 +4487,11 @@ call_trace_protected(Py_tracefunc func, PyObject *obj, { PyObject *type, *value, *traceback; int err; - PyErr_Fetch(&type, &value, &traceback); + _PyErr_Fetch(tstate, &type, &value, &traceback); err = call_trace(func, obj, tstate, frame, what, arg); if (err == 0) { - PyErr_Restore(type, value, traceback); + _PyErr_Restore(tstate, type, value, traceback); return 0; } else { @@ -4672,12 +4693,26 @@ _PyEval_GetAsyncGenFinalizer(void) return tstate->async_gen_finalizer; } +static PyFrameObject * +_PyEval_GetFrame(PyThreadState *tstate) +{ + return _PyRuntime.gilstate.getframe(tstate); +} + +PyFrameObject * +PyEval_GetFrame(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return _PyEval_GetFrame(tstate); +} + PyObject * PyEval_GetBuiltins(void) { - PyFrameObject *current_frame = PyEval_GetFrame(); + PyThreadState *tstate = _PyThreadState_GET(); + PyFrameObject *current_frame = _PyEval_GetFrame(tstate); if (current_frame == NULL) - return _PyInterpreterState_GET_UNSAFE()->builtins; + return tstate->interp->builtins; else return current_frame->f_builtins; } @@ -4686,12 +4721,13 @@ PyEval_GetBuiltins(void) PyObject * _PyEval_GetBuiltinId(_Py_Identifier *name) { + PyThreadState *tstate = _PyThreadState_GET(); PyObject *attr = _PyDict_GetItemIdWithError(PyEval_GetBuiltins(), name); if (attr) { Py_INCREF(attr); } - else if (!PyErr_Occurred()) { - PyErr_SetObject(PyExc_AttributeError, _PyUnicode_FromId(name)); + else if (!_PyErr_Occurred(tstate)) { + _PyErr_SetObject(tstate, PyExc_AttributeError, _PyUnicode_FromId(name)); } return attr; } @@ -4699,14 +4735,16 @@ _PyEval_GetBuiltinId(_Py_Identifier *name) PyObject * PyEval_GetLocals(void) { - PyFrameObject *current_frame = PyEval_GetFrame(); + PyThreadState *tstate = _PyThreadState_GET(); + PyFrameObject *current_frame = _PyEval_GetFrame(tstate); if (current_frame == NULL) { - PyErr_SetString(PyExc_SystemError, "frame does not exist"); + _PyErr_SetString(tstate, PyExc_SystemError, "frame does not exist"); return NULL; } - if (PyFrame_FastToLocalsWithError(current_frame) < 0) + if (PyFrame_FastToLocalsWithError(current_frame) < 0) { return NULL; + } assert(current_frame->f_locals != NULL); return current_frame->f_locals; @@ -4715,26 +4753,21 @@ PyEval_GetLocals(void) PyObject * PyEval_GetGlobals(void) { - PyFrameObject *current_frame = PyEval_GetFrame(); - if (current_frame == NULL) + PyThreadState *tstate = _PyThreadState_GET(); + PyFrameObject *current_frame = _PyEval_GetFrame(tstate); + if (current_frame == NULL) { return NULL; + } assert(current_frame->f_globals != NULL); return current_frame->f_globals; } -PyFrameObject * -PyEval_GetFrame(void) -{ - _PyRuntimeState *runtime = &_PyRuntime; - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - return runtime->gilstate.getframe(tstate); -} - int PyEval_MergeCompilerFlags(PyCompilerFlags *cf) { - PyFrameObject *current_frame = PyEval_GetFrame(); + PyThreadState *tstate = _PyThreadState_GET(); + PyFrameObject *current_frame = _PyEval_GetFrame(tstate); int result = cf->cf_flags != 0; if (current_frame != NULL) { @@ -4883,7 +4916,7 @@ call_function(PyThreadState *tstate, PyObject ***pp_stack, Py_ssize_t oparg, PyO Py_DECREF(func); } - assert((x != NULL) ^ (PyErr_Occurred() != NULL)); + assert((x != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); /* Clear the stack of the function object. */ while ((*pp_stack) > pfunc) { @@ -4939,17 +4972,18 @@ do_call_core(PyThreadState *tstate, PyObject *func, PyObject *callargs, PyObject int _PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi) { + PyThreadState *tstate = _PyThreadState_GET(); if (v != Py_None) { Py_ssize_t x; if (PyIndex_Check(v)) { x = PyNumber_AsSsize_t(v, NULL); - if (x == -1 && PyErr_Occurred()) + if (x == -1 && _PyErr_Occurred(tstate)) return 0; } else { - PyErr_SetString(PyExc_TypeError, - "slice indices must be integers or " - "None or have an __index__ method"); + _PyErr_SetString(tstate, PyExc_TypeError, + "slice indices must be integers or " + "None or have an __index__ method"); return 0; } *pi = x; @@ -4960,16 +4994,17 @@ _PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi) int _PyEval_SliceIndexNotNone(PyObject *v, Py_ssize_t *pi) { + PyThreadState *tstate = _PyThreadState_GET(); Py_ssize_t x; if (PyIndex_Check(v)) { x = PyNumber_AsSsize_t(v, NULL); - if (x == -1 && PyErr_Occurred()) + if (x == -1 && _PyErr_Occurred(tstate)) return 0; } else { - PyErr_SetString(PyExc_TypeError, - "slice indices must be integers or " - "have an __index__ method"); + _PyErr_SetString(tstate, PyExc_TypeError, + "slice indices must be integers or " + "have an __index__ method"); return 0; } *pi = x; @@ -4981,7 +5016,7 @@ _PyEval_SliceIndexNotNone(PyObject *v, Py_ssize_t *pi) "BaseException is not allowed" static PyObject * -cmp_outcome(int op, PyObject *v, PyObject *w) +cmp_outcome(PyThreadState *tstate, int op, PyObject *v, PyObject *w) { int res = 0; switch (op) { @@ -5009,16 +5044,16 @@ cmp_outcome(int op, PyObject *v, PyObject *w) for (i = 0; i < length; i += 1) { PyObject *exc = PyTuple_GET_ITEM(w, i); if (!PyExceptionClass_Check(exc)) { - PyErr_SetString(PyExc_TypeError, - CANNOT_CATCH_MSG); + _PyErr_SetString(tstate, PyExc_TypeError, + CANNOT_CATCH_MSG); return NULL; } } } else { if (!PyExceptionClass_Check(w)) { - PyErr_SetString(PyExc_TypeError, - CANNOT_CATCH_MSG); + _PyErr_SetString(tstate, PyExc_TypeError, + CANNOT_CATCH_MSG); return NULL; } } @@ -5033,7 +5068,8 @@ cmp_outcome(int op, PyObject *v, PyObject *w) } static PyObject * -import_name(PyFrameObject *f, PyObject *name, PyObject *fromlist, PyObject *level) +import_name(PyThreadState *tstate, PyFrameObject *f, + PyObject *name, PyObject *fromlist, PyObject *level) { _Py_IDENTIFIER(__import__); PyObject *import_func, *res; @@ -5041,16 +5077,16 @@ import_name(PyFrameObject *f, PyObject *name, PyObject *fromlist, PyObject *leve import_func = _PyDict_GetItemIdWithError(f->f_builtins, &PyId___import__); if (import_func == NULL) { - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_ImportError, "__import__ not found"); + if (!_PyErr_Occurred(tstate)) { + _PyErr_SetString(tstate, PyExc_ImportError, "__import__ not found"); } return NULL; } /* Fast path for not overloaded __import__. */ - if (import_func == _PyInterpreterState_GET_UNSAFE()->import_func) { + if (import_func == tstate->interp->import_func) { int ilevel = _PyLong_AsInt(level); - if (ilevel == -1 && PyErr_Occurred()) { + if (ilevel == -1 && _PyErr_Occurred(tstate)) { return NULL; } res = PyImport_ImportModuleLevelObject( @@ -5075,7 +5111,7 @@ import_name(PyFrameObject *f, PyObject *name, PyObject *fromlist, PyObject *leve } static PyObject * -import_from(PyObject *v, PyObject *name) +import_from(PyThreadState *tstate, PyObject *v, PyObject *name) { PyObject *x; _Py_IDENTIFIER(__name__); @@ -5102,7 +5138,7 @@ import_from(PyObject *v, PyObject *name) } x = PyImport_GetModule(fullmodname); Py_DECREF(fullmodname); - if (x == NULL && !PyErr_Occurred()) { + if (x == NULL && !_PyErr_Occurred(tstate)) { goto error; } Py_DECREF(pkgname); @@ -5120,7 +5156,7 @@ import_from(PyObject *v, PyObject *name) } if (pkgpath == NULL || !PyUnicode_Check(pkgpath)) { - PyErr_Clear(); + _PyErr_Clear(tstate); errmsg = PyUnicode_FromFormat( "cannot import name %R from %R (unknown location)", name, pkgname_or_unknown @@ -5144,7 +5180,7 @@ import_from(PyObject *v, PyObject *name) } static int -import_all_from(PyObject *locals, PyObject *v) +import_all_from(PyThreadState *tstate, PyObject *locals, PyObject *v) { _Py_IDENTIFIER(__all__); _Py_IDENTIFIER(__dict__); @@ -5161,7 +5197,7 @@ import_all_from(PyObject *locals, PyObject *v) return -1; } if (dict == NULL) { - PyErr_SetString(PyExc_ImportError, + _PyErr_SetString(tstate, PyExc_ImportError, "from-import-* object has no __dict__ and no __all__"); return -1; } @@ -5175,10 +5211,12 @@ import_all_from(PyObject *locals, PyObject *v) for (pos = 0, err = 0; ; pos++) { name = PySequence_GetItem(all, pos); if (name == NULL) { - if (!PyErr_ExceptionMatches(PyExc_IndexError)) + if (!_PyErr_ExceptionMatches(tstate, PyExc_IndexError)) { err = -1; - else - PyErr_Clear(); + } + else { + _PyErr_Clear(tstate); + } break; } if (!PyUnicode_Check(name)) { @@ -5189,17 +5227,17 @@ import_all_from(PyObject *locals, PyObject *v) break; } if (!PyUnicode_Check(modname)) { - PyErr_Format(PyExc_TypeError, - "module __name__ must be a string, not %.100s", - Py_TYPE(modname)->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "module __name__ must be a string, not %.100s", + Py_TYPE(modname)->tp_name); } else { - PyErr_Format(PyExc_TypeError, - "%s in %U.%s must be str, not %.100s", - skip_leading_underscores ? "Key" : "Item", - modname, - skip_leading_underscores ? "__dict__" : "__all__", - Py_TYPE(name)->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "%s in %U.%s must be str, not %.100s", + skip_leading_underscores ? "Key" : "Item", + modname, + skip_leading_underscores ? "__dict__" : "__all__", + Py_TYPE(name)->tp_name); } Py_DECREF(modname); Py_DECREF(name); @@ -5234,22 +5272,22 @@ import_all_from(PyObject *locals, PyObject *v) } static int -check_args_iterable(PyObject *func, PyObject *args) +check_args_iterable(PyThreadState *tstate, PyObject *func, PyObject *args) { if (args->ob_type->tp_iter == NULL && !PySequence_Check(args)) { - PyErr_Format(PyExc_TypeError, - "%.200s%.200s argument after * " - "must be an iterable, not %.200s", - PyEval_GetFuncName(func), - PyEval_GetFuncDesc(func), - args->ob_type->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "%.200s%.200s argument after * " + "must be an iterable, not %.200s", + PyEval_GetFuncName(func), + PyEval_GetFuncDesc(func), + args->ob_type->tp_name); return -1; } return 0; } static void -format_kwargs_error(PyObject *func, PyObject *kwargs) +format_kwargs_error(PyThreadState *tstate, PyObject *func, PyObject *kwargs) { /* _PyDict_MergeEx raises attribute * error (percolated from an attempt @@ -5257,44 +5295,46 @@ format_kwargs_error(PyObject *func, PyObject *kwargs) * a type error if its second argument * is not a mapping. */ - if (PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Format(PyExc_TypeError, - "%.200s%.200s argument after ** " - "must be a mapping, not %.200s", - PyEval_GetFuncName(func), - PyEval_GetFuncDesc(func), - kwargs->ob_type->tp_name); - } - else if (PyErr_ExceptionMatches(PyExc_KeyError)) { + if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { + _PyErr_Format(tstate, PyExc_TypeError, + "%.200s%.200s argument after ** " + "must be a mapping, not %.200s", + PyEval_GetFuncName(func), + PyEval_GetFuncDesc(func), + kwargs->ob_type->tp_name); + } + else if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { PyObject *exc, *val, *tb; - PyErr_Fetch(&exc, &val, &tb); + _PyErr_Fetch(tstate, &exc, &val, &tb); if (val && PyTuple_Check(val) && PyTuple_GET_SIZE(val) == 1) { PyObject *key = PyTuple_GET_ITEM(val, 0); if (!PyUnicode_Check(key)) { - PyErr_Format(PyExc_TypeError, - "%.200s%.200s keywords must be strings", - PyEval_GetFuncName(func), - PyEval_GetFuncDesc(func)); - } else { - PyErr_Format(PyExc_TypeError, - "%.200s%.200s got multiple " - "values for keyword argument '%U'", - PyEval_GetFuncName(func), - PyEval_GetFuncDesc(func), - key); + _PyErr_Format(tstate, PyExc_TypeError, + "%.200s%.200s keywords must be strings", + PyEval_GetFuncName(func), + PyEval_GetFuncDesc(func)); + } + else { + _PyErr_Format(tstate, PyExc_TypeError, + "%.200s%.200s got multiple " + "values for keyword argument '%U'", + PyEval_GetFuncName(func), + PyEval_GetFuncDesc(func), + key); } Py_XDECREF(exc); Py_XDECREF(val); Py_XDECREF(tb); } else { - PyErr_Restore(exc, val, tb); + _PyErr_Restore(tstate, exc, val, tb); } } } static void -format_exc_check_arg(PyObject *exc, const char *format_str, PyObject *obj) +format_exc_check_arg(PyThreadState *tstate, PyObject *exc, + const char *format_str, PyObject *obj) { const char *obj_str; @@ -5305,52 +5345,52 @@ format_exc_check_arg(PyObject *exc, const char *format_str, PyObject *obj) if (!obj_str) return; - PyErr_Format(exc, format_str, obj_str); + _PyErr_Format(tstate, exc, format_str, obj_str); } static void -format_exc_unbound(PyCodeObject *co, int oparg) +format_exc_unbound(PyThreadState *tstate, PyCodeObject *co, int oparg) { PyObject *name; /* Don't stomp existing exception */ - if (PyErr_Occurred()) + if (_PyErr_Occurred(tstate)) return; if (oparg < PyTuple_GET_SIZE(co->co_cellvars)) { name = PyTuple_GET_ITEM(co->co_cellvars, oparg); - format_exc_check_arg( + format_exc_check_arg(tstate, PyExc_UnboundLocalError, UNBOUNDLOCAL_ERROR_MSG, name); } else { name = PyTuple_GET_ITEM(co->co_freevars, oparg - PyTuple_GET_SIZE(co->co_cellvars)); - format_exc_check_arg(PyExc_NameError, + format_exc_check_arg(tstate, PyExc_NameError, UNBOUNDFREE_ERROR_MSG, name); } } static void -format_awaitable_error(PyTypeObject *type, int prevopcode) +format_awaitable_error(PyThreadState *tstate, PyTypeObject *type, int prevopcode) { if (type->tp_as_async == NULL || type->tp_as_async->am_await == NULL) { if (prevopcode == BEFORE_ASYNC_WITH) { - PyErr_Format(PyExc_TypeError, - "'async with' received an object from __aenter__ " - "that does not implement __await__: %.100s", - type->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "'async with' received an object from __aenter__ " + "that does not implement __await__: %.100s", + type->tp_name); } else if (prevopcode == WITH_CLEANUP_START) { - PyErr_Format(PyExc_TypeError, - "'async with' received an object from __aexit__ " - "that does not implement __await__: %.100s", - type->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "'async with' received an object from __aexit__ " + "that does not implement __await__: %.100s", + type->tp_name); } } } static PyObject * -unicode_concatenate(PyObject *v, PyObject *w, +unicode_concatenate(PyThreadState *tstate, PyObject *v, PyObject *w, PyFrameObject *f, const _Py_CODEUNIT *next_instr) { PyObject *res; @@ -5390,7 +5430,7 @@ unicode_concatenate(PyObject *v, PyObject *w, if (locals && PyDict_CheckExact(locals)) { PyObject *w = PyDict_GetItemWithError(locals, name); if ((w == v && PyDict_DelItem(locals, name) != 0) || - (w == NULL && PyErr_Occurred())) + (w == NULL && _PyErr_Occurred(tstate))) { Py_DECREF(v); return NULL; diff --git a/Python/errors.c b/Python/errors.c index d9b69d9..e721f19 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -3,6 +3,7 @@ #include "Python.h" #include "pycore_coreconfig.h" +#include "pycore_pyerrors.h" #include "pycore_pystate.h" #include "pycore_traceback.h" @@ -27,13 +28,13 @@ _Py_IDENTIFIER(builtins); _Py_IDENTIFIER(stderr); -/* Forward declaration */ -static void _PyErr_Fetch(PyThreadState *tstate, PyObject **p_type, - PyObject **p_value, PyObject **p_traceback); -static void _PyErr_Clear(PyThreadState *tstate); +/* Forward declarations */ +static PyObject * +_PyErr_FormatV(PyThreadState *tstate, PyObject *exception, + const char *format, va_list vargs); -static void +void _PyErr_Restore(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *traceback) { @@ -95,7 +96,7 @@ _PyErr_CreateException(PyObject *exception, PyObject *value) } } -static void +void _PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value) { PyObject *exc_value; @@ -103,9 +104,9 @@ _PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value) if (exception != NULL && !PyExceptionClass_Check(exception)) { - PyErr_Format(PyExc_SystemError, - "exception %R not a BaseException subclass", - exception); + _PyErr_Format(tstate, PyExc_SystemError, + "exception %R not a BaseException subclass", + exception); return; } @@ -181,7 +182,7 @@ _PyErr_SetKeyError(PyObject *arg) Py_DECREF(tup); } -static void +void _PyErr_SetNone(PyThreadState *tstate, PyObject *exception) { _PyErr_SetObject(tstate, exception, (PyObject *)NULL); @@ -196,7 +197,7 @@ PyErr_SetNone(PyObject *exception) } -static void +void _PyErr_SetString(PyThreadState *tstate, PyObject *exception, const char *string) { @@ -213,13 +214,6 @@ PyErr_SetString(PyObject *exception, const char *string) } -static PyObject* -_PyErr_Occurred(PyThreadState *tstate) -{ - return tstate == NULL ? NULL : tstate->curexc_type; -} - - PyObject* _Py_HOT_FUNCTION PyErr_Occurred(void) { @@ -261,10 +255,17 @@ PyErr_GivenExceptionMatches(PyObject *err, PyObject *exc) int +_PyErr_ExceptionMatches(PyThreadState *tstate, PyObject *exc) +{ + return PyErr_GivenExceptionMatches(_PyErr_Occurred(tstate), exc); +} + + +int PyErr_ExceptionMatches(PyObject *exc) { PyThreadState *tstate = _PyThreadState_GET(); - return PyErr_GivenExceptionMatches(_PyErr_Occurred(tstate), exc); + return _PyErr_ExceptionMatches(tstate, exc); } @@ -278,7 +279,7 @@ PyErr_ExceptionMatches(PyObject *exc) XXX: should PyErr_NormalizeException() also call PyException_SetTraceback() with the resulting value and tb? */ -static void +void _PyErr_NormalizeException(PyThreadState *tstate, PyObject **exc, PyObject **val, PyObject **tb) { @@ -390,7 +391,7 @@ PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb) } -static void +void _PyErr_Fetch(PyThreadState *tstate, PyObject **p_type, PyObject **p_value, PyObject **p_traceback) { @@ -412,7 +413,7 @@ PyErr_Fetch(PyObject **p_type, PyObject **p_value, PyObject **p_traceback) } -static void +void _PyErr_Clear(PyThreadState *tstate) { _PyErr_Restore(tstate, NULL, NULL, NULL); @@ -506,7 +507,7 @@ _PyErr_FormatVFromCause(PyThreadState *tstate, PyObject *exception, Py_DECREF(exc); assert(!_PyErr_Occurred(tstate)); - PyErr_FormatV(exception, format, vargs); + _PyErr_FormatV(tstate, exception, format, vargs); _PyErr_Fetch(tstate, &exc, &val2, &tb); _PyErr_NormalizeException(tstate, &exc, &val2, &tb); @@ -895,9 +896,10 @@ PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path) void _PyErr_BadInternalCall(const char *filename, int lineno) { - PyErr_Format(PyExc_SystemError, - "%s:%d: bad argument to internal function", - filename, lineno); + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_Format(tstate, PyExc_SystemError, + "%s:%d: bad argument to internal function", + filename, lineno); } /* Remove the preprocessor macro for PyErr_BadInternalCall() so that we can @@ -907,16 +909,17 @@ void PyErr_BadInternalCall(void) { assert(0 && "bad argument to internal function"); - PyErr_Format(PyExc_SystemError, - "bad argument to internal function"); + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_SetString(tstate, PyExc_SystemError, + "bad argument to internal function"); } #define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__) -PyObject * -PyErr_FormatV(PyObject *exception, const char *format, va_list vargs) +static PyObject * +_PyErr_FormatV(PyThreadState *tstate, PyObject *exception, + const char *format, va_list vargs) { - PyThreadState *tstate = _PyThreadState_GET(); PyObject* string; /* Issue #23571: PyUnicode_FromFormatV() must not be called with an @@ -932,15 +935,40 @@ PyErr_FormatV(PyObject *exception, const char *format, va_list vargs) PyObject * +PyErr_FormatV(PyObject *exception, const char *format, va_list vargs) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return _PyErr_FormatV(tstate, exception, format, vargs); +} + + +PyObject * +_PyErr_Format(PyThreadState *tstate, PyObject *exception, + const char *format, ...) +{ + va_list vargs; +#ifdef HAVE_STDARG_PROTOTYPES + va_start(vargs, format); +#else + va_start(vargs); +#endif + _PyErr_FormatV(tstate, exception, format, vargs); + va_end(vargs); + return NULL; +} + + +PyObject * PyErr_Format(PyObject *exception, const char *format, ...) { + PyThreadState *tstate = _PyThreadState_GET(); va_list vargs; #ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); #else va_start(vargs); #endif - PyErr_FormatV(exception, format, vargs); + _PyErr_FormatV(tstate, exception, format, vargs); va_end(vargs); return NULL; } diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 7219f54..26cb02a 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -12,6 +12,7 @@ #include "Python-ast.h" #undef Yield /* undefine macro conflicting with */ +#include "pycore_pyerrors.h" #include "pycore_pylifecycle.h" #include "pycore_pystate.h" #include "grammar.h" @@ -542,12 +543,6 @@ finally: return 0; } -void -PyErr_Print(void) -{ - PyErr_PrintEx(1); -} - static void print_error_text(PyObject *f, int offset, PyObject *text_obj) { @@ -667,34 +662,38 @@ handle_system_exit(void) } -void -PyErr_PrintEx(int set_sys_last_vars) +static void +_PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars) { PyObject *exception, *v, *tb, *hook; handle_system_exit(); - PyErr_Fetch(&exception, &v, &tb); - if (exception == NULL) - return; - PyErr_NormalizeException(&exception, &v, &tb); + _PyErr_Fetch(tstate, &exception, &v, &tb); + if (exception == NULL) { + goto done; + } + + _PyErr_NormalizeException(tstate, &exception, &v, &tb); if (tb == NULL) { tb = Py_None; Py_INCREF(tb); } PyException_SetTraceback(v, tb); - if (exception == NULL) - return; + if (exception == NULL) { + goto done; + } + /* Now we know v != NULL too */ if (set_sys_last_vars) { if (_PySys_SetObjectId(&PyId_last_type, exception) < 0) { - PyErr_Clear(); + _PyErr_Clear(tstate); } if (_PySys_SetObjectId(&PyId_last_value, v) < 0) { - PyErr_Clear(); + _PyErr_Clear(tstate); } if (_PySys_SetObjectId(&PyId_last_traceback, tb) < 0) { - PyErr_Clear(); + _PyErr_Clear(tstate); } } hook = _PySys_GetObjectId(&PyId_excepthook); @@ -710,8 +709,8 @@ PyErr_PrintEx(int set_sys_last_vars) handle_system_exit(); PyObject *exception2, *v2, *tb2; - PyErr_Fetch(&exception2, &v2, &tb2); - PyErr_NormalizeException(&exception2, &v2, &tb2); + _PyErr_Fetch(tstate, &exception2, &v2, &tb2); + _PyErr_NormalizeException(tstate, &exception2, &v2, &tb2); /* It should not be possible for exception2 or v2 to be NULL. However PyErr_Display() can't tolerate NULLs, so just be safe. */ @@ -733,15 +732,37 @@ PyErr_PrintEx(int set_sys_last_vars) Py_XDECREF(tb2); } Py_XDECREF(result); - } else { + } + else { PySys_WriteStderr("sys.excepthook is missing\n"); PyErr_Display(exception, v, tb); } + +done: Py_XDECREF(exception); Py_XDECREF(v); Py_XDECREF(tb); } +void +_PyErr_Print(PyThreadState *tstate) +{ + _PyErr_PrintEx(tstate, 1); +} + +void +PyErr_PrintEx(int set_sys_last_vars) +{ + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_PrintEx(tstate, set_sys_last_vars); +} + +void +PyErr_Print(void) +{ + PyErr_PrintEx(1); +} + static void print_exception(PyObject *f, PyObject *value) { -- cgit v0.12