mirror of https://github.com/python/cpython
gh-103092: Isolate _ctypes, part 1 (#103893)
Establish global state and port the following types to heap types: - DictRemover_Type - PyCArg_Type - PyCThunk_Type - PyCField_Type - StructParam_Type
This commit is contained in:
parent
63842bd907
commit
e9c777208f
|
@ -126,6 +126,8 @@ bytes(cdata)
|
||||||
|
|
||||||
#include "pycore_long.h" // _PyLong_GetZero()
|
#include "pycore_long.h" // _PyLong_GetZero()
|
||||||
|
|
||||||
|
ctypes_state global_state;
|
||||||
|
|
||||||
PyObject *PyExc_ArgError = NULL;
|
PyObject *PyExc_ArgError = NULL;
|
||||||
|
|
||||||
/* This dict maps ctypes types to POINTER types */
|
/* This dict maps ctypes types to POINTER types */
|
||||||
|
@ -150,13 +152,32 @@ typedef struct {
|
||||||
PyObject *dict;
|
PyObject *dict;
|
||||||
} DictRemoverObject;
|
} DictRemoverObject;
|
||||||
|
|
||||||
|
static int
|
||||||
|
_DictRemover_traverse(DictRemoverObject *self, visitproc visit, void *arg)
|
||||||
|
{
|
||||||
|
Py_VISIT(Py_TYPE(self));
|
||||||
|
Py_VISIT(self->key);
|
||||||
|
Py_VISIT(self->dict);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_DictRemover_clear(DictRemoverObject *self)
|
||||||
|
{
|
||||||
|
Py_CLEAR(self->key);
|
||||||
|
Py_CLEAR(self->dict);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_DictRemover_dealloc(PyObject *myself)
|
_DictRemover_dealloc(PyObject *myself)
|
||||||
{
|
{
|
||||||
|
PyTypeObject *tp = Py_TYPE(myself);
|
||||||
DictRemoverObject *self = (DictRemoverObject *)myself;
|
DictRemoverObject *self = (DictRemoverObject *)myself;
|
||||||
Py_XDECREF(self->key);
|
PyObject_GC_UnTrack(myself);
|
||||||
Py_XDECREF(self->dict);
|
(void)_DictRemover_clear(self);
|
||||||
Py_TYPE(self)->tp_free(myself);
|
tp->tp_free(myself);
|
||||||
|
Py_DECREF(tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -173,47 +194,23 @@ _DictRemover_call(PyObject *myself, PyObject *args, PyObject *kw)
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyTypeObject DictRemover_Type = {
|
PyDoc_STRVAR(dictremover_doc, "deletes a key from a dictionary");
|
||||||
PyVarObject_HEAD_INIT(NULL, 0)
|
|
||||||
"_ctypes.DictRemover", /* tp_name */
|
static PyType_Slot dictremover_slots[] = {
|
||||||
sizeof(DictRemoverObject), /* tp_basicsize */
|
{Py_tp_dealloc, _DictRemover_dealloc},
|
||||||
0, /* tp_itemsize */
|
{Py_tp_traverse, _DictRemover_traverse},
|
||||||
_DictRemover_dealloc, /* tp_dealloc */
|
{Py_tp_clear, _DictRemover_clear},
|
||||||
0, /* tp_vectorcall_offset */
|
{Py_tp_call, _DictRemover_call},
|
||||||
0, /* tp_getattr */
|
{Py_tp_doc, (void *)dictremover_doc},
|
||||||
0, /* tp_setattr */
|
{0, NULL},
|
||||||
0, /* tp_as_async */
|
};
|
||||||
0, /* tp_repr */
|
|
||||||
0, /* tp_as_number */
|
static PyType_Spec dictremover_spec = {
|
||||||
0, /* tp_as_sequence */
|
.name = "_ctypes.DictRemover",
|
||||||
0, /* tp_as_mapping */
|
.basicsize = sizeof(DictRemoverObject),
|
||||||
0, /* tp_hash */
|
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
|
||||||
_DictRemover_call, /* tp_call */
|
Py_TPFLAGS_IMMUTABLETYPE),
|
||||||
0, /* tp_str */
|
.slots = dictremover_slots,
|
||||||
0, /* tp_getattro */
|
|
||||||
0, /* tp_setattro */
|
|
||||||
0, /* tp_as_buffer */
|
|
||||||
/* XXX should participate in GC? */
|
|
||||||
Py_TPFLAGS_DEFAULT, /* tp_flags */
|
|
||||||
PyDoc_STR("deletes a key from a dictionary"), /* tp_doc */
|
|
||||||
0, /* tp_traverse */
|
|
||||||
0, /* tp_clear */
|
|
||||||
0, /* tp_richcompare */
|
|
||||||
0, /* tp_weaklistoffset */
|
|
||||||
0, /* tp_iter */
|
|
||||||
0, /* tp_iternext */
|
|
||||||
0, /* 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 */
|
|
||||||
0, /* tp_new */
|
|
||||||
0, /* tp_free */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -224,7 +221,8 @@ PyDict_SetItemProxy(PyObject *dict, PyObject *key, PyObject *item)
|
||||||
PyObject *proxy;
|
PyObject *proxy;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
obj = _PyObject_CallNoArgs((PyObject *)&DictRemover_Type);
|
ctypes_state *st = GLOBAL_STATE();
|
||||||
|
obj = _PyObject_CallNoArgs((PyObject *)st->DictRemover_Type);
|
||||||
if (obj == NULL)
|
if (obj == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -415,23 +413,45 @@ typedef struct {
|
||||||
PyObject *keep; // If set, a reference to the original CDataObject.
|
PyObject *keep; // If set, a reference to the original CDataObject.
|
||||||
} StructParamObject;
|
} StructParamObject;
|
||||||
|
|
||||||
|
static int
|
||||||
|
StructParam_traverse(StructParamObject *self, visitproc visit, void *arg)
|
||||||
|
{
|
||||||
|
Py_VISIT(Py_TYPE(self));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
StructParam_clear(StructParamObject *self)
|
||||||
|
{
|
||||||
|
Py_CLEAR(self->keep);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
StructParam_dealloc(PyObject *myself)
|
StructParam_dealloc(PyObject *myself)
|
||||||
{
|
{
|
||||||
StructParamObject *self = (StructParamObject *)myself;
|
StructParamObject *self = (StructParamObject *)myself;
|
||||||
Py_XDECREF(self->keep);
|
PyTypeObject *tp = Py_TYPE(self);
|
||||||
|
PyObject_GC_UnTrack(myself);
|
||||||
|
(void)StructParam_clear(self);
|
||||||
PyMem_Free(self->ptr);
|
PyMem_Free(self->ptr);
|
||||||
Py_TYPE(self)->tp_free(myself);
|
tp->tp_free(myself);
|
||||||
|
Py_DECREF(tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyType_Slot structparam_slots[] = {
|
||||||
|
{Py_tp_traverse, StructParam_traverse},
|
||||||
|
{Py_tp_clear, StructParam_clear},
|
||||||
|
{Py_tp_dealloc, StructParam_dealloc},
|
||||||
|
{0, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
static PyTypeObject StructParam_Type = {
|
static PyType_Spec structparam_spec = {
|
||||||
PyVarObject_HEAD_INIT(NULL, 0)
|
.name = "_ctypes.StructParam_Type",
|
||||||
.tp_name = "_ctypes.StructParam_Type",
|
.basicsize = sizeof(StructParamObject),
|
||||||
.tp_basicsize = sizeof(StructParamObject),
|
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE |
|
||||||
.tp_dealloc = StructParam_dealloc,
|
Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_DISALLOW_INSTANTIATION),
|
||||||
.tp_flags = Py_TPFLAGS_DEFAULT,
|
.slots = structparam_slots,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -460,7 +480,9 @@ StructUnionType_paramfunc(CDataObject *self)
|
||||||
/* Create a Python object which calls PyMem_Free(ptr) in
|
/* Create a Python object which calls PyMem_Free(ptr) in
|
||||||
its deallocator. The object will be destroyed
|
its deallocator. The object will be destroyed
|
||||||
at _ctypes_callproc() cleanup. */
|
at _ctypes_callproc() cleanup. */
|
||||||
obj = (&StructParam_Type)->tp_alloc(&StructParam_Type, 0);
|
ctypes_state *st = GLOBAL_STATE();
|
||||||
|
PyTypeObject *tp = st->StructParam_Type;
|
||||||
|
obj = tp->tp_alloc(tp, 0);
|
||||||
if (obj == NULL) {
|
if (obj == NULL) {
|
||||||
PyMem_Free(ptr);
|
PyMem_Free(ptr);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -800,7 +822,8 @@ CDataType_from_param(PyObject *type, PyObject *value)
|
||||||
if (res) {
|
if (res) {
|
||||||
return Py_NewRef(value);
|
return Py_NewRef(value);
|
||||||
}
|
}
|
||||||
if (PyCArg_CheckExact(value)) {
|
ctypes_state *st = GLOBAL_STATE();
|
||||||
|
if (PyCArg_CheckExact(st, value)) {
|
||||||
PyCArgObject *p = (PyCArgObject *)value;
|
PyCArgObject *p = (PyCArgObject *)value;
|
||||||
PyObject *ob = p->obj;
|
PyObject *ob = p->obj;
|
||||||
const char *ob_name;
|
const char *ob_name;
|
||||||
|
@ -1683,7 +1706,8 @@ c_wchar_p_from_param(PyObject *type, PyObject *value)
|
||||||
return Py_NewRef(value);
|
return Py_NewRef(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (PyCArg_CheckExact(value)) {
|
ctypes_state *st = GLOBAL_STATE();
|
||||||
|
if (PyCArg_CheckExact(st, value)) {
|
||||||
/* byref(c_char(...)) */
|
/* byref(c_char(...)) */
|
||||||
PyCArgObject *a = (PyCArgObject *)value;
|
PyCArgObject *a = (PyCArgObject *)value;
|
||||||
StgDictObject *dict = PyObject_stgdict(a->obj);
|
StgDictObject *dict = PyObject_stgdict(a->obj);
|
||||||
|
@ -1746,7 +1770,8 @@ c_char_p_from_param(PyObject *type, PyObject *value)
|
||||||
return Py_NewRef(value);
|
return Py_NewRef(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (PyCArg_CheckExact(value)) {
|
ctypes_state *st = GLOBAL_STATE();
|
||||||
|
if (PyCArg_CheckExact(st, value)) {
|
||||||
/* byref(c_char(...)) */
|
/* byref(c_char(...)) */
|
||||||
PyCArgObject *a = (PyCArgObject *)value;
|
PyCArgObject *a = (PyCArgObject *)value;
|
||||||
StgDictObject *dict = PyObject_stgdict(a->obj);
|
StgDictObject *dict = PyObject_stgdict(a->obj);
|
||||||
|
@ -1847,7 +1872,8 @@ c_void_p_from_param(PyObject *type, PyObject *value)
|
||||||
return Py_NewRef(value);
|
return Py_NewRef(value);
|
||||||
}
|
}
|
||||||
/* byref(...) */
|
/* byref(...) */
|
||||||
if (PyCArg_CheckExact(value)) {
|
ctypes_state *st = GLOBAL_STATE();
|
||||||
|
if (PyCArg_CheckExact(st, value)) {
|
||||||
/* byref(c_xxx()) */
|
/* byref(c_xxx()) */
|
||||||
PyCArgObject *a = (PyCArgObject *)value;
|
PyCArgObject *a = (PyCArgObject *)value;
|
||||||
if (a->tag == 'P') {
|
if (a->tag == 'P') {
|
||||||
|
@ -5635,12 +5661,22 @@ _ctypes_add_types(PyObject *mod)
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define CREATE_TYPE(MOD, TP, SPEC) do { \
|
||||||
|
PyObject *type = PyType_FromMetaclass(NULL, MOD, SPEC, NULL); \
|
||||||
|
if (type == NULL) { \
|
||||||
|
return -1; \
|
||||||
|
} \
|
||||||
|
TP = (PyTypeObject *)type; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
ctypes_state *st = GLOBAL_STATE();
|
||||||
|
|
||||||
/* Note:
|
/* Note:
|
||||||
ob_type is the metatype (the 'type'), defaults to PyType_Type,
|
ob_type is the metatype (the 'type'), defaults to PyType_Type,
|
||||||
tp_base is the base type, defaults to 'object' aka PyBaseObject_Type.
|
tp_base is the base type, defaults to 'object' aka PyBaseObject_Type.
|
||||||
*/
|
*/
|
||||||
TYPE_READY(&PyCArg_Type);
|
CREATE_TYPE(mod, st->PyCArg_Type, &carg_spec);
|
||||||
TYPE_READY(&PyCThunk_Type);
|
CREATE_TYPE(mod, st->PyCThunk_Type, &cthunk_spec);
|
||||||
TYPE_READY(&PyCData_Type);
|
TYPE_READY(&PyCData_Type);
|
||||||
/* StgDict is derived from PyDict_Type */
|
/* StgDict is derived from PyDict_Type */
|
||||||
TYPE_READY_BASE(&PyCStgDict_Type, &PyDict_Type);
|
TYPE_READY_BASE(&PyCStgDict_Type, &PyDict_Type);
|
||||||
|
@ -5673,17 +5709,15 @@ _ctypes_add_types(PyObject *mod)
|
||||||
* Simple classes
|
* Simple classes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* PyCField_Type is derived from PyBaseObject_Type */
|
CREATE_TYPE(mod, st->PyCField_Type, &cfield_spec);
|
||||||
TYPE_READY(&PyCField_Type);
|
|
||||||
|
|
||||||
/*************************************************
|
/*************************************************
|
||||||
*
|
*
|
||||||
* Other stuff
|
* Other stuff
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DictRemover_Type.tp_new = PyType_GenericNew;
|
CREATE_TYPE(mod, st->DictRemover_Type, &dictremover_spec);
|
||||||
TYPE_READY(&DictRemover_Type);
|
CREATE_TYPE(mod, st->StructParam_Type, &structparam_spec);
|
||||||
TYPE_READY(&StructParam_Type);
|
|
||||||
|
|
||||||
#ifdef MS_WIN32
|
#ifdef MS_WIN32
|
||||||
TYPE_READY_BASE(&PyComError_Type, (PyTypeObject*)PyExc_Exception);
|
TYPE_READY_BASE(&PyComError_Type, (PyTypeObject*)PyExc_Exception);
|
||||||
|
@ -5692,6 +5726,7 @@ _ctypes_add_types(PyObject *mod)
|
||||||
#undef TYPE_READY
|
#undef TYPE_READY
|
||||||
#undef TYPE_READY_BASE
|
#undef TYPE_READY_BASE
|
||||||
#undef MOD_ADD_TYPE
|
#undef MOD_ADD_TYPE
|
||||||
|
#undef CREATE_TYPE
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,23 +28,11 @@
|
||||||
|
|
||||||
/**************************************************************/
|
/**************************************************************/
|
||||||
|
|
||||||
static void
|
|
||||||
CThunkObject_dealloc(PyObject *myself)
|
|
||||||
{
|
|
||||||
CThunkObject *self = (CThunkObject *)myself;
|
|
||||||
PyObject_GC_UnTrack(self);
|
|
||||||
Py_XDECREF(self->converters);
|
|
||||||
Py_XDECREF(self->callable);
|
|
||||||
Py_XDECREF(self->restype);
|
|
||||||
if (self->pcl_write)
|
|
||||||
Py_ffi_closure_free(self->pcl_write);
|
|
||||||
PyObject_GC_Del(self);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
CThunkObject_traverse(PyObject *myself, visitproc visit, void *arg)
|
CThunkObject_traverse(PyObject *myself, visitproc visit, void *arg)
|
||||||
{
|
{
|
||||||
CThunkObject *self = (CThunkObject *)myself;
|
CThunkObject *self = (CThunkObject *)myself;
|
||||||
|
Py_VISIT(Py_TYPE(self));
|
||||||
Py_VISIT(self->converters);
|
Py_VISIT(self->converters);
|
||||||
Py_VISIT(self->callable);
|
Py_VISIT(self->callable);
|
||||||
Py_VISIT(self->restype);
|
Py_VISIT(self->restype);
|
||||||
|
@ -61,36 +49,35 @@ CThunkObject_clear(PyObject *myself)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyTypeObject PyCThunk_Type = {
|
static void
|
||||||
PyVarObject_HEAD_INIT(NULL, 0)
|
CThunkObject_dealloc(PyObject *myself)
|
||||||
"_ctypes.CThunkObject",
|
{
|
||||||
sizeof(CThunkObject), /* tp_basicsize */
|
CThunkObject *self = (CThunkObject *)myself;
|
||||||
sizeof(ffi_type), /* tp_itemsize */
|
PyTypeObject *tp = Py_TYPE(myself);
|
||||||
CThunkObject_dealloc, /* tp_dealloc */
|
PyObject_GC_UnTrack(self);
|
||||||
0, /* tp_vectorcall_offset */
|
(void)CThunkObject_clear(myself);
|
||||||
0, /* tp_getattr */
|
if (self->pcl_write) {
|
||||||
0, /* tp_setattr */
|
Py_ffi_closure_free(self->pcl_write);
|
||||||
0, /* tp_as_async */
|
}
|
||||||
0, /* tp_repr */
|
PyObject_GC_Del(self);
|
||||||
0, /* tp_as_number */
|
Py_DECREF(tp);
|
||||||
0, /* tp_as_sequence */
|
}
|
||||||
0, /* tp_as_mapping */
|
|
||||||
0, /* tp_hash */
|
static PyType_Slot cthunk_slots[] = {
|
||||||
0, /* tp_call */
|
{Py_tp_doc, (void *)PyDoc_STR("CThunkObject")},
|
||||||
0, /* tp_str */
|
{Py_tp_dealloc, CThunkObject_dealloc},
|
||||||
0, /* tp_getattro */
|
{Py_tp_traverse, CThunkObject_traverse},
|
||||||
0, /* tp_setattro */
|
{Py_tp_clear, CThunkObject_clear},
|
||||||
0, /* tp_as_buffer */
|
{0, NULL},
|
||||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
|
};
|
||||||
PyDoc_STR("CThunkObject"), /* tp_doc */
|
|
||||||
CThunkObject_traverse, /* tp_traverse */
|
PyType_Spec cthunk_spec = {
|
||||||
CThunkObject_clear, /* tp_clear */
|
.name = "_ctypes.CThunkObject",
|
||||||
0, /* tp_richcompare */
|
.basicsize = sizeof(CThunkObject),
|
||||||
0, /* tp_weaklistoffset */
|
.itemsize = sizeof(ffi_type),
|
||||||
0, /* tp_iter */
|
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
|
||||||
0, /* tp_iternext */
|
Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION),
|
||||||
0, /* tp_methods */
|
.slots = cthunk_slots,
|
||||||
0, /* tp_members */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**************************************************************/
|
/**************************************************************/
|
||||||
|
@ -320,7 +307,8 @@ static CThunkObject* CThunkObject_new(Py_ssize_t nargs)
|
||||||
CThunkObject *p;
|
CThunkObject *p;
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
|
|
||||||
p = PyObject_GC_NewVar(CThunkObject, &PyCThunk_Type, nargs);
|
ctypes_state *st = GLOBAL_STATE();
|
||||||
|
p = PyObject_GC_NewVar(CThunkObject, st->PyCThunk_Type, nargs);
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -357,7 +345,10 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable,
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
assert(CThunk_CheckExact((PyObject *)p));
|
#ifdef Py_DEBUG
|
||||||
|
ctypes_state *st = GLOBAL_STATE();
|
||||||
|
assert(CThunk_CheckExact(st, (PyObject *)p));
|
||||||
|
#endif
|
||||||
|
|
||||||
p->pcl_write = Py_ffi_closure_alloc(sizeof(ffi_closure), &p->pcl_exec);
|
p->pcl_write = Py_ffi_closure_alloc(sizeof(ffi_closure), &p->pcl_exec);
|
||||||
if (p->pcl_write == NULL) {
|
if (p->pcl_write == NULL) {
|
||||||
|
|
|
@ -469,21 +469,41 @@ PyCArgObject *
|
||||||
PyCArgObject_new(void)
|
PyCArgObject_new(void)
|
||||||
{
|
{
|
||||||
PyCArgObject *p;
|
PyCArgObject *p;
|
||||||
p = PyObject_New(PyCArgObject, &PyCArg_Type);
|
ctypes_state *st = GLOBAL_STATE();
|
||||||
|
p = PyObject_GC_New(PyCArgObject, st->PyCArg_Type);
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
p->pffi_type = NULL;
|
p->pffi_type = NULL;
|
||||||
p->tag = '\0';
|
p->tag = '\0';
|
||||||
p->obj = NULL;
|
p->obj = NULL;
|
||||||
memset(&p->value, 0, sizeof(p->value));
|
memset(&p->value, 0, sizeof(p->value));
|
||||||
|
PyObject_GC_Track(p);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
PyCArg_traverse(PyCArgObject *self, visitproc visit, void *arg)
|
||||||
|
{
|
||||||
|
Py_VISIT(Py_TYPE(self));
|
||||||
|
Py_VISIT(self->obj);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
PyCArg_clear(PyCArgObject *self)
|
||||||
|
{
|
||||||
|
Py_CLEAR(self->obj);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
PyCArg_dealloc(PyCArgObject *self)
|
PyCArg_dealloc(PyCArgObject *self)
|
||||||
{
|
{
|
||||||
Py_XDECREF(self->obj);
|
PyTypeObject *tp = Py_TYPE(self);
|
||||||
PyObject_Free(self);
|
PyObject_GC_UnTrack(self);
|
||||||
|
(void)PyCArg_clear(self);
|
||||||
|
tp->tp_free((PyObject *)self);
|
||||||
|
Py_DECREF(tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -567,36 +587,21 @@ static PyMemberDef PyCArgType_members[] = {
|
||||||
{ NULL },
|
{ NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
PyTypeObject PyCArg_Type = {
|
static PyType_Slot carg_slots[] = {
|
||||||
PyVarObject_HEAD_INIT(NULL, 0)
|
{Py_tp_dealloc, PyCArg_dealloc},
|
||||||
"CArgObject",
|
{Py_tp_traverse, PyCArg_traverse},
|
||||||
sizeof(PyCArgObject),
|
{Py_tp_clear, PyCArg_clear},
|
||||||
0,
|
{Py_tp_repr, PyCArg_repr},
|
||||||
(destructor)PyCArg_dealloc, /* tp_dealloc */
|
{Py_tp_members, PyCArgType_members},
|
||||||
0, /* tp_vectorcall_offset */
|
{0, NULL},
|
||||||
0, /* tp_getattr */
|
};
|
||||||
0, /* tp_setattr */
|
|
||||||
0, /* tp_as_async */
|
PyType_Spec carg_spec = {
|
||||||
(reprfunc)PyCArg_repr, /* tp_repr */
|
.name = "_ctypes.CArgObject",
|
||||||
0, /* tp_as_number */
|
.basicsize = sizeof(PyCArgObject),
|
||||||
0, /* tp_as_sequence */
|
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
|
||||||
0, /* tp_as_mapping */
|
Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION),
|
||||||
0, /* tp_hash */
|
.slots = carg_slots,
|
||||||
0, /* tp_call */
|
|
||||||
0, /* tp_str */
|
|
||||||
0, /* tp_getattro */
|
|
||||||
0, /* tp_setattro */
|
|
||||||
0, /* tp_as_buffer */
|
|
||||||
Py_TPFLAGS_DEFAULT, /* tp_flags */
|
|
||||||
0, /* tp_doc */
|
|
||||||
0, /* tp_traverse */
|
|
||||||
0, /* tp_clear */
|
|
||||||
0, /* tp_richcompare */
|
|
||||||
0, /* tp_weaklistoffset */
|
|
||||||
0, /* tp_iter */
|
|
||||||
0, /* tp_iternext */
|
|
||||||
0, /* tp_methods */
|
|
||||||
PyCArgType_members, /* tp_members */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************/
|
/****************************************************************/
|
||||||
|
@ -669,7 +674,8 @@ static int ConvParam(PyObject *obj, Py_ssize_t index, struct argument *pa)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PyCArg_CheckExact(obj)) {
|
ctypes_state *st = GLOBAL_STATE();
|
||||||
|
if (PyCArg_CheckExact(st, obj)) {
|
||||||
PyCArgObject *carg = (PyCArgObject *)obj;
|
PyCArgObject *carg = (PyCArgObject *)obj;
|
||||||
pa->ffi_type = carg->pffi_type;
|
pa->ffi_type = carg->pffi_type;
|
||||||
pa->keep = Py_NewRef(obj);
|
pa->keep = Py_NewRef(obj);
|
||||||
|
|
|
@ -61,7 +61,9 @@ PyCField_FromDesc(PyObject *desc, Py_ssize_t index,
|
||||||
#define CONT_BITFIELD 2
|
#define CONT_BITFIELD 2
|
||||||
#define EXPAND_BITFIELD 3
|
#define EXPAND_BITFIELD 3
|
||||||
|
|
||||||
self = (CFieldObject *)PyCField_Type.tp_alloc((PyTypeObject *)&PyCField_Type, 0);
|
ctypes_state *st = GLOBAL_STATE();
|
||||||
|
PyTypeObject *tp = st->PyCField_Type;
|
||||||
|
self = (CFieldObject *)tp->tp_alloc(tp, 0);
|
||||||
if (self == NULL)
|
if (self == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
dict = PyType_stgdict(desc);
|
dict = PyType_stgdict(desc);
|
||||||
|
@ -256,6 +258,7 @@ static PyGetSetDef PyCField_getset[] = {
|
||||||
static int
|
static int
|
||||||
PyCField_traverse(CFieldObject *self, visitproc visit, void *arg)
|
PyCField_traverse(CFieldObject *self, visitproc visit, void *arg)
|
||||||
{
|
{
|
||||||
|
Py_VISIT(Py_TYPE(self));
|
||||||
Py_VISIT(self->proto);
|
Py_VISIT(self->proto);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -270,9 +273,11 @@ PyCField_clear(CFieldObject *self)
|
||||||
static void
|
static void
|
||||||
PyCField_dealloc(PyObject *self)
|
PyCField_dealloc(PyObject *self)
|
||||||
{
|
{
|
||||||
|
PyTypeObject *tp = Py_TYPE(self);
|
||||||
PyObject_GC_UnTrack(self);
|
PyObject_GC_UnTrack(self);
|
||||||
PyCField_clear((CFieldObject *)self);
|
(void)PyCField_clear((CFieldObject *)self);
|
||||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||||
|
Py_DECREF(tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -296,46 +301,24 @@ PyCField_repr(CFieldObject *self)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyTypeObject PyCField_Type = {
|
static PyType_Slot cfield_slots[] = {
|
||||||
PyVarObject_HEAD_INIT(NULL, 0)
|
{Py_tp_dealloc, PyCField_dealloc},
|
||||||
"_ctypes.CField", /* tp_name */
|
{Py_tp_repr, PyCField_repr},
|
||||||
sizeof(CFieldObject), /* tp_basicsize */
|
{Py_tp_doc, (void *)PyDoc_STR("Structure/Union member")},
|
||||||
0, /* tp_itemsize */
|
{Py_tp_traverse, PyCField_traverse},
|
||||||
PyCField_dealloc, /* tp_dealloc */
|
{Py_tp_clear, PyCField_clear},
|
||||||
0, /* tp_vectorcall_offset */
|
{Py_tp_getset, PyCField_getset},
|
||||||
0, /* tp_getattr */
|
{Py_tp_descr_get, PyCField_get},
|
||||||
0, /* tp_setattr */
|
{Py_tp_descr_set, PyCField_set},
|
||||||
0, /* tp_as_async */
|
{0, NULL},
|
||||||
(reprfunc)PyCField_repr, /* tp_repr */
|
};
|
||||||
0, /* tp_as_number */
|
|
||||||
0, /* tp_as_sequence */
|
PyType_Spec cfield_spec = {
|
||||||
0, /* tp_as_mapping */
|
.name = "_ctypes.CField",
|
||||||
0, /* tp_hash */
|
.basicsize = sizeof(CFieldObject),
|
||||||
0, /* tp_call */
|
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
|
||||||
0, /* tp_str */
|
Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION),
|
||||||
0, /* tp_getattro */
|
.slots = cfield_slots,
|
||||||
0, /* tp_setattro */
|
|
||||||
0, /* tp_as_buffer */
|
|
||||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
|
|
||||||
PyDoc_STR("Structure/Union member"), /* tp_doc */
|
|
||||||
(traverseproc)PyCField_traverse, /* tp_traverse */
|
|
||||||
(inquiry)PyCField_clear, /* tp_clear */
|
|
||||||
0, /* tp_richcompare */
|
|
||||||
0, /* tp_weaklistoffset */
|
|
||||||
0, /* tp_iter */
|
|
||||||
0, /* tp_iternext */
|
|
||||||
0, /* tp_methods */
|
|
||||||
0, /* tp_members */
|
|
||||||
PyCField_getset, /* tp_getset */
|
|
||||||
0, /* tp_base */
|
|
||||||
0, /* tp_dict */
|
|
||||||
(descrgetfunc)PyCField_get, /* tp_descr_get */
|
|
||||||
(descrsetfunc)PyCField_set, /* tp_descr_set */
|
|
||||||
0, /* tp_dictoffset */
|
|
||||||
0, /* tp_init */
|
|
||||||
0, /* tp_alloc */
|
|
||||||
0, /* tp_new */
|
|
||||||
0, /* tp_free */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,22 @@
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PyTypeObject *DictRemover_Type;
|
||||||
|
PyTypeObject *PyCArg_Type;
|
||||||
|
PyTypeObject *PyCField_Type;
|
||||||
|
PyTypeObject *PyCThunk_Type;
|
||||||
|
PyTypeObject *StructParam_Type;
|
||||||
|
} ctypes_state;
|
||||||
|
|
||||||
|
extern ctypes_state global_state;
|
||||||
|
|
||||||
|
#define GLOBAL_STATE() (&global_state)
|
||||||
|
|
||||||
|
extern PyType_Spec carg_spec;
|
||||||
|
extern PyType_Spec cfield_spec;
|
||||||
|
extern PyType_Spec cthunk_spec;
|
||||||
|
|
||||||
typedef struct tagPyCArgObject PyCArgObject;
|
typedef struct tagPyCArgObject PyCArgObject;
|
||||||
typedef struct tagCDataObject CDataObject;
|
typedef struct tagCDataObject CDataObject;
|
||||||
typedef PyObject *(* GETFUNC)(void *, Py_ssize_t size);
|
typedef PyObject *(* GETFUNC)(void *, Py_ssize_t size);
|
||||||
|
@ -88,8 +104,7 @@ typedef struct {
|
||||||
ffi_type *ffi_restype;
|
ffi_type *ffi_restype;
|
||||||
ffi_type *atypes[1];
|
ffi_type *atypes[1];
|
||||||
} CThunkObject;
|
} CThunkObject;
|
||||||
extern PyTypeObject PyCThunk_Type;
|
#define CThunk_CheckExact(st, v) Py_IS_TYPE(v, st->PyCThunk_Type)
|
||||||
#define CThunk_CheckExact(v) Py_IS_TYPE(v, &PyCThunk_Type)
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* First part identical to tagCDataObject */
|
/* First part identical to tagCDataObject */
|
||||||
|
@ -141,7 +156,6 @@ extern PyTypeObject PyCSimpleType_Type;
|
||||||
#define PyCSimpleTypeObject_CheckExact(v) Py_IS_TYPE(v, &PyCSimpleType_Type)
|
#define PyCSimpleTypeObject_CheckExact(v) Py_IS_TYPE(v, &PyCSimpleType_Type)
|
||||||
#define PyCSimpleTypeObject_Check(v) PyObject_TypeCheck(v, &PyCSimpleType_Type)
|
#define PyCSimpleTypeObject_Check(v) PyObject_TypeCheck(v, &PyCSimpleType_Type)
|
||||||
|
|
||||||
extern PyTypeObject PyCField_Type;
|
|
||||||
extern struct fielddesc *_ctypes_get_fielddesc(const char *fmt);
|
extern struct fielddesc *_ctypes_get_fielddesc(const char *fmt);
|
||||||
|
|
||||||
|
|
||||||
|
@ -334,8 +348,7 @@ struct tagPyCArgObject {
|
||||||
Py_ssize_t size; /* for the 'V' tag */
|
Py_ssize_t size; /* for the 'V' tag */
|
||||||
};
|
};
|
||||||
|
|
||||||
extern PyTypeObject PyCArg_Type;
|
#define PyCArg_CheckExact(st, v) Py_IS_TYPE(v, st->PyCArg_Type)
|
||||||
#define PyCArg_CheckExact(v) Py_IS_TYPE(v, &PyCArg_Type)
|
|
||||||
extern PyCArgObject *PyCArgObject_new(void);
|
extern PyCArgObject *PyCArgObject_new(void);
|
||||||
|
|
||||||
extern PyObject *
|
extern PyObject *
|
||||||
|
|
|
@ -225,6 +225,8 @@ MakeFields(PyObject *type, CFieldObject *descr,
|
||||||
if (fieldlist == NULL)
|
if (fieldlist == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
ctypes_state *st = GLOBAL_STATE();
|
||||||
|
PyTypeObject *cfield_tp = st->PyCField_Type;
|
||||||
for (i = 0; i < PySequence_Fast_GET_SIZE(fieldlist); ++i) {
|
for (i = 0; i < PySequence_Fast_GET_SIZE(fieldlist); ++i) {
|
||||||
PyObject *pair = PySequence_Fast_GET_ITEM(fieldlist, i); /* borrowed */
|
PyObject *pair = PySequence_Fast_GET_ITEM(fieldlist, i); /* borrowed */
|
||||||
PyObject *fname, *ftype, *bits;
|
PyObject *fname, *ftype, *bits;
|
||||||
|
@ -240,7 +242,7 @@ MakeFields(PyObject *type, CFieldObject *descr,
|
||||||
Py_DECREF(fieldlist);
|
Py_DECREF(fieldlist);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (!Py_IS_TYPE(fdescr, &PyCField_Type)) {
|
if (!Py_IS_TYPE(fdescr, cfield_tp)) {
|
||||||
PyErr_SetString(PyExc_TypeError, "unexpected type");
|
PyErr_SetString(PyExc_TypeError, "unexpected type");
|
||||||
Py_DECREF(fdescr);
|
Py_DECREF(fdescr);
|
||||||
Py_DECREF(fieldlist);
|
Py_DECREF(fieldlist);
|
||||||
|
@ -257,13 +259,13 @@ MakeFields(PyObject *type, CFieldObject *descr,
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
new_descr = (CFieldObject *)PyCField_Type.tp_alloc((PyTypeObject *)&PyCField_Type, 0);
|
new_descr = (CFieldObject *)cfield_tp->tp_alloc(cfield_tp, 0);
|
||||||
if (new_descr == NULL) {
|
if (new_descr == NULL) {
|
||||||
Py_DECREF(fdescr);
|
Py_DECREF(fdescr);
|
||||||
Py_DECREF(fieldlist);
|
Py_DECREF(fieldlist);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
assert(Py_IS_TYPE(new_descr, &PyCField_Type));
|
assert(Py_IS_TYPE(new_descr, cfield_tp));
|
||||||
new_descr->size = fdescr->size;
|
new_descr->size = fdescr->size;
|
||||||
new_descr->offset = fdescr->offset + offset;
|
new_descr->offset = fdescr->offset + offset;
|
||||||
new_descr->index = fdescr->index + index;
|
new_descr->index = fdescr->index + index;
|
||||||
|
@ -304,6 +306,8 @@ MakeAnonFields(PyObject *type)
|
||||||
if (anon_names == NULL)
|
if (anon_names == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
ctypes_state *st = GLOBAL_STATE();
|
||||||
|
PyTypeObject *cfield_tp = st->PyCField_Type;
|
||||||
for (i = 0; i < PySequence_Fast_GET_SIZE(anon_names); ++i) {
|
for (i = 0; i < PySequence_Fast_GET_SIZE(anon_names); ++i) {
|
||||||
PyObject *fname = PySequence_Fast_GET_ITEM(anon_names, i); /* borrowed */
|
PyObject *fname = PySequence_Fast_GET_ITEM(anon_names, i); /* borrowed */
|
||||||
CFieldObject *descr = (CFieldObject *)PyObject_GetAttr(type, fname);
|
CFieldObject *descr = (CFieldObject *)PyObject_GetAttr(type, fname);
|
||||||
|
@ -311,7 +315,7 @@ MakeAnonFields(PyObject *type)
|
||||||
Py_DECREF(anon_names);
|
Py_DECREF(anon_names);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (!Py_IS_TYPE(descr, &PyCField_Type)) {
|
if (!Py_IS_TYPE(descr, cfield_tp)) {
|
||||||
PyErr_Format(PyExc_AttributeError,
|
PyErr_Format(PyExc_AttributeError,
|
||||||
"'%U' is specified in _anonymous_ but not in "
|
"'%U' is specified in _anonymous_ but not in "
|
||||||
"_fields_",
|
"_fields_",
|
||||||
|
|
|
@ -341,7 +341,6 @@ Modules/_testcapi/vectorcall.c - MethodDescriptor2_Type -
|
||||||
##-----------------------
|
##-----------------------
|
||||||
## static types
|
## static types
|
||||||
|
|
||||||
Modules/_ctypes/_ctypes.c - DictRemover_Type -
|
|
||||||
Modules/_ctypes/_ctypes.c - PyCArrayType_Type -
|
Modules/_ctypes/_ctypes.c - PyCArrayType_Type -
|
||||||
Modules/_ctypes/_ctypes.c - PyCArray_Type -
|
Modules/_ctypes/_ctypes.c - PyCArray_Type -
|
||||||
Modules/_ctypes/_ctypes.c - PyCData_Type -
|
Modules/_ctypes/_ctypes.c - PyCData_Type -
|
||||||
|
@ -352,18 +351,14 @@ Modules/_ctypes/_ctypes.c - PyCPointer_Type -
|
||||||
Modules/_ctypes/_ctypes.c - PyCSimpleType_Type -
|
Modules/_ctypes/_ctypes.c - PyCSimpleType_Type -
|
||||||
Modules/_ctypes/_ctypes.c - PyCStructType_Type -
|
Modules/_ctypes/_ctypes.c - PyCStructType_Type -
|
||||||
Modules/_ctypes/_ctypes.c - Simple_Type -
|
Modules/_ctypes/_ctypes.c - Simple_Type -
|
||||||
Modules/_ctypes/_ctypes.c - StructParam_Type -
|
|
||||||
Modules/_ctypes/_ctypes.c - Struct_Type -
|
Modules/_ctypes/_ctypes.c - Struct_Type -
|
||||||
Modules/_ctypes/_ctypes.c - UnionType_Type -
|
Modules/_ctypes/_ctypes.c - UnionType_Type -
|
||||||
Modules/_ctypes/_ctypes.c - Union_Type -
|
Modules/_ctypes/_ctypes.c - Union_Type -
|
||||||
Modules/_ctypes/callbacks.c - PyCThunk_Type -
|
|
||||||
Modules/_ctypes/callproc.c - PyCArg_Type -
|
Modules/_ctypes/callproc.c - PyCArg_Type -
|
||||||
Modules/_ctypes/cfield.c - PyCField_Type -
|
|
||||||
Modules/_ctypes/ctypes.h - PyCArg_Type -
|
Modules/_ctypes/ctypes.h - PyCArg_Type -
|
||||||
Modules/_ctypes/ctypes.h - PyCArrayType_Type -
|
Modules/_ctypes/ctypes.h - PyCArrayType_Type -
|
||||||
Modules/_ctypes/ctypes.h - PyCArray_Type -
|
Modules/_ctypes/ctypes.h - PyCArray_Type -
|
||||||
Modules/_ctypes/ctypes.h - PyCData_Type -
|
Modules/_ctypes/ctypes.h - PyCData_Type -
|
||||||
Modules/_ctypes/ctypes.h - PyCField_Type -
|
|
||||||
Modules/_ctypes/ctypes.h - PyCFuncPtrType_Type -
|
Modules/_ctypes/ctypes.h - PyCFuncPtrType_Type -
|
||||||
Modules/_ctypes/ctypes.h - PyCFuncPtr_Type -
|
Modules/_ctypes/ctypes.h - PyCFuncPtr_Type -
|
||||||
Modules/_ctypes/ctypes.h - PyCPointerType_Type -
|
Modules/_ctypes/ctypes.h - PyCPointerType_Type -
|
||||||
|
@ -371,7 +366,6 @@ Modules/_ctypes/ctypes.h - PyCPointer_Type -
|
||||||
Modules/_ctypes/ctypes.h - PyCSimpleType_Type -
|
Modules/_ctypes/ctypes.h - PyCSimpleType_Type -
|
||||||
Modules/_ctypes/ctypes.h - PyCStgDict_Type -
|
Modules/_ctypes/ctypes.h - PyCStgDict_Type -
|
||||||
Modules/_ctypes/ctypes.h - PyCStructType_Type -
|
Modules/_ctypes/ctypes.h - PyCStructType_Type -
|
||||||
Modules/_ctypes/ctypes.h - PyCThunk_Type -
|
|
||||||
Modules/_ctypes/ctypes.h - PyExc_ArgError -
|
Modules/_ctypes/ctypes.h - PyExc_ArgError -
|
||||||
Modules/_ctypes/ctypes.h - _ctypes_conversion_encoding -
|
Modules/_ctypes/ctypes.h - _ctypes_conversion_encoding -
|
||||||
Modules/_ctypes/ctypes.h - _ctypes_conversion_errors -
|
Modules/_ctypes/ctypes.h - _ctypes_conversion_errors -
|
||||||
|
@ -454,6 +448,8 @@ Modules/_decimal/_decimal.c - SignalTuple -
|
||||||
Modules/_asynciomodule.c - fi_freelist -
|
Modules/_asynciomodule.c - fi_freelist -
|
||||||
Modules/_asynciomodule.c - fi_freelist_len -
|
Modules/_asynciomodule.c - fi_freelist_len -
|
||||||
Modules/_ctypes/_ctypes.c - _ctypes_ptrtype_cache -
|
Modules/_ctypes/_ctypes.c - _ctypes_ptrtype_cache -
|
||||||
|
Modules/_ctypes/_ctypes.c - global_state -
|
||||||
|
Modules/_ctypes/ctypes.h - global_state -
|
||||||
Modules/_tkinter.c - tcl_lock -
|
Modules/_tkinter.c - tcl_lock -
|
||||||
Modules/_tkinter.c - excInCmd -
|
Modules/_tkinter.c - excInCmd -
|
||||||
Modules/_tkinter.c - valInCmd -
|
Modules/_tkinter.c - valInCmd -
|
||||||
|
|
Can't render this file because it has a wrong number of fields in line 4.
|
Loading…
Reference in New Issue