| 
									
										
										
										
											2023-10-17 14:30:31 +02:00
										 |  |  | // clinic/vectorcall.c.h uses internal pycore_modsupport.h API
 | 
					
						
							|  |  |  | #define PYTESTCAPI_NEED_INTERNAL_API
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-08 17:56:26 +02:00
										 |  |  | #include "parts.h"
 | 
					
						
							| 
									
										
										
										
											2022-08-04 17:19:29 +02:00
										 |  |  | #include "clinic/vectorcall.c.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-25 15:28:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-04 17:19:29 +02:00
										 |  |  | #include <stddef.h>                 // offsetof
 | 
					
						
							| 
									
										
										
										
											2022-07-08 17:56:26 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-09 12:08:18 +00:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | module _testcapi | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | /*[clinic end generated code: output=da39a3ee5e6b4b0d input=6361033e795369fc]*/ | 
					
						
							| 
									
										
										
										
											2022-07-08 17:56:26 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Test PEP 590 - Vectorcall */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | fastcall_args(PyObject *args, PyObject ***stack, Py_ssize_t *nargs) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (args == Py_None) { | 
					
						
							|  |  |  |         *stack = NULL; | 
					
						
							|  |  |  |         *nargs = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (PyTuple_Check(args)) { | 
					
						
							|  |  |  |         *stack = ((PyTupleObject *)args)->ob_item; | 
					
						
							|  |  |  |         *nargs = PyTuple_GET_SIZE(args); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_TypeError, "args must be None or a tuple"); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-09 12:08:18 +00:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | _testcapi.pyobject_fastcalldict | 
					
						
							|  |  |  |     func: object | 
					
						
							|  |  |  |     func_args: object | 
					
						
							|  |  |  |     kwargs: object | 
					
						
							|  |  |  |     / | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							| 
									
										
										
										
											2022-07-08 17:56:26 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2023-07-09 12:08:18 +00:00
										 |  |  | _testcapi_pyobject_fastcalldict_impl(PyObject *module, PyObject *func, | 
					
						
							|  |  |  |                                      PyObject *func_args, PyObject *kwargs) | 
					
						
							|  |  |  | /*[clinic end generated code: output=35902ece94de4418 input=b9c0196ca7d5f9e4]*/ | 
					
						
							| 
									
										
										
										
											2022-07-08 17:56:26 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     PyObject **stack; | 
					
						
							|  |  |  |     Py_ssize_t nargs; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (fastcall_args(func_args, &stack, &nargs) < 0) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (kwargs == Py_None) { | 
					
						
							|  |  |  |         kwargs = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (!PyDict_Check(kwargs)) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_TypeError, "kwnames must be None or a dict"); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return PyObject_VectorcallDict(func, stack, nargs, kwargs); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-09 12:08:18 +00:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | _testcapi.pyobject_vectorcall | 
					
						
							|  |  |  |     func: object | 
					
						
							|  |  |  |     func_args: object | 
					
						
							|  |  |  |     kwnames: object | 
					
						
							|  |  |  |     / | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-08 17:56:26 +02:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2023-07-09 12:08:18 +00:00
										 |  |  | _testcapi_pyobject_vectorcall_impl(PyObject *module, PyObject *func, | 
					
						
							|  |  |  |                                    PyObject *func_args, PyObject *kwnames) | 
					
						
							|  |  |  | /*[clinic end generated code: output=ff77245bc6afe0d8 input=a0668dfef625764c]*/ | 
					
						
							| 
									
										
										
										
											2022-07-08 17:56:26 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     PyObject **stack; | 
					
						
							|  |  |  |     Py_ssize_t nargs, nkw; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (fastcall_args(func_args, &stack, &nargs) < 0) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (kwnames == Py_None) { | 
					
						
							|  |  |  |         kwnames = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (PyTuple_Check(kwnames)) { | 
					
						
							|  |  |  |         nkw = PyTuple_GET_SIZE(kwnames); | 
					
						
							|  |  |  |         if (nargs < nkw) { | 
					
						
							|  |  |  |             PyErr_SetString(PyExc_ValueError, "kwnames longer than args"); | 
					
						
							|  |  |  |             return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         nargs -= nkw; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_TypeError, "kwnames must be None or a tuple"); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return PyObject_Vectorcall(func, stack, nargs, kwnames); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-15 08:42:37 -07:00
										 |  |  | static PyObject * | 
					
						
							|  |  |  | override_vectorcall(PyObject *callable, PyObject *const *args, size_t nargsf, | 
					
						
							|  |  |  |                     PyObject *kwnames) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return PyUnicode_FromString("overridden"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | function_setvectorcall(PyObject *self, PyObject *func) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!PyFunction_Check(func)) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_TypeError, "'func' must be a function"); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     PyFunction_SetVectorcall((PyFunctionObject *)func, (vectorcallfunc)override_vectorcall); | 
					
						
							|  |  |  |     Py_RETURN_NONE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-09 12:08:18 +00:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | _testcapi.pyvectorcall_call | 
					
						
							|  |  |  |     func: object | 
					
						
							|  |  |  |     argstuple: object | 
					
						
							|  |  |  |     kwargs: object = NULL | 
					
						
							|  |  |  |     / | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-08 17:56:26 +02:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2023-07-09 12:08:18 +00:00
										 |  |  | _testcapi_pyvectorcall_call_impl(PyObject *module, PyObject *func, | 
					
						
							|  |  |  |                                  PyObject *argstuple, PyObject *kwargs) | 
					
						
							|  |  |  | /*[clinic end generated code: output=809046fe78511306 input=4376ee7cabd698ce]*/ | 
					
						
							| 
									
										
										
										
											2022-07-08 17:56:26 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     if (!PyTuple_Check(argstuple)) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_TypeError, "args must be a tuple"); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (kwargs != NULL && !PyDict_Check(kwargs)) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_TypeError, "kwargs must be a dict"); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return PyVectorcall_Call(func, argstuple, kwargs); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-04 17:19:29 +02:00
										 |  |  | PyObject * | 
					
						
							|  |  |  | VectorCallClass_tpcall(PyObject *self, PyObject *args, PyObject *kwargs) { | 
					
						
							|  |  |  |     return PyUnicode_FromString("tp_call"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject * | 
					
						
							|  |  |  | VectorCallClass_vectorcall(PyObject *callable, | 
					
						
							|  |  |  |                             PyObject *const *args, | 
					
						
							|  |  |  |                             size_t nargsf, | 
					
						
							|  |  |  |                             PyObject *kwnames) { | 
					
						
							|  |  |  |     return PyUnicode_FromString("vectorcall"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | class _testcapi.VectorCallClass "PyObject *" "&PyType_Type" | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							| 
									
										
										
										
											2023-08-04 07:28:25 +02:00
										 |  |  | /*[clinic end generated code: output=da39a3ee5e6b4b0d input=95c63c1a47f9a995]*/ | 
					
						
							| 
									
										
										
										
											2022-08-04 17:19:29 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | _testcapi.VectorCallClass.set_vectorcall | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     type: object(subclass_of="&PyType_Type", type="PyTypeObject *") | 
					
						
							|  |  |  |     / | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Set self's vectorcall function for `type` to one that returns "vectorcall" | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | _testcapi_VectorCallClass_set_vectorcall_impl(PyObject *self, | 
					
						
							|  |  |  |                                               PyTypeObject *type) | 
					
						
							|  |  |  | /*[clinic end generated code: output=b37f0466f15da903 input=840de66182c7d71a]*/ | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!PyObject_TypeCheck(self, type)) { | 
					
						
							|  |  |  |         return PyErr_Format( | 
					
						
							|  |  |  |             PyExc_TypeError, | 
					
						
							|  |  |  |             "expected %s instance", | 
					
						
							|  |  |  |             PyType_GetName(type)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (!type->tp_vectorcall_offset) { | 
					
						
							|  |  |  |         return PyErr_Format( | 
					
						
							|  |  |  |             PyExc_TypeError, | 
					
						
							|  |  |  |             "type %s has no vectorcall offset", | 
					
						
							|  |  |  |             PyType_GetName(type)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     *(vectorcallfunc*)((char*)self + type->tp_vectorcall_offset) = ( | 
					
						
							|  |  |  |         VectorCallClass_vectorcall); | 
					
						
							|  |  |  |     Py_RETURN_NONE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyMethodDef VectorCallClass_methods[] = { | 
					
						
							|  |  |  |     _TESTCAPI_VECTORCALLCLASS_SET_VECTORCALL_METHODDEF | 
					
						
							|  |  |  |     {NULL, NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyMemberDef VectorCallClass_members[] = { | 
					
						
							| 
									
										
										
										
											2023-07-25 15:28:30 +02:00
										 |  |  |     {"__vectorcalloffset__", Py_T_PYSSIZET, 0/* set later */, Py_READONLY}, | 
					
						
							| 
									
										
										
										
											2022-08-04 17:19:29 +02:00
										 |  |  |     {NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyType_Slot VectorCallClass_slots[] = { | 
					
						
							|  |  |  |     {Py_tp_call, VectorCallClass_tpcall}, | 
					
						
							|  |  |  |     {Py_tp_members, VectorCallClass_members}, | 
					
						
							|  |  |  |     {Py_tp_methods, VectorCallClass_methods}, | 
					
						
							|  |  |  |     {0}, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | _testcapi.make_vectorcall_class | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     base: object(subclass_of="&PyType_Type", type="PyTypeObject *") = NULL | 
					
						
							|  |  |  |     / | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Create a class whose instances return "tpcall" when called. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | When the "set_vectorcall" method is called on an instance, a vectorcall | 
					
						
							|  |  |  | function that returns "vectorcall" will be installed. | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | _testcapi_make_vectorcall_class_impl(PyObject *module, PyTypeObject *base) | 
					
						
							|  |  |  | /*[clinic end generated code: output=16dcfc3062ddf968 input=f72e01ccf52de2b4]*/ | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!base) { | 
					
						
							|  |  |  |         base = (PyTypeObject *)&PyBaseObject_Type; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     VectorCallClass_members[0].offset = base->tp_basicsize; | 
					
						
							|  |  |  |     PyType_Spec spec = { | 
					
						
							|  |  |  |         .name = "_testcapi.VectorcallClass", | 
					
						
							| 
									
										
										
										
											2022-08-08 10:58:29 +02:00
										 |  |  |         .basicsize = (int)(base->tp_basicsize + sizeof(vectorcallfunc)), | 
					
						
							| 
									
										
										
										
											2022-08-04 17:19:29 +02:00
										 |  |  |         .flags = Py_TPFLAGS_DEFAULT | 
					
						
							|  |  |  |             | Py_TPFLAGS_HAVE_VECTORCALL | 
					
						
							|  |  |  |             | Py_TPFLAGS_BASETYPE, | 
					
						
							|  |  |  |         .slots = VectorCallClass_slots, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return PyType_FromSpecWithBases(&spec, (PyObject *)base); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | _testcapi.has_vectorcall_flag -> bool | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     type: object(subclass_of="&PyType_Type", type="PyTypeObject *") | 
					
						
							|  |  |  |     / | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Return true iff Py_TPFLAGS_HAVE_VECTORCALL is set on the class. | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | _testcapi_has_vectorcall_flag_impl(PyObject *module, PyTypeObject *type) | 
					
						
							|  |  |  | /*[clinic end generated code: output=3ae8d1374388c671 input=8eee492ac548749e]*/ | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return PyType_HasFeature(type, Py_TPFLAGS_HAVE_VECTORCALL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-08 17:56:26 +02:00
										 |  |  | static PyMethodDef TestMethods[] = { | 
					
						
							| 
									
										
										
										
											2023-07-09 12:08:18 +00:00
										 |  |  |     _TESTCAPI_PYOBJECT_FASTCALLDICT_METHODDEF | 
					
						
							|  |  |  |     _TESTCAPI_PYOBJECT_VECTORCALL_METHODDEF | 
					
						
							| 
									
										
										
										
											2022-09-15 08:42:37 -07:00
										 |  |  |     {"function_setvectorcall", function_setvectorcall, METH_O}, | 
					
						
							| 
									
										
										
										
											2023-07-09 12:08:18 +00:00
										 |  |  |     _TESTCAPI_PYVECTORCALL_CALL_METHODDEF | 
					
						
							| 
									
										
										
										
											2022-08-04 17:19:29 +02:00
										 |  |  |     _TESTCAPI_MAKE_VECTORCALL_CLASS_METHODDEF | 
					
						
							|  |  |  |     _TESTCAPI_HAS_VECTORCALL_FLAG_METHODDEF | 
					
						
							| 
									
										
										
										
											2022-07-08 17:56:26 +02:00
										 |  |  |     {NULL}, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  |     PyObject_HEAD | 
					
						
							|  |  |  |     vectorcallfunc vectorcall; | 
					
						
							|  |  |  | } MethodDescriptorObject; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | MethodDescriptor_vectorcall(PyObject *callable, PyObject *const *args, | 
					
						
							|  |  |  |                             size_t nargsf, PyObject *kwnames) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /* True if using the vectorcall function in MethodDescriptorObject
 | 
					
						
							|  |  |  |      * but False for MethodDescriptor2Object */ | 
					
						
							|  |  |  |     MethodDescriptorObject *md = (MethodDescriptorObject *)callable; | 
					
						
							|  |  |  |     return PyBool_FromLong(md->vectorcall != NULL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | MethodDescriptor_new(PyTypeObject* type, PyObject* args, PyObject *kw) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     MethodDescriptorObject *op = (MethodDescriptorObject *)type->tp_alloc(type, 0); | 
					
						
							|  |  |  |     op->vectorcall = MethodDescriptor_vectorcall; | 
					
						
							|  |  |  |     return (PyObject *)op; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | func_descr_get(PyObject *func, PyObject *obj, PyObject *type) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (obj == Py_None || obj == NULL) { | 
					
						
							| 
									
										
										
										
											2022-11-13 16:04:33 +01:00
										 |  |  |         return Py_NewRef(func); | 
					
						
							| 
									
										
										
										
											2022-07-08 17:56:26 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     return PyMethod_New(func, obj); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | nop_descr_get(PyObject *func, PyObject *obj, PyObject *type) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-11-13 16:04:33 +01:00
										 |  |  |     return Py_NewRef(func); | 
					
						
							| 
									
										
										
										
											2022-07-08 17:56:26 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | call_return_args(PyObject *self, PyObject *args, PyObject *kwargs) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-11-13 16:04:33 +01:00
										 |  |  |     return Py_NewRef(args); | 
					
						
							| 
									
										
										
										
											2022-07-08 17:56:26 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyTypeObject MethodDescriptorBase_Type = { | 
					
						
							|  |  |  |     PyVarObject_HEAD_INIT(NULL, 0) | 
					
						
							|  |  |  |     "MethodDescriptorBase", | 
					
						
							|  |  |  |     sizeof(MethodDescriptorObject), | 
					
						
							|  |  |  |     .tp_new = MethodDescriptor_new, | 
					
						
							|  |  |  |     .tp_call = PyVectorcall_Call, | 
					
						
							|  |  |  |     .tp_vectorcall_offset = offsetof(MethodDescriptorObject, vectorcall), | 
					
						
							|  |  |  |     .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | | 
					
						
							|  |  |  |                 Py_TPFLAGS_METHOD_DESCRIPTOR | Py_TPFLAGS_HAVE_VECTORCALL, | 
					
						
							|  |  |  |     .tp_descr_get = func_descr_get, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyTypeObject MethodDescriptorDerived_Type = { | 
					
						
							|  |  |  |     PyVarObject_HEAD_INIT(NULL, 0) | 
					
						
							|  |  |  |     "MethodDescriptorDerived", | 
					
						
							|  |  |  |     .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyTypeObject MethodDescriptorNopGet_Type = { | 
					
						
							|  |  |  |     PyVarObject_HEAD_INIT(NULL, 0) | 
					
						
							|  |  |  |     "MethodDescriptorNopGet", | 
					
						
							|  |  |  |     .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, | 
					
						
							|  |  |  |     .tp_call = call_return_args, | 
					
						
							|  |  |  |     .tp_descr_get = nop_descr_get, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  |     MethodDescriptorObject base; | 
					
						
							|  |  |  |     vectorcallfunc vectorcall; | 
					
						
							|  |  |  | } MethodDescriptor2Object; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | MethodDescriptor2_new(PyTypeObject* type, PyObject* args, PyObject *kw) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     MethodDescriptor2Object *op = PyObject_New(MethodDescriptor2Object, type); | 
					
						
							| 
									
										
										
										
											2024-07-16 11:29:33 +03:00
										 |  |  |     if (op == NULL) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-07-08 17:56:26 +02:00
										 |  |  |     op->base.vectorcall = NULL; | 
					
						
							|  |  |  |     op->vectorcall = MethodDescriptor_vectorcall; | 
					
						
							|  |  |  |     return (PyObject *)op; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyTypeObject MethodDescriptor2_Type = { | 
					
						
							|  |  |  |     PyVarObject_HEAD_INIT(NULL, 0) | 
					
						
							|  |  |  |     "MethodDescriptor2", | 
					
						
							|  |  |  |     sizeof(MethodDescriptor2Object), | 
					
						
							|  |  |  |     .tp_new = MethodDescriptor2_new, | 
					
						
							|  |  |  |     .tp_call = PyVectorcall_Call, | 
					
						
							|  |  |  |     .tp_vectorcall_offset = offsetof(MethodDescriptor2Object, vectorcall), | 
					
						
							|  |  |  |     .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_VECTORCALL, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | _PyTestCapi_Init_Vectorcall(PyObject *m) { | 
					
						
							|  |  |  |     if (PyModule_AddFunctions(m, TestMethods) < 0) { | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (PyType_Ready(&MethodDescriptorBase_Type) < 0) { | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (PyModule_AddType(m, &MethodDescriptorBase_Type) < 0) { | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     MethodDescriptorDerived_Type.tp_base = &MethodDescriptorBase_Type; | 
					
						
							|  |  |  |     if (PyType_Ready(&MethodDescriptorDerived_Type) < 0) { | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (PyModule_AddType(m, &MethodDescriptorDerived_Type) < 0) { | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     MethodDescriptorNopGet_Type.tp_base = &MethodDescriptorBase_Type; | 
					
						
							|  |  |  |     if (PyType_Ready(&MethodDescriptorNopGet_Type) < 0) { | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (PyModule_AddType(m, &MethodDescriptorNopGet_Type) < 0) { | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     MethodDescriptor2_Type.tp_base = &MethodDescriptorBase_Type; | 
					
						
							|  |  |  |     if (PyType_Ready(&MethodDescriptor2_Type) < 0) { | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (PyModule_AddType(m, &MethodDescriptor2_Type) < 0) { | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } |