blob: c091d88364a40a408340cbc93ed0cb7a0998b663 [file] [log] [blame]
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001/*****************************************************************
2 This file should be kept compatible with Python 2.3, see PEP 291.
3 *****************************************************************/
4
Thomas Hellerd4c93202006-03-08 19:35:11 +00005#include "Python.h"
6#include "compile.h" /* required only for 2.3, as it seems */
7#include "frameobject.h"
8
9#include <ffi.h>
10#ifdef MS_WIN32
11#include <windows.h>
12#endif
13#include "ctypes.h"
14
15static void
16PrintError(char *msg, ...)
17{
18 char buf[512];
19 PyObject *f = PySys_GetObject("stderr");
20 va_list marker;
21
22 va_start(marker, msg);
23 vsnprintf(buf, sizeof(buf), msg, marker);
24 va_end(marker);
25 if (f)
26 PyFile_WriteString(buf, f);
27 PyErr_Print();
28}
29
30
31/* after code that pyrex generates */
32void _AddTraceback(char *funcname, char *filename, int lineno)
33{
34 PyObject *py_srcfile = 0;
35 PyObject *py_funcname = 0;
36 PyObject *py_globals = 0;
37 PyObject *empty_tuple = 0;
38 PyObject *empty_string = 0;
39 PyCodeObject *py_code = 0;
40 PyFrameObject *py_frame = 0;
41
42 py_srcfile = PyString_FromString(filename);
43 if (!py_srcfile) goto bad;
44 py_funcname = PyString_FromString(funcname);
45 if (!py_funcname) goto bad;
46 py_globals = PyDict_New();
47 if (!py_globals) goto bad;
48 empty_tuple = PyTuple_New(0);
49 if (!empty_tuple) goto bad;
50 empty_string = PyString_FromString("");
51 if (!empty_string) goto bad;
52 py_code = PyCode_New(
53 0, /*int argcount,*/
54 0, /*int nlocals,*/
55 0, /*int stacksize,*/
56 0, /*int flags,*/
57 empty_string, /*PyObject *code,*/
58 empty_tuple, /*PyObject *consts,*/
59 empty_tuple, /*PyObject *names,*/
60 empty_tuple, /*PyObject *varnames,*/
61 empty_tuple, /*PyObject *freevars,*/
62 empty_tuple, /*PyObject *cellvars,*/
63 py_srcfile, /*PyObject *filename,*/
64 py_funcname, /*PyObject *name,*/
65 lineno, /*int firstlineno,*/
66 empty_string /*PyObject *lnotab*/
67 );
68 if (!py_code) goto bad;
69 py_frame = PyFrame_New(
70 PyThreadState_Get(), /*PyThreadState *tstate,*/
71 py_code, /*PyCodeObject *code,*/
72 py_globals, /*PyObject *globals,*/
73 0 /*PyObject *locals*/
74 );
75 if (!py_frame) goto bad;
76 py_frame->f_lineno = lineno;
77 PyTraceBack_Here(py_frame);
78 bad:
79 Py_XDECREF(py_globals);
80 Py_XDECREF(py_srcfile);
81 Py_XDECREF(py_funcname);
82 Py_XDECREF(empty_tuple);
83 Py_XDECREF(empty_string);
84 Py_XDECREF(py_code);
85 Py_XDECREF(py_frame);
86}
87
88#ifdef MS_WIN32
89/*
90 * We must call AddRef() on non-NULL COM pointers we receive as arguments
91 * to callback functions - these functions are COM method implementations.
92 * The Python instances we create have a __del__ method which calls Release().
93 *
94 * The presence of a class attribute named '_needs_com_addref_' triggers this
95 * behaviour. It would also be possible to call the AddRef() Python method,
96 * after checking for PyObject_IsTrue(), but this would probably be somewhat
97 * slower.
98 */
99static void
100TryAddRef(StgDictObject *dict, CDataObject *obj)
101{
102 IUnknown *punk;
103
104 if (NULL == PyDict_GetItemString((PyObject *)dict, "_needs_com_addref_"))
105 return;
106
107 punk = *(IUnknown **)obj->b_ptr;
108 if (punk)
109 punk->lpVtbl->AddRef(punk);
110 return;
111}
112#endif
113
114/******************************************************************************
115 *
116 * Call the python object with all arguments
117 *
118 */
119static void _CallPythonObject(void *mem,
120 ffi_type *restype,
121 SETFUNC setfunc,
122 PyObject *callable,
123 PyObject *converters,
124 void **pArgs)
125{
126 int i;
127 PyObject *result;
128 PyObject *arglist = NULL;
129 int nArgs;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000130#ifdef WITH_THREAD
Thomas Hellerd4c93202006-03-08 19:35:11 +0000131 PyGILState_STATE state = PyGILState_Ensure();
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000132#endif
Thomas Hellerd4c93202006-03-08 19:35:11 +0000133
134 nArgs = PySequence_Length(converters);
135 /* Hm. What to return in case of error?
136 For COM, 0xFFFFFFFF seems better than 0.
137 */
138 if (nArgs < 0) {
139 PrintError("BUG: PySequence_Length");
140 goto Done;
141 }
142
143 arglist = PyTuple_New(nArgs);
144 if (!arglist) {
145 PrintError("PyTuple_New()");
146 goto Done;
147 }
148 for (i = 0; i < nArgs; ++i) {
149 /* Note: new reference! */
150 PyObject *cnv = PySequence_GetItem(converters, i);
151 StgDictObject *dict;
152 if (cnv)
153 dict = PyType_stgdict(cnv);
154 else {
155 PrintError("Getting argument converter %d\n", i);
156 goto Done;
157 }
158
159 if (dict && dict->getfunc && !IsSimpleSubType(cnv)) {
160 PyObject *v = dict->getfunc(*pArgs, dict->size);
161 if (!v) {
162 PrintError("create argument %d:\n", i);
163 Py_DECREF(cnv);
164 goto Done;
165 }
166 PyTuple_SET_ITEM(arglist, i, v);
167 /* XXX XXX XX
168 We have the problem that c_byte or c_short have dict->size of
169 1 resp. 4, but these parameters are pushed as sizeof(int) bytes.
170 BTW, the same problem occurrs when they are pushed as parameters
171 */
172 } else if (dict) {
173 /* Hm, shouldn't we use CData_AtAddress() or something like that instead? */
174 CDataObject *obj = (CDataObject *)PyObject_CallFunctionObjArgs(cnv, NULL);
175 if (!obj) {
176 PrintError("create argument %d:\n", i);
177 Py_DECREF(cnv);
178 goto Done;
179 }
180 if (!CDataObject_Check(obj)) {
181 Py_DECREF(obj);
182 Py_DECREF(cnv);
183 PrintError("unexpected result of create argument %d:\n", i);
184 goto Done;
185 }
186 memcpy(obj->b_ptr, *pArgs, dict->size);
187 PyTuple_SET_ITEM(arglist, i, (PyObject *)obj);
188#ifdef MS_WIN32
189 TryAddRef(dict, obj);
190#endif
191 } else {
192 PyErr_SetString(PyExc_TypeError,
193 "cannot build parameter");
194 PrintError("Parsing argument %d\n", i);
195 Py_DECREF(cnv);
196 goto Done;
197 }
198 Py_DECREF(cnv);
199 /* XXX error handling! */
200 pArgs++;
201 }
202
203#define CHECK(what, x) \
204if (x == NULL) _AddTraceback(what, __FILE__, __LINE__ - 1), PyErr_Print()
205
206 result = PyObject_CallObject(callable, arglist);
207 CHECK("'calling callback function'", result);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000208 if ((restype != &ffi_type_void) && result && result != Py_None) {
Thomas Hellerd4c93202006-03-08 19:35:11 +0000209 PyObject *keep;
210 assert(setfunc);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000211#ifdef WORDS_BIGENDIAN
212 /* See the corresponding code in callproc.c, around line 961 */
213 if (restype->type != FFI_TYPE_FLOAT && restype->size < sizeof(ffi_arg))
214 mem = (char *)mem + sizeof(ffi_arg) - restype->size;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000215#endif
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000216 keep = setfunc(mem, result, 0);
217 CHECK("'converting callback result'", keep);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000218 /* keep is an object we have to keep alive so that the result
219 stays valid. If there is no such object, the setfunc will
220 have returned Py_None.
221
222 If there is such an object, we have no choice than to keep
223 it alive forever - but a refcount and/or memory leak will
224 be the result. EXCEPT when restype is py_object - Python
225 itself knows how to manage the refcount of these objects.
226 */
227 if (keep == NULL) /* Could not convert callback result. */
228 PyErr_WriteUnraisable(Py_None);
229 else if (keep == Py_None) /* Nothing to keep */
230 Py_DECREF(keep);
231 else if (setfunc != getentry("O")->setfunc) {
232 if (-1 == PyErr_Warn(PyExc_RuntimeWarning,
233 "memory leak in callback function."))
234 PyErr_WriteUnraisable(Py_None);
235 }
236 }
237 Py_XDECREF(result);
238 Done:
239 Py_XDECREF(arglist);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000240#ifdef WITH_THREAD
Thomas Hellerd4c93202006-03-08 19:35:11 +0000241 PyGILState_Release(state);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000242#endif
Thomas Hellerd4c93202006-03-08 19:35:11 +0000243}
244
Thomas Hellerd4c93202006-03-08 19:35:11 +0000245static void closure_fcn(ffi_cif *cif,
246 void *resp,
247 void **args,
248 void *userdata)
249{
250 ffi_info *p = userdata;
251
252 _CallPythonObject(resp,
253 p->restype,
254 p->setfunc,
255 p->callable,
256 p->converters,
257 args);
258}
259
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000260ffi_info *AllocFunctionCallback(PyObject *callable,
261 PyObject *converters,
262 PyObject *restype,
263 int is_cdecl)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000264{
265 int result;
266 ffi_info *p;
267 int nArgs, i;
268 ffi_abi cc;
269
270 nArgs = PySequence_Size(converters);
271 p = (ffi_info *)PyMem_Malloc(sizeof(ffi_info) + sizeof(ffi_type) * (nArgs + 1));
272 if (p == NULL) {
273 PyErr_NoMemory();
274 return NULL;
275 }
276 p->pcl = MallocClosure();
277 if (p->pcl == NULL) {
Thomas Hellerd4c93202006-03-08 19:35:11 +0000278 PyErr_NoMemory();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000279 goto error;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000280 }
281
282 for (i = 0; i < nArgs; ++i) {
283 PyObject *cnv = PySequence_GetItem(converters, i);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000284 if (cnv == NULL)
285 goto error;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000286 p->atypes[i] = GetType(cnv);
287 Py_DECREF(cnv);
288 }
289 p->atypes[i] = NULL;
290
291 if (restype == Py_None) {
292 p->setfunc = NULL;
293 p->restype = &ffi_type_void;
294 } else {
295 StgDictObject *dict = PyType_stgdict(restype);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000296 if (dict == NULL)
297 goto error;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000298 p->setfunc = dict->setfunc;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000299 p->restype = &dict->ffi_type_pointer;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000300 }
301
302 cc = FFI_DEFAULT_ABI;
303#if defined(MS_WIN32) && !defined(_WIN32_WCE)
304 if (is_cdecl == 0)
305 cc = FFI_STDCALL;
306#endif
307 result = ffi_prep_cif(&p->cif, cc, nArgs,
308 GetType(restype),
309 &p->atypes[0]);
310 if (result != FFI_OK) {
311 PyErr_Format(PyExc_RuntimeError,
312 "ffi_prep_cif failed with %d", result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000313 goto error;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000314 }
315 result = ffi_prep_closure(p->pcl, &p->cif, closure_fcn, p);
316 if (result != FFI_OK) {
317 PyErr_Format(PyExc_RuntimeError,
318 "ffi_prep_closure failed with %d", result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000319 goto error;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000320 }
321
322 p->converters = converters;
323 p->callable = callable;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000324 return p;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000325
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000326 error:
327 if (p) {
328 if (p->pcl)
329 FreeClosure(p->pcl);
330 PyMem_Free(p);
331 }
332 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000333}
334
335/****************************************************************************
336 *
337 * callback objects: initialization
338 */
339
340void init_callbacks_in_module(PyObject *m)
341{
342 if (PyType_Ready((PyTypeObject *)&PyType_Type) < 0)
343 return;
344}
345
346#ifdef MS_WIN32
347
348static void LoadPython(void)
349{
350 if (!Py_IsInitialized()) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000351#ifdef WITH_THREAD
Thomas Hellerd4c93202006-03-08 19:35:11 +0000352 PyEval_InitThreads();
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000353#endif
Thomas Hellerd4c93202006-03-08 19:35:11 +0000354 Py_Initialize();
355 }
356}
357
358/******************************************************************/
359
360long Call_GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
361{
362 PyObject *mod, *func, *result;
363 long retval;
364 static PyObject *context;
365
366 if (context == NULL)
367 context = PyString_FromString("_ctypes.DllGetClassObject");
368
369 mod = PyImport_ImportModule("ctypes");
370 if (!mod) {
371 PyErr_WriteUnraisable(context ? context : Py_None);
372 /* There has been a warning before about this already */
373 return E_FAIL;
374 }
375
376 func = PyObject_GetAttrString(mod, "DllGetClassObject");
377 Py_DECREF(mod);
378 if (!func) {
379 PyErr_WriteUnraisable(context ? context : Py_None);
380 return E_FAIL;
381 }
382
383 result = PyObject_CallFunction(func,
384 "iii", rclsid, riid, ppv);
385 Py_DECREF(func);
386 if (!result) {
387 PyErr_WriteUnraisable(context ? context : Py_None);
388 return E_FAIL;
389 }
390
391 retval = PyInt_AsLong(result);
392 if (PyErr_Occurred()) {
393 PyErr_WriteUnraisable(context ? context : Py_None);
394 retval = E_FAIL;
395 }
396 Py_DECREF(result);
397 return retval;
398}
399
400STDAPI DllGetClassObject(REFCLSID rclsid,
401 REFIID riid,
402 LPVOID *ppv)
403{
404 long result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000405#ifdef WITH_THREAD
Thomas Hellerd4c93202006-03-08 19:35:11 +0000406 PyGILState_STATE state;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000407#endif
Thomas Hellerd4c93202006-03-08 19:35:11 +0000408
409 LoadPython();
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000410#ifdef WITH_THREAD
Thomas Hellerd4c93202006-03-08 19:35:11 +0000411 state = PyGILState_Ensure();
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000412#endif
Thomas Hellerd4c93202006-03-08 19:35:11 +0000413 result = Call_GetClassObject(rclsid, riid, ppv);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000414#ifdef WITH_THREAD
Thomas Hellerd4c93202006-03-08 19:35:11 +0000415 PyGILState_Release(state);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000416#endif
Thomas Hellerd4c93202006-03-08 19:35:11 +0000417 return result;
418}
419
420long Call_CanUnloadNow(void)
421{
422 PyObject *mod, *func, *result;
423 long retval;
424 static PyObject *context;
425
426 if (context == NULL)
427 context = PyString_FromString("_ctypes.DllCanUnloadNow");
428
429 mod = PyImport_ImportModule("ctypes");
430 if (!mod) {
431/* OutputDebugString("Could not import ctypes"); */
432 /* We assume that this error can only occur when shutting
433 down, so we silently ignore it */
434 PyErr_Clear();
435 return E_FAIL;
436 }
437 /* Other errors cannot be raised, but are printed to stderr */
438 func = PyObject_GetAttrString(mod, "DllCanUnloadNow");
439 Py_DECREF(mod);
440 if (!func) {
441 PyErr_WriteUnraisable(context ? context : Py_None);
442 return E_FAIL;
443 }
444
445 result = PyObject_CallFunction(func, NULL);
446 Py_DECREF(func);
447 if (!result) {
448 PyErr_WriteUnraisable(context ? context : Py_None);
449 return E_FAIL;
450 }
451
452 retval = PyInt_AsLong(result);
453 if (PyErr_Occurred()) {
454 PyErr_WriteUnraisable(context ? context : Py_None);
455 retval = E_FAIL;
456 }
457 Py_DECREF(result);
458 return retval;
459}
460
461/*
462 DllRegisterServer and DllUnregisterServer still missing
463*/
464
465STDAPI DllCanUnloadNow(void)
466{
467 long result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000468#ifdef WITH_THREAD
Thomas Hellerd4c93202006-03-08 19:35:11 +0000469 PyGILState_STATE state = PyGILState_Ensure();
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000470#endif
Thomas Hellerd4c93202006-03-08 19:35:11 +0000471 result = Call_CanUnloadNow();
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000472#ifdef WITH_THREAD
Thomas Hellerd4c93202006-03-08 19:35:11 +0000473 PyGILState_Release(state);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000474#endif
Thomas Hellerd4c93202006-03-08 19:35:11 +0000475 return result;
476}
477
478#ifndef Py_NO_ENABLE_SHARED
479BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvRes)
480{
481 switch(fdwReason) {
482 case DLL_PROCESS_ATTACH:
483 DisableThreadLibraryCalls(hinstDLL);
484 break;
485 }
486 return TRUE;
487}
488#endif
489
490#endif
491
492/*
493 Local Variables:
494 compile-command: "cd .. && python setup.py -q build_ext"
495 End:
496*/