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