Bug Summary

File:Modules/_ctypes/callbacks.c
Location:line 270, column 20
Description:Dereference of undefined pointer value

Annotated Source Code

1#include "Python.h"
2#include "frameobject.h"
3
4#include <ffi.h>
5#ifdef MS_WIN32
6#include <windows.h>
7#endif
8#include "ctypes.h"
9
10/**************************************************************/
11
12static void
13CThunkObject_dealloc(PyObject *_self)
14{
15 CThunkObject *self = (CThunkObject *)_self;
16 Py_XDECREF(self->converters)do { if ((self->converters) == ((void*)0)) ; else do { if (
_Py_RefTotal-- , --((PyObject*)(self->converters))->ob_refcnt
!= 0) { if (((PyObject*)self->converters)->ob_refcnt <
0) _Py_NegativeRefcount("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 16, (PyObject *)(self->converters)); } else _Py_Dealloc(
(PyObject *)(self->converters)); } while (0); } while (0)
;
17 Py_XDECREF(self->callable)do { if ((self->callable) == ((void*)0)) ; else do { if (_Py_RefTotal
-- , --((PyObject*)(self->callable))->ob_refcnt != 0) {
if (((PyObject*)self->callable)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 17, (PyObject *)(self->callable)); } else _Py_Dealloc((PyObject
*)(self->callable)); } while (0); } while (0)
;
18 Py_XDECREF(self->restype)do { if ((self->restype) == ((void*)0)) ; else do { if (_Py_RefTotal
-- , --((PyObject*)(self->restype))->ob_refcnt != 0) { if
(((PyObject*)self->restype)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 18, (PyObject *)(self->restype)); } else _Py_Dealloc((PyObject
*)(self->restype)); } while (0); } while (0)
;
19 if (self->pcl_write)
20 ffi_closure_free(self->pcl_write);
21 PyObject_GC_Del(self);
22}
23
24static int
25CThunkObject_traverse(PyObject *_self, visitproc visit, void *arg)
26{
27 CThunkObject *self = (CThunkObject *)_self;
28 Py_VISIT(self->converters)do { if (self->converters) { int vret = visit((PyObject *)
(self->converters), arg); if (vret) return vret; } } while
(0)
;
29 Py_VISIT(self->callable)do { if (self->callable) { int vret = visit((PyObject *)(self
->callable), arg); if (vret) return vret; } } while (0)
;
30 Py_VISIT(self->restype)do { if (self->restype) { int vret = visit((PyObject *)(self
->restype), arg); if (vret) return vret; } } while (0)
;
31 return 0;
32}
33
34static int
35CThunkObject_clear(PyObject *_self)
36{
37 CThunkObject *self = (CThunkObject *)_self;
38 Py_CLEAR(self->converters)do { if (self->converters) { PyObject *_py_tmp = (PyObject
*)(self->converters); (self->converters) = ((void*)0);
do { if (_Py_RefTotal-- , --((PyObject*)(_py_tmp))->ob_refcnt
!= 0) { if (((PyObject*)_py_tmp)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 38, (PyObject *)(_py_tmp)); } else _Py_Dealloc((PyObject *)
(_py_tmp)); } while (0); } } while (0)
;
39 Py_CLEAR(self->callable)do { if (self->callable) { PyObject *_py_tmp = (PyObject *
)(self->callable); (self->callable) = ((void*)0); do { if
(_Py_RefTotal-- , --((PyObject*)(_py_tmp))->ob_refcnt != 0
) { if (((PyObject*)_py_tmp)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 39, (PyObject *)(_py_tmp)); } else _Py_Dealloc((PyObject *)
(_py_tmp)); } while (0); } } while (0)
;
40 Py_CLEAR(self->restype)do { if (self->restype) { PyObject *_py_tmp = (PyObject *)
(self->restype); (self->restype) = ((void*)0); do { if (
_Py_RefTotal-- , --((PyObject*)(_py_tmp))->ob_refcnt != 0)
{ if (((PyObject*)_py_tmp)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 40, (PyObject *)(_py_tmp)); } else _Py_Dealloc((PyObject *)
(_py_tmp)); } while (0); } } while (0)
;
41 return 0;
42}
43
44PyTypeObject PyCThunk_Type = {
45 PyVarObject_HEAD_INIT(NULL, 0){ { 0, 0, 1, ((void*)0) }, 0 },
46 "_ctypes.CThunkObject",
47 sizeof(CThunkObject), /* tp_basicsize */
48 sizeof(ffi_type), /* tp_itemsize */
49 CThunkObject_dealloc, /* tp_dealloc */
50 0, /* tp_print */
51 0, /* tp_getattr */
52 0, /* tp_setattr */
53 0, /* tp_reserved */
54 0, /* tp_repr */
55 0, /* tp_as_number */
56 0, /* tp_as_sequence */
57 0, /* tp_as_mapping */
58 0, /* tp_hash */
59 0, /* tp_call */
60 0, /* tp_str */
61 0, /* tp_getattro */
62 0, /* tp_setattro */
63 0, /* tp_as_buffer */
64 Py_TPFLAGS_DEFAULT( 0 | (1L<<18) | 0) | Py_TPFLAGS_HAVE_GC(1L<<14), /* tp_flags */
65 "CThunkObject", /* tp_doc */
66 CThunkObject_traverse, /* tp_traverse */
67 CThunkObject_clear, /* tp_clear */
68 0, /* tp_richcompare */
69 0, /* tp_weaklistoffset */
70 0, /* tp_iter */
71 0, /* tp_iternext */
72 0, /* tp_methods */
73 0, /* tp_members */
74};
75
76/**************************************************************/
77
78static void
79PrintError(char *msg, ...)
80{
81 char buf[512];
82 PyObject *f = PySys_GetObject("stderr");
83 va_list marker;
84
85 va_start(marker, msg)__builtin_va_start(marker, msg);
86 vsnprintf(buf, sizeof(buf), msg, marker)__builtin___vsnprintf_chk (buf, sizeof(buf), 0, __builtin_object_size
(buf, 2 > 1), msg, marker)
;
87 va_end(marker)__builtin_va_end(marker);
88 if (f != NULL((void*)0) && f != Py_None(&_Py_NoneStruct))
89 PyFile_WriteString(buf, f);
90 PyErr_Print();
91}
92
93
94/* after code that pyrex generates */
95void _ctypes_add_traceback(char *funcname, char *filename, int lineno)
96{
97 PyObject *py_globals = 0;
98 PyCodeObject *py_code = 0;
99 PyFrameObject *py_frame = 0;
100
101 py_globals = PyDict_New();
102 if (!py_globals) goto bad;
103 py_code = PyCode_NewEmpty(filename, funcname, lineno);
104 if (!py_code) goto bad;
105 py_frame = PyFrame_New(
106 PyThreadState_Get(), /*PyThreadState *tstate,*/
107 py_code, /*PyCodeObject *code,*/
108 py_globals, /*PyObject *globals,*/
109 0 /*PyObject *locals*/
110 );
111 if (!py_frame) goto bad;
112 py_frame->f_lineno = lineno;
113 PyTraceBack_Here(py_frame);
114 bad:
115 Py_XDECREF(py_globals)do { if ((py_globals) == ((void*)0)) ; else do { if (_Py_RefTotal
-- , --((PyObject*)(py_globals))->ob_refcnt != 0) { if (((
PyObject*)py_globals)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 115, (PyObject *)(py_globals)); } else _Py_Dealloc((PyObject
*)(py_globals)); } while (0); } while (0)
;
116 Py_XDECREF(py_code)do { if ((py_code) == ((void*)0)) ; else do { if (_Py_RefTotal
-- , --((PyObject*)(py_code))->ob_refcnt != 0) { if (((PyObject
*)py_code)->ob_refcnt < 0) _Py_NegativeRefcount("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 116, (PyObject *)(py_code)); } else _Py_Dealloc((PyObject *
)(py_code)); } while (0); } while (0)
;
117 Py_XDECREF(py_frame)do { if ((py_frame) == ((void*)0)) ; else do { if (_Py_RefTotal
-- , --((PyObject*)(py_frame))->ob_refcnt != 0) { if (((PyObject
*)py_frame)->ob_refcnt < 0) _Py_NegativeRefcount("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 117, (PyObject *)(py_frame)); } else _Py_Dealloc((PyObject *
)(py_frame)); } while (0); } while (0)
;
118}
119
120#ifdef MS_WIN32
121/*
122 * We must call AddRef() on non-NULL COM pointers we receive as arguments
123 * to callback functions - these functions are COM method implementations.
124 * The Python instances we create have a __del__ method which calls Release().
125 *
126 * The presence of a class attribute named '_needs_com_addref_' triggers this
127 * behaviour. It would also be possible to call the AddRef() Python method,
128 * after checking for PyObject_IsTrue(), but this would probably be somewhat
129 * slower.
130 */
131static void
132TryAddRef(StgDictObject *dict, CDataObject *obj)
133{
134 IUnknown *punk;
135
136 if (NULL((void*)0) == PyDict_GetItemString((PyObject *)dict, "_needs_com_addref_"))
137 return;
138
139 punk = *(IUnknown **)obj->b_ptr;
140 if (punk)
141 punk->lpVtbl->AddRef(punk);
142 return;
143}
144#endif
145
146/******************************************************************************
147 *
148 * Call the python object with all arguments
149 *
150 */
151static void _CallPythonObject(void *mem,
152 ffi_type *restype,
153 SETFUNC setfunc,
154 PyObject *callable,
155 PyObject *converters,
156 int flags,
157 void **pArgs)
158{
159 Py_ssize_t i;
160 PyObject *result;
161 PyObject *arglist = NULL((void*)0);
162 Py_ssize_t nArgs;
163 PyObject *error_object = NULL((void*)0);
164 int *space;
165#ifdef WITH_THREAD1
166 PyGILState_STATE state = PyGILState_Ensure();
167#endif
168
169 nArgs = PySequence_LengthPySequence_Size(converters);
170 /* Hm. What to return in case of error?
171 For COM, 0xFFFFFFFF seems better than 0.
172 */
173 if (nArgs < 0) {
1
Taking false branch
174 PrintError("BUG: PySequence_Length");
175 goto Done;
176 }
177
178 arglist = PyTuple_New(nArgs);
179 if (!arglist) {
2
Taking false branch
180 PrintError("PyTuple_New()");
181 goto Done;
182 }
183 for (i = 0; i < nArgs; ++i) {
3
Loop condition is false. Execution continues on line 241
184 /* Note: new reference! */
185 PyObject *cnv = PySequence_GetItem(converters, i);
186 StgDictObject *dict;
187 if (cnv)
188 dict = PyType_stgdict(cnv);
189 else {
190 PrintError("Getting argument converter %d\n", i);
191 goto Done;
192 }
193
194 if (dict && dict->getfunc && !_ctypes_simple_instance(cnv)) {
195 PyObject *v = dict->getfunc(*pArgs, dict->size);
196 if (!v) {
197 PrintError("create argument %d:\n", i);
198 Py_DECREF(cnv)do { if (_Py_RefTotal-- , --((PyObject*)(cnv))->ob_refcnt !=
0) { if (((PyObject*)cnv)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 198, (PyObject *)(cnv)); } else _Py_Dealloc((PyObject *)(cnv
)); } while (0)
;
199 goto Done;
200 }
201 PyTuple_SET_ITEM(arglist, i, v)(((PyTupleObject *)(arglist))->ob_item[i] = v);
202 /* XXX XXX XX
203 We have the problem that c_byte or c_short have dict->size of
204 1 resp. 4, but these parameters are pushed as sizeof(int) bytes.
205 BTW, the same problem occurrs when they are pushed as parameters
206 */
207 } else if (dict) {
208 /* Hm, shouldn't we use PyCData_AtAddress() or something like that instead? */
209 CDataObject *obj = (CDataObject *)PyObject_CallFunctionObjArgs(cnv, NULL((void*)0));
210 if (!obj) {
211 PrintError("create argument %d:\n", i);
212 Py_DECREF(cnv)do { if (_Py_RefTotal-- , --((PyObject*)(cnv))->ob_refcnt !=
0) { if (((PyObject*)cnv)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 212, (PyObject *)(cnv)); } else _Py_Dealloc((PyObject *)(cnv
)); } while (0)
;
213 goto Done;
214 }
215 if (!CDataObject_Check(obj)((((PyObject*)(obj))->ob_type) == (&PyCData_Type) || PyType_IsSubtype
((((PyObject*)(obj))->ob_type), (&PyCData_Type)))
) {
216 Py_DECREF(obj)do { if (_Py_RefTotal-- , --((PyObject*)(obj))->ob_refcnt !=
0) { if (((PyObject*)obj)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 216, (PyObject *)(obj)); } else _Py_Dealloc((PyObject *)(obj
)); } while (0)
;
217 Py_DECREF(cnv)do { if (_Py_RefTotal-- , --((PyObject*)(cnv))->ob_refcnt !=
0) { if (((PyObject*)cnv)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 217, (PyObject *)(cnv)); } else _Py_Dealloc((PyObject *)(cnv
)); } while (0)
;
218 PrintError("unexpected result of create argument %d:\n", i);
219 goto Done;
220 }
221 memcpy(obj->b_ptr, *pArgs, dict->size)((__builtin_object_size (obj->b_ptr, 0) != (size_t) -1) ? __builtin___memcpy_chk
(obj->b_ptr, *pArgs, dict->size, __builtin_object_size
(obj->b_ptr, 0)) : __inline_memcpy_chk (obj->b_ptr, *pArgs
, dict->size))
;
222 PyTuple_SET_ITEM(arglist, i, (PyObject *)obj)(((PyTupleObject *)(arglist))->ob_item[i] = (PyObject *)obj
)
;
223#ifdef MS_WIN32
224 TryAddRef(dict, obj);
225#endif
226 } else {
227 PyErr_SetString(PyExc_TypeError,
228 "cannot build parameter");
229 PrintError("Parsing argument %d\n", i);
230 Py_DECREF(cnv)do { if (_Py_RefTotal-- , --((PyObject*)(cnv))->ob_refcnt !=
0) { if (((PyObject*)cnv)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 230, (PyObject *)(cnv)); } else _Py_Dealloc((PyObject *)(cnv
)); } while (0)
;
231 goto Done;
232 }
233 Py_DECREF(cnv)do { if (_Py_RefTotal-- , --((PyObject*)(cnv))->ob_refcnt !=
0) { if (((PyObject*)cnv)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 233, (PyObject *)(cnv)); } else _Py_Dealloc((PyObject *)(cnv
)); } while (0)
;
234 /* XXX error handling! */
235 pArgs++;
236 }
237
238#define CHECK(what, x)if (x == ((void*)0)) _ctypes_add_traceback(what, "_ctypes/callbacks.c"
, 238 - 1), PyErr_Print()
\
239if (x == NULL((void*)0)) _ctypes_add_traceback(what, "_ctypes/callbacks.c", __LINE__239 - 1), PyErr_Print()
240
241 if (flags & (FUNCFLAG_USE_ERRNO0x8 | FUNCFLAG_USE_LASTERROR0x10)) {
4
Taking false branch
242 error_object = _ctypes_get_errobj(&space);
243 if (error_object == NULL((void*)0))
244 goto Done;
245 if (flags & FUNCFLAG_USE_ERRNO0x8) {
246 int temp = space[0];
247 space[0] = errno(*__error());
248 errno(*__error()) = temp;
249 }
250#ifdef MS_WIN32
251 if (flags & FUNCFLAG_USE_LASTERROR0x10) {
252 int temp = space[1];
253 space[1] = GetLastError();
254 SetLastError(temp);
255 }
256#endif
257 }
258
259 result = PyObject_CallObject(callable, arglist);
260 CHECK("'calling callback function'", result)if (result == ((void*)0)) _ctypes_add_traceback("'calling callback function'"
, "_ctypes/callbacks.c", 260 - 1), PyErr_Print()
;
261
262#ifdef MS_WIN32
263 if (flags & FUNCFLAG_USE_LASTERROR0x10) {
264 int temp = space[1];
265 space[1] = GetLastError();
266 SetLastError(temp);
267 }
268#endif
269 if (flags & FUNCFLAG_USE_ERRNO0x8) {
5
Taking true branch
270 int temp = space[0];
6
Dereference of undefined pointer value
271 space[0] = errno(*__error());
272 errno(*__error()) = temp;
273 }
274 Py_XDECREF(error_object)do { if ((error_object) == ((void*)0)) ; else do { if (_Py_RefTotal
-- , --((PyObject*)(error_object))->ob_refcnt != 0) { if (
((PyObject*)error_object)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 274, (PyObject *)(error_object)); } else _Py_Dealloc((PyObject
*)(error_object)); } while (0); } while (0)
;
275
276 if ((restype != &ffi_type_void) && result) {
277 PyObject *keep;
278 assert(setfunc)(__builtin_expect(!(setfunc), 0) ? __assert_rtn(__func__, "/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 278, "setfunc") : (void)0)
;
279#ifdef WORDS_BIGENDIAN
280 /* See the corresponding code in callproc.c, around line 961 */
281 if (restype->type != FFI_TYPE_FLOAT2 && restype->size < sizeof(ffi_arg))
282 mem = (char *)mem + sizeof(ffi_arg) - restype->size;
283#endif
284 keep = setfunc(mem, result, 0);
285 CHECK("'converting callback result'", keep)if (keep == ((void*)0)) _ctypes_add_traceback("'converting callback result'"
, "_ctypes/callbacks.c", 285 - 1), PyErr_Print()
;
286 /* keep is an object we have to keep alive so that the result
287 stays valid. If there is no such object, the setfunc will
288 have returned Py_None.
289
290 If there is such an object, we have no choice than to keep
291 it alive forever - but a refcount and/or memory leak will
292 be the result. EXCEPT when restype is py_object - Python
293 itself knows how to manage the refcount of these objects.
294 */
295 if (keep == NULL((void*)0)) /* Could not convert callback result. */
296 PyErr_WriteUnraisable(callable);
297 else if (keep == Py_None(&_Py_NoneStruct)) /* Nothing to keep */
298 Py_DECREF(keep)do { if (_Py_RefTotal-- , --((PyObject*)(keep))->ob_refcnt
!= 0) { if (((PyObject*)keep)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 298, (PyObject *)(keep)); } else _Py_Dealloc((PyObject *)(keep
)); } while (0)
;
299 else if (setfunc != _ctypes_get_fielddesc("O")->setfunc) {
300 if (-1 == PyErr_WarnEx(PyExc_RuntimeWarning,
301 "memory leak in callback function.",
302 1))
303 PyErr_WriteUnraisable(callable);
304 }
305 }
306 Py_XDECREF(result)do { if ((result) == ((void*)0)) ; else do { if (_Py_RefTotal
-- , --((PyObject*)(result))->ob_refcnt != 0) { if (((PyObject
*)result)->ob_refcnt < 0) _Py_NegativeRefcount("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 306, (PyObject *)(result)); } else _Py_Dealloc((PyObject *)
(result)); } while (0); } while (0)
;
307 Done:
308 Py_XDECREF(arglist)do { if ((arglist) == ((void*)0)) ; else do { if (_Py_RefTotal
-- , --((PyObject*)(arglist))->ob_refcnt != 0) { if (((PyObject
*)arglist)->ob_refcnt < 0) _Py_NegativeRefcount("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 308, (PyObject *)(arglist)); } else _Py_Dealloc((PyObject *
)(arglist)); } while (0); } while (0)
;
309#ifdef WITH_THREAD1
310 PyGILState_Release(state);
311#endif
312}
313
314static void closure_fcn(ffi_cif *cif,
315 void *resp,
316 void **args,
317 void *userdata)
318{
319 CThunkObject *p = (CThunkObject *)userdata;
320
321 _CallPythonObject(resp,
322 p->ffi_restype,
323 p->setfunc,
324 p->callable,
325 p->converters,
326 p->flags,
327 args);
328}
329
330static CThunkObject* CThunkObject_new(Py_ssize_t nArgs)
331{
332 CThunkObject *p;
333 int i;
334
335 p = PyObject_GC_NewVar(CThunkObject, &PyCThunk_Type, nArgs)( (CThunkObject *) _PyObject_GC_NewVar((&PyCThunk_Type), (
nArgs)) )
;
336 if (p == NULL((void*)0)) {
337 PyErr_NoMemory();
338 return NULL((void*)0);
339 }
340
341 p->pcl_exec = NULL((void*)0);
342 p->pcl_write = NULL((void*)0);
343 memset(&p->cif, 0, sizeof(p->cif))((__builtin_object_size (&p->cif, 0) != (size_t) -1) ?
__builtin___memset_chk (&p->cif, 0, sizeof(p->cif)
, __builtin_object_size (&p->cif, 0)) : __inline_memset_chk
(&p->cif, 0, sizeof(p->cif)))
;
344 p->converters = NULL((void*)0);
345 p->callable = NULL((void*)0);
346 p->setfunc = NULL((void*)0);
347 p->ffi_restype = NULL((void*)0);
348
349 for (i = 0; i < nArgs + 1; ++i)
350 p->atypes[i] = NULL((void*)0);
351 PyObject_GC_Track((PyObject *)p);
352 return p;
353}
354
355CThunkObject *_ctypes_alloc_callback(PyObject *callable,
356 PyObject *converters,
357 PyObject *restype,
358 int flags)
359{
360 int result;
361 CThunkObject *p;
362 Py_ssize_t nArgs, i;
363 ffi_abi cc;
364
365 nArgs = PySequence_Size(converters);
366 p = CThunkObject_new(nArgs);
367 if (p == NULL((void*)0))
368 return NULL((void*)0);
369
370 assert(CThunk_CheckExact((PyObject *)p))(__builtin_expect(!((((PyObject *)p)->ob_type == &PyCThunk_Type
)), 0) ? __assert_rtn(__func__, "/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 370, "CThunk_CheckExact((PyObject *)p)") : (void)0)
;
371
372 p->pcl_write = ffi_closure_alloc(sizeof(ffi_closure),
373 &p->pcl_exec);
374 if (p->pcl_write == NULL((void*)0)) {
375 PyErr_NoMemory();
376 goto error;
377 }
378
379 p->flags = flags;
380 for (i = 0; i < nArgs; ++i) {
381 PyObject *cnv = PySequence_GetItem(converters, i);
382 if (cnv == NULL((void*)0))
383 goto error;
384 p->atypes[i] = _ctypes_get_ffi_type(cnv);
385 Py_DECREF(cnv)do { if (_Py_RefTotal-- , --((PyObject*)(cnv))->ob_refcnt !=
0) { if (((PyObject*)cnv)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 385, (PyObject *)(cnv)); } else _Py_Dealloc((PyObject *)(cnv
)); } while (0)
;
386 }
387 p->atypes[i] = NULL((void*)0);
388
389 Py_INCREF(restype)( _Py_RefTotal++ , ((PyObject*)(restype))->ob_refcnt++);
390 p->restype = restype;
391 if (restype == Py_None(&_Py_NoneStruct)) {
392 p->setfunc = NULL((void*)0);
393 p->ffi_restype = &ffi_type_void;
394 } else {
395 StgDictObject *dict = PyType_stgdict(restype);
396 if (dict == NULL((void*)0) || dict->setfunc == NULL((void*)0)) {
397 PyErr_SetString(PyExc_TypeError,
398 "invalid result type for callback function");
399 goto error;
400 }
401 p->setfunc = dict->setfunc;
402 p->ffi_restype = &dict->ffi_type_pointer;
403 }
404
405 cc = FFI_DEFAULT_ABI;
406#if defined(MS_WIN32) && !defined(_WIN32_WCE) && !defined(MS_WIN64)
407 if ((flags & FUNCFLAG_CDECL0x1) == 0)
408 cc = FFI_STDCALL;
409#endif
410 result = ffi_prep_cif(&p->cif, cc,
411 Py_SAFE_DOWNCAST(nArgs, Py_ssize_t, int)((__builtin_expect(!((Py_ssize_t)(int)(nArgs) == (nArgs)), 0)
? __assert_rtn(__func__, "/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 411, "(Py_ssize_t)(int)(nArgs) == (nArgs)") : (void)0), (int
)(nArgs))
,
412 _ctypes_get_ffi_type(restype),
413 &p->atypes[0]);
414 if (result != FFI_OK) {
415 PyErr_Format(PyExc_RuntimeError,
416 "ffi_prep_cif failed with %d", result);
417 goto error;
418 }
419#if defined(X86_DARWIN) || defined(POWERPC_DARWIN)
420 result = ffi_prep_closure(p->pcl_write, &p->cif, closure_fcn, p);
421#else
422 result = ffi_prep_closure_loc(p->pcl_write, &p->cif, closure_fcn,
423 p,
424 p->pcl_exec);
425#endif
426 if (result != FFI_OK) {
427 PyErr_Format(PyExc_RuntimeError,
428 "ffi_prep_closure failed with %d", result);
429 goto error;
430 }
431
432 Py_INCREF(converters)( _Py_RefTotal++ , ((PyObject*)(converters))->ob_refcnt++);
433 p->converters = converters;
434 Py_INCREF(callable)( _Py_RefTotal++ , ((PyObject*)(callable))->ob_refcnt++);
435 p->callable = callable;
436 return p;
437
438 error:
439 Py_XDECREF(p)do { if ((p) == ((void*)0)) ; else do { if (_Py_RefTotal-- , --
((PyObject*)(p))->ob_refcnt != 0) { if (((PyObject*)p)->
ob_refcnt < 0) _Py_NegativeRefcount("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 439, (PyObject *)(p)); } else _Py_Dealloc((PyObject *)(p));
} while (0); } while (0)
;
440 return NULL((void*)0);
441}
442
443#ifdef MS_WIN32
444
445static void LoadPython(void)
446{
447 if (!Py_IsInitialized()) {
448#ifdef WITH_THREAD1
449 PyEval_InitThreads();
450#endif
451 Py_Initialize();
452 }
453}
454
455/******************************************************************/
456
457long Call_GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
458{
459 PyObject *mod, *func, *result;
460 long retval;
461 static PyObject *context;
462
463 if (context == NULL((void*)0))
464 context = PyUnicode_InternFromString("_ctypes.DllGetClassObject");
465
466 mod = PyImport_ImportModuleNoBlock("ctypes");
467 if (!mod) {
468 PyErr_WriteUnraisable(context ? context : Py_None(&_Py_NoneStruct));
469 /* There has been a warning before about this already */
470 return E_FAIL;
471 }
472
473 func = PyObject_GetAttrString(mod, "DllGetClassObject");
474 Py_DECREF(mod)do { if (_Py_RefTotal-- , --((PyObject*)(mod))->ob_refcnt !=
0) { if (((PyObject*)mod)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 474, (PyObject *)(mod)); } else _Py_Dealloc((PyObject *)(mod
)); } while (0)
;
475 if (!func) {
476 PyErr_WriteUnraisable(context ? context : Py_None(&_Py_NoneStruct));
477 return E_FAIL;
478 }
479
480 {
481 PyObject *py_rclsid = PyLong_FromVoidPtr((void *)rclsid);
482 PyObject *py_riid = PyLong_FromVoidPtr((void *)riid);
483 PyObject *py_ppv = PyLong_FromVoidPtr(ppv);
484 if (!py_rclsid || !py_riid || !py_ppv) {
485 Py_XDECREF(py_rclsid)do { if ((py_rclsid) == ((void*)0)) ; else do { if (_Py_RefTotal
-- , --((PyObject*)(py_rclsid))->ob_refcnt != 0) { if (((PyObject
*)py_rclsid)->ob_refcnt < 0) _Py_NegativeRefcount("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 485, (PyObject *)(py_rclsid)); } else _Py_Dealloc((PyObject
*)(py_rclsid)); } while (0); } while (0)
;
486 Py_XDECREF(py_riid)do { if ((py_riid) == ((void*)0)) ; else do { if (_Py_RefTotal
-- , --((PyObject*)(py_riid))->ob_refcnt != 0) { if (((PyObject
*)py_riid)->ob_refcnt < 0) _Py_NegativeRefcount("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 486, (PyObject *)(py_riid)); } else _Py_Dealloc((PyObject *
)(py_riid)); } while (0); } while (0)
;
487 Py_XDECREF(py_ppv)do { if ((py_ppv) == ((void*)0)) ; else do { if (_Py_RefTotal
-- , --((PyObject*)(py_ppv))->ob_refcnt != 0) { if (((PyObject
*)py_ppv)->ob_refcnt < 0) _Py_NegativeRefcount("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 487, (PyObject *)(py_ppv)); } else _Py_Dealloc((PyObject *)
(py_ppv)); } while (0); } while (0)
;
488 Py_DECREF(func)do { if (_Py_RefTotal-- , --((PyObject*)(func))->ob_refcnt
!= 0) { if (((PyObject*)func)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 488, (PyObject *)(func)); } else _Py_Dealloc((PyObject *)(func
)); } while (0)
;
489 PyErr_WriteUnraisable(context ? context : Py_None(&_Py_NoneStruct));
490 return E_FAIL;
491 }
492 result = PyObject_CallFunctionObjArgs(func,
493 py_rclsid,
494 py_riid,
495 py_ppv,
496 NULL((void*)0));
497 Py_DECREF(py_rclsid)do { if (_Py_RefTotal-- , --((PyObject*)(py_rclsid))->ob_refcnt
!= 0) { if (((PyObject*)py_rclsid)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 497, (PyObject *)(py_rclsid)); } else _Py_Dealloc((PyObject
*)(py_rclsid)); } while (0)
;
498 Py_DECREF(py_riid)do { if (_Py_RefTotal-- , --((PyObject*)(py_riid))->ob_refcnt
!= 0) { if (((PyObject*)py_riid)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 498, (PyObject *)(py_riid)); } else _Py_Dealloc((PyObject *
)(py_riid)); } while (0)
;
499 Py_DECREF(py_ppv)do { if (_Py_RefTotal-- , --((PyObject*)(py_ppv))->ob_refcnt
!= 0) { if (((PyObject*)py_ppv)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 499, (PyObject *)(py_ppv)); } else _Py_Dealloc((PyObject *)
(py_ppv)); } while (0)
;
500 }
501 Py_DECREF(func)do { if (_Py_RefTotal-- , --((PyObject*)(func))->ob_refcnt
!= 0) { if (((PyObject*)func)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 501, (PyObject *)(func)); } else _Py_Dealloc((PyObject *)(func
)); } while (0)
;
502 if (!result) {
503 PyErr_WriteUnraisable(context ? context : Py_None(&_Py_NoneStruct));
504 return E_FAIL;
505 }
506
507 retval = PyLong_AsLong(result);
508 if (PyErr_Occurred()) {
509 PyErr_WriteUnraisable(context ? context : Py_None(&_Py_NoneStruct));
510 retval = E_FAIL;
511 }
512 Py_DECREF(result)do { if (_Py_RefTotal-- , --((PyObject*)(result))->ob_refcnt
!= 0) { if (((PyObject*)result)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 512, (PyObject *)(result)); } else _Py_Dealloc((PyObject *)
(result)); } while (0)
;
513 return retval;
514}
515
516STDAPI DllGetClassObject(REFCLSID rclsid,
517 REFIID riid,
518 LPVOID *ppv)
519{
520 long result;
521#ifdef WITH_THREAD1
522 PyGILState_STATE state;
523#endif
524
525 LoadPython();
526#ifdef WITH_THREAD1
527 state = PyGILState_Ensure();
528#endif
529 result = Call_GetClassObject(rclsid, riid, ppv);
530#ifdef WITH_THREAD1
531 PyGILState_Release(state);
532#endif
533 return result;
534}
535
536long Call_CanUnloadNow(void)
537{
538 PyObject *mod, *func, *result;
539 long retval;
540 static PyObject *context;
541
542 if (context == NULL((void*)0))
543 context = PyUnicode_InternFromString("_ctypes.DllCanUnloadNow");
544
545 mod = PyImport_ImportModuleNoBlock("ctypes");
546 if (!mod) {
547/* OutputDebugString("Could not import ctypes"); */
548 /* We assume that this error can only occur when shutting
549 down, so we silently ignore it */
550 PyErr_Clear();
551 return E_FAIL;
552 }
553 /* Other errors cannot be raised, but are printed to stderr */
554 func = PyObject_GetAttrString(mod, "DllCanUnloadNow");
555 Py_DECREF(mod)do { if (_Py_RefTotal-- , --((PyObject*)(mod))->ob_refcnt !=
0) { if (((PyObject*)mod)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 555, (PyObject *)(mod)); } else _Py_Dealloc((PyObject *)(mod
)); } while (0)
;
556 if (!func) {
557 PyErr_WriteUnraisable(context ? context : Py_None(&_Py_NoneStruct));
558 return E_FAIL;
559 }
560
561 result = PyObject_CallFunction(func, NULL((void*)0));
562 Py_DECREF(func)do { if (_Py_RefTotal-- , --((PyObject*)(func))->ob_refcnt
!= 0) { if (((PyObject*)func)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 562, (PyObject *)(func)); } else _Py_Dealloc((PyObject *)(func
)); } while (0)
;
563 if (!result) {
564 PyErr_WriteUnraisable(context ? context : Py_None(&_Py_NoneStruct));
565 return E_FAIL;
566 }
567
568 retval = PyLong_AsLong(result);
569 if (PyErr_Occurred()) {
570 PyErr_WriteUnraisable(context ? context : Py_None(&_Py_NoneStruct));
571 retval = E_FAIL;
572 }
573 Py_DECREF(result)do { if (_Py_RefTotal-- , --((PyObject*)(result))->ob_refcnt
!= 0) { if (((PyObject*)result)->ob_refcnt < 0) _Py_NegativeRefcount
("/Users/brett/Dev/python/3.x/py3k/Modules/_ctypes/callbacks.c"
, 573, (PyObject *)(result)); } else _Py_Dealloc((PyObject *)
(result)); } while (0)
;
574 return retval;
575}
576
577/*
578 DllRegisterServer and DllUnregisterServer still missing
579*/
580
581STDAPI DllCanUnloadNow(void)
582{
583 long result;
584#ifdef WITH_THREAD1
585 PyGILState_STATE state = PyGILState_Ensure();
586#endif
587 result = Call_CanUnloadNow();
588#ifdef WITH_THREAD1
589 PyGILState_Release(state);
590#endif
591 return result;
592}
593
594#ifndef Py_NO_ENABLE_SHARED
595BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvRes)
596{
597 switch(fdwReason) {
598 case DLL_PROCESS_ATTACH:
599 DisableThreadLibraryCalls(hinstDLL);
600 break;
601 }
602 return TRUE;
603}
604#endif
605
606#endif
607
608/*
609 Local Variables:
610 compile-command: "cd .. && python setup.py -q build_ext"
611 End:
612*/