diff options
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_testclinic.c | 43 | ||||
-rw-r--r-- | Modules/clinic/_testclinic.c.h | 51 | ||||
-rw-r--r-- | Modules/clinic/gcmodule.c.h | 36 | ||||
-rw-r--r-- | Modules/gcmodule.c | 39 |
4 files changed, 95 insertions, 74 deletions
diff --git a/Modules/_testclinic.c b/Modules/_testclinic.c index ca884af1aa2..e3c8ba9b0b5 100644 --- a/Modules/_testclinic.c +++ b/Modules/_testclinic.c @@ -58,6 +58,20 @@ pack_arguments_newref(int argc, ...) return tuple; } +static PyObject * +pack_varargs_to_tuple(Py_ssize_t varargssize, PyObject *const *args) +{ + assert(!PyErr_Occurred()); + PyObject *tuple = PyTuple_New(varargssize); + if (!tuple) { + return NULL; + } + for (Py_ssize_t i = 0; i < varargssize; i++) { + PyTuple_SET_ITEM(tuple, i, Py_NewRef(args[i])); + } + return tuple; +} + /* Pack arguments to a tuple. * `wrapper` is function which converts primitive type to PyObject. * `arg_type` is type that arguments should be converted to before wrapped. */ @@ -970,10 +984,16 @@ varpos [clinic start generated code]*/ static PyObject * -varpos_impl(PyObject *module, PyObject *args) -/*[clinic end generated code: output=7b0b9545872bdca4 input=f87cd674145d394c]*/ +varpos_impl(PyObject *module, Py_ssize_t nargs, PyObject *const *args) +/*[clinic end generated code: output=b65096f423fb5dcc input=f87cd674145d394c]*/ { - return Py_NewRef(args); + PyObject *vararg_tuple = pack_varargs_to_tuple(nargs, args); + if (!vararg_tuple) { + return NULL; + } + PyObject *result = pack_arguments_newref(1, vararg_tuple); + Py_DECREF(vararg_tuple); + return result; } @@ -989,10 +1009,16 @@ posonly_varpos static PyObject * posonly_varpos_impl(PyObject *module, PyObject *a, PyObject *b, - PyObject *args) -/*[clinic end generated code: output=5dae5eb2a0d623cd input=c9fd7895cfbaabba]*/ + Py_ssize_t nargs, PyObject *const *args) +/*[clinic end generated code: output=d10d43d86d117ab3 input=c9fd7895cfbaabba]*/ { - return pack_arguments_newref(3, a, b, args); + PyObject *vararg_tuple = pack_varargs_to_tuple(nargs, args); + if (!vararg_tuple) { + return NULL; + } + PyObject *result = pack_arguments_newref(3, a, b, vararg_tuple); + Py_DECREF(vararg_tuple); + return result; } @@ -1157,8 +1183,9 @@ Proof-of-concept of GH-99233 refcount error bug. [clinic start generated code]*/ static PyObject * -gh_99233_refcount_impl(PyObject *module, PyObject *args) -/*[clinic end generated code: output=585855abfbca9a7f input=eecfdc2092d90dc3]*/ +gh_99233_refcount_impl(PyObject *module, Py_ssize_t nargs, + PyObject *const *args) +/*[clinic end generated code: output=b570007e61e5c670 input=eecfdc2092d90dc3]*/ { Py_RETURN_NONE; } diff --git a/Modules/clinic/_testclinic.c.h b/Modules/clinic/_testclinic.c.h index 1988c069710..7e29998c7db 100644 --- a/Modules/clinic/_testclinic.c.h +++ b/Modules/clinic/_testclinic.c.h @@ -2530,28 +2530,22 @@ PyDoc_STRVAR(varpos__doc__, {"varpos", _PyCFunction_CAST(varpos), METH_FASTCALL, varpos__doc__}, static PyObject * -varpos_impl(PyObject *module, PyObject *args); +varpos_impl(PyObject *module, Py_ssize_t nargs, PyObject *const *args); static PyObject * varpos(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - PyObject *__clinic_args = NULL; + Py_ssize_t nvararg = nargs - 0; + PyObject *const *__clinic_args = NULL; if (!_PyArg_CheckPositional("varpos", nargs, 0, PY_SSIZE_T_MAX)) { goto exit; } - __clinic_args = PyTuple_New(nargs - 0); - if (!__clinic_args) { - goto exit; - } - for (Py_ssize_t i = 0; i < nargs - 0; ++i) { - PyTuple_SET_ITEM(__clinic_args, i, Py_NewRef(args[0 + i])); - } - return_value = varpos_impl(module, __clinic_args); + __clinic_args = args + 0; + return_value = varpos_impl(module, nvararg, __clinic_args); exit: - Py_XDECREF(__clinic_args); return return_value; } @@ -2565,32 +2559,26 @@ PyDoc_STRVAR(posonly_varpos__doc__, static PyObject * posonly_varpos_impl(PyObject *module, PyObject *a, PyObject *b, - PyObject *args); + Py_ssize_t nargs, PyObject *const *args); static PyObject * posonly_varpos(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; + Py_ssize_t nvararg = nargs - 2; PyObject *a; PyObject *b; - PyObject *__clinic_args = NULL; + PyObject *const *__clinic_args = NULL; if (!_PyArg_CheckPositional("posonly_varpos", nargs, 2, PY_SSIZE_T_MAX)) { goto exit; } a = args[0]; b = args[1]; - __clinic_args = PyTuple_New(nargs - 2); - if (!__clinic_args) { - goto exit; - } - for (Py_ssize_t i = 0; i < nargs - 2; ++i) { - PyTuple_SET_ITEM(__clinic_args, i, Py_NewRef(args[2 + i])); - } - return_value = posonly_varpos_impl(module, a, b, __clinic_args); + __clinic_args = args + 2; + return_value = posonly_varpos_impl(module, a, b, nvararg, __clinic_args); exit: - Py_XDECREF(__clinic_args); return return_value; } @@ -3136,28 +3124,23 @@ PyDoc_STRVAR(gh_99233_refcount__doc__, {"gh_99233_refcount", _PyCFunction_CAST(gh_99233_refcount), METH_FASTCALL, gh_99233_refcount__doc__}, static PyObject * -gh_99233_refcount_impl(PyObject *module, PyObject *args); +gh_99233_refcount_impl(PyObject *module, Py_ssize_t nargs, + PyObject *const *args); static PyObject * gh_99233_refcount(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - PyObject *__clinic_args = NULL; + Py_ssize_t nvararg = nargs - 0; + PyObject *const *__clinic_args = NULL; if (!_PyArg_CheckPositional("gh_99233_refcount", nargs, 0, PY_SSIZE_T_MAX)) { goto exit; } - __clinic_args = PyTuple_New(nargs - 0); - if (!__clinic_args) { - goto exit; - } - for (Py_ssize_t i = 0; i < nargs - 0; ++i) { - PyTuple_SET_ITEM(__clinic_args, i, Py_NewRef(args[0 + i])); - } - return_value = gh_99233_refcount_impl(module, __clinic_args); + __clinic_args = args + 0; + return_value = gh_99233_refcount_impl(module, nvararg, __clinic_args); exit: - Py_XDECREF(__clinic_args); return return_value; } @@ -3693,4 +3676,4 @@ exit: Py_XDECREF(__clinic_args); return return_value; } -/*[clinic end generated code: output=76ecbb38c632bde8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7662d07e7d29cbeb input=a9049054013a1b77]*/ diff --git a/Modules/clinic/gcmodule.c.h b/Modules/clinic/gcmodule.c.h index 9fff4da616b..be3bd35b4ff 100644 --- a/Modules/clinic/gcmodule.c.h +++ b/Modules/clinic/gcmodule.c.h @@ -312,28 +312,23 @@ PyDoc_STRVAR(gc_get_referrers__doc__, {"get_referrers", _PyCFunction_CAST(gc_get_referrers), METH_FASTCALL, gc_get_referrers__doc__}, static PyObject * -gc_get_referrers_impl(PyObject *module, PyObject *args); +gc_get_referrers_impl(PyObject *module, Py_ssize_t nargs, + PyObject *const *args); static PyObject * gc_get_referrers(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - PyObject *__clinic_args = NULL; + Py_ssize_t nvararg = nargs - 0; + PyObject *const *__clinic_args = NULL; if (!_PyArg_CheckPositional("get_referrers", nargs, 0, PY_SSIZE_T_MAX)) { goto exit; } - __clinic_args = PyTuple_New(nargs - 0); - if (!__clinic_args) { - goto exit; - } - for (Py_ssize_t i = 0; i < nargs - 0; ++i) { - PyTuple_SET_ITEM(__clinic_args, i, Py_NewRef(args[0 + i])); - } - return_value = gc_get_referrers_impl(module, __clinic_args); + __clinic_args = args + 0; + return_value = gc_get_referrers_impl(module, nvararg, __clinic_args); exit: - Py_XDECREF(__clinic_args); return return_value; } @@ -347,28 +342,23 @@ PyDoc_STRVAR(gc_get_referents__doc__, {"get_referents", _PyCFunction_CAST(gc_get_referents), METH_FASTCALL, gc_get_referents__doc__}, static PyObject * -gc_get_referents_impl(PyObject *module, PyObject *args); +gc_get_referents_impl(PyObject *module, Py_ssize_t nargs, + PyObject *const *args); static PyObject * gc_get_referents(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - PyObject *__clinic_args = NULL; + Py_ssize_t nvararg = nargs - 0; + PyObject *const *__clinic_args = NULL; if (!_PyArg_CheckPositional("get_referents", nargs, 0, PY_SSIZE_T_MAX)) { goto exit; } - __clinic_args = PyTuple_New(nargs - 0); - if (!__clinic_args) { - goto exit; - } - for (Py_ssize_t i = 0; i < nargs - 0; ++i) { - PyTuple_SET_ITEM(__clinic_args, i, Py_NewRef(args[0 + i])); - } - return_value = gc_get_referents_impl(module, __clinic_args); + __clinic_args = args + 0; + return_value = gc_get_referents_impl(module, nvararg, __clinic_args); exit: - Py_XDECREF(__clinic_args); return return_value; } @@ -585,4 +575,4 @@ gc_get_freeze_count(PyObject *module, PyObject *Py_UNUSED(ignored)) exit: return return_value; } -/*[clinic end generated code: output=0a7e91917adcb937 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f488a0d4d6bd3687 input=a9049054013a1b77]*/ diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 57e4aae9ed5..f5fea5aa4dd 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -8,6 +8,7 @@ #include "pycore_gc.h" #include "pycore_object.h" // _PyObject_IS_GC() #include "pycore_pystate.h" // _PyInterpreterState_GET() +#include "pycore_tuple.h" // _PyTuple_FromArray() typedef struct _gc_runtime_state GCState; @@ -221,15 +222,25 @@ Return the list of objects that directly refer to any of 'objs'. [clinic start generated code]*/ static PyObject * -gc_get_referrers_impl(PyObject *module, PyObject *args) -/*[clinic end generated code: output=296a09587f6a86b5 input=bae96961b14a0922]*/ +gc_get_referrers_impl(PyObject *module, Py_ssize_t nargs, + PyObject *const *args) +/*[clinic end generated code: output=1d44a7695ea25c40 input=bae96961b14a0922]*/ { - if (PySys_Audit("gc.get_referrers", "(O)", args) < 0) { + PyObject *varargs = _PyTuple_FromArray(args, nargs); + + if (!varargs) { + return NULL; + } + if (PySys_Audit("gc.get_referrers", "(O)", varargs) < 0) { + Py_DECREF(varargs); return NULL; } PyInterpreterState *interp = _PyInterpreterState_GET(); - return _PyGC_GetReferrers(interp, args); + PyObject *result = _PyGC_GetReferrers(interp, varargs); + + Py_DECREF(varargs); + return result; } /* Append obj to list; return true if error (out of memory), false if OK. */ @@ -269,27 +280,37 @@ Return the list of objects that are directly referred to by 'objs'. [clinic start generated code]*/ static PyObject * -gc_get_referents_impl(PyObject *module, PyObject *args) -/*[clinic end generated code: output=d47dc02cefd06fe8 input=b3ceab0c34038cbf]*/ +gc_get_referents_impl(PyObject *module, Py_ssize_t nargs, + PyObject *const *args) +/*[clinic end generated code: output=e459f3e8c0d19311 input=b3ceab0c34038cbf]*/ { - if (PySys_Audit("gc.get_referents", "(O)", args) < 0) { + PyObject *varargs = _PyTuple_FromArray(args, nargs); + + if (!varargs) { + return NULL; + } + if (PySys_Audit("gc.get_referents", "(O)", varargs) < 0) { + Py_DECREF(varargs); return NULL; } PyInterpreterState *interp = _PyInterpreterState_GET(); PyObject *result = PyList_New(0); - if (result == NULL) + if (result == NULL) { + Py_DECREF(varargs); return NULL; + } // NOTE: stop the world is a no-op in default build _PyEval_StopTheWorld(interp); - int err = append_referrents(result, args); + int err = append_referrents(result, varargs); _PyEval_StartTheWorld(interp); if (err < 0) { Py_CLEAR(result); } + Py_DECREF(varargs); return result; } |