mirror of
https://github.com/python/cpython.git
synced 2025-10-12 09:53:19 +00:00

* Remove '#include "structmember.h"'. * If needed, add <stddef.h> to get offsetof() function. * Update Parser/asdl_c.py to regenerate Python/Python-ast.c. * Replace: * T_SHORT => Py_T_SHORT * T_INT => Py_T_INT * T_LONG => Py_T_LONG * T_FLOAT => Py_T_FLOAT * T_DOUBLE => Py_T_DOUBLE * T_STRING => Py_T_STRING * T_OBJECT => _Py_T_OBJECT * T_CHAR => Py_T_CHAR * T_BYTE => Py_T_BYTE * T_UBYTE => Py_T_UBYTE * T_USHORT => Py_T_USHORT * T_UINT => Py_T_UINT * T_ULONG => Py_T_ULONG * T_STRING_INPLACE => Py_T_STRING_INPLACE * T_BOOL => Py_T_BOOL * T_OBJECT_EX => Py_T_OBJECT_EX * T_LONGLONG => Py_T_LONGLONG * T_ULONGLONG => Py_T_ULONGLONG * T_PYSSIZET => Py_T_PYSSIZET * T_NONE => _Py_T_NONE * READONLY => Py_READONLY * PY_AUDIT_READ => Py_AUDIT_READ * READ_RESTRICTED => Py_AUDIT_READ * PY_WRITE_RESTRICTED => _Py_WRITE_RESTRICTED * RESTRICTED => (READ_RESTRICTED | _Py_WRITE_RESTRICTED)
179 lines
4 KiB
C
179 lines
4 KiB
C
#define Py_LIMITED_API 0x030c0000 // 3.12
|
|
#include "parts.h"
|
|
|
|
#ifdef LIMITED_API_AVAILABLE
|
|
|
|
|
|
|
|
/* Test Vectorcall in the limited API */
|
|
|
|
static PyObject *
|
|
LimitedVectorCallClass_tpcall(PyObject *self, PyObject *args, PyObject *kwargs) {
|
|
return PyUnicode_FromString("tp_call called");
|
|
}
|
|
|
|
static PyObject *
|
|
LimitedVectorCallClass_vectorcall(PyObject *callable,
|
|
PyObject *const *args,
|
|
size_t nargsf,
|
|
PyObject *kwnames) {
|
|
return PyUnicode_FromString("vectorcall called");
|
|
}
|
|
|
|
static PyObject *
|
|
LimitedVectorCallClass_new(PyTypeObject *tp, PyTypeObject *a, PyTypeObject *kw)
|
|
{
|
|
PyObject *self = ((allocfunc)PyType_GetSlot(tp, Py_tp_alloc))(tp, 0);
|
|
if (!self) {
|
|
return NULL;
|
|
}
|
|
*(vectorcallfunc*)((char*)self + sizeof(PyObject)) = (
|
|
LimitedVectorCallClass_vectorcall);
|
|
return self;
|
|
}
|
|
|
|
static PyObject *
|
|
call_vectorcall(PyObject* self, PyObject *callable)
|
|
{
|
|
PyObject *args[3] = { NULL, NULL, NULL };
|
|
PyObject *kwname = NULL, *kwnames = NULL, *result = NULL;
|
|
|
|
args[1] = PyUnicode_FromString("foo");
|
|
if (!args[1]) {
|
|
goto leave;
|
|
}
|
|
|
|
args[2] = PyUnicode_FromString("bar");
|
|
if (!args[2]) {
|
|
goto leave;
|
|
}
|
|
|
|
kwname = PyUnicode_InternFromString("baz");
|
|
if (!kwname) {
|
|
goto leave;
|
|
}
|
|
|
|
kwnames = PyTuple_New(1);
|
|
if (!kwnames) {
|
|
goto leave;
|
|
}
|
|
|
|
if (PyTuple_SetItem(kwnames, 0, kwname)) {
|
|
goto leave;
|
|
}
|
|
|
|
result = PyObject_Vectorcall(
|
|
callable,
|
|
args + 1,
|
|
1 | PY_VECTORCALL_ARGUMENTS_OFFSET,
|
|
kwnames
|
|
);
|
|
|
|
leave:
|
|
Py_XDECREF(args[1]);
|
|
Py_XDECREF(args[2]);
|
|
Py_XDECREF(kwnames);
|
|
|
|
return result;
|
|
}
|
|
|
|
static PyObject *
|
|
call_vectorcall_method(PyObject* self, PyObject *callable)
|
|
{
|
|
PyObject *args[3] = { NULL, NULL, NULL };
|
|
PyObject *name = NULL, *kwname = NULL,
|
|
*kwnames = NULL, *result = NULL;
|
|
|
|
name = PyUnicode_FromString("f");
|
|
if (!name) {
|
|
goto leave;
|
|
}
|
|
|
|
args[0] = callable;
|
|
args[1] = PyUnicode_FromString("foo");
|
|
if (!args[1]) {
|
|
goto leave;
|
|
}
|
|
|
|
args[2] = PyUnicode_FromString("bar");
|
|
if (!args[2]) {
|
|
goto leave;
|
|
}
|
|
|
|
kwname = PyUnicode_InternFromString("baz");
|
|
if (!kwname) {
|
|
goto leave;
|
|
}
|
|
|
|
kwnames = PyTuple_New(1);
|
|
if (!kwnames) {
|
|
goto leave;
|
|
}
|
|
|
|
if (PyTuple_SetItem(kwnames, 0, kwname)) {
|
|
goto leave;
|
|
}
|
|
|
|
|
|
result = PyObject_VectorcallMethod(
|
|
name,
|
|
args,
|
|
2 | PY_VECTORCALL_ARGUMENTS_OFFSET,
|
|
kwnames
|
|
);
|
|
|
|
leave:
|
|
Py_XDECREF(name);
|
|
Py_XDECREF(args[1]);
|
|
Py_XDECREF(args[2]);
|
|
Py_XDECREF(kwnames);
|
|
|
|
return result;
|
|
}
|
|
|
|
static PyMemberDef LimitedVectorCallClass_members[] = {
|
|
{"__vectorcalloffset__", Py_T_PYSSIZET, sizeof(PyObject), Py_READONLY},
|
|
{NULL}
|
|
};
|
|
|
|
static PyType_Slot LimitedVectorallClass_slots[] = {
|
|
{Py_tp_new, LimitedVectorCallClass_new},
|
|
{Py_tp_call, LimitedVectorCallClass_tpcall},
|
|
{Py_tp_members, LimitedVectorCallClass_members},
|
|
{0},
|
|
};
|
|
|
|
static PyType_Spec LimitedVectorCallClass_spec = {
|
|
.name = "_testcapi.LimitedVectorCallClass",
|
|
.basicsize = (int)(sizeof(PyObject) + sizeof(vectorcallfunc)),
|
|
.flags = Py_TPFLAGS_DEFAULT
|
|
| Py_TPFLAGS_HAVE_VECTORCALL
|
|
| Py_TPFLAGS_BASETYPE,
|
|
.slots = LimitedVectorallClass_slots,
|
|
};
|
|
|
|
static PyMethodDef TestMethods[] = {
|
|
{"call_vectorcall", call_vectorcall, METH_O},
|
|
{"call_vectorcall_method", call_vectorcall_method, METH_O},
|
|
{NULL},
|
|
};
|
|
|
|
int
|
|
_PyTestCapi_Init_VectorcallLimited(PyObject *m) {
|
|
if (PyModule_AddFunctions(m, TestMethods) < 0) {
|
|
return -1;
|
|
}
|
|
|
|
PyObject *LimitedVectorCallClass = PyType_FromModuleAndSpec(
|
|
m, &LimitedVectorCallClass_spec, NULL);
|
|
if (!LimitedVectorCallClass) {
|
|
return -1;
|
|
}
|
|
if (PyModule_AddType(m, (PyTypeObject *)LimitedVectorCallClass) < 0) {
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#endif // LIMITED_API_AVAILABLE
|