diff options
author | Victor Stinner <vstinner@python.org> | 2019-11-04 23:51:22 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-11-04 23:51:22 (GMT) |
commit | be434dc0380d9f5c7c800de9943cc46d55fd9491 (patch) | |
tree | bbf95dcf9ccc433e071cb4ce09984b5c5128f67e /Objects/methodobject.c | |
parent | f4b1e3d7c64985f5d5b00f6cc9a1c146bbbfd613 (diff) | |
download | cpython-be434dc0380d9f5c7c800de9943cc46d55fd9491.zip cpython-be434dc0380d9f5c7c800de9943cc46d55fd9491.tar.gz cpython-be434dc0380d9f5c7c800de9943cc46d55fd9491.tar.bz2 |
bpo-38644: Pass tstate to Py_EnterRecursiveCall() (GH-16997)
* Add _Py_EnterRecursiveCall() and _Py_LeaveRecursiveCall() which
require a tstate argument.
* Pass tstate to _Py_MakeRecCheck() and _Py_CheckRecursiveCall().
* Convert Py_EnterRecursiveCall() and Py_LeaveRecursiveCall() macros
to static inline functions.
_PyThreadState_GET() is the most efficient way to get the tstate, and
so using it with _Py_EnterRecursiveCall() and
_Py_LeaveRecursiveCall() should be a little bit more efficient than
using Py_EnterRecursiveCall() and Py_LeaveRecursiveCall() which use
the "slower" PyThreadState_GET().
Diffstat (limited to 'Objects/methodobject.c')
-rw-r--r-- | Objects/methodobject.c | 50 |
1 files changed, 28 insertions, 22 deletions
diff --git a/Objects/methodobject.c b/Objects/methodobject.c index a5f0c5d..3ce1560 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -3,6 +3,7 @@ #include "Python.h" #include "pycore_object.h" +#include "pycore_pyerrors.h" #include "pycore_pymem.h" #include "pycore_pystate.h" #include "structmember.h" @@ -344,22 +345,22 @@ get_name(PyObject *func) typedef void (*funcptr)(void); static inline int -cfunction_check_kwargs(PyObject *func, PyObject *kwnames) +cfunction_check_kwargs(PyThreadState *tstate, PyObject *func, PyObject *kwnames) { - assert(!PyErr_Occurred()); + assert(!_PyErr_Occurred(tstate)); assert(PyCFunction_Check(func)); if (kwnames && PyTuple_GET_SIZE(kwnames)) { - PyErr_Format(PyExc_TypeError, - "%.200s() takes no keyword arguments", get_name(func)); + _PyErr_Format(tstate, PyExc_TypeError, + "%.200s() takes no keyword arguments", get_name(func)); return -1; } return 0; } static inline funcptr -cfunction_enter_call(PyObject *func) +cfunction_enter_call(PyThreadState *tstate, PyObject *func) { - if (Py_EnterRecursiveCall(" while calling a Python object")) { + if (_Py_EnterRecursiveCall(tstate, " while calling a Python object")) { return NULL; } return (funcptr)PyCFunction_GET_FUNCTION(func); @@ -370,17 +371,18 @@ static PyObject * cfunction_vectorcall_FASTCALL( PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) { - if (cfunction_check_kwargs(func, kwnames)) { + PyThreadState *tstate = _PyThreadState_GET(); + if (cfunction_check_kwargs(tstate, func, kwnames)) { return NULL; } Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); _PyCFunctionFast meth = (_PyCFunctionFast) - cfunction_enter_call(func); + cfunction_enter_call(tstate, func); if (meth == NULL) { return NULL; } PyObject *result = meth(PyCFunction_GET_SELF(func), args, nargs); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(tstate); return result; } @@ -388,14 +390,15 @@ static PyObject * cfunction_vectorcall_FASTCALL_KEYWORDS( PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) { + PyThreadState *tstate = _PyThreadState_GET(); Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); _PyCFunctionFastWithKeywords meth = (_PyCFunctionFastWithKeywords) - cfunction_enter_call(func); + cfunction_enter_call(tstate, func); if (meth == NULL) { return NULL; } PyObject *result = meth(PyCFunction_GET_SELF(func), args, nargs, kwnames); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(tstate); return result; } @@ -403,21 +406,23 @@ static PyObject * cfunction_vectorcall_NOARGS( PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) { - if (cfunction_check_kwargs(func, kwnames)) { + PyThreadState *tstate = _PyThreadState_GET(); + if (cfunction_check_kwargs(tstate, func, kwnames)) { return NULL; } Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); if (nargs != 0) { - PyErr_Format(PyExc_TypeError, - "%.200s() takes no arguments (%zd given)", get_name(func), nargs); + _PyErr_Format(tstate, PyExc_TypeError, + "%.200s() takes no arguments (%zd given)", + get_name(func), nargs); return NULL; } - PyCFunction meth = (PyCFunction)cfunction_enter_call(func); + PyCFunction meth = (PyCFunction)cfunction_enter_call(tstate, func); if (meth == NULL) { return NULL; } PyObject *result = meth(PyCFunction_GET_SELF(func), NULL); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(tstate); return result; } @@ -425,22 +430,23 @@ static PyObject * cfunction_vectorcall_O( PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) { - if (cfunction_check_kwargs(func, kwnames)) { + PyThreadState *tstate = _PyThreadState_GET(); + if (cfunction_check_kwargs(tstate, func, kwnames)) { return NULL; } Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); if (nargs != 1) { - PyErr_Format(PyExc_TypeError, - "%.200s() takes exactly one argument (%zd given)", - get_name(func), nargs); + _PyErr_Format(tstate, PyExc_TypeError, + "%.200s() takes exactly one argument (%zd given)", + get_name(func), nargs); return NULL; } - PyCFunction meth = (PyCFunction)cfunction_enter_call(func); + PyCFunction meth = (PyCFunction)cfunction_enter_call(tstate, func); if (meth == NULL) { return NULL; } PyObject *result = meth(PyCFunction_GET_SELF(func), args[0]); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(tstate); return result; } |