]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-103092: Ensure `_ctypes.c` static types are accessed via global state (#113857)
authorneonene <53406459+neonene@users.noreply.github.com>
Mon, 22 Jan 2024 13:40:36 +0000 (22:40 +0900)
committerGitHub <noreply@github.com>
Mon, 22 Jan 2024 13:40:36 +0000 (14:40 +0100)
Modules/_ctypes/_ctypes.c
Modules/_ctypes/callbacks.c
Modules/_ctypes/callproc.c
Modules/_ctypes/cfield.c
Modules/_ctypes/ctypes.h
Modules/_ctypes/stgdict.c

index b51a03b5497fed5b895e9c006ccfa00007e7de8f..94245ae41afffc6600678ec11d0392db8ae13f2e 100644 (file)
@@ -128,15 +128,26 @@ bytes(cdata)
 
 #include "pycore_long.h"          // _PyLong_GetZero()
 
-ctypes_state global_state;
+static PyTypeObject Union_Type;
+static PyTypeObject Struct_Type;
+static PyTypeObject Simple_Type;
+
+ctypes_state global_state = {
+    .PyCStgDict_Type = &PyCStgDict_Type,
+    .PyCData_Type = &PyCData_Type,
+    .Struct_Type = &Struct_Type,
+    .Union_Type = &Union_Type,
+    .PyCArray_Type = &PyCArray_Type,
+    .Simple_Type = &Simple_Type,
+    .PyCPointer_Type = &PyCPointer_Type,
+    .PyCFuncPtr_Type = &PyCFuncPtr_Type,
+};
 
 PyObject *PyExc_ArgError = NULL;
 
 /* This dict maps ctypes types to POINTER types */
 PyObject *_ctypes_ptrtype_cache = NULL;
 
-static PyTypeObject Simple_Type;
-
 /* a callable object used for unpickling:
    strong reference to _ctypes._unpickle() function */
 static PyObject *_unpickle;
@@ -521,14 +532,16 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt
 
     /* keep this for bw compatibility */
     int r = PyDict_Contains(result->tp_dict, &_Py_ID(_abstract_));
-    if (r > 0)
+    if (r > 0) {
         return (PyObject *)result;
+    }
     if (r < 0) {
         Py_DECREF(result);
         return NULL;
     }
 
-    dict = (StgDictObject *)_PyObject_CallNoArgs((PyObject *)&PyCStgDict_Type);
+    ctypes_state *st = GLOBAL_STATE();
+    dict = (StgDictObject *)_PyObject_CallNoArgs((PyObject *)st->PyCStgDict_Type);
     if (!dict) {
         Py_DECREF(result);
         return NULL;
@@ -568,8 +581,9 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt
     else {
         StgDictObject *basedict = PyType_stgdict((PyObject *)result->tp_base);
 
-        if (basedict == NULL)
+        if (basedict == NULL) {
             return (PyObject *)result;
+        }
         /* copy base dict */
         if (-1 == PyCStgDict_clone(dict, basedict)) {
             Py_DECREF(result);
@@ -1023,16 +1037,19 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
 
     typedict = PyTuple_GetItem(args, 2);
-    if (!typedict)
+    if (!typedict) {
         return NULL;
+    }
 /*
   stgdict items size, align, length contain info about pointers itself,
   stgdict->proto has info about the pointed to type!
 */
+    ctypes_state *st = GLOBAL_STATE();
     stgdict = (StgDictObject *)_PyObject_CallNoArgs(
-        (PyObject *)&PyCStgDict_Type);
-    if (!stgdict)
+        (PyObject *)st->PyCStgDict_Type);
+    if (!stgdict) {
         return NULL;
+    }
     stgdict->size = sizeof(void *);
     stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment;
     stgdict->length = 1;
@@ -1149,7 +1166,8 @@ PyCPointerType_from_param(PyObject *type, PyObject *value)
         break;
     }
 
-    if (PointerObject_Check(value) || ArrayObject_Check(value)) {
+    ctypes_state *st = GLOBAL_STATE();
+    if (PointerObject_Check(st, value) || ArrayObject_Check(st, value)) {
         /* Array instances are also pointers when
            the item types are the same.
         */
@@ -1448,11 +1466,12 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
         goto error;
     }
 
+    ctypes_state *st = GLOBAL_STATE();
     stgdict = (StgDictObject *)_PyObject_CallNoArgs(
-        (PyObject *)&PyCStgDict_Type);
-    if (!stgdict)
+        (PyObject *)st->PyCStgDict_Type);
+    if (!stgdict) {
         goto error;
-
+    }
     itemdict = PyType_stgdict(type_attr);
     if (!itemdict) {
         PyErr_SetString(PyExc_TypeError,
@@ -1587,7 +1606,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 *st = GLOBAL_STATE();
+    if (ArrayObject_Check(st, value) || PointerObject_Check(st, value)) {
         /* c_wchar array instance or pointer(c_wchar(...)) */
         StgDictObject *dt = PyObject_stgdict(value);
         StgDictObject *dict;
@@ -1597,7 +1617,6 @@ c_wchar_p_from_param(PyObject *type, PyObject *value)
             return Py_NewRef(value);
         }
     }
-    ctypes_state *st = GLOBAL_STATE();
     if (PyCArg_CheckExact(st, value)) {
         /* byref(c_char(...)) */
         PyCArgObject *a = (PyCArgObject *)value;
@@ -1651,7 +1670,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 *st = GLOBAL_STATE();
+    if (ArrayObject_Check(st, value) || PointerObject_Check(st, value)) {
         /* c_char array instance or pointer(c_char(...)) */
         StgDictObject *dt = PyObject_stgdict(value);
         StgDictObject *dict;
@@ -1661,7 +1681,6 @@ c_char_p_from_param(PyObject *type, PyObject *value)
             return Py_NewRef(value);
         }
     }
-    ctypes_state *st = GLOBAL_STATE();
     if (PyCArg_CheckExact(st, value)) {
         /* byref(c_char(...)) */
         PyCArgObject *a = (PyCArgObject *)value;
@@ -1757,13 +1776,13 @@ c_void_p_from_param(PyObject *type, PyObject *value)
         /* c_void_p instances */
         return Py_NewRef(value);
     }
+    ctypes_state *st = GLOBAL_STATE();
 /* ctypes array or pointer instance */
-    if (ArrayObject_Check(value) || PointerObject_Check(value)) {
+    if (ArrayObject_Check(st, value) || PointerObject_Check(st, value)) {
         /* Any array or pointer is accepted */
         return Py_NewRef(value);
     }
 /* byref(...) */
-    ctypes_state *st = GLOBAL_STATE();
     if (PyCArg_CheckExact(st, value)) {
         /* byref(c_xxx()) */
         PyCArgObject *a = (PyCArgObject *)value;
@@ -1772,7 +1791,7 @@ c_void_p_from_param(PyObject *type, PyObject *value)
         }
     }
 /* function pointer */
-    if (PyCFuncPtrObject_Check(value)) {
+    if (PyCFuncPtrObject_Check(st, value)) {
         PyCArgObject *parg;
         PyCFuncPtrObject *func;
         func = (PyCFuncPtrObject *)value;
@@ -1788,7 +1807,11 @@ 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(st, value)
+        && stgd->proto
+        && PyUnicode_Check(stgd->proto))
+    {
         PyCArgObject *parg;
 
         switch (PyUnicode_AsUTF8(stgd->proto)[0]) {
@@ -1870,8 +1893,9 @@ static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject
     if (result == NULL)
         return NULL;
 
+    ctypes_state *st = GLOBAL_STATE();
     stgdict = (StgDictObject *)_PyObject_CallNoArgs(
-        (PyObject *)&PyCStgDict_Type);
+        (PyObject *)st->PyCStgDict_Type);
     if (!stgdict) {
         Py_DECREF(result);
         return NULL;
@@ -1981,11 +2005,12 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
         goto error;
     }
 
+    ctypes_state *st = GLOBAL_STATE();
     stgdict = (StgDictObject *)_PyObject_CallNoArgs(
-        (PyObject *)&PyCStgDict_Type);
-    if (!stgdict)
+        (PyObject *)st->PyCStgDict_Type);
+    if (!stgdict) {
         goto error;
-
+    }
     stgdict->ffi_type_pointer = *fmt->pffi_type;
     stgdict->align = fmt->pffi_type->alignment;
     stgdict->length = 0;
@@ -2006,7 +2031,7 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
     stgdict->paramfunc = PyCSimpleType_paramfunc;
 /*
-    if (result->tp_base != &Simple_Type) {
+    if (result->tp_base != st->Simple_Type) {
         stgdict->setfunc = NULL;
         stgdict->getfunc = NULL;
     }
@@ -2026,7 +2051,7 @@ 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) {
+    if (result->tp_base == st->Simple_Type) {
         switch (*proto_str) {
         case 'z': /* c_char_p */
             ml = &c_char_p_method;
@@ -2070,7 +2095,6 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
         }
     }
 
-    ctypes_state *st = GLOBAL_STATE();
     if (type == st->PyCSimpleType_Type
         && fmt->setfunc_swapped
         && fmt->getfunc_swapped)
@@ -2408,11 +2432,12 @@ PyCFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     PyTypeObject *result;
     StgDictObject *stgdict;
 
+    ctypes_state *st = GLOBAL_STATE();
     stgdict = (StgDictObject *)_PyObject_CallNoArgs(
-        (PyObject *)&PyCStgDict_Type);
-    if (!stgdict)
+        (PyObject *)st->PyCStgDict_Type);
+    if (!stgdict) {
         return NULL;
-
+    }
     stgdict->paramfunc = PyCFuncPtrType_paramfunc;
     /* We do NOT expose the function signature in the format string.  It
        is impossible, generally, because the only requirement for the
@@ -2623,7 +2648,8 @@ static PyMemberDef PyCData_members[] = {
 static PyObject *
 PyCData_item_type(PyObject *type)
 {
-    if (PyCArrayTypeObject_Check(type)) {
+    ctypes_state *st = GLOBAL_STATE();
+    if (PyCArrayTypeObject_Check(st, type)) {
         StgDictObject *stg_dict;
         PyObject *elem_type;
 
@@ -2832,14 +2858,14 @@ PyCData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr)
     }
     dict->flags |= DICTFLAG_FINAL;
     cmem = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
-    if (cmem == NULL)
+    if (cmem == NULL) {
         return NULL;
-    assert(CDataObject_Check(cmem));
-
+    }
+    assert(CDataObject_Check(GLOBAL_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(GLOBAL_STATE(), base));
         cmem->b_ptr = adr;
         cmem->b_needsfree = 0;
         cmem->b_base = (CDataObject *)Py_NewRef(base);
@@ -2878,9 +2904,10 @@ PyCData_AtAddress(PyObject *type, void *buf)
     dict->flags |= DICTFLAG_FINAL;
 
     pd = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
-    if (!pd)
+    if (!pd) {
         return NULL;
-    assert(CDataObject_Check(pd));
+    }
+    assert(CDataObject_Check(GLOBAL_STATE(), pd));
     pd->b_ptr = (char *)buf;
     pd->b_length = dict->length;
     pd->b_size = dict->size;
@@ -2895,9 +2922,11 @@ PyCData_AtAddress(PyObject *type, void *buf)
 int _ctypes_simple_instance(PyObject *obj)
 {
     PyTypeObject *type = (PyTypeObject *)obj;
+    ctypes_state *st = GLOBAL_STATE();
 
-    if (PyCSimpleTypeObject_Check(type))
-        return type->tp_base != &Simple_Type;
+    if (PyCSimpleTypeObject_Check(st, type)) {
+        return type->tp_base != st->Simple_Type;
+    }
     return 0;
 }
 
@@ -2925,10 +2954,11 @@ _PyCData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
     CDataObject *src;
     int err;
 
-    if (setfunc)
+    if (setfunc) {
         return setfunc(ptr, value, size);
-
-    if (!CDataObject_Check(value)) {
+    }
+    ctypes_state *st = GLOBAL_STATE();
+    if (!CDataObject_Check(st, value)) {
         StgDictObject *dict = PyType_stgdict(type);
         if (dict && dict->setfunc)
             return dict->setfunc(ptr, value, size);
@@ -2950,7 +2980,7 @@ _PyCData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
                                 size, ptr);
             Py_DECREF(ob);
             return result;
-        } else if (value == Py_None && PyCPointerTypeObject_Check(type)) {
+        } else if (value == Py_None && PyCPointerTypeObject_Check(st, type)) {
             *(void **)ptr = NULL;
             Py_RETURN_NONE;
         } else {
@@ -2971,7 +3001,7 @@ _PyCData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
                src->b_ptr,
                size);
 
-        if (PyCPointerTypeObject_Check(type)) {
+        if (PyCPointerTypeObject_Check(st, type)) {
             /* XXX */
         }
 
@@ -2982,8 +3012,8 @@ _PyCData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
         return Py_NewRef(value);
     }
 
-    if (PyCPointerTypeObject_Check(type)
-        && ArrayObject_Check(value)) {
+    if (PyCPointerTypeObject_Check(st, type)
+        && ArrayObject_Check(st, value)) {
         StgDictObject *p1, *p2;
         PyObject *keep;
         p1 = PyObject_stgdict(value);
@@ -3031,8 +3061,9 @@ PyCData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
 {
     CDataObject *mem = (CDataObject *)dst;
     PyObject *result;
+    ctypes_state *st = GLOBAL_STATE();
 
-    if (!CDataObject_Check(dst)) {
+    if (!CDataObject_Check(st, dst)) {
         PyErr_SetString(PyExc_TypeError,
                         "not a ctype instance");
         return -1;
@@ -3252,13 +3283,14 @@ static int
 _check_outarg_type(PyObject *arg, Py_ssize_t index)
 {
     StgDictObject *dict;
+    ctypes_state *st = GLOBAL_STATE();
 
-    if (PyCPointerTypeObject_Check(arg))
+    if (PyCPointerTypeObject_Check(st, arg)) {
         return 1;
-
-    if (PyCArrayTypeObject_Check(arg))
+    }
+    if (PyCArrayTypeObject_Check(st, arg)) {
         return 1;
-
+    }
     dict = PyType_stgdict(arg);
     if (dict
         /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
@@ -3627,7 +3659,9 @@ static PyObject *
 _byref(PyObject *obj)
 {
     PyCArgObject *parg;
-    if (!CDataObject_Check(obj)) {
+    ctypes_state *st = GLOBAL_STATE();
+
+    if (!CDataObject_Check(st, obj)) {
         PyErr_SetString(PyExc_TypeError,
                         "expected CData instance");
         return NULL;
@@ -3735,6 +3769,7 @@ _build_callargs(PyCFuncPtrObject *self, PyObject *argtypes,
         inargs_index = 1;
     }
 #endif
+    ctypes_state *st = GLOBAL_STATE();
     for (i = 0; i < len; ++i) {
         PyObject *item = PyTuple_GET_ITEM(paramflags, i);
         PyObject *ob;
@@ -3806,11 +3841,13 @@ _build_callargs(PyCFuncPtrObject *self, PyObject *argtypes,
                     ((PyTypeObject *)ob)->tp_name);
                 goto error;
             }
-            if (PyCArrayTypeObject_Check(ob))
+            if (PyCArrayTypeObject_Check(st, ob)) {
                 ob = _PyObject_CallNoArgs(ob);
-            else
+            }
+            else {
                 /* Create an instance of the pointed-to type */
                 ob = _PyObject_CallNoArgs(dict->proto);
+            }
             /*
                XXX Is the following correct any longer?
                We must not pass a byref() to the array then but
@@ -3962,7 +3999,8 @@ PyCFuncPtr_call(PyCFuncPtrObject *self, PyObject *inargs, PyObject *kwds)
                             "native com method call without 'this' parameter");
             return NULL;
         }
-        if (!CDataObject_Check(this)) {
+        ctypes_state *st = GLOBAL_STATE();
+        if (!CDataObject_Check(st, this)) {
             PyErr_SetString(PyExc_TypeError,
                             "Expected a COM this pointer as first argument");
             return NULL;
@@ -4733,12 +4771,11 @@ PyCArrayType_from_ctype(PyObject *itemtype, Py_ssize_t length)
     sprintf(name, "%.200s_Array_%ld",
         ((PyTypeObject *)itemtype)->tp_name, (long)length);
 #endif
-
     ctypes_state *st = GLOBAL_STATE();
     result = PyObject_CallFunction((PyObject *)st->PyCArrayType_Type,
                                    "s(O){s:n,s:O}",
                                    name,
-                                   &PyCArray_Type,
+                                   st->PyCArray_Type,
                                    "_length_",
                                    length,
                                    "_type_",
@@ -4849,8 +4886,9 @@ static PyObject *
 Simple_repr(CDataObject *self)
 {
     PyObject *val, *result;
+    ctypes_state *st = GLOBAL_STATE();
 
-    if (Py_TYPE(self)->tp_base != &Simple_Type) {
+    if (Py_TYPE(self)->tp_base != st->Simple_Type) {
         return PyUnicode_FromFormat("<%s object at %p>",
                                    Py_TYPE(self)->tp_name, self);
     }
@@ -5013,7 +5051,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 *st = GLOBAL_STATE();
+    if (!CDataObject_Check(st, value)) {
         int res = PyObject_IsInstance(value, stgdict->proto);
         if (res == -1)
             return -1;
@@ -5395,11 +5434,14 @@ static int
 cast_check_pointertype(PyObject *arg)
 {
     StgDictObject *dict;
+    ctypes_state *st = GLOBAL_STATE();
 
-    if (PyCPointerTypeObject_Check(arg))
+    if (PyCPointerTypeObject_Check(st, arg)) {
         return 1;
-    if (PyCFuncPtrTypeObject_Check(arg))
+    }
+    if (PyCFuncPtrTypeObject_Check(st, arg)) {
         return 1;
+    }
     dict = PyType_stgdict(arg);
     if (dict != NULL && dict->proto != NULL) {
         if (PyUnicode_Check(dict->proto)
@@ -5432,7 +5474,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 *st = GLOBAL_STATE();
+    if (CDataObject_Check(st, src)) {
         CDataObject *obj = (CDataObject *)src;
         CDataObject *container;
 
@@ -5536,9 +5579,9 @@ _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);
+    TYPE_READY(st->PyCData_Type);
     /* StgDict is derived from PyDict_Type */
-    TYPE_READY_BASE(&PyCStgDict_Type, &PyDict_Type);
+    TYPE_READY_BASE(st->PyCStgDict_Type, &PyDict_Type);
 
     /*************************************************
      *
@@ -5561,12 +5604,12 @@ _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(st->Struct_Type, st->PyCStructType_Type, st->PyCData_Type);
+    MOD_ADD_TYPE(st->Union_Type, st->UnionType_Type, st->PyCData_Type);
+    MOD_ADD_TYPE(st->PyCPointer_Type, st->PyCPointerType_Type, st->PyCData_Type);
+    MOD_ADD_TYPE(st->PyCArray_Type, st->PyCArrayType_Type, st->PyCData_Type);
+    MOD_ADD_TYPE(st->Simple_Type, st->PyCSimpleType_Type, st->PyCData_Type);
+    MOD_ADD_TYPE(st->PyCFuncPtr_Type, st->PyCFuncPtrType_Type, st->PyCData_Type);
 
     /*************************************************
      *
index 154e9f43983cdb0084569484b54d14453103aba0..f70479435915ff0abf217818da7c91f803249502 100644 (file)
@@ -151,6 +151,7 @@ static void _CallPythonObject(void *mem,
     assert(nargs <= CTYPES_MAX_ARGCOUNT);
     PyObject **args = alloca(nargs * sizeof(PyObject *));
     PyObject **cnvs = PySequence_Fast_ITEMS(converters);
+    ctypes_state *st = GLOBAL_STATE();
     for (i = 0; i < nargs; i++) {
         PyObject *cnv = cnvs[i]; // borrowed ref
         StgDictObject *dict;
@@ -175,7 +176,7 @@ static void _CallPythonObject(void *mem,
                 PrintError("create argument %zd:\n", i);
                 goto Done;
             }
-            if (!CDataObject_Check(obj)) {
+            if (!CDataObject_Check(st, obj)) {
                 Py_DECREF(obj);
                 PrintError("unexpected result of create argument %zd:\n", i);
                 goto Done;
index 3b11cd7f58ce4b291e8c06d9a775f80989e5240d..97d1dbaae03d4f8e594606d07d92fa897bbd4367 100644 (file)
@@ -1686,11 +1686,13 @@ sizeof_func(PyObject *self, PyObject *obj)
     StgDictObject *dict;
 
     dict = PyType_stgdict(obj);
-    if (dict)
+    if (dict) {
         return PyLong_FromSsize_t(dict->size);
-
-    if (CDataObject_Check(obj))
+    }
+    ctypes_state *st = GLOBAL_STATE();
+    if (CDataObject_Check(st, obj)) {
         return PyLong_FromSsize_t(((CDataObject *)obj)->b_size);
+    }
     PyErr_SetString(PyExc_TypeError,
                     "this type has no size");
     return NULL;
@@ -1744,7 +1746,8 @@ byref(PyObject *self, PyObject *args)
         if (offset == -1 && PyErr_Occurred())
             return NULL;
     }
-    if (!CDataObject_Check(obj)) {
+    ctypes_state *st = GLOBAL_STATE();
+    if (!CDataObject_Check(st, obj)) {
         PyErr_Format(PyExc_TypeError,
                      "byref() argument must be a ctypes instance, not '%s'",
                      Py_TYPE(obj)->tp_name);
@@ -1769,7 +1772,8 @@ PyDoc_STRVAR(addressof_doc,
 static PyObject *
 addressof(PyObject *self, PyObject *obj)
 {
-    if (!CDataObject_Check(obj)) {
+    ctypes_state *st = GLOBAL_STATE();
+    if (!CDataObject_Check(st, obj)) {
         PyErr_SetString(PyExc_TypeError,
                         "invalid type");
         return NULL;
@@ -1925,13 +1929,14 @@ create_pointer_type(PyObject *module, PyObject *cls)
         // found or error
         return result;
     }
+    ctypes_state *st = GLOBAL_STATE();
     // not found
     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(st->PyCPointer_Type),
                                        "N(O){}",
                                        name,
-                                       &PyCPointer_Type);
+                                       st->PyCPointer_Type);
         if (result == NULL)
             return result;
         key = PyLong_FromVoidPtr(result);
@@ -1942,10 +1947,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(st->PyCPointer_Type),
                                        "N(O){sO}",
                                        name,
-                                       &PyCPointer_Type,
+                                       st->PyCPointer_Type,
                                        "_type_", cls);
         if (result == NULL)
             return result;
index bfb40e5c5393fcb1ce5661b4c33c4d7afea2d02d..1d5b0b14bc39e546d393038af297fbb5b329183b 100644 (file)
@@ -111,7 +111,7 @@ PyCField_FromDesc(PyObject *desc, Py_ssize_t index,
     /*  Field descriptors for 'c_char * n' are be scpecial cased to
         return a Python string instead of an Array object instance...
     */
-    if (PyCArrayTypeObject_Check(proto)) {
+    if (PyCArrayTypeObject_Check(st, proto)) {
         StgDictObject *adict = PyType_stgdict(proto);
         StgDictObject *idict;
         if (adict && adict->proto) {
@@ -204,7 +204,8 @@ PyCField_set(CFieldObject *self, PyObject *inst, PyObject *value)
 {
     CDataObject *dst;
     char *ptr;
-    if (!CDataObject_Check(inst)) {
+    ctypes_state *st = GLOBAL_STATE();
+    if (!CDataObject_Check(st, inst)) {
         PyErr_SetString(PyExc_TypeError,
                         "not a ctype instance");
         return -1;
@@ -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 *st = GLOBAL_STATE();
+    if (!CDataObject_Check(st, inst)) {
         PyErr_SetString(PyExc_TypeError,
                         "not a ctype instance");
         return NULL;
index 55e9f77778807911cad3f175372c94efe7a7bdf9..1989723f6f3dbb16aab207146f19eea3c9abcf62 100644 (file)
@@ -37,9 +37,7 @@ typedef struct {
     PyTypeObject *PyCArg_Type;
     PyTypeObject *PyCField_Type;
     PyTypeObject *PyCThunk_Type;
-#ifdef MS_WIN32
-    PyTypeObject *PyComError_Type;
-#endif
+    PyTypeObject *PyCStgDict_Type;
     PyTypeObject *StructParam_Type;
     PyTypeObject *PyCStructType_Type;
     PyTypeObject *UnionType_Type;
@@ -47,6 +45,16 @@ typedef struct {
     PyTypeObject *PyCArrayType_Type;
     PyTypeObject *PyCSimpleType_Type;
     PyTypeObject *PyCFuncPtrType_Type;
+    PyTypeObject *PyCData_Type;
+    PyTypeObject *Struct_Type;
+    PyTypeObject *Union_Type;
+    PyTypeObject *PyCArray_Type;
+    PyTypeObject *Simple_Type;
+    PyTypeObject *PyCPointer_Type;
+    PyTypeObject *PyCFuncPtr_Type;
+#ifdef MS_WIN32
+    PyTypeObject *PyComError_Type;
+#endif
 } ctypes_state;
 
 extern ctypes_state global_state;
@@ -147,8 +155,8 @@ typedef struct {
 } PyCFuncPtrObject;
 
 extern PyTypeObject PyCStgDict_Type;
-#define PyCStgDict_CheckExact(v)            Py_IS_TYPE(v, &PyCStgDict_Type)
-#define PyCStgDict_Check(v)         PyObject_TypeCheck(v, &PyCStgDict_Type)
+#define PyCStgDict_CheckExact(st, v)        Py_IS_TYPE((v), (st)->PyCStgDict_Type)
+#define PyCStgDict_Check(st, v)     PyObject_TypeCheck((v), (st)->PyCStgDict_Type)
 
 extern int PyCStructUnionType_update_stgdict(PyObject *fields, PyObject *type, int isStruct);
 extern int PyType_stginfo(PyTypeObject *self, Py_ssize_t *psize, Py_ssize_t *palign, Py_ssize_t *plength);
@@ -157,12 +165,12 @@ extern int PyObject_stginfo(PyObject *self, Py_ssize_t *psize, Py_ssize_t *palig
 
 
 extern PyTypeObject PyCData_Type;
-#define CDataObject_CheckExact(v)       Py_IS_TYPE(v, &PyCData_Type)
-#define CDataObject_Check(v)            PyObject_TypeCheck(v, &PyCData_Type)
+#define CDataObject_CheckExact(st, v)  Py_IS_TYPE((v), (st)->PyCData_Type)
+#define CDataObject_Check(st, v)       PyObject_TypeCheck((v), (st)->PyCData_Type)
 #define _CDataObject_HasExternalBuffer(v)  ((v)->b_ptr != (char *)&(v)->b_value)
 
-#define PyCSimpleTypeObject_CheckExact(v)       Py_IS_TYPE(v, GLOBAL_STATE()->PyCSimpleType_Type)
-#define PyCSimpleTypeObject_Check(v)    PyObject_TypeCheck(v, GLOBAL_STATE()->PyCSimpleType_Type)
+#define PyCSimpleTypeObject_CheckExact(st, v)  Py_IS_TYPE((v), (st)->PyCSimpleType_Type)
+#define PyCSimpleTypeObject_Check(st, v)       PyObject_TypeCheck((v), (st)->PyCSimpleType_Type)
 
 extern struct fielddesc *_ctypes_get_fielddesc(const char *fmt);
 
@@ -180,13 +188,13 @@ extern PyTypeObject PyCArray_Type;
 extern PyTypeObject PyCPointer_Type;
 extern PyTypeObject PyCFuncPtr_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, GLOBAL_STATE()->PyCPointerType_Type)
-#define PyCFuncPtrObject_Check(v)               PyObject_TypeCheck(v, &PyCFuncPtr_Type)
-#define PyCFuncPtrTypeObject_Check(v)   PyObject_TypeCheck(v, GLOBAL_STATE()->PyCFuncPtrType_Type)
-#define PyCStructTypeObject_Check(v)    PyObject_TypeCheck(v, GLOBAL_STATE()->PyCStructType_Type)
+#define PyCArrayTypeObject_Check(st, v)   PyObject_TypeCheck((v), (st)->PyCArrayType_Type)
+#define ArrayObject_Check(st, v)          PyObject_TypeCheck((v), (st)->PyCArray_Type)
+#define PointerObject_Check(st, v)        PyObject_TypeCheck((v), (st)->PyCPointer_Type)
+#define PyCPointerTypeObject_Check(st, v) PyObject_TypeCheck((v), (st)->PyCPointerType_Type)
+#define PyCFuncPtrObject_Check(st,v)      PyObject_TypeCheck((v), (st)->PyCFuncPtr_Type)
+#define PyCFuncPtrTypeObject_Check(st, v) PyObject_TypeCheck((v), (st)->PyCFuncPtrType_Type)
+#define PyCStructTypeObject_Check(st, v)  PyObject_TypeCheck((v), (st)->PyCStructType_Type)
 
 extern PyObject *
 PyCArrayType_from_ctype(PyObject *itemtype, Py_ssize_t length);
index fb3e20e8db3e27ec60b42f9eb3d2b601e6b92d65..2397015ba658895f0e1c4afd1510338eff560e0d 100644 (file)
@@ -184,11 +184,14 @@ PyType_stgdict(PyObject *obj)
 {
     PyTypeObject *type;
 
-    if (!PyType_Check(obj))
+    if (!PyType_Check(obj)) {
         return NULL;
+    }
+    ctypes_state *st = GLOBAL_STATE();
     type = (PyTypeObject *)obj;
-    if (!type->tp_dict || !PyCStgDict_CheckExact(type->tp_dict))
+    if (!type->tp_dict || !PyCStgDict_CheckExact(st, type->tp_dict)) {
         return NULL;
+    }
     return (StgDictObject *)type->tp_dict;
 }
 
@@ -201,8 +204,10 @@ StgDictObject *
 PyObject_stgdict(PyObject *self)
 {
     PyTypeObject *type = Py_TYPE(self);
-    if (!type->tp_dict || !PyCStgDict_CheckExact(type->tp_dict))
+    ctypes_state *st = GLOBAL_STATE();
+    if (!type->tp_dict || !PyCStgDict_CheckExact(st, type->tp_dict)) {
         return NULL;
+    }
     return (StgDictObject *)type->tp_dict;
 }
 
@@ -505,6 +510,7 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct
     if (stgdict->format == NULL)
         return -1;
 
+    ctypes_state *st = GLOBAL_STATE();
     for (i = 0; i < len; ++i) {
         PyObject *name = NULL, *desc = NULL;
         PyObject *pair = PySequence_GetItem(fields, i);
@@ -518,8 +524,9 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct
             Py_XDECREF(pair);
             return -1;
         }
-        if (PyCArrayTypeObject_Check(desc))
+        if (PyCArrayTypeObject_Check(st, desc)) {
             arrays_seen = 1;
+        }
         dict = PyType_stgdict(desc);
         if (dict == NULL) {
             Py_DECREF(pair);
@@ -806,7 +813,7 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct
                     i);
                 return -1;
             }
-            if (!PyCArrayTypeObject_Check(desc)) {
+            if (!PyCArrayTypeObject_Check(st, desc)) {
                 /* Not an array. Just need an ffi_type pointer. */
                 num_ffi_type_pointers++;
             }
@@ -906,7 +913,7 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct
                 return -1;
             }
             assert(element_index < (ffi_ofs + len)); /* will be used below */
-            if (!PyCArrayTypeObject_Check(desc)) {
+            if (!PyCArrayTypeObject_Check(st, desc)) {
                 /* Not an array. Just copy over the element ffi_type. */
                 element_types[element_index++] = &dict->ffi_type_pointer;
             }