summaryrefslogtreecommitdiffstats
path: root/Objects/methodobject.c
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2019-11-04 23:51:22 (GMT)
committerGitHub <noreply@github.com>2019-11-04 23:51:22 (GMT)
commitbe434dc0380d9f5c7c800de9943cc46d55fd9491 (patch)
treebbf95dcf9ccc433e071cb4ce09984b5c5128f67e /Objects/methodobject.c
parentf4b1e3d7c64985f5d5b00f6cc9a1c146bbbfd613 (diff)
downloadcpython-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.c50
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;
}