mirror of
https://github.com/python/cpython.git
synced 2025-08-30 21:48:47 +00:00
gh-132097: allow AC to disable fastcall convention to avoid UBSan failures (#131605)
This commit is contained in:
parent
ea23c897cd
commit
50e518e886
5 changed files with 252 additions and 140 deletions
|
@ -1443,25 +1443,69 @@ _testclinic_TestClass_defclass_posonly_varpos_impl(PyObject *self,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* # Do NOT use __new__ to generate this method. Compare:
|
||||
*
|
||||
* [1] With __new__ (METH_KEYWORDS must be added even if we don't want to)
|
||||
*
|
||||
* varpos_no_fastcall(PyTypeObject *type, PyObject *args, PyObject *kwargs)
|
||||
* varpos_no_fastcall_impl(PyTypeObject *type, PyObject *args)
|
||||
* no auto-generated METHODDEF macro
|
||||
*
|
||||
* [2] Without __new__ (automatically METH_FASTCALL, not good for this test)
|
||||
*
|
||||
* varpos_no_fastcall_impl(PyObject *type, PyObject *args)
|
||||
* varpos_no_fastcall(PyObject *type, PyObject *const *args, Py_ssize_t nargs)
|
||||
* flags = METH_FASTCALL|METH_CLASS
|
||||
*
|
||||
* [3] Without __new__ + "@disable fastcall" (what we want)
|
||||
*
|
||||
* varpos_no_fastcall(PyObject *type, PyObject *args)
|
||||
* varpos_no_fastcall_impl(PyTypeObject *type, PyObject *args)
|
||||
* flags = METH_VARARGS|METH_CLASS
|
||||
*
|
||||
* We want to test a non-fastcall class method but without triggering an
|
||||
* undefined behaviour at runtime in cfunction_call().
|
||||
*
|
||||
* At runtime, a METH_VARARGS method called in cfunction_call() must be:
|
||||
*
|
||||
* (PyObject *, PyObject *) -> PyObject *
|
||||
* (PyObject *, PyObject *, PyObject *) -> PyObject *
|
||||
*
|
||||
* depending on whether METH_KEYWORDS is present or not.
|
||||
*
|
||||
* AC determines whether a method is a __new__-like method solely bsaed
|
||||
* on the method name, and not on its usage or its c_basename, and those
|
||||
* methods must always be used with METH_VARARGS|METH_KEYWORDS|METH_CLASS.
|
||||
*
|
||||
* In particular, using [1] forces us to add METH_KEYWORDS even though
|
||||
* the test shouldn't be expecting keyword arguments. Using [2] is also
|
||||
* not possible since we want to test non-fastcalls. This is the reason
|
||||
* why we need to be able to disable the METH_FASTCALL flag.
|
||||
*/
|
||||
|
||||
/*[clinic input]
|
||||
@disable fastcall
|
||||
@classmethod
|
||||
_testclinic.TestClass.__new__ as varpos_no_fastcall
|
||||
_testclinic.TestClass.varpos_no_fastcall
|
||||
|
||||
*args: tuple
|
||||
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
varpos_no_fastcall_impl(PyTypeObject *type, PyObject *args)
|
||||
/*[clinic end generated code: output=04e94f2898bb2dde input=c5d3d30a6589f97f]*/
|
||||
_testclinic_TestClass_varpos_no_fastcall_impl(PyTypeObject *type,
|
||||
PyObject *args)
|
||||
/*[clinic end generated code: output=edfacec733aeb9c5 input=3f298d143aa98048]*/
|
||||
{
|
||||
return Py_NewRef(args);
|
||||
}
|
||||
|
||||
|
||||
/*[clinic input]
|
||||
@disable fastcall
|
||||
@classmethod
|
||||
_testclinic.TestClass.__new__ as posonly_varpos_no_fastcall
|
||||
_testclinic.TestClass.posonly_varpos_no_fastcall
|
||||
|
||||
a: object
|
||||
b: object
|
||||
|
@ -1471,17 +1515,20 @@ _testclinic.TestClass.__new__ as posonly_varpos_no_fastcall
|
|||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
posonly_varpos_no_fastcall_impl(PyTypeObject *type, PyObject *a, PyObject *b,
|
||||
PyObject *args)
|
||||
/*[clinic end generated code: output=b0a0425719f69f5a input=10f29f2c2c6bfdc4]*/
|
||||
_testclinic_TestClass_posonly_varpos_no_fastcall_impl(PyTypeObject *type,
|
||||
PyObject *a,
|
||||
PyObject *b,
|
||||
PyObject *args)
|
||||
/*[clinic end generated code: output=2c5184aebe020085 input=3621dd172c5193d8]*/
|
||||
{
|
||||
return pack_arguments_newref(3, a, b, args);
|
||||
}
|
||||
|
||||
|
||||
/*[clinic input]
|
||||
@disable fastcall
|
||||
@classmethod
|
||||
_testclinic.TestClass.__new__ as posonly_req_opt_varpos_no_fastcall
|
||||
_testclinic.TestClass.posonly_req_opt_varpos_no_fastcall
|
||||
|
||||
a: object
|
||||
b: object = False
|
||||
|
@ -1491,17 +1538,20 @@ _testclinic.TestClass.__new__ as posonly_req_opt_varpos_no_fastcall
|
|||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
posonly_req_opt_varpos_no_fastcall_impl(PyTypeObject *type, PyObject *a,
|
||||
PyObject *b, PyObject *args)
|
||||
/*[clinic end generated code: output=3c44915b1a554e2d input=d319302a8748147c]*/
|
||||
_testclinic_TestClass_posonly_req_opt_varpos_no_fastcall_impl(PyTypeObject *type,
|
||||
PyObject *a,
|
||||
PyObject *b,
|
||||
PyObject *args)
|
||||
/*[clinic end generated code: output=08e533d59bceadf6 input=922fa7851b32e2dd]*/
|
||||
{
|
||||
return pack_arguments_newref(3, a, b, args);
|
||||
}
|
||||
|
||||
|
||||
/*[clinic input]
|
||||
@disable fastcall
|
||||
@classmethod
|
||||
_testclinic.TestClass.__new__ as posonly_poskw_varpos_no_fastcall
|
||||
_testclinic.TestClass.posonly_poskw_varpos_no_fastcall
|
||||
|
||||
a: object
|
||||
/
|
||||
|
@ -1511,34 +1561,39 @@ _testclinic.TestClass.__new__ as posonly_poskw_varpos_no_fastcall
|
|||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
posonly_poskw_varpos_no_fastcall_impl(PyTypeObject *type, PyObject *a,
|
||||
PyObject *b, PyObject *args)
|
||||
/*[clinic end generated code: output=6ad74bed4bdc7f96 input=1f8c113e749414a3]*/
|
||||
_testclinic_TestClass_posonly_poskw_varpos_no_fastcall_impl(PyTypeObject *type,
|
||||
PyObject *a,
|
||||
PyObject *b,
|
||||
PyObject *args)
|
||||
/*[clinic end generated code: output=8ecfda20850e689f input=60443fe0bb8fe3e0]*/
|
||||
{
|
||||
return pack_arguments_newref(3, a, b, args);
|
||||
}
|
||||
|
||||
|
||||
/*[clinic input]
|
||||
@disable fastcall
|
||||
@classmethod
|
||||
_testclinic.TestClass.__new__ as varpos_array_no_fastcall
|
||||
_testclinic.TestClass.varpos_array_no_fastcall
|
||||
|
||||
*args: array
|
||||
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
varpos_array_no_fastcall_impl(PyTypeObject *type, PyObject * const *args,
|
||||
Py_ssize_t args_length)
|
||||
/*[clinic end generated code: output=f99d984346c60d42 input=368d8eea6de48c12]*/
|
||||
_testclinic_TestClass_varpos_array_no_fastcall_impl(PyTypeObject *type,
|
||||
PyObject * const *args,
|
||||
Py_ssize_t args_length)
|
||||
/*[clinic end generated code: output=27c9da663e942617 input=9ba5ae1f1eb58777]*/
|
||||
{
|
||||
return _PyTuple_FromArray(args, args_length);
|
||||
}
|
||||
|
||||
|
||||
/*[clinic input]
|
||||
@disable fastcall
|
||||
@classmethod
|
||||
_testclinic.TestClass.__new__ as posonly_varpos_array_no_fastcall
|
||||
_testclinic.TestClass.posonly_varpos_array_no_fastcall
|
||||
|
||||
a: object
|
||||
b: object
|
||||
|
@ -1548,18 +1603,21 @@ _testclinic.TestClass.__new__ as posonly_varpos_array_no_fastcall
|
|||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
posonly_varpos_array_no_fastcall_impl(PyTypeObject *type, PyObject *a,
|
||||
PyObject *b, PyObject * const *args,
|
||||
Py_ssize_t args_length)
|
||||
/*[clinic end generated code: output=1eec4da1fb5b5978 input=7330c8d819a23548]*/
|
||||
_testclinic_TestClass_posonly_varpos_array_no_fastcall_impl(PyTypeObject *type,
|
||||
PyObject *a,
|
||||
PyObject *b,
|
||||
PyObject * const *args,
|
||||
Py_ssize_t args_length)
|
||||
/*[clinic end generated code: output=71e676f1870b5a7e input=18eadf4c6eaab613]*/
|
||||
{
|
||||
return pack_arguments_2pos_varpos(a, b, args, args_length);
|
||||
}
|
||||
|
||||
|
||||
/*[clinic input]
|
||||
@disable fastcall
|
||||
@classmethod
|
||||
_testclinic.TestClass.__new__ as posonly_req_opt_varpos_array_no_fastcall
|
||||
_testclinic.TestClass.posonly_req_opt_varpos_array_no_fastcall
|
||||
|
||||
a: object
|
||||
b: object = False
|
||||
|
@ -1569,19 +1627,21 @@ _testclinic.TestClass.__new__ as posonly_req_opt_varpos_array_no_fastcall
|
|||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
posonly_req_opt_varpos_array_no_fastcall_impl(PyTypeObject *type,
|
||||
PyObject *a, PyObject *b,
|
||||
PyObject * const *args,
|
||||
Py_ssize_t args_length)
|
||||
/*[clinic end generated code: output=88041c2176135218 input=7f5fd34ee5f9e0bf]*/
|
||||
_testclinic_TestClass_posonly_req_opt_varpos_array_no_fastcall_impl(PyTypeObject *type,
|
||||
PyObject *a,
|
||||
PyObject *b,
|
||||
PyObject * const *args,
|
||||
Py_ssize_t args_length)
|
||||
/*[clinic end generated code: output=abb395cae91d48ac input=5bf791fdad70b480]*/
|
||||
{
|
||||
return pack_arguments_2pos_varpos(a, b, args, args_length);
|
||||
}
|
||||
|
||||
|
||||
/*[clinic input]
|
||||
@disable fastcall
|
||||
@classmethod
|
||||
_testclinic.TestClass.__new__ as posonly_poskw_varpos_array_no_fastcall
|
||||
_testclinic.TestClass.posonly_poskw_varpos_array_no_fastcall
|
||||
|
||||
a: object
|
||||
/
|
||||
|
@ -1591,11 +1651,12 @@ _testclinic.TestClass.__new__ as posonly_poskw_varpos_array_no_fastcall
|
|||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
posonly_poskw_varpos_array_no_fastcall_impl(PyTypeObject *type, PyObject *a,
|
||||
PyObject *b,
|
||||
PyObject * const *args,
|
||||
Py_ssize_t args_length)
|
||||
/*[clinic end generated code: output=70eda18c3667681e input=2b0fcd7bd9bb865c]*/
|
||||
_testclinic_TestClass_posonly_poskw_varpos_array_no_fastcall_impl(PyTypeObject *type,
|
||||
PyObject *a,
|
||||
PyObject *b,
|
||||
PyObject * const *args,
|
||||
Py_ssize_t args_length)
|
||||
/*[clinic end generated code: output=aaddd9530048b229 input=9ed3842f4d472d45]*/
|
||||
{
|
||||
return pack_arguments_2pos_varpos(a, b, args, args_length);
|
||||
}
|
||||
|
@ -1606,27 +1667,15 @@ static struct PyMethodDef test_class_methods[] = {
|
|||
_TESTCLINIC_TESTCLASS_DEFCLASS_VARPOS_METHODDEF
|
||||
_TESTCLINIC_TESTCLASS_DEFCLASS_POSONLY_VARPOS_METHODDEF
|
||||
|
||||
{"varpos_no_fastcall", _PyCFunction_CAST(varpos_no_fastcall),
|
||||
METH_VARARGS|METH_KEYWORDS|METH_CLASS, ""},
|
||||
{"posonly_varpos_no_fastcall", _PyCFunction_CAST(posonly_varpos_no_fastcall),
|
||||
METH_VARARGS|METH_KEYWORDS|METH_CLASS, ""},
|
||||
{"posonly_req_opt_varpos_no_fastcall", _PyCFunction_CAST(posonly_req_opt_varpos_no_fastcall),
|
||||
METH_VARARGS|METH_KEYWORDS|METH_CLASS, ""},
|
||||
{"posonly_poskw_varpos_no_fastcall", _PyCFunction_CAST(posonly_poskw_varpos_no_fastcall),
|
||||
METH_VARARGS|METH_KEYWORDS|METH_CLASS, ""},
|
||||
_TESTCLINIC_TESTCLASS_VARPOS_NO_FASTCALL_METHODDEF
|
||||
_TESTCLINIC_TESTCLASS_POSONLY_VARPOS_NO_FASTCALL_METHODDEF
|
||||
_TESTCLINIC_TESTCLASS_POSONLY_REQ_OPT_VARPOS_NO_FASTCALL_METHODDEF
|
||||
_TESTCLINIC_TESTCLASS_POSONLY_POSKW_VARPOS_NO_FASTCALL_METHODDEF
|
||||
|
||||
{"varpos_array_no_fastcall",
|
||||
_PyCFunction_CAST(varpos_array_no_fastcall),
|
||||
METH_VARARGS|METH_KEYWORDS|METH_CLASS, ""},
|
||||
{"posonly_varpos_array_no_fastcall",
|
||||
_PyCFunction_CAST(posonly_varpos_array_no_fastcall),
|
||||
METH_VARARGS|METH_KEYWORDS|METH_CLASS, ""},
|
||||
{"posonly_req_opt_varpos_array_no_fastcall",
|
||||
_PyCFunction_CAST(posonly_req_opt_varpos_array_no_fastcall),
|
||||
METH_VARARGS|METH_KEYWORDS|METH_CLASS, ""},
|
||||
{"posonly_poskw_varpos_array_no_fastcall",
|
||||
_PyCFunction_CAST(posonly_poskw_varpos_array_no_fastcall),
|
||||
METH_VARARGS|METH_KEYWORDS|METH_CLASS, ""},
|
||||
_TESTCLINIC_TESTCLASS_VARPOS_ARRAY_NO_FASTCALL_METHODDEF
|
||||
_TESTCLINIC_TESTCLASS_POSONLY_VARPOS_ARRAY_NO_FASTCALL_METHODDEF
|
||||
_TESTCLINIC_TESTCLASS_POSONLY_REQ_OPT_VARPOS_ARRAY_NO_FASTCALL_METHODDEF
|
||||
_TESTCLINIC_TESTCLASS_POSONLY_POSKW_VARPOS_ARRAY_NO_FASTCALL_METHODDEF
|
||||
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
|
210
Modules/clinic/_testclinic.c.h
generated
210
Modules/clinic/_testclinic.c.h
generated
|
@ -4067,48 +4067,56 @@ exit:
|
|||
return return_value;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
varpos_no_fastcall_impl(PyTypeObject *type, PyObject *args);
|
||||
PyDoc_STRVAR(_testclinic_TestClass_varpos_no_fastcall__doc__,
|
||||
"varpos_no_fastcall($type, /, *args)\n"
|
||||
"--\n"
|
||||
"\n");
|
||||
|
||||
#define _TESTCLINIC_TESTCLASS_VARPOS_NO_FASTCALL_METHODDEF \
|
||||
{"varpos_no_fastcall", (PyCFunction)_testclinic_TestClass_varpos_no_fastcall, METH_VARARGS|METH_CLASS, _testclinic_TestClass_varpos_no_fastcall__doc__},
|
||||
|
||||
static PyObject *
|
||||
varpos_no_fastcall(PyTypeObject *type, PyObject *args, PyObject *kwargs)
|
||||
_testclinic_TestClass_varpos_no_fastcall_impl(PyTypeObject *type,
|
||||
PyObject *args);
|
||||
|
||||
static PyObject *
|
||||
_testclinic_TestClass_varpos_no_fastcall(PyObject *type, PyObject *args)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
PyTypeObject *base_tp = &PyBaseObject_Type;
|
||||
PyObject *__clinic_args = NULL;
|
||||
|
||||
if ((type == base_tp || type->tp_init == base_tp->tp_init) &&
|
||||
!_PyArg_NoKeywords("TestClass", kwargs)) {
|
||||
goto exit;
|
||||
}
|
||||
__clinic_args = Py_NewRef(args);
|
||||
return_value = varpos_no_fastcall_impl(type, __clinic_args);
|
||||
return_value = _testclinic_TestClass_varpos_no_fastcall_impl((PyTypeObject *)type, __clinic_args);
|
||||
|
||||
exit:
|
||||
/* Cleanup for args */
|
||||
Py_XDECREF(__clinic_args);
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
posonly_varpos_no_fastcall_impl(PyTypeObject *type, PyObject *a, PyObject *b,
|
||||
PyObject *args);
|
||||
PyDoc_STRVAR(_testclinic_TestClass_posonly_varpos_no_fastcall__doc__,
|
||||
"posonly_varpos_no_fastcall($type, a, b, /, *args)\n"
|
||||
"--\n"
|
||||
"\n");
|
||||
|
||||
#define _TESTCLINIC_TESTCLASS_POSONLY_VARPOS_NO_FASTCALL_METHODDEF \
|
||||
{"posonly_varpos_no_fastcall", (PyCFunction)_testclinic_TestClass_posonly_varpos_no_fastcall, METH_VARARGS|METH_CLASS, _testclinic_TestClass_posonly_varpos_no_fastcall__doc__},
|
||||
|
||||
static PyObject *
|
||||
posonly_varpos_no_fastcall(PyTypeObject *type, PyObject *args, PyObject *kwargs)
|
||||
_testclinic_TestClass_posonly_varpos_no_fastcall_impl(PyTypeObject *type,
|
||||
PyObject *a,
|
||||
PyObject *b,
|
||||
PyObject *args);
|
||||
|
||||
static PyObject *
|
||||
_testclinic_TestClass_posonly_varpos_no_fastcall(PyObject *type, PyObject *args)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
PyTypeObject *base_tp = &PyBaseObject_Type;
|
||||
PyObject *a;
|
||||
PyObject *b;
|
||||
PyObject *__clinic_args = NULL;
|
||||
|
||||
if ((type == base_tp || type->tp_init == base_tp->tp_init) &&
|
||||
!_PyArg_NoKeywords("TestClass", kwargs)) {
|
||||
goto exit;
|
||||
}
|
||||
if (!_PyArg_CheckPositional("TestClass", PyTuple_GET_SIZE(args), 2, PY_SSIZE_T_MAX)) {
|
||||
if (!_PyArg_CheckPositional("posonly_varpos_no_fastcall", PyTuple_GET_SIZE(args), 2, PY_SSIZE_T_MAX)) {
|
||||
goto exit;
|
||||
}
|
||||
a = PyTuple_GET_ITEM(args, 0);
|
||||
|
@ -4117,7 +4125,7 @@ posonly_varpos_no_fastcall(PyTypeObject *type, PyObject *args, PyObject *kwargs)
|
|||
if (!__clinic_args) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = posonly_varpos_no_fastcall_impl(type, a, b, __clinic_args);
|
||||
return_value = _testclinic_TestClass_posonly_varpos_no_fastcall_impl((PyTypeObject *)type, a, b, __clinic_args);
|
||||
|
||||
exit:
|
||||
/* Cleanup for args */
|
||||
|
@ -4126,24 +4134,29 @@ exit:
|
|||
return return_value;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
posonly_req_opt_varpos_no_fastcall_impl(PyTypeObject *type, PyObject *a,
|
||||
PyObject *b, PyObject *args);
|
||||
PyDoc_STRVAR(_testclinic_TestClass_posonly_req_opt_varpos_no_fastcall__doc__,
|
||||
"posonly_req_opt_varpos_no_fastcall($type, a, b=False, /, *args)\n"
|
||||
"--\n"
|
||||
"\n");
|
||||
|
||||
#define _TESTCLINIC_TESTCLASS_POSONLY_REQ_OPT_VARPOS_NO_FASTCALL_METHODDEF \
|
||||
{"posonly_req_opt_varpos_no_fastcall", (PyCFunction)_testclinic_TestClass_posonly_req_opt_varpos_no_fastcall, METH_VARARGS|METH_CLASS, _testclinic_TestClass_posonly_req_opt_varpos_no_fastcall__doc__},
|
||||
|
||||
static PyObject *
|
||||
posonly_req_opt_varpos_no_fastcall(PyTypeObject *type, PyObject *args, PyObject *kwargs)
|
||||
_testclinic_TestClass_posonly_req_opt_varpos_no_fastcall_impl(PyTypeObject *type,
|
||||
PyObject *a,
|
||||
PyObject *b,
|
||||
PyObject *args);
|
||||
|
||||
static PyObject *
|
||||
_testclinic_TestClass_posonly_req_opt_varpos_no_fastcall(PyObject *type, PyObject *args)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
PyTypeObject *base_tp = &PyBaseObject_Type;
|
||||
PyObject *a;
|
||||
PyObject *b = Py_False;
|
||||
PyObject *__clinic_args = NULL;
|
||||
|
||||
if ((type == base_tp || type->tp_init == base_tp->tp_init) &&
|
||||
!_PyArg_NoKeywords("TestClass", kwargs)) {
|
||||
goto exit;
|
||||
}
|
||||
if (!_PyArg_CheckPositional("TestClass", PyTuple_GET_SIZE(args), 1, PY_SSIZE_T_MAX)) {
|
||||
if (!_PyArg_CheckPositional("posonly_req_opt_varpos_no_fastcall", PyTuple_GET_SIZE(args), 1, PY_SSIZE_T_MAX)) {
|
||||
goto exit;
|
||||
}
|
||||
a = PyTuple_GET_ITEM(args, 0);
|
||||
|
@ -4156,7 +4169,7 @@ skip_optional:
|
|||
if (!__clinic_args) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = posonly_req_opt_varpos_no_fastcall_impl(type, a, b, __clinic_args);
|
||||
return_value = _testclinic_TestClass_posonly_req_opt_varpos_no_fastcall_impl((PyTypeObject *)type, a, b, __clinic_args);
|
||||
|
||||
exit:
|
||||
/* Cleanup for args */
|
||||
|
@ -4165,12 +4178,22 @@ exit:
|
|||
return return_value;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
posonly_poskw_varpos_no_fastcall_impl(PyTypeObject *type, PyObject *a,
|
||||
PyObject *b, PyObject *args);
|
||||
PyDoc_STRVAR(_testclinic_TestClass_posonly_poskw_varpos_no_fastcall__doc__,
|
||||
"posonly_poskw_varpos_no_fastcall($type, a, /, b, *args)\n"
|
||||
"--\n"
|
||||
"\n");
|
||||
|
||||
#define _TESTCLINIC_TESTCLASS_POSONLY_POSKW_VARPOS_NO_FASTCALL_METHODDEF \
|
||||
{"posonly_poskw_varpos_no_fastcall", _PyCFunction_CAST(_testclinic_TestClass_posonly_poskw_varpos_no_fastcall), METH_VARARGS|METH_KEYWORDS|METH_CLASS, _testclinic_TestClass_posonly_poskw_varpos_no_fastcall__doc__},
|
||||
|
||||
static PyObject *
|
||||
posonly_poskw_varpos_no_fastcall(PyTypeObject *type, PyObject *args, PyObject *kwargs)
|
||||
_testclinic_TestClass_posonly_poskw_varpos_no_fastcall_impl(PyTypeObject *type,
|
||||
PyObject *a,
|
||||
PyObject *b,
|
||||
PyObject *args);
|
||||
|
||||
static PyObject *
|
||||
_testclinic_TestClass_posonly_poskw_varpos_no_fastcall(PyObject *type, PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
|
||||
|
@ -4196,7 +4219,7 @@ posonly_poskw_varpos_no_fastcall(PyTypeObject *type, PyObject *args, PyObject *k
|
|||
static const char * const _keywords[] = {"", "b", NULL};
|
||||
static _PyArg_Parser _parser = {
|
||||
.keywords = _keywords,
|
||||
.fname = "TestClass",
|
||||
.fname = "posonly_poskw_varpos_no_fastcall",
|
||||
.kwtuple = KWTUPLE,
|
||||
};
|
||||
#undef KWTUPLE
|
||||
|
@ -4218,7 +4241,7 @@ posonly_poskw_varpos_no_fastcall(PyTypeObject *type, PyObject *args, PyObject *k
|
|||
if (!__clinic_args) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = posonly_poskw_varpos_no_fastcall_impl(type, a, b, __clinic_args);
|
||||
return_value = _testclinic_TestClass_posonly_poskw_varpos_no_fastcall_impl((PyTypeObject *)type, a, b, __clinic_args);
|
||||
|
||||
exit:
|
||||
/* Cleanup for args */
|
||||
|
@ -4227,83 +4250,95 @@ exit:
|
|||
return return_value;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
varpos_array_no_fastcall_impl(PyTypeObject *type, PyObject * const *args,
|
||||
Py_ssize_t args_length);
|
||||
PyDoc_STRVAR(_testclinic_TestClass_varpos_array_no_fastcall__doc__,
|
||||
"varpos_array_no_fastcall($type, /, *args)\n"
|
||||
"--\n"
|
||||
"\n");
|
||||
|
||||
#define _TESTCLINIC_TESTCLASS_VARPOS_ARRAY_NO_FASTCALL_METHODDEF \
|
||||
{"varpos_array_no_fastcall", (PyCFunction)_testclinic_TestClass_varpos_array_no_fastcall, METH_VARARGS|METH_CLASS, _testclinic_TestClass_varpos_array_no_fastcall__doc__},
|
||||
|
||||
static PyObject *
|
||||
varpos_array_no_fastcall(PyTypeObject *type, PyObject *args, PyObject *kwargs)
|
||||
_testclinic_TestClass_varpos_array_no_fastcall_impl(PyTypeObject *type,
|
||||
PyObject * const *args,
|
||||
Py_ssize_t args_length);
|
||||
|
||||
static PyObject *
|
||||
_testclinic_TestClass_varpos_array_no_fastcall(PyObject *type, PyObject *args)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
PyTypeObject *base_tp = &PyBaseObject_Type;
|
||||
PyObject * const *__clinic_args;
|
||||
Py_ssize_t args_length;
|
||||
|
||||
if ((type == base_tp || type->tp_init == base_tp->tp_init) &&
|
||||
!_PyArg_NoKeywords("TestClass", kwargs)) {
|
||||
goto exit;
|
||||
}
|
||||
__clinic_args = _PyTuple_ITEMS(args);
|
||||
args_length = PyTuple_GET_SIZE(args);
|
||||
return_value = varpos_array_no_fastcall_impl(type, __clinic_args, args_length);
|
||||
return_value = _testclinic_TestClass_varpos_array_no_fastcall_impl((PyTypeObject *)type, __clinic_args, args_length);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
posonly_varpos_array_no_fastcall_impl(PyTypeObject *type, PyObject *a,
|
||||
PyObject *b, PyObject * const *args,
|
||||
Py_ssize_t args_length);
|
||||
PyDoc_STRVAR(_testclinic_TestClass_posonly_varpos_array_no_fastcall__doc__,
|
||||
"posonly_varpos_array_no_fastcall($type, a, b, /, *args)\n"
|
||||
"--\n"
|
||||
"\n");
|
||||
|
||||
#define _TESTCLINIC_TESTCLASS_POSONLY_VARPOS_ARRAY_NO_FASTCALL_METHODDEF \
|
||||
{"posonly_varpos_array_no_fastcall", (PyCFunction)_testclinic_TestClass_posonly_varpos_array_no_fastcall, METH_VARARGS|METH_CLASS, _testclinic_TestClass_posonly_varpos_array_no_fastcall__doc__},
|
||||
|
||||
static PyObject *
|
||||
posonly_varpos_array_no_fastcall(PyTypeObject *type, PyObject *args, PyObject *kwargs)
|
||||
_testclinic_TestClass_posonly_varpos_array_no_fastcall_impl(PyTypeObject *type,
|
||||
PyObject *a,
|
||||
PyObject *b,
|
||||
PyObject * const *args,
|
||||
Py_ssize_t args_length);
|
||||
|
||||
static PyObject *
|
||||
_testclinic_TestClass_posonly_varpos_array_no_fastcall(PyObject *type, PyObject *args)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
PyTypeObject *base_tp = &PyBaseObject_Type;
|
||||
PyObject *a;
|
||||
PyObject *b;
|
||||
PyObject * const *__clinic_args;
|
||||
Py_ssize_t args_length;
|
||||
|
||||
if ((type == base_tp || type->tp_init == base_tp->tp_init) &&
|
||||
!_PyArg_NoKeywords("TestClass", kwargs)) {
|
||||
goto exit;
|
||||
}
|
||||
if (!_PyArg_CheckPositional("TestClass", PyTuple_GET_SIZE(args), 2, PY_SSIZE_T_MAX)) {
|
||||
if (!_PyArg_CheckPositional("posonly_varpos_array_no_fastcall", PyTuple_GET_SIZE(args), 2, PY_SSIZE_T_MAX)) {
|
||||
goto exit;
|
||||
}
|
||||
a = PyTuple_GET_ITEM(args, 0);
|
||||
b = PyTuple_GET_ITEM(args, 1);
|
||||
__clinic_args = _PyTuple_ITEMS(args) + 2;
|
||||
args_length = PyTuple_GET_SIZE(args) - 2;
|
||||
return_value = posonly_varpos_array_no_fastcall_impl(type, a, b, __clinic_args, args_length);
|
||||
return_value = _testclinic_TestClass_posonly_varpos_array_no_fastcall_impl((PyTypeObject *)type, a, b, __clinic_args, args_length);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
posonly_req_opt_varpos_array_no_fastcall_impl(PyTypeObject *type,
|
||||
PyObject *a, PyObject *b,
|
||||
PyObject * const *args,
|
||||
Py_ssize_t args_length);
|
||||
PyDoc_STRVAR(_testclinic_TestClass_posonly_req_opt_varpos_array_no_fastcall__doc__,
|
||||
"posonly_req_opt_varpos_array_no_fastcall($type, a, b=False, /, *args)\n"
|
||||
"--\n"
|
||||
"\n");
|
||||
|
||||
#define _TESTCLINIC_TESTCLASS_POSONLY_REQ_OPT_VARPOS_ARRAY_NO_FASTCALL_METHODDEF \
|
||||
{"posonly_req_opt_varpos_array_no_fastcall", (PyCFunction)_testclinic_TestClass_posonly_req_opt_varpos_array_no_fastcall, METH_VARARGS|METH_CLASS, _testclinic_TestClass_posonly_req_opt_varpos_array_no_fastcall__doc__},
|
||||
|
||||
static PyObject *
|
||||
posonly_req_opt_varpos_array_no_fastcall(PyTypeObject *type, PyObject *args, PyObject *kwargs)
|
||||
_testclinic_TestClass_posonly_req_opt_varpos_array_no_fastcall_impl(PyTypeObject *type,
|
||||
PyObject *a,
|
||||
PyObject *b,
|
||||
PyObject * const *args,
|
||||
Py_ssize_t args_length);
|
||||
|
||||
static PyObject *
|
||||
_testclinic_TestClass_posonly_req_opt_varpos_array_no_fastcall(PyObject *type, PyObject *args)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
PyTypeObject *base_tp = &PyBaseObject_Type;
|
||||
PyObject *a;
|
||||
PyObject *b = Py_False;
|
||||
PyObject * const *__clinic_args;
|
||||
Py_ssize_t args_length;
|
||||
|
||||
if ((type == base_tp || type->tp_init == base_tp->tp_init) &&
|
||||
!_PyArg_NoKeywords("TestClass", kwargs)) {
|
||||
goto exit;
|
||||
}
|
||||
if (!_PyArg_CheckPositional("TestClass", PyTuple_GET_SIZE(args), 1, PY_SSIZE_T_MAX)) {
|
||||
if (!_PyArg_CheckPositional("posonly_req_opt_varpos_array_no_fastcall", PyTuple_GET_SIZE(args), 1, PY_SSIZE_T_MAX)) {
|
||||
goto exit;
|
||||
}
|
||||
a = PyTuple_GET_ITEM(args, 0);
|
||||
|
@ -4314,20 +4349,29 @@ posonly_req_opt_varpos_array_no_fastcall(PyTypeObject *type, PyObject *args, PyO
|
|||
skip_optional:
|
||||
__clinic_args = PyTuple_GET_SIZE(args) > 2 ? _PyTuple_ITEMS(args) + 2 : _PyTuple_ITEMS(args);
|
||||
args_length = Py_MAX(0, PyTuple_GET_SIZE(args) - 2);
|
||||
return_value = posonly_req_opt_varpos_array_no_fastcall_impl(type, a, b, __clinic_args, args_length);
|
||||
return_value = _testclinic_TestClass_posonly_req_opt_varpos_array_no_fastcall_impl((PyTypeObject *)type, a, b, __clinic_args, args_length);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
posonly_poskw_varpos_array_no_fastcall_impl(PyTypeObject *type, PyObject *a,
|
||||
PyObject *b,
|
||||
PyObject * const *args,
|
||||
Py_ssize_t args_length);
|
||||
PyDoc_STRVAR(_testclinic_TestClass_posonly_poskw_varpos_array_no_fastcall__doc__,
|
||||
"posonly_poskw_varpos_array_no_fastcall($type, a, /, b, *args)\n"
|
||||
"--\n"
|
||||
"\n");
|
||||
|
||||
#define _TESTCLINIC_TESTCLASS_POSONLY_POSKW_VARPOS_ARRAY_NO_FASTCALL_METHODDEF \
|
||||
{"posonly_poskw_varpos_array_no_fastcall", _PyCFunction_CAST(_testclinic_TestClass_posonly_poskw_varpos_array_no_fastcall), METH_VARARGS|METH_KEYWORDS|METH_CLASS, _testclinic_TestClass_posonly_poskw_varpos_array_no_fastcall__doc__},
|
||||
|
||||
static PyObject *
|
||||
posonly_poskw_varpos_array_no_fastcall(PyTypeObject *type, PyObject *args, PyObject *kwargs)
|
||||
_testclinic_TestClass_posonly_poskw_varpos_array_no_fastcall_impl(PyTypeObject *type,
|
||||
PyObject *a,
|
||||
PyObject *b,
|
||||
PyObject * const *args,
|
||||
Py_ssize_t args_length);
|
||||
|
||||
static PyObject *
|
||||
_testclinic_TestClass_posonly_poskw_varpos_array_no_fastcall(PyObject *type, PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
|
||||
|
@ -4353,7 +4397,7 @@ posonly_poskw_varpos_array_no_fastcall(PyTypeObject *type, PyObject *args, PyObj
|
|||
static const char * const _keywords[] = {"", "b", NULL};
|
||||
static _PyArg_Parser _parser = {
|
||||
.keywords = _keywords,
|
||||
.fname = "TestClass",
|
||||
.fname = "posonly_poskw_varpos_array_no_fastcall",
|
||||
.kwtuple = KWTUPLE,
|
||||
};
|
||||
#undef KWTUPLE
|
||||
|
@ -4374,9 +4418,9 @@ posonly_poskw_varpos_array_no_fastcall(PyTypeObject *type, PyObject *args, PyObj
|
|||
b = fastargs[1];
|
||||
__clinic_args = PyTuple_GET_SIZE(args) > 2 ? _PyTuple_ITEMS(args) + 2 : _PyTuple_ITEMS(args);
|
||||
args_length = Py_MAX(0, PyTuple_GET_SIZE(args) - 2);
|
||||
return_value = posonly_poskw_varpos_array_no_fastcall_impl(type, a, b, __clinic_args, args_length);
|
||||
return_value = _testclinic_TestClass_posonly_poskw_varpos_array_no_fastcall_impl((PyTypeObject *)type, a, b, __clinic_args, args_length);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
/*[clinic end generated code: output=a3726ee0a94090d1 input=a9049054013a1b77]*/
|
||||
/*[clinic end generated code: output=ea0b8fb0949fa49f input=a9049054013a1b77]*/
|
||||
|
|
|
@ -260,6 +260,7 @@ class DSLParser:
|
|||
preserve_output: bool
|
||||
critical_section: bool
|
||||
target_critical_section: list[str]
|
||||
disable_fastcall: bool
|
||||
from_version_re = re.compile(r'([*/]) +\[from +(.+)\]')
|
||||
|
||||
def __init__(self, clinic: Clinic) -> None:
|
||||
|
@ -296,6 +297,7 @@ class DSLParser:
|
|||
self.preserve_output = False
|
||||
self.critical_section = False
|
||||
self.target_critical_section = []
|
||||
self.disable_fastcall = False
|
||||
|
||||
def directive_module(self, name: str) -> None:
|
||||
fields = name.split('.')[:-1]
|
||||
|
@ -423,6 +425,18 @@ class DSLParser:
|
|||
self.target_critical_section.extend(args)
|
||||
self.critical_section = True
|
||||
|
||||
def at_disable(self, *args: str) -> None:
|
||||
if self.kind is not CALLABLE:
|
||||
fail("Can't set @disable, function is not a normal callable")
|
||||
if not args:
|
||||
fail("@disable expects at least one argument")
|
||||
features = list(args)
|
||||
if 'fastcall' in features:
|
||||
features.remove('fastcall')
|
||||
self.disable_fastcall = True
|
||||
if features:
|
||||
fail("invalid argument for @disable:", features[0])
|
||||
|
||||
def at_getter(self) -> None:
|
||||
match self.kind:
|
||||
case FunctionKind.GETTER:
|
||||
|
@ -691,6 +705,7 @@ class DSLParser:
|
|||
kind=self.kind,
|
||||
coexist=self.coexist,
|
||||
critical_section=self.critical_section,
|
||||
disable_fastcall=self.disable_fastcall,
|
||||
target_critical_section=self.target_critical_section,
|
||||
forced_text_signature=self.forced_text_signature
|
||||
)
|
||||
|
|
|
@ -109,6 +109,7 @@ class Function:
|
|||
docstring_only: bool = False
|
||||
forced_text_signature: str | None = None
|
||||
critical_section: bool = False
|
||||
disable_fastcall: bool = False
|
||||
target_critical_section: list[str] = dc.field(default_factory=list)
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
|
|
|
@ -260,7 +260,10 @@ class ParseArgsCodeGen:
|
|||
if self.func.critical_section:
|
||||
self.codegen.add_include('pycore_critical_section.h',
|
||||
'Py_BEGIN_CRITICAL_SECTION()')
|
||||
self.fastcall = not self.is_new_or_init()
|
||||
if self.func.disable_fastcall:
|
||||
self.fastcall = False
|
||||
else:
|
||||
self.fastcall = not self.is_new_or_init()
|
||||
|
||||
self.pos_only = 0
|
||||
self.min_pos = 0
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue