Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 58 additions & 38 deletions Modules/_ctypes/_ctypes.c
Original file line numberDiff line numberDiff line change
Expand Up@@ -1149,7 +1149,8 @@ PyCPointerType_from_param(PyObject *type, PyObject *value)
break;
}

if (PointerObject_Check(value) || ArrayObject_Check(value)){
ctypes_state *state = GLOBAL_STATE();
if (PointerObject_Check(state, value) || ArrayObject_Check(state, value)){
/* Array instances are also pointers when
the item types are the same.
*/
Expand DownExpand Up@@ -1587,7 +1588,8 @@ c_wchar_p_from_param(PyObject *type, PyObject *value)
if (res){
return Py_NewRef(value);
}
if (ArrayObject_Check(value) || PointerObject_Check(value)){
ctypes_state *state = GLOBAL_STATE();
if (ArrayObject_Check(state, value) || PointerObject_Check(state, value)){
/* c_wchar array instance or pointer(c_wchar(...)) */
StgDictObject *dt = PyObject_stgdict(value);
StgDictObject *dict;
Expand DownExpand Up@@ -1651,7 +1653,8 @@ c_char_p_from_param(PyObject *type, PyObject *value)
if (res){
return Py_NewRef(value);
}
if (ArrayObject_Check(value) || PointerObject_Check(value)){
ctypes_state *state = GLOBAL_STATE();
if (ArrayObject_Check(state, value) || PointerObject_Check(state, value)){
/* c_char array instance or pointer(c_char(...)) */
StgDictObject *dt = PyObject_stgdict(value);
StgDictObject *dict;
Expand DownExpand Up@@ -1758,21 +1761,21 @@ c_void_p_from_param(PyObject *type, PyObject *value)
return Py_NewRef(value);
}
/* ctypes array or pointer instance */
if (ArrayObject_Check(value) || PointerObject_Check(value)){
ctypes_state *state = GLOBAL_STATE();
if (ArrayObject_Check(state, value) || PointerObject_Check(state, value)){
/* Any array or pointer is accepted */
return Py_NewRef(value);
}
/* byref(...) */
ctypes_state *st = GLOBAL_STATE();
if (PyCArg_CheckExact(st, value)){
if (PyCArg_CheckExact(state, value)){
/* byref(c_xxx()) */
PyCArgObject *a = (PyCArgObject *)value;
if (a->tag == 'P'){
return Py_NewRef(value);
}
}
/* function pointer */
if (PyCFuncPtrObject_Check(value)){
if (PyCFuncPtrObject_Check(state, value)){
PyCArgObject *parg;
PyCFuncPtrObject *func;
func = (PyCFuncPtrObject *)value;
Expand All@@ -1788,7 +1791,7 @@ c_void_p_from_param(PyObject *type, PyObject *value)
}
/* c_char_p, c_wchar_p */
stgd = PyObject_stgdict(value);
if (stgd && CDataObject_Check(value) && stgd->proto && PyUnicode_Check(stgd->proto)){
if (stgd && CDataObject_Check(state, value) && stgd->proto && PyUnicode_Check(stgd->proto)){
PyCArgObject *parg;

switch (PyUnicode_AsUTF8(stgd->proto)[0]){
Expand DownExpand Up@@ -2006,7 +2009,7 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)

stgdict->paramfunc = PyCSimpleType_paramfunc;
/*
if (result->tp_base != &Simple_Type){
if (result->tp_base != state->Simple_Type){
stgdict->setfunc = NULL;
stgdict->getfunc = NULL;
}
Expand All@@ -2026,7 +2029,8 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
/* Install from_param class methods in ctypes base classes.
Overrides the PyCSimpleType_from_param generic method.
*/
if (result->tp_base == &Simple_Type){
ctypes_state *state = GLOBAL_STATE();
if (result->tp_base == state->Simple_Type){
switch (*proto_str){
case 'z': /* c_char_p */
ml = &c_char_p_method;
Expand DownExpand Up@@ -2834,12 +2838,13 @@ PyCData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr)
cmem = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
if (cmem == NULL)
return NULL;
assert(CDataObject_Check(cmem));
ctypes_state *state = GLOBAL_STATE();
assert(CDataObject_Check(state, cmem));

cmem->b_length = dict->length;
cmem->b_size = dict->size;
if (base){/* use base's buffer */
assert(CDataObject_Check(base));
assert(CDataObject_Check(state, base));
cmem->b_ptr = adr;
cmem->b_needsfree = 0;
cmem->b_base = (CDataObject *)Py_NewRef(base);
Expand DownExpand Up@@ -2880,7 +2885,8 @@ PyCData_AtAddress(PyObject *type, void *buf)
pd = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
if (!pd)
return NULL;
assert(CDataObject_Check(pd));
ctypes_state *state = GLOBAL_STATE();
assert(CDataObject_Check(state, pd));
pd->b_ptr = (char *)buf;
pd->b_length = dict->length;
pd->b_size = dict->size;
Expand All@@ -2896,8 +2902,10 @@ int _ctypes_simple_instance(PyObject *obj)
{
PyTypeObject *type = (PyTypeObject *)obj;

if (PyCSimpleTypeObject_Check(type))
return type->tp_base != &Simple_Type;
if (PyCSimpleTypeObject_Check(type)){
ctypes_state *state = GLOBAL_STATE();
return type->tp_base != state->Simple_Type;
}
return 0;
}

Expand All@@ -2919,16 +2927,17 @@ PyCData_get(PyObject *type, GETFUNC getfunc, PyObject *src,
Helper function for PyCData_set below.
*/
static PyObject *
_PyCData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
Py_ssize_t size, char *ptr)
_PyCData_set(ctypes_state *state, CDataObject *dst, PyObject *type,
SETFUNC setfunc, PyObject *value,
Py_ssize_t size, char *ptr)
{
CDataObject *src;
int err;

if (setfunc)
return setfunc(ptr, value, size);

if (!CDataObject_Check(value)){
if (!CDataObject_Check(state, value)){
StgDictObject *dict = PyType_stgdict(type);
if (dict && dict->setfunc)
return dict->setfunc(ptr, value, size);
Expand All@@ -2946,8 +2955,8 @@ _PyCData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
((PyTypeObject *)type)->tp_name);
return NULL;
}
result = _PyCData_set(dst, type, setfunc, ob,
size, ptr);
result = _PyCData_set(state, dst, type, setfunc, ob,
size, ptr);
Py_DECREF(ob);
return result;
} else if (value == Py_None && PyCPointerTypeObject_Check(type)){
Expand DownExpand Up@@ -2983,7 +2992,7 @@ _PyCData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
}

if (PyCPointerTypeObject_Check(type)
&& ArrayObject_Check(value)){
&& ArrayObject_Check(state, value)){
StgDictObject *p1, *p2;
PyObject *keep;
p1 = PyObject_stgdict(value);
Expand DownExpand Up@@ -3032,14 +3041,15 @@ PyCData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
CDataObject *mem = (CDataObject *)dst;
PyObject *result;

if (!CDataObject_Check(dst)){
ctypes_state *state = GLOBAL_STATE();
if (!CDataObject_Check(state, dst)){
PyErr_SetString(PyExc_TypeError,
"not a ctype instance");
return -1;
}

result = _PyCData_set(mem, type, setfunc, value,
size, ptr);
result = _PyCData_set(state, mem, type, setfunc, value,
size, ptr);
if (result == NULL)
return -1;

Expand DownExpand Up@@ -3627,7 +3637,8 @@ static PyObject *
_byref(PyObject *obj)
{
PyCArgObject *parg;
if (!CDataObject_Check(obj)){
ctypes_state *state = GLOBAL_STATE();
if (!CDataObject_Check(state, obj)){
PyErr_SetString(PyExc_TypeError,
"expected CData instance");
return NULL;
Expand DownExpand Up@@ -3962,7 +3973,8 @@ PyCFuncPtr_call(PyCFuncPtrObject *self, PyObject *inargs, PyObject *kwds)
"native com method call without 'this' parameter");
return NULL;
}
if (!CDataObject_Check(this)){
ctypes_state *state = GLOBAL_STATE();
if (!CDataObject_Check(state, this)){
PyErr_SetString(PyExc_TypeError,
"Expected a COM this pointer as first argument");
return NULL;
Expand DownExpand Up@@ -4734,11 +4746,11 @@ PyCArrayType_from_ctype(PyObject *itemtype, Py_ssize_t length)
((PyTypeObject *)itemtype)->tp_name, (long)length);
#endif

ctypes_state *st = GLOBAL_STATE();
result = PyObject_CallFunction((PyObject *)st->PyCArrayType_Type,
ctypes_state *state = GLOBAL_STATE();
result = PyObject_CallFunction((PyObject *)state->PyCArrayType_Type,
"s(O){s:n,s:O}",
name,
&PyCArray_Type,
state->PyCArray_Type,
"_length_",
length,
"_type_",
Expand DownExpand Up@@ -4850,7 +4862,8 @@ Simple_repr(CDataObject *self)
{
PyObject *val, *result;

if (Py_TYPE(self)->tp_base != &Simple_Type){
ctypes_state *state = GLOBAL_STATE();
if (Py_TYPE(self)->tp_base != state->Simple_Type){
return PyUnicode_FromFormat("<%s object at %p>",
Py_TYPE(self)->tp_name, self);
}
Expand DownExpand Up@@ -5013,7 +5026,8 @@ Pointer_set_contents(CDataObject *self, PyObject *value, void *closure)
stgdict = PyObject_stgdict((PyObject *)self);
assert(stgdict); /* Cannot be NULL for pointer instances */
assert(stgdict->proto);
if (!CDataObject_Check(value)){
ctypes_state *state = GLOBAL_STATE();
if (!CDataObject_Check(state, value)){
int res = PyObject_IsInstance(value, stgdict->proto);
if (res == -1)
return -1;
Expand DownExpand Up@@ -5432,7 +5446,8 @@ cast(void *ptr, PyObject *src, PyObject *ctype)
It must certainly contain the source objects one.
It must contain the source object itself.
*/
if (CDataObject_Check(src)){
ctypes_state *state = GLOBAL_STATE();
if (CDataObject_Check(state, src)){
CDataObject *obj = (CDataObject *)src;
CDataObject *container;

Expand DownExpand Up@@ -5537,6 +5552,8 @@ _ctypes_add_types(PyObject *mod)
CREATE_TYPE(mod, st->PyCArg_Type, &carg_spec, NULL);
CREATE_TYPE(mod, st->PyCThunk_Type, &cthunk_spec, NULL);
TYPE_READY(&PyCData_Type);
st->PyCData_Type = &PyCData_Type;

/* StgDict is derived from PyDict_Type */
TYPE_READY_BASE(&PyCStgDict_Type, &PyDict_Type);

Expand All@@ -5561,12 +5578,15 @@ _ctypes_add_types(PyObject *mod)
* Classes using a custom metaclass
*/

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, st->PyCFuncPtrType_Type, &PyCData_Type);
MOD_ADD_TYPE(&Struct_Type, st->PyCStructType_Type, st->PyCData_Type);
MOD_ADD_TYPE(&Union_Type, st->UnionType_Type, st->PyCData_Type);
MOD_ADD_TYPE(&PyCPointer_Type, st->PyCPointerType_Type, st->PyCData_Type);
st->PyCPointer_Type = &PyCPointer_Type;
MOD_ADD_TYPE(&PyCArray_Type, st->PyCArrayType_Type, st->PyCData_Type);
st->PyCArray_Type = &PyCArray_Type;
MOD_ADD_TYPE(&Simple_Type, st->PyCSimpleType_Type, st->PyCData_Type);
st->Simple_Type = &Simple_Type;
MOD_ADD_TYPE(&PyCFuncPtr_Type, st->PyCFuncPtrType_Type, st->PyCData_Type);

/*************************************************
*
Expand Down
7 changes: 4 additions & 3 deletions Modules/_ctypes/callbacks.c
Original file line numberDiff line numberDiff line change
Expand Up@@ -144,7 +144,8 @@ static void _CallPythonObject(void *mem,
Py_ssize_t i = 0, j = 0, nargs = 0;
PyObject *error_object = NULL;
int *space;
PyGILState_STATE state = PyGILState_Ensure();
PyGILState_STATE gil_state = PyGILState_Ensure();
ctypes_state *state = GLOBAL_STATE();

assert(PyTuple_Check(converters));
nargs = PyTuple_GET_SIZE(converters);
Expand DownExpand Up@@ -175,7 +176,7 @@ static void _CallPythonObject(void *mem,
PrintError("create argument %zd:\n", i);
goto Done;
}
if (!CDataObject_Check(obj)){
if (!CDataObject_Check(state, obj)){
Py_DECREF(obj);
PrintError("unexpected result of create argument %zd:\n", i);
goto Done;
Expand DownExpand Up@@ -285,7 +286,7 @@ static void _CallPythonObject(void *mem,
for (j = 0; j < i; j++){
Py_DECREF(args[j]);
}
PyGILState_Release(state);
PyGILState_Release(gil_state);
}

static void closure_fcn(ffi_cif *cif,
Expand Down
20 changes: 13 additions & 7 deletions Modules/_ctypes/callproc.c
Original file line numberDiff line numberDiff line change
Expand Up@@ -1689,8 +1689,10 @@ sizeof_func(PyObject *self, PyObject *obj)
if (dict)
return PyLong_FromSsize_t(dict->size);

if (CDataObject_Check(obj))
ctypes_state *state = GLOBAL_STATE();
if (CDataObject_Check(state, obj)){
return PyLong_FromSsize_t(((CDataObject *)obj)->b_size);
}
PyErr_SetString(PyExc_TypeError,
"this type has no size");
return NULL;
Expand DownExpand Up@@ -1744,7 +1746,8 @@ byref(PyObject *self, PyObject *args)
if (offset == -1 && PyErr_Occurred())
return NULL;
}
if (!CDataObject_Check(obj)){
ctypes_state *state = GLOBAL_STATE();
if (!CDataObject_Check(state, obj)){
PyErr_Format(PyExc_TypeError,
"byref() argument must be a ctypes instance, not '%s'",
Py_TYPE(obj)->tp_name);
Expand All@@ -1769,7 +1772,8 @@ PyDoc_STRVAR(addressof_doc,
static PyObject *
addressof(PyObject *self, PyObject *obj)
{
if (!CDataObject_Check(obj)){
ctypes_state *state = GLOBAL_STATE();
if (!CDataObject_Check(state, obj)){
PyErr_SetString(PyExc_TypeError,
"invalid type");
return NULL;
Expand DownExpand Up@@ -1925,13 +1929,15 @@ create_pointer_type(PyObject *module, PyObject *cls)
// found or error
return result;
}

// not found
ctypes_state *state = GLOBAL_STATE();
if (PyUnicode_CheckExact(cls)){
PyObject *name = PyUnicode_FromFormat("LP_%U", cls);
result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type),
result = PyObject_CallFunction((PyObject *)Py_TYPE(state->PyCPointer_Type),
"N(O){}",
name,
&PyCPointer_Type);
state->PyCPointer_Type);
if (result == NULL)
return result;
key = PyLong_FromVoidPtr(result);
Expand All@@ -1942,10 +1948,10 @@ create_pointer_type(PyObject *module, PyObject *cls)
} else if (PyType_Check(cls)){
typ = (PyTypeObject *)cls;
PyObject *name = PyUnicode_FromFormat("LP_%s", typ->tp_name);
result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type),
result = PyObject_CallFunction((PyObject *)Py_TYPE(state->PyCPointer_Type),
"N(O){sO}",
name,
&PyCPointer_Type,
state->PyCPointer_Type,
"_type_", cls);
if (result == NULL)
return result;
Expand Down
6 changes: 4 additions & 2 deletions Modules/_ctypes/cfield.c
Original file line numberDiff line numberDiff line change
Expand Up@@ -204,7 +204,8 @@ PyCField_set(CFieldObject *self, PyObject *inst, PyObject *value)
{
CDataObject *dst;
char *ptr;
if (!CDataObject_Check(inst)){
ctypes_state *state = GLOBAL_STATE();
if (!CDataObject_Check(state, inst)){
PyErr_SetString(PyExc_TypeError,
"not a ctype instance");
return -1;
Expand All@@ -227,7 +228,8 @@ PyCField_get(CFieldObject *self, PyObject *inst, PyTypeObject *type)
if (inst == NULL){
return Py_NewRef(self);
}
if (!CDataObject_Check(inst)){
ctypes_state *state = GLOBAL_STATE();
if (!CDataObject_Check(state, inst)){
PyErr_SetString(PyExc_TypeError,
"not a ctype instance");
return NULL;
Expand Down
Loading