From d5a196d3526a275ddd79c0680be21df809ea985e Mon Sep 17 00:00:00 2001 From: AN Long Date: Fri, 22 Dec 2023 19:10:21 +0800 Subject: [PATCH 01/16] convert PyCSimpleType_Type to heap type --- Modules/_ctypes/_ctypes.c | 70 +++++++++++++++------------------------ Modules/_ctypes/ctypes.h | 8 ++--- 2 files changed, 31 insertions(+), 47 deletions(-) diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index f909a9496b6526..1e4f15fd420b03 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -2175,7 +2175,8 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } } - if (type == &PyCSimpleType_Type && fmt->setfunc_swapped && fmt->getfunc_swapped) { + ctypes_state *st = GLOBAL_STATE(); + if (type == st->PyCSimpleType_Type && fmt->setfunc_swapped && fmt->getfunc_swapped) { PyObject *swapped = CreateSwappedType(type, args, kwds, proto, fmt); StgDictObject *sw_dict; @@ -2283,6 +2284,13 @@ PyCSimpleType_from_param(PyObject *type, PyObject *value) return NULL; } +static int +PyCSimpleType_traverse(PyTypeObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return 0; +} + static PyMethodDef PyCSimpleType_methods[] = { { "from_param", PyCSimpleType_from_param, METH_O, from_param_doc }, { "from_address", CDataType_from_address, METH_O, from_address_doc }, @@ -2292,46 +2300,20 @@ static PyMethodDef PyCSimpleType_methods[] = { { NULL, NULL }, }; -PyTypeObject PyCSimpleType_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.PyCSimpleType", /* tp_name */ - 0, /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - &CDataType_as_sequence, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - PyDoc_STR("metatype for the PyCSimpleType Objects"), /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - PyCSimpleType_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - PyCSimpleType_new, /* tp_new */ - 0, /* tp_free */ +static PyType_Slot pycsimple_type_type_slots[] = { + {Py_sq_repeat, CDataType_repeat}, + {Py_tp_doc, PyDoc_STR("metatype for the PyCSimpleType Objects")}, + {Py_tp_methods, PyCSimpleType_methods}, + {Py_tp_new, PyCSimpleType_new}, + {Py_tp_traverse, PyCSimpleType_traverse}, + {0, NULL}, +}; + +PyType_Spec pycsimple_type_type_spec = { + .name = "_ctypes.PyCSimpleType", + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = pycsimple_type_type_slots, }; /******************************************************************/ @@ -5694,7 +5676,9 @@ _ctypes_add_types(PyObject *mod) TYPE_READY_BASE(&UnionType_Type, &PyType_Type); TYPE_READY_BASE(&PyCPointerType_Type, &PyType_Type); TYPE_READY_BASE(&PyCArrayType_Type, &PyType_Type); - TYPE_READY_BASE(&PyCSimpleType_Type, &PyType_Type); + // TYPE_READY_BASE(&PyCSimpleType_Type, &PyType_Type); + CREATE_TYPE(mod, st->PyCSimpleType_Type, &pycsimple_type_type_spec, + &PyType_Type); TYPE_READY_BASE(&PyCFuncPtrType_Type, &PyType_Type); /************************************************* @@ -5706,7 +5690,7 @@ _ctypes_add_types(PyObject *mod) MOD_ADD_TYPE(&Union_Type, &UnionType_Type, &PyCData_Type); MOD_ADD_TYPE(&PyCPointer_Type, &PyCPointerType_Type, &PyCData_Type); MOD_ADD_TYPE(&PyCArray_Type, &PyCArrayType_Type, &PyCData_Type); - MOD_ADD_TYPE(&Simple_Type, &PyCSimpleType_Type, &PyCData_Type); + MOD_ADD_TYPE(&Simple_Type, st->PyCSimpleType_Type, &PyCData_Type); MOD_ADD_TYPE(&PyCFuncPtr_Type, &PyCFuncPtrType_Type, &PyCData_Type); /************************************************* diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h index 8891a0a741de7b..b459ecf6d38722 100644 --- a/Modules/_ctypes/ctypes.h +++ b/Modules/_ctypes/ctypes.h @@ -33,7 +33,7 @@ #endif typedef struct { - PyTypeObject *DictRemover_Type; +PyTypeObject *DictRemover_Type; PyTypeObject *PyCArg_Type; PyTypeObject *PyCField_Type; PyTypeObject *PyCThunk_Type; @@ -41,6 +41,7 @@ typedef struct { PyTypeObject *PyComError_Type; #endif PyTypeObject *StructParam_Type; + PyTypeObject *PyCSimpleType_Type; } ctypes_state; extern ctypes_state global_state; @@ -155,9 +156,8 @@ extern PyTypeObject PyCData_Type; #define CDataObject_Check(v) PyObject_TypeCheck(v, &PyCData_Type) #define _CDataObject_HasExternalBuffer(v) ((v)->b_ptr != (char *)&(v)->b_value) -extern PyTypeObject PyCSimpleType_Type; -#define PyCSimpleTypeObject_CheckExact(v) Py_IS_TYPE(v, &PyCSimpleType_Type) -#define PyCSimpleTypeObject_Check(v) PyObject_TypeCheck(v, &PyCSimpleType_Type) +#define PyCSimpleTypeObject_CheckExact(v) Py_IS_TYPE(v, GLOBAL_STATE()->PyCSimpleType_Type) +#define PyCSimpleTypeObject_Check(v) PyObject_TypeCheck(v, GLOBAL_STATE()->PyCSimpleType_Type) extern struct fielddesc *_ctypes_get_fielddesc(const char *fmt); From 78acadfe5e855c4874b639176c89e3e8d3ce06dc Mon Sep 17 00:00:00 2001 From: AN Long Date: Mon, 1 Jan 2024 22:58:50 +0800 Subject: [PATCH 02/16] turn all meta type to heap type --- Modules/_ctypes/_ctypes.c | 314 ++++++++++++-------------------------- Modules/_ctypes/ctypes.h | 19 +-- 2 files changed, 111 insertions(+), 222 deletions(-) diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 1e4f15fd420b03..70429235479053 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -903,8 +903,12 @@ static int CDataType_traverse(PyTypeObject *self, visitproc visit, void *arg) { StgDictObject *dict = PyType_stgdict((PyObject *)self); - if (dict) + if (dict) { Py_VISIT(dict->proto); + } + if (!(self->tp_base->tp_flags & Py_TPFLAGS_HEAPTYPE)) { + Py_VISIT(Py_TYPE(self)); + } return PyType_Type.tp_traverse((PyObject *)self, visit, arg); } @@ -935,91 +939,41 @@ UnionType_setattro(PyObject *self, PyObject *key, PyObject *value) return 0; } +static PyType_Slot pycstruct_type_type_slots[] = { + {Py_sq_repeat, CDataType_repeat}, + {Py_tp_setattro, PyCStructType_setattro}, + {Py_tp_doc, PyDoc_STR("metatype for the CData Objects")}, + {Py_tp_traverse, CDataType_traverse}, + {Py_tp_clear, CDataType_clear}, + {Py_tp_methods, CDataType_methods}, + {Py_tp_new, PyCStructType_new}, + {0, NULL}, +}; -PyTypeObject PyCStructType_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.PyCStructType", /* tp_name */ - 0, /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - &CDataType_as_sequence, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - PyCStructType_setattro, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - PyDoc_STR("metatype for the CData Objects"), /* tp_doc */ - (traverseproc)CDataType_traverse, /* tp_traverse */ - (inquiry)CDataType_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - CDataType_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - PyCStructType_new, /* tp_new */ - 0, /* tp_free */ +PyType_Spec pycstruct_type_type_spec = { + .name = "_ctypes.PyCStructType", + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = pycstruct_type_type_slots, }; -static PyTypeObject UnionType_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.UnionType", /* tp_name */ - 0, /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - &CDataType_as_sequence, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - UnionType_setattro, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - PyDoc_STR("metatype for the CData Objects"), /* tp_doc */ - (traverseproc)CDataType_traverse, /* tp_traverse */ - (inquiry)CDataType_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - CDataType_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - UnionType_new, /* tp_new */ - 0, /* tp_free */ +static PyType_Slot union_type_type_slots[] = { + {Py_sq_repeat, CDataType_repeat}, + {Py_tp_setattro, UnionType_setattro}, + {Py_tp_doc, PyDoc_STR("metatype for the Union Objects")}, + {Py_tp_traverse, CDataType_traverse}, + {Py_tp_clear, CDataType_clear}, + {Py_tp_methods, CDataType_methods}, + {Py_tp_new, UnionType_new}, + {0, NULL}, }; +static PyType_Spec union_type_type_spec = { + .name = "_ctypes.UnionType", + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = union_type_type_slots, +}; /******************************************************************/ @@ -1234,46 +1188,21 @@ static PyMethodDef PyCPointerType_methods[] = { { NULL, NULL }, }; -PyTypeObject PyCPointerType_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.PyCPointerType", /* tp_name */ - 0, /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - &CDataType_as_sequence, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - PyDoc_STR("metatype for the Pointer Objects"), /* tp_doc */ - (traverseproc)CDataType_traverse, /* tp_traverse */ - (inquiry)CDataType_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - PyCPointerType_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - PyCPointerType_new, /* tp_new */ - 0, /* tp_free */ +static PyType_Slot pycpointer_type_type_slots[] = { + {Py_sq_repeat, CDataType_repeat}, + {Py_tp_doc, PyDoc_STR("metatype for the Pointer Objects")}, + {Py_tp_traverse, CDataType_traverse}, + {Py_tp_clear, CDataType_clear}, + {Py_tp_methods, PyCPointerType_methods}, + {Py_tp_new, PyCPointerType_new}, + {0, NULL}, +}; + +static PyType_Spec pycpointer_type_type_spec = { + .name = "_ctypes.PyCPointerType", + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = pycpointer_type_type_slots, }; @@ -1606,48 +1535,28 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } -PyTypeObject PyCArrayType_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.PyCArrayType", /* tp_name */ - 0, /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - &CDataType_as_sequence, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - PyDoc_STR("metatype for the Array Objects"), /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - CDataType_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - PyCArrayType_new, /* tp_new */ - 0, /* tp_free */ +static int +PyCArrayType_traverse(PyTypeObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return 0; +} + +static PyType_Slot pycarray_type_type_slots[] = { + {Py_sq_repeat, CDataType_repeat}, + {Py_tp_doc, PyDoc_STR("metatype for the Array Objects")}, + {Py_tp_traverse, PyCArrayType_traverse}, + {Py_tp_methods, CDataType_methods}, + {Py_tp_new, PyCArrayType_new}, + {0, NULL}, }; +static PyType_Spec pycarray_type_type_spec = { + .name = "_ctypes.PyCArrayType", + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = pycarray_type_type_slots, +}; /******************************************************************/ /* @@ -2557,46 +2466,21 @@ PyCFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return (PyObject *)result; } -PyTypeObject PyCFuncPtrType_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.PyCFuncPtrType", /* tp_name */ - 0, /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - &CDataType_as_sequence, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - PyDoc_STR("metatype for C function pointers"), /* tp_doc */ - (traverseproc)CDataType_traverse, /* tp_traverse */ - (inquiry)CDataType_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - CDataType_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - PyCFuncPtrType_new, /* tp_new */ - 0, /* tp_free */ +static PyType_Slot pycfunc_ptr_type_type_slots[] = { + {Py_sq_repeat, CDataType_repeat}, + {Py_tp_doc, PyDoc_STR("metatype for C function pointers")}, + {Py_tp_traverse, CDataType_traverse}, + {Py_tp_clear, CDataType_clear}, + {Py_tp_methods, CDataType_methods}, + {Py_tp_new, PyCFuncPtrType_new}, + {0, NULL}, +}; + +static PyType_Spec pycfunc_ptr_type_type_spec = { + .name = "_ctypes.PyCFuncPtrType", + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = pycfunc_ptr_type_type_slots, }; @@ -4863,7 +4747,8 @@ PyCArrayType_from_ctype(PyObject *itemtype, Py_ssize_t length) ((PyTypeObject *)itemtype)->tp_name, (long)length); #endif - result = PyObject_CallFunction((PyObject *)&PyCArrayType_Type, + ctypes_state *st = GLOBAL_STATE(); + result = PyObject_CallFunction((PyObject *)st->PyCArrayType_Type, "s(O){s:n,s:O}", name, &PyCArray_Type, @@ -5672,26 +5557,29 @@ _ctypes_add_types(PyObject *mod) * * Metaclasses */ - TYPE_READY_BASE(&PyCStructType_Type, &PyType_Type); - TYPE_READY_BASE(&UnionType_Type, &PyType_Type); - TYPE_READY_BASE(&PyCPointerType_Type, &PyType_Type); - TYPE_READY_BASE(&PyCArrayType_Type, &PyType_Type); - // TYPE_READY_BASE(&PyCSimpleType_Type, &PyType_Type); + CREATE_TYPE(mod, st->PyCStructType_Type, &pycstruct_type_type_spec, + &PyType_Type); + CREATE_TYPE(mod, st->UnionType_Type, &union_type_type_spec, &PyType_Type); + CREATE_TYPE(mod, st->PyCPointerType_Type, &pycpointer_type_type_spec, + &PyType_Type); + CREATE_TYPE(mod, st->PyCArrayType_Type, &pycarray_type_type_spec, + &PyType_Type); CREATE_TYPE(mod, st->PyCSimpleType_Type, &pycsimple_type_type_spec, &PyType_Type); - TYPE_READY_BASE(&PyCFuncPtrType_Type, &PyType_Type); + CREATE_TYPE(mod, st->PyCFuncPtrType_Type, &pycfunc_ptr_type_type_spec, + &PyType_Type); /************************************************* * * Classes using a custom metaclass */ - MOD_ADD_TYPE(&Struct_Type, &PyCStructType_Type, &PyCData_Type); - MOD_ADD_TYPE(&Union_Type, &UnionType_Type, &PyCData_Type); - MOD_ADD_TYPE(&PyCPointer_Type, &PyCPointerType_Type, &PyCData_Type); - MOD_ADD_TYPE(&PyCArray_Type, &PyCArrayType_Type, &PyCData_Type); + MOD_ADD_TYPE(&Struct_Type, st->PyCStructType_Type, &PyCData_Type); + MOD_ADD_TYPE(&Union_Type, st->UnionType_Type, &PyCData_Type); + MOD_ADD_TYPE(&PyCPointer_Type, st->PyCPointerType_Type, &PyCData_Type); + MOD_ADD_TYPE(&PyCArray_Type, st->PyCArrayType_Type, &PyCData_Type); MOD_ADD_TYPE(&Simple_Type, st->PyCSimpleType_Type, &PyCData_Type); - MOD_ADD_TYPE(&PyCFuncPtr_Type, &PyCFuncPtrType_Type, &PyCData_Type); + MOD_ADD_TYPE(&PyCFuncPtr_Type, st->PyCFuncPtrType_Type, &PyCData_Type); /************************************************* * diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h index b459ecf6d38722..bc96992330593b 100644 --- a/Modules/_ctypes/ctypes.h +++ b/Modules/_ctypes/ctypes.h @@ -42,6 +42,11 @@ PyTypeObject *DictRemover_Type; #endif PyTypeObject *StructParam_Type; PyTypeObject *PyCSimpleType_Type; + PyTypeObject *PyCStructType_Type; + PyTypeObject *UnionType_Type; + PyTypeObject *PyCPointerType_Type; + PyTypeObject *PyCArrayType_Type; + PyTypeObject *PyCFuncPtrType_Type; } ctypes_state; extern ctypes_state global_state; @@ -119,7 +124,7 @@ typedef struct { Py_ssize_t b_size; /* size of memory block in bytes */ Py_ssize_t b_length; /* number of references we need */ Py_ssize_t b_index; /* index of this object into base's - b_object list */ + b_object list */ PyObject *b_objects; /* list of references we need to keep */ union value b_value; /* end of tagCDataObject, additional fields follow */ @@ -171,21 +176,17 @@ PyCField_FromDesc(PyObject *desc, Py_ssize_t index, extern PyObject *PyCData_AtAddress(PyObject *type, void *buf); extern PyObject *PyCData_FromBytes(PyObject *type, char *data, Py_ssize_t length); -extern PyTypeObject PyCArrayType_Type; extern PyTypeObject PyCArray_Type; -extern PyTypeObject PyCPointerType_Type; extern PyTypeObject PyCPointer_Type; extern PyTypeObject PyCFuncPtr_Type; -extern PyTypeObject PyCFuncPtrType_Type; -extern PyTypeObject PyCStructType_Type; -#define PyCArrayTypeObject_Check(v) PyObject_TypeCheck(v, &PyCArrayType_Type) +#define PyCArrayTypeObject_Check(v) PyObject_TypeCheck(v, GLOBAL_STATE()->PyCArrayType_Type) #define ArrayObject_Check(v) PyObject_TypeCheck(v, &PyCArray_Type) #define PointerObject_Check(v) PyObject_TypeCheck(v, &PyCPointer_Type) -#define PyCPointerTypeObject_Check(v) PyObject_TypeCheck(v, &PyCPointerType_Type) +#define PyCPointerTypeObject_Check(v) PyObject_TypeCheck(v, GLOBAL_STATE()->PyCPointerType_Type) #define PyCFuncPtrObject_Check(v) PyObject_TypeCheck(v, &PyCFuncPtr_Type) -#define PyCFuncPtrTypeObject_Check(v) PyObject_TypeCheck(v, &PyCFuncPtrType_Type) -#define PyCStructTypeObject_Check(v) PyObject_TypeCheck(v, &PyCStructType_Type) +#define PyCFuncPtrTypeObject_Check(v) PyObject_TypeCheck(v, GLOBAL_STATE()->PyCFuncPtrType_Type) +#define PyCStructTypeObject_Check(v) PyObject_TypeCheck(v, GLOBAL_STATE()->PyCStructType_Type) extern PyObject * PyCArrayType_from_ctype(PyObject *itemtype, Py_ssize_t length); From 799494dba77283e8f7c5f867bc456214cb4ef07c Mon Sep 17 00:00:00 2001 From: AN Long Date: Mon, 1 Jan 2024 23:04:16 +0800 Subject: [PATCH 03/16] simplify the slots and spec names --- Modules/_ctypes/_ctypes.c | 48 +++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 70429235479053..8db32928e69a92 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -939,7 +939,7 @@ UnionType_setattro(PyObject *self, PyObject *key, PyObject *value) return 0; } -static PyType_Slot pycstruct_type_type_slots[] = { +static PyType_Slot pycstruct_type_slots[] = { {Py_sq_repeat, CDataType_repeat}, {Py_tp_setattro, PyCStructType_setattro}, {Py_tp_doc, PyDoc_STR("metatype for the CData Objects")}, @@ -950,14 +950,14 @@ static PyType_Slot pycstruct_type_type_slots[] = { {0, NULL}, }; -PyType_Spec pycstruct_type_type_spec = { +PyType_Spec pycstruct_type_spec = { .name = "_ctypes.PyCStructType", .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE), - .slots = pycstruct_type_type_slots, + .slots = pycstruct_type_slots, }; -static PyType_Slot union_type_type_slots[] = { +static PyType_Slot union_type_slots[] = { {Py_sq_repeat, CDataType_repeat}, {Py_tp_setattro, UnionType_setattro}, {Py_tp_doc, PyDoc_STR("metatype for the Union Objects")}, @@ -968,11 +968,11 @@ static PyType_Slot union_type_type_slots[] = { {0, NULL}, }; -static PyType_Spec union_type_type_spec = { +static PyType_Spec union_type_spec = { .name = "_ctypes.UnionType", .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE), - .slots = union_type_type_slots, + .slots = union_type_slots, }; /******************************************************************/ @@ -1188,7 +1188,7 @@ static PyMethodDef PyCPointerType_methods[] = { { NULL, NULL }, }; -static PyType_Slot pycpointer_type_type_slots[] = { +static PyType_Slot pycpointer_type_slots[] = { {Py_sq_repeat, CDataType_repeat}, {Py_tp_doc, PyDoc_STR("metatype for the Pointer Objects")}, {Py_tp_traverse, CDataType_traverse}, @@ -1198,11 +1198,11 @@ static PyType_Slot pycpointer_type_type_slots[] = { {0, NULL}, }; -static PyType_Spec pycpointer_type_type_spec = { +static PyType_Spec pycpointer_type_spec = { .name = "_ctypes.PyCPointerType", .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE), - .slots = pycpointer_type_type_slots, + .slots = pycpointer_type_slots, }; @@ -1542,7 +1542,7 @@ PyCArrayType_traverse(PyTypeObject *self, visitproc visit, void *arg) return 0; } -static PyType_Slot pycarray_type_type_slots[] = { +static PyType_Slot pycarray_type_slots[] = { {Py_sq_repeat, CDataType_repeat}, {Py_tp_doc, PyDoc_STR("metatype for the Array Objects")}, {Py_tp_traverse, PyCArrayType_traverse}, @@ -1551,11 +1551,11 @@ static PyType_Slot pycarray_type_type_slots[] = { {0, NULL}, }; -static PyType_Spec pycarray_type_type_spec = { +static PyType_Spec pycarray_type_spec = { .name = "_ctypes.PyCArrayType", .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE), - .slots = pycarray_type_type_slots, + .slots = pycarray_type_slots, }; /******************************************************************/ @@ -2209,7 +2209,7 @@ static PyMethodDef PyCSimpleType_methods[] = { { NULL, NULL }, }; -static PyType_Slot pycsimple_type_type_slots[] = { +static PyType_Slot pycsimple_type_slots[] = { {Py_sq_repeat, CDataType_repeat}, {Py_tp_doc, PyDoc_STR("metatype for the PyCSimpleType Objects")}, {Py_tp_methods, PyCSimpleType_methods}, @@ -2218,11 +2218,11 @@ static PyType_Slot pycsimple_type_type_slots[] = { {0, NULL}, }; -PyType_Spec pycsimple_type_type_spec = { +PyType_Spec pycsimple_type_spec = { .name = "_ctypes.PyCSimpleType", .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE), - .slots = pycsimple_type_type_slots, + .slots = pycsimple_type_slots, }; /******************************************************************/ @@ -2466,7 +2466,7 @@ PyCFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return (PyObject *)result; } -static PyType_Slot pycfunc_ptr_type_type_slots[] = { +static PyType_Slot pycfuncptr_type_slots[] = { {Py_sq_repeat, CDataType_repeat}, {Py_tp_doc, PyDoc_STR("metatype for C function pointers")}, {Py_tp_traverse, CDataType_traverse}, @@ -2476,11 +2476,11 @@ static PyType_Slot pycfunc_ptr_type_type_slots[] = { {0, NULL}, }; -static PyType_Spec pycfunc_ptr_type_type_spec = { +static PyType_Spec pycfuncptr_type_spec = { .name = "_ctypes.PyCFuncPtrType", .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE), - .slots = pycfunc_ptr_type_type_slots, + .slots = pycfuncptr_type_slots, }; @@ -5557,16 +5557,16 @@ _ctypes_add_types(PyObject *mod) * * Metaclasses */ - CREATE_TYPE(mod, st->PyCStructType_Type, &pycstruct_type_type_spec, + CREATE_TYPE(mod, st->PyCStructType_Type, &pycstruct_type_spec, &PyType_Type); - CREATE_TYPE(mod, st->UnionType_Type, &union_type_type_spec, &PyType_Type); - CREATE_TYPE(mod, st->PyCPointerType_Type, &pycpointer_type_type_spec, + CREATE_TYPE(mod, st->UnionType_Type, &union_type_spec, &PyType_Type); + CREATE_TYPE(mod, st->PyCPointerType_Type, &pycpointer_type_spec, &PyType_Type); - CREATE_TYPE(mod, st->PyCArrayType_Type, &pycarray_type_type_spec, + CREATE_TYPE(mod, st->PyCArrayType_Type, &pycarray_type_spec, &PyType_Type); - CREATE_TYPE(mod, st->PyCSimpleType_Type, &pycsimple_type_type_spec, + CREATE_TYPE(mod, st->PyCSimpleType_Type, &pycsimple_type_spec, &PyType_Type); - CREATE_TYPE(mod, st->PyCFuncPtrType_Type, &pycfunc_ptr_type_type_spec, + CREATE_TYPE(mod, st->PyCFuncPtrType_Type, &pycfuncptr_type_spec, &PyType_Type); /************************************************* From ad3e1eca27652441bbd9e04d3a5a833df5076463 Mon Sep 17 00:00:00 2001 From: AN Long Date: Mon, 1 Jan 2024 23:06:35 +0800 Subject: [PATCH 04/16] update the traverse function --- Modules/_ctypes/_ctypes.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 8db32928e69a92..2821ea2fd2d067 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -906,9 +906,7 @@ CDataType_traverse(PyTypeObject *self, visitproc visit, void *arg) if (dict) { Py_VISIT(dict->proto); } - if (!(self->tp_base->tp_flags & Py_TPFLAGS_HEAPTYPE)) { - Py_VISIT(Py_TYPE(self)); - } + Py_VISIT(Py_TYPE(self)); return PyType_Type.tp_traverse((PyObject *)self, visit, arg); } From 55d9fc4b612ae83879d9b5aff987972c444a0e0f Mon Sep 17 00:00:00 2001 From: AN Long Date: Mon, 1 Jan 2024 23:31:16 +0800 Subject: [PATCH 05/16] fix codes ident --- Modules/_ctypes/ctypes.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h index bc96992330593b..d7eabfc597d677 100644 --- a/Modules/_ctypes/ctypes.h +++ b/Modules/_ctypes/ctypes.h @@ -33,7 +33,7 @@ #endif typedef struct { -PyTypeObject *DictRemover_Type; + PyTypeObject *DictRemover_Type; PyTypeObject *PyCArg_Type; PyTypeObject *PyCField_Type; PyTypeObject *PyCThunk_Type; From fc9180459731333ee90f654d956fda3023620cb0 Mon Sep 17 00:00:00 2001 From: AN Long Date: Mon, 1 Jan 2024 23:45:16 +0800 Subject: [PATCH 06/16] remove unused CDataType_as_sequence --- Modules/_ctypes/_ctypes.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 2821ea2fd2d067..6fd26935ea9c16 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -876,20 +876,6 @@ CDataType_repeat(PyObject *self, Py_ssize_t length) return PyCArrayType_from_ctype(self, length); } -static PySequenceMethods CDataType_as_sequence = { - 0, /* inquiry sq_length; */ - 0, /* binaryfunc sq_concat; */ - CDataType_repeat, /* intargfunc sq_repeat; */ - 0, /* intargfunc sq_item; */ - 0, /* intintargfunc sq_slice; */ - 0, /* intobjargproc sq_ass_item; */ - 0, /* intintobjargproc sq_ass_slice; */ - 0, /* objobjproc sq_contains; */ - - 0, /* binaryfunc sq_inplace_concat; */ - 0, /* intargfunc sq_inplace_repeat; */ -}; - static int CDataType_clear(PyTypeObject *self) { From d1b9652f1a75907303e466167232dca19e2e740c Mon Sep 17 00:00:00 2001 From: AN Long Date: Wed, 3 Jan 2024 17:28:07 +0800 Subject: [PATCH 07/16] Update Modules/_ctypes/_ctypes.c Co-authored-by: Erlend E. Aasland --- Modules/_ctypes/_ctypes.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 6fd26935ea9c16..9baec882aeec30 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -924,13 +924,15 @@ UnionType_setattro(PyObject *self, PyObject *key, PyObject *value) } static PyType_Slot pycstruct_type_slots[] = { - {Py_sq_repeat, CDataType_repeat}, {Py_tp_setattro, PyCStructType_setattro}, {Py_tp_doc, PyDoc_STR("metatype for the CData Objects")}, {Py_tp_traverse, CDataType_traverse}, {Py_tp_clear, CDataType_clear}, {Py_tp_methods, CDataType_methods}, {Py_tp_new, PyCStructType_new}, + + // Sequence protocol. + {Py_sq_repeat, CDataType_repeat}, {0, NULL}, }; From 5bfea09fe5675ad17a13493b5a70a49478975d25 Mon Sep 17 00:00:00 2001 From: AN Long Date: Wed, 3 Jan 2024 17:28:18 +0800 Subject: [PATCH 08/16] Update Modules/_ctypes/_ctypes.c Co-authored-by: Erlend E. Aasland --- Modules/_ctypes/_ctypes.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 9baec882aeec30..aae512cea8c842 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -944,13 +944,15 @@ PyType_Spec pycstruct_type_spec = { }; static PyType_Slot union_type_slots[] = { - {Py_sq_repeat, CDataType_repeat}, {Py_tp_setattro, UnionType_setattro}, {Py_tp_doc, PyDoc_STR("metatype for the Union Objects")}, {Py_tp_traverse, CDataType_traverse}, {Py_tp_clear, CDataType_clear}, {Py_tp_methods, CDataType_methods}, {Py_tp_new, UnionType_new}, + + // Sequence protocol. + {Py_sq_repeat, CDataType_repeat}, {0, NULL}, }; From 3b661b7b48c3d6ac4ea938e34f485a19a66d74b1 Mon Sep 17 00:00:00 2001 From: AN Long Date: Wed, 3 Jan 2024 17:28:26 +0800 Subject: [PATCH 09/16] Update Modules/_ctypes/_ctypes.c Co-authored-by: Erlend E. Aasland --- Modules/_ctypes/_ctypes.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index aae512cea8c842..27c772df239657 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -1177,12 +1177,14 @@ static PyMethodDef PyCPointerType_methods[] = { }; static PyType_Slot pycpointer_type_slots[] = { - {Py_sq_repeat, CDataType_repeat}, {Py_tp_doc, PyDoc_STR("metatype for the Pointer Objects")}, {Py_tp_traverse, CDataType_traverse}, {Py_tp_clear, CDataType_clear}, {Py_tp_methods, PyCPointerType_methods}, {Py_tp_new, PyCPointerType_new}, + + // Sequence protocol. + {Py_sq_repeat, CDataType_repeat}, {0, NULL}, }; From 748d18c84828af30764230815fa50f472be87335 Mon Sep 17 00:00:00 2001 From: AN Long Date: Wed, 3 Jan 2024 17:28:34 +0800 Subject: [PATCH 10/16] Update Modules/_ctypes/_ctypes.c Co-authored-by: Erlend E. Aasland --- Modules/_ctypes/_ctypes.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 27c772df239657..815c9750bbcb2a 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -1533,11 +1533,13 @@ PyCArrayType_traverse(PyTypeObject *self, visitproc visit, void *arg) } static PyType_Slot pycarray_type_slots[] = { - {Py_sq_repeat, CDataType_repeat}, {Py_tp_doc, PyDoc_STR("metatype for the Array Objects")}, {Py_tp_traverse, PyCArrayType_traverse}, {Py_tp_methods, CDataType_methods}, {Py_tp_new, PyCArrayType_new}, + + // Sequence protocol. + {Py_sq_repeat, CDataType_repeat}, {0, NULL}, }; From 774407589dde12b7f9a37a37197f950307e3a2e4 Mon Sep 17 00:00:00 2001 From: AN Long Date: Wed, 3 Jan 2024 17:32:27 +0800 Subject: [PATCH 11/16] Update Modules/_ctypes/_ctypes.c Co-authored-by: Erlend E. Aasland --- Modules/_ctypes/_ctypes.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 815c9750bbcb2a..0d402cdf0da7f9 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -2077,7 +2077,10 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } ctypes_state *st = GLOBAL_STATE(); - if (type == st->PyCSimpleType_Type && fmt->setfunc_swapped && fmt->getfunc_swapped) { + if (type == st->PyCSimpleType_Type + && fmt->setfunc_swapped + && fmt->getfunc_swapped) + { PyObject *swapped = CreateSwappedType(type, args, kwds, proto, fmt); StgDictObject *sw_dict; From abe4c3fdfb5a6caf32d09a454df200ef73d57b89 Mon Sep 17 00:00:00 2001 From: AN Long Date: Wed, 3 Jan 2024 17:32:35 +0800 Subject: [PATCH 12/16] Update Modules/_ctypes/_ctypes.c Co-authored-by: Erlend E. Aasland --- Modules/_ctypes/_ctypes.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 0d402cdf0da7f9..6ac9a46a55f828 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -2205,11 +2205,13 @@ static PyMethodDef PyCSimpleType_methods[] = { }; static PyType_Slot pycsimple_type_slots[] = { - {Py_sq_repeat, CDataType_repeat}, {Py_tp_doc, PyDoc_STR("metatype for the PyCSimpleType Objects")}, {Py_tp_methods, PyCSimpleType_methods}, {Py_tp_new, PyCSimpleType_new}, {Py_tp_traverse, PyCSimpleType_traverse}, + + // Sequence protocol. + {Py_sq_repeat, CDataType_repeat}, {0, NULL}, }; From 04cf63f5eedfdd4697934aaafb0f7511d7739f1b Mon Sep 17 00:00:00 2001 From: AN Long Date: Wed, 3 Jan 2024 17:32:54 +0800 Subject: [PATCH 13/16] Update Modules/_ctypes/_ctypes.c Co-authored-by: Erlend E. Aasland --- Modules/_ctypes/_ctypes.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 6ac9a46a55f828..761cb26a490ac8 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -2464,12 +2464,14 @@ PyCFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } static PyType_Slot pycfuncptr_type_slots[] = { - {Py_sq_repeat, CDataType_repeat}, {Py_tp_doc, PyDoc_STR("metatype for C function pointers")}, {Py_tp_traverse, CDataType_traverse}, {Py_tp_clear, CDataType_clear}, {Py_tp_methods, CDataType_methods}, {Py_tp_new, PyCFuncPtrType_new}, + + // Sequence protocol. + {Py_sq_repeat, CDataType_repeat}, {0, NULL}, }; From 96194a1f3302012ee77275f0deb24851c10526e0 Mon Sep 17 00:00:00 2001 From: AN Long Date: Wed, 3 Jan 2024 19:06:19 +0800 Subject: [PATCH 14/16] re-order the metatypes in ctypes.h --- Modules/_ctypes/ctypes.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h index d7eabfc597d677..55e9f777788079 100644 --- a/Modules/_ctypes/ctypes.h +++ b/Modules/_ctypes/ctypes.h @@ -41,11 +41,11 @@ typedef struct { PyTypeObject *PyComError_Type; #endif PyTypeObject *StructParam_Type; - PyTypeObject *PyCSimpleType_Type; PyTypeObject *PyCStructType_Type; PyTypeObject *UnionType_Type; PyTypeObject *PyCPointerType_Type; PyTypeObject *PyCArrayType_Type; + PyTypeObject *PyCSimpleType_Type; PyTypeObject *PyCFuncPtrType_Type; } ctypes_state; From 1877f7b9d3c327a4f254b8d5790af665d39a9c7d Mon Sep 17 00:00:00 2001 From: AN Long Date: Thu, 4 Jan 2024 17:33:09 +0800 Subject: [PATCH 15/16] fix memory leak --- Modules/_ctypes/_ctypes.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 761cb26a490ac8..3450daa1731f68 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -930,7 +930,7 @@ static PyType_Slot pycstruct_type_slots[] = { {Py_tp_clear, CDataType_clear}, {Py_tp_methods, CDataType_methods}, {Py_tp_new, PyCStructType_new}, - + // Sequence protocol. {Py_sq_repeat, CDataType_repeat}, {0, NULL}, @@ -1529,7 +1529,13 @@ static int PyCArrayType_traverse(PyTypeObject *self, visitproc visit, void *arg) { Py_VISIT(Py_TYPE(self)); - return 0; + return PyType_Type.tp_traverse((PyObject *)self, visit, arg); +} + +static int +PyCArrayType_clear(PyObject *self) +{ + return PyType_Type.tp_clear(self); } static PyType_Slot pycarray_type_slots[] = { @@ -1537,6 +1543,7 @@ static PyType_Slot pycarray_type_slots[] = { {Py_tp_traverse, PyCArrayType_traverse}, {Py_tp_methods, CDataType_methods}, {Py_tp_new, PyCArrayType_new}, + {Py_tp_clear, PyCArrayType_clear}, // Sequence protocol. {Py_sq_repeat, CDataType_repeat}, @@ -2192,7 +2199,13 @@ static int PyCSimpleType_traverse(PyTypeObject *self, visitproc visit, void *arg) { Py_VISIT(Py_TYPE(self)); - return 0; + return PyType_Type.tp_traverse((PyObject *)self, visit, arg); +} + +static int +PyCSimpleType_clear(PyObject *self) +{ + return PyType_Type.tp_clear(self); } static PyMethodDef PyCSimpleType_methods[] = { @@ -2209,6 +2222,7 @@ static PyType_Slot pycsimple_type_slots[] = { {Py_tp_methods, PyCSimpleType_methods}, {Py_tp_new, PyCSimpleType_new}, {Py_tp_traverse, PyCSimpleType_traverse}, + {Py_tp_clear, PyCSimpleType_clear}, // Sequence protocol. {Py_sq_repeat, CDataType_repeat}, From 1c09a0c0af9a0dd0fc4fb7d916fcab3ede83b292 Mon Sep 17 00:00:00 2001 From: AN Long Date: Sat, 13 Jan 2024 20:16:33 +0800 Subject: [PATCH 16/16] Using traverse / clear slot function from CDataType --- Modules/_ctypes/_ctypes.c | 34 ++++------------------------------ 1 file changed, 4 insertions(+), 30 deletions(-) diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 960492028d7ac9..b51a03b5497fed 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -1525,25 +1525,12 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } -static int -PyCArrayType_traverse(PyTypeObject *self, visitproc visit, void *arg) -{ - Py_VISIT(Py_TYPE(self)); - return PyType_Type.tp_traverse((PyObject *)self, visit, arg); -} - -static int -PyCArrayType_clear(PyObject *self) -{ - return PyType_Type.tp_clear(self); -} - static PyType_Slot pycarray_type_slots[] = { {Py_tp_doc, PyDoc_STR("metatype for the Array Objects")}, - {Py_tp_traverse, PyCArrayType_traverse}, + {Py_tp_traverse, CDataType_traverse}, {Py_tp_methods, CDataType_methods}, {Py_tp_new, PyCArrayType_new}, - {Py_tp_clear, PyCArrayType_clear}, + {Py_tp_clear, CDataType_clear}, // Sequence protocol. {Py_sq_repeat, CDataType_repeat}, @@ -2195,19 +2182,6 @@ PyCSimpleType_from_param(PyObject *type, PyObject *value) return NULL; } -static int -PyCSimpleType_traverse(PyTypeObject *self, visitproc visit, void *arg) -{ - Py_VISIT(Py_TYPE(self)); - return PyType_Type.tp_traverse((PyObject *)self, visit, arg); -} - -static int -PyCSimpleType_clear(PyObject *self) -{ - return PyType_Type.tp_clear(self); -} - static PyMethodDef PyCSimpleType_methods[] = { { "from_param", PyCSimpleType_from_param, METH_O, from_param_doc }, { "from_address", CDataType_from_address, METH_O, from_address_doc }, @@ -2221,8 +2195,8 @@ static PyType_Slot pycsimple_type_slots[] = { {Py_tp_doc, PyDoc_STR("metatype for the PyCSimpleType Objects")}, {Py_tp_methods, PyCSimpleType_methods}, {Py_tp_new, PyCSimpleType_new}, - {Py_tp_traverse, PyCSimpleType_traverse}, - {Py_tp_clear, PyCSimpleType_clear}, + {Py_tp_traverse, CDataType_traverse}, + {Py_tp_clear, CDataType_clear}, // Sequence protocol. {Py_sq_repeat, CDataType_repeat},