lib_obj.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
  1. /* A Lib object is what is in the "lib" attribute of a C extension
  2. module originally created by recompile().
  3. A Lib object is special in the sense that it has a custom
  4. __getattr__ which returns C globals, functions and constants. The
  5. original idea was to raise AttributeError for anything else, even
  6. attrs like '__class__', but it breaks various things; now, standard
  7. attrs are returned, but in the unlikely case where a user cdef()s
  8. the same name, then the standard attr is hidden (and the various
  9. things like introspection might break).
  10. A Lib object has got a reference to the _cffi_type_context_s
  11. structure, which is used to create lazily the objects returned by
  12. __getattr__.
  13. */
  14. #if defined(_asan_enabled_)
  15. void __lsan_ignore_object(const void* p);
  16. #endif
  17. inline static void MarkAsIntentionallyLeaked(const void* ptr) {
  18. #if defined(_asan_enabled_)
  19. __lsan_ignore_object(ptr);
  20. #else
  21. (void)ptr;
  22. #endif
  23. }
  24. struct CPyExtFunc_s {
  25. PyMethodDef md;
  26. void *direct_fn;
  27. PyObject *direct_fn_cdata;
  28. int type_index;
  29. char doc[1];
  30. };
  31. struct LibObject_s {
  32. PyObject_HEAD
  33. builder_c_t *l_types_builder; /* same as the one on the ffi object */
  34. PyObject *l_dict; /* content, built lazily */
  35. PyObject *l_libname; /* some string that gives the name of the lib */
  36. FFIObject *l_ffi; /* reference back to the ffi object */
  37. void *l_libhandle; /* the dlopen()ed handle, if any */
  38. int l_auto_close; /* if we must dlclose() this handle */
  39. };
  40. static struct CPyExtFunc_s *_cpyextfunc_get(PyObject *x)
  41. {
  42. PyObject *y;
  43. LibObject *lo;
  44. PyCFunctionObject *fo;
  45. if (!PyCFunction_Check(x))
  46. return NULL;
  47. y = PyCFunction_GET_SELF(x);
  48. if (!LibObject_Check(y))
  49. return NULL;
  50. fo = (PyCFunctionObject *)x;
  51. lo = (LibObject *)y;
  52. if (lo->l_libname != fo->m_module)
  53. return NULL;
  54. return (struct CPyExtFunc_s *)(fo->m_ml);
  55. }
  56. static PyObject *_cpyextfunc_type(LibObject *lib, struct CPyExtFunc_s *exf)
  57. {
  58. PyObject *tuple, *result;
  59. tuple = realize_c_type_or_func(lib->l_types_builder,
  60. lib->l_types_builder->ctx.types,
  61. exf->type_index);
  62. if (tuple == NULL)
  63. return NULL;
  64. /* 'tuple' is a tuple of length 1 containing the real CT_FUNCTIONPTR
  65. object */
  66. result = PyTuple_GetItem(tuple, 0);
  67. Py_XINCREF(result);
  68. Py_DECREF(tuple);
  69. return result;
  70. }
  71. static PyObject *_cpyextfunc_type_index(PyObject *x)
  72. {
  73. struct CPyExtFunc_s *exf;
  74. LibObject *lib;
  75. assert(PyErr_Occurred());
  76. exf = _cpyextfunc_get(x);
  77. if (exf == NULL)
  78. return NULL; /* still the same exception is set */
  79. PyErr_Clear();
  80. lib = (LibObject *)PyCFunction_GET_SELF(x);
  81. return _cpyextfunc_type(lib, exf);
  82. }
  83. static void cdlopen_close_ignore_errors(void *libhandle); /* forward */
  84. static void *cdlopen_fetch(PyObject *libname, void *libhandle,
  85. const char *symbol);
  86. static void lib_dealloc(LibObject *lib)
  87. {
  88. PyObject_GC_UnTrack(lib);
  89. if (lib->l_auto_close)
  90. cdlopen_close_ignore_errors(lib->l_libhandle);
  91. Py_DECREF(lib->l_dict);
  92. Py_DECREF(lib->l_libname);
  93. Py_DECREF(lib->l_ffi);
  94. PyObject_GC_Del(lib);
  95. }
  96. static int lib_traverse(LibObject *lib, visitproc visit, void *arg)
  97. {
  98. Py_VISIT(lib->l_dict);
  99. Py_VISIT(lib->l_libname);
  100. Py_VISIT(lib->l_ffi);
  101. return 0;
  102. }
  103. static PyObject *lib_repr(LibObject *lib)
  104. {
  105. return PyText_FromFormat("<Lib object for '%.200s'>",
  106. PyText_AS_UTF8(lib->l_libname));
  107. }
  108. static PyObject *lib_build_cpython_func(LibObject *lib,
  109. const struct _cffi_global_s *g,
  110. const char *s, int flags)
  111. {
  112. /* First make sure the argument types and return type are really
  113. built. The C extension code can then assume that they are,
  114. by calling _cffi_type().
  115. */
  116. PyObject *result = NULL;
  117. CTypeDescrObject **pfargs = NULL;
  118. CTypeDescrObject *fresult;
  119. Py_ssize_t nargs = 0;
  120. struct CPyExtFunc_s *xfunc;
  121. int i, type_index = _CFFI_GETARG(g->type_op);
  122. _cffi_opcode_t *opcodes = lib->l_types_builder->ctx.types;
  123. static const char *const format = ";\n\nCFFI C function from %s.lib";
  124. const char *libname = PyText_AS_UTF8(lib->l_libname);
  125. struct funcbuilder_s funcbuilder;
  126. /* return type: */
  127. fresult = realize_c_func_return_type(lib->l_types_builder, opcodes,
  128. type_index);
  129. if (fresult == NULL)
  130. goto error;
  131. /* argument types: */
  132. /* note that if the arguments are already built, they have a
  133. pointer in the 'opcodes' array, and GETOP() returns a
  134. random even value. But OP_FUNCTION_END is odd, so the
  135. condition below still works correctly. */
  136. i = type_index + 1;
  137. while (_CFFI_GETOP(opcodes[i]) != _CFFI_OP_FUNCTION_END)
  138. i++;
  139. pfargs = alloca(sizeof(CTypeDescrObject *) * (i - type_index - 1));
  140. i = type_index + 1;
  141. while (_CFFI_GETOP(opcodes[i]) != _CFFI_OP_FUNCTION_END) {
  142. CTypeDescrObject *ct = realize_c_type(lib->l_types_builder, opcodes, i);
  143. if (ct == NULL)
  144. goto error;
  145. pfargs[nargs++] = ct;
  146. i++;
  147. }
  148. memset(&funcbuilder, 0, sizeof(funcbuilder));
  149. if (fb_build_name(&funcbuilder, g->name, pfargs, nargs, fresult, 0) < 0)
  150. goto error;
  151. /* The few bytes of memory we allocate here appear to leak, but
  152. this is not a real leak. Indeed, CPython never unloads its C
  153. extension modules. There is only one PyMem_Malloc() per real
  154. C function in a CFFI C extension module. That means that this
  155. PyMem_Malloc() could also have been written with a static
  156. global variable generated for each CPYTHON_BLTN defined in the
  157. C extension, and the effect would be the same (but a bit more
  158. complicated).
  159. */
  160. xfunc = PyMem_Malloc(sizeof(struct CPyExtFunc_s) +
  161. funcbuilder.nb_bytes +
  162. strlen(format) + strlen(libname));
  163. if (xfunc == NULL) {
  164. PyErr_NoMemory();
  165. goto error;
  166. }
  167. memset((char *)xfunc, 0, sizeof(struct CPyExtFunc_s));
  168. assert(g->address);
  169. xfunc->md.ml_meth = (PyCFunction)g->address;
  170. xfunc->md.ml_flags = flags;
  171. xfunc->md.ml_name = g->name;
  172. xfunc->md.ml_doc = xfunc->doc;
  173. xfunc->direct_fn = g->size_or_direct_fn;
  174. xfunc->type_index = type_index;
  175. /* build the docstring */
  176. funcbuilder.bufferp = xfunc->doc;
  177. if (fb_build_name(&funcbuilder, g->name, pfargs, nargs, fresult, 0) < 0)
  178. goto error;
  179. sprintf(funcbuilder.bufferp - 1, format, libname);
  180. /* done building the docstring */
  181. result = PyCFunction_NewEx(&xfunc->md, (PyObject *)lib, lib->l_libname);
  182. /* fall-through */
  183. error:
  184. Py_XDECREF(fresult);
  185. while (nargs > 0) {
  186. --nargs;
  187. Py_DECREF(pfargs[nargs]);
  188. }
  189. return result;
  190. }
  191. static PyObject *lib_build_and_cache_attr(LibObject *lib, PyObject *name,
  192. int recursion)
  193. {
  194. /* does not return a new reference! */
  195. PyObject *x;
  196. int index;
  197. const struct _cffi_global_s *g;
  198. CTypeDescrObject *ct;
  199. builder_c_t *types_builder = lib->l_types_builder;
  200. const char *s = PyText_AsUTF8(name);
  201. if (s == NULL)
  202. return NULL;
  203. index = search_in_globals(&types_builder->ctx, s, strlen(s));
  204. if (index < 0) {
  205. if (types_builder->included_libs != NULL) {
  206. Py_ssize_t i;
  207. PyObject *included_ffis = types_builder->included_ffis;
  208. PyObject *included_libs = types_builder->included_libs;
  209. if (recursion > 100) {
  210. PyErr_SetString(PyExc_RuntimeError,
  211. "recursion overflow in ffi.include() delegations");
  212. return NULL;
  213. }
  214. for (i = 0; i < PyTuple_GET_SIZE(included_libs); i++) {
  215. LibObject *lib1;
  216. lib1 = (LibObject *)PyTuple_GET_ITEM(included_libs, i);
  217. if (lib1 != NULL) {
  218. x = PyDict_GetItem(lib1->l_dict, name);
  219. if (x != NULL) {
  220. Py_INCREF(x);
  221. goto found;
  222. }
  223. x = lib_build_and_cache_attr(lib1, name, recursion + 1);
  224. if (x != NULL) {
  225. Py_INCREF(x);
  226. goto found;
  227. }
  228. }
  229. else {
  230. FFIObject *ffi1;
  231. ffi1 = (FFIObject *)PyTuple_GetItem(included_ffis, i);
  232. if (ffi1 == NULL)
  233. return NULL;
  234. x = ffi_fetch_int_constant(ffi1, s, recursion + 1);
  235. if (x != NULL)
  236. goto found;
  237. }
  238. if (PyErr_Occurred())
  239. return NULL;
  240. }
  241. }
  242. if (recursion > 0)
  243. return NULL; /* no error set, continue looking elsewhere */
  244. PyErr_Format(PyExc_AttributeError,
  245. "cffi library '%.200s' has no function, constant "
  246. "or global variable named '%.200s'",
  247. PyText_AS_UTF8(lib->l_libname), s);
  248. return NULL;
  249. }
  250. g = &types_builder->ctx.globals[index];
  251. switch (_CFFI_GETOP(g->type_op)) {
  252. case _CFFI_OP_CPYTHON_BLTN_V:
  253. x = lib_build_cpython_func(lib, g, s, METH_VARARGS);
  254. break;
  255. case _CFFI_OP_CPYTHON_BLTN_N:
  256. x = lib_build_cpython_func(lib, g, s, METH_NOARGS);
  257. break;
  258. case _CFFI_OP_CPYTHON_BLTN_O:
  259. x = lib_build_cpython_func(lib, g, s, METH_O);
  260. break;
  261. case _CFFI_OP_CONSTANT_INT:
  262. case _CFFI_OP_ENUM:
  263. {
  264. /* a constant integer whose value, in an "unsigned long long",
  265. is obtained by calling the function at g->address */
  266. x = realize_global_int(types_builder, index);
  267. break;
  268. }
  269. case _CFFI_OP_CONSTANT:
  270. case _CFFI_OP_DLOPEN_CONST:
  271. {
  272. /* a constant which is not of integer type */
  273. char *data;
  274. ct = realize_c_type(types_builder, types_builder->ctx.types,
  275. _CFFI_GETARG(g->type_op));
  276. if (ct == NULL)
  277. return NULL;
  278. if (ct->ct_size <= 0) {
  279. PyErr_Format(FFIError, "constant '%s' is of type '%s', "
  280. "whose size is not known", s, ct->ct_name);
  281. return NULL;
  282. }
  283. if (g->address == NULL) {
  284. /* for dlopen() style */
  285. assert(_CFFI_GETOP(g->type_op) == _CFFI_OP_DLOPEN_CONST);
  286. data = cdlopen_fetch(lib->l_libname, lib->l_libhandle, s);
  287. if (data == NULL)
  288. return NULL;
  289. }
  290. else {
  291. /* The few bytes of memory we allocate here appear to leak, but
  292. this is not a real leak. Indeed, CPython never unloads its C
  293. extension modules. There is only one PyMem_Malloc() per real
  294. non-integer C constant in a CFFI C extension module. That
  295. means that this PyMem_Malloc() could also have been written
  296. with a static global variable generated for each OP_CONSTANT
  297. defined in the C extension, and the effect would be the same
  298. (but a bit more complicated).
  299. Note that we used to do alloca(), but see issue #198. We
  300. could still do alloca(), or explicit PyMem_Free(), in some
  301. cases; but there is no point and it only makes the remaining
  302. less-common cases more suspicious.
  303. */
  304. assert(_CFFI_GETOP(g->type_op) == _CFFI_OP_CONSTANT);
  305. data = PyMem_Malloc(ct->ct_size);
  306. if (data == NULL) {
  307. PyErr_NoMemory();
  308. return NULL;
  309. }
  310. MarkAsIntentionallyLeaked(data);
  311. ((void(*)(char*))g->address)(data);
  312. }
  313. x = convert_to_object(data, ct);
  314. Py_DECREF(ct);
  315. break;
  316. }
  317. case _CFFI_OP_GLOBAL_VAR:
  318. {
  319. /* global variable of the exact type specified here
  320. (nowadays, only used by the ABI mode or backward
  321. compatibility; see _CFFI_OP_GLOBAL_VAR_F for the API mode)
  322. */
  323. Py_ssize_t g_size = (Py_ssize_t)g->size_or_direct_fn;
  324. ct = realize_c_type(types_builder, types_builder->ctx.types,
  325. _CFFI_GETARG(g->type_op));
  326. if (ct == NULL)
  327. return NULL;
  328. if (g_size != ct->ct_size && g_size != 0 && ct->ct_size > 0) {
  329. PyErr_Format(FFIError,
  330. "global variable '%.200s' should be %zd bytes "
  331. "according to the cdef, but is actually %zd",
  332. s, ct->ct_size, g_size);
  333. x = NULL;
  334. }
  335. else {
  336. void *address = g->address;
  337. if (address == NULL) {
  338. /* for dlopen() style */
  339. address = cdlopen_fetch(lib->l_libname, lib->l_libhandle, s);
  340. if (address == NULL)
  341. return NULL;
  342. }
  343. x = make_global_var(name, ct, address, NULL);
  344. }
  345. Py_DECREF(ct);
  346. break;
  347. }
  348. case _CFFI_OP_GLOBAL_VAR_F:
  349. ct = realize_c_type(types_builder, types_builder->ctx.types,
  350. _CFFI_GETARG(g->type_op));
  351. if (ct == NULL)
  352. return NULL;
  353. x = make_global_var(name, ct, NULL, (gs_fetch_addr_fn)g->address);
  354. Py_DECREF(ct);
  355. break;
  356. case _CFFI_OP_DLOPEN_FUNC:
  357. {
  358. /* For dlopen(): the function of the given 'name'. We use
  359. dlsym() to get the address of something in the dynamic
  360. library, which we interpret as being exactly a function of
  361. the specified type.
  362. */
  363. PyObject *ct1;
  364. void *address = cdlopen_fetch(lib->l_libname, lib->l_libhandle, s);
  365. if (address == NULL)
  366. return NULL;
  367. ct1 = realize_c_type_or_func(types_builder,
  368. types_builder->ctx.types,
  369. _CFFI_GETARG(g->type_op));
  370. if (ct1 == NULL)
  371. return NULL;
  372. assert(!CTypeDescr_Check(ct1)); /* must be a function */
  373. x = new_simple_cdata(address, unwrap_fn_as_fnptr(ct1));
  374. Py_DECREF(ct1);
  375. break;
  376. }
  377. case _CFFI_OP_EXTERN_PYTHON:
  378. /* for reading 'lib.bar' where bar is declared with extern "Python" */
  379. ct = realize_c_type(types_builder, types_builder->ctx.types,
  380. _CFFI_GETARG(g->type_op));
  381. if (ct == NULL)
  382. return NULL;
  383. x = convert_to_object((char *)&g->size_or_direct_fn, ct);
  384. Py_DECREF(ct);
  385. break;
  386. default:
  387. PyErr_Format(PyExc_NotImplementedError, "in lib_build_attr: op=%d",
  388. (int)_CFFI_GETOP(g->type_op));
  389. return NULL;
  390. }
  391. found:
  392. if (x != NULL) {
  393. int err = PyDict_SetItem(lib->l_dict, name, x);
  394. Py_DECREF(x);
  395. if (err < 0) /* else there is still one ref left in the dict */
  396. return NULL;
  397. }
  398. return x;
  399. }
  400. #define LIB_GET_OR_CACHE_ADDR(x, lib, name, error) \
  401. do { \
  402. x = PyDict_GetItem(lib->l_dict, name); \
  403. if (x == NULL) { \
  404. x = lib_build_and_cache_attr(lib, name, 0); \
  405. if (x == NULL) { \
  406. error; \
  407. } \
  408. } \
  409. } while (0)
  410. static PyObject *_lib_dir1(LibObject *lib, int ignore_global_vars)
  411. {
  412. const struct _cffi_global_s *g = lib->l_types_builder->ctx.globals;
  413. int i, count = 0, total = lib->l_types_builder->ctx.num_globals;
  414. PyObject *s, *lst = PyList_New(total);
  415. if (lst == NULL)
  416. return NULL;
  417. for (i = 0; i < total; i++) {
  418. if (ignore_global_vars) {
  419. int op = _CFFI_GETOP(g[i].type_op);
  420. if (op == _CFFI_OP_GLOBAL_VAR || op == _CFFI_OP_GLOBAL_VAR_F)
  421. continue;
  422. }
  423. s = PyText_FromString(g[i].name);
  424. if (s == NULL)
  425. goto error;
  426. PyList_SET_ITEM(lst, count, s);
  427. count++;
  428. }
  429. if (PyList_SetSlice(lst, count, total, NULL) < 0)
  430. goto error;
  431. return lst;
  432. error:
  433. Py_DECREF(lst);
  434. return NULL;
  435. }
  436. static PyObject *_lib_dict(LibObject *lib)
  437. {
  438. const struct _cffi_global_s *g = lib->l_types_builder->ctx.globals;
  439. int i, total = lib->l_types_builder->ctx.num_globals;
  440. PyObject *name, *x, *d = PyDict_New();
  441. if (d == NULL)
  442. return NULL;
  443. for (i = 0; i < total; i++) {
  444. name = PyText_FromString(g[i].name);
  445. if (name == NULL)
  446. goto error;
  447. LIB_GET_OR_CACHE_ADDR(x, lib, name, goto error);
  448. if (PyDict_SetItem(d, name, x) < 0)
  449. goto error;
  450. Py_DECREF(name);
  451. }
  452. return d;
  453. error:
  454. Py_XDECREF(name);
  455. Py_DECREF(d);
  456. return NULL;
  457. }
  458. static PyObject *lib_getattr(LibObject *lib, PyObject *name)
  459. {
  460. const char *p;
  461. PyObject *x;
  462. LIB_GET_OR_CACHE_ADDR(x, lib, name, goto missing);
  463. if (GlobSupport_Check(x)) {
  464. return read_global_var((GlobSupportObject *)x);
  465. }
  466. Py_INCREF(x);
  467. return x;
  468. missing:
  469. /*** ATTRIBUTEERROR IS SET HERE ***/
  470. p = PyText_AsUTF8(name);
  471. if (p == NULL)
  472. return NULL;
  473. if (strcmp(p, "__all__") == 0) {
  474. PyErr_Clear();
  475. return _lib_dir1(lib, 1);
  476. }
  477. if (strcmp(p, "__dict__") == 0) {
  478. PyErr_Clear();
  479. return _lib_dict(lib);
  480. }
  481. if (strcmp(p, "__class__") == 0) {
  482. PyErr_Clear();
  483. x = (PyObject *)&PyModule_Type;
  484. /* ^^^ used to be Py_TYPE(lib). But HAAAAAACK! That makes
  485. help() behave correctly. I couldn't find a more reasonable
  486. way. Urgh. */
  487. Py_INCREF(x);
  488. return x;
  489. }
  490. /* this hack is for Python 3.5, and also to give a more
  491. module-like behavior */
  492. if (strcmp(p, "__name__") == 0) {
  493. PyErr_Clear();
  494. return PyText_FromFormat("%s.lib", PyText_AS_UTF8(lib->l_libname));
  495. }
  496. #if PY_MAJOR_VERSION >= 3
  497. if (strcmp(p, "__loader__") == 0 || strcmp(p, "__spec__") == 0) {
  498. /* some more module-like behavior hacks */
  499. PyErr_Clear();
  500. Py_INCREF(Py_None);
  501. return Py_None;
  502. }
  503. #endif
  504. return NULL;
  505. }
  506. static int lib_setattr(LibObject *lib, PyObject *name, PyObject *val)
  507. {
  508. PyObject *x;
  509. LIB_GET_OR_CACHE_ADDR(x, lib, name, return -1);
  510. if (val == NULL) {
  511. PyErr_SetString(PyExc_AttributeError, "C attribute cannot be deleted");
  512. return -1;
  513. }
  514. if (GlobSupport_Check(x)) {
  515. return write_global_var((GlobSupportObject *)x, val);
  516. }
  517. PyErr_Format(PyExc_AttributeError,
  518. "cannot write to function or constant '%.200s'",
  519. PyText_Check(name) ? PyText_AS_UTF8(name) : "?");
  520. return -1;
  521. }
  522. static PyObject *lib_dir(PyObject *self, PyObject *noarg)
  523. {
  524. return _lib_dir1((LibObject *)self, 0);
  525. }
  526. static PyMethodDef lib_methods[] = {
  527. {"__dir__", lib_dir, METH_NOARGS},
  528. {NULL, NULL} /* sentinel */
  529. };
  530. static PyTypeObject Lib_Type = {
  531. PyVarObject_HEAD_INIT(NULL, 0)
  532. "_cffi_backend.Lib",
  533. sizeof(LibObject),
  534. 0,
  535. (destructor)lib_dealloc, /* tp_dealloc */
  536. 0, /* tp_print */
  537. 0, /* tp_getattr */
  538. 0, /* tp_setattr */
  539. 0, /* tp_compare */
  540. (reprfunc)lib_repr, /* tp_repr */
  541. 0, /* tp_as_number */
  542. 0, /* tp_as_sequence */
  543. 0, /* tp_as_mapping */
  544. 0, /* tp_hash */
  545. 0, /* tp_call */
  546. 0, /* tp_str */
  547. (getattrofunc)lib_getattr, /* tp_getattro */
  548. (setattrofunc)lib_setattr, /* tp_setattro */
  549. 0, /* tp_as_buffer */
  550. Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
  551. 0, /* tp_doc */
  552. (traverseproc)lib_traverse, /* tp_traverse */
  553. 0, /* tp_clear */
  554. 0, /* tp_richcompare */
  555. 0, /* tp_weaklistoffset */
  556. 0, /* tp_iter */
  557. 0, /* tp_iternext */
  558. lib_methods, /* tp_methods */
  559. 0, /* tp_members */
  560. 0, /* tp_getset */
  561. 0, /* tp_base */
  562. 0, /* tp_dict */
  563. 0, /* tp_descr_get */
  564. 0, /* tp_descr_set */
  565. offsetof(LibObject, l_dict), /* tp_dictoffset */
  566. };
  567. static LibObject *lib_internal_new(FFIObject *ffi, const char *module_name,
  568. void *dlopen_libhandle, int auto_close)
  569. {
  570. LibObject *lib;
  571. PyObject *libname, *dict;
  572. libname = PyText_FromString(module_name);
  573. if (libname == NULL)
  574. goto err1;
  575. dict = PyDict_New();
  576. if (dict == NULL)
  577. goto err2;
  578. lib = (LibObject *)PyType_GenericAlloc(&Lib_Type, 0);
  579. if (lib == NULL)
  580. goto err3;
  581. lib->l_types_builder = &ffi->types_builder;
  582. lib->l_dict = dict;
  583. lib->l_libname = libname;
  584. Py_INCREF(ffi);
  585. lib->l_ffi = ffi;
  586. lib->l_libhandle = dlopen_libhandle;
  587. lib->l_auto_close = auto_close;
  588. return lib;
  589. err3:
  590. Py_DECREF(dict);
  591. err2:
  592. Py_DECREF(libname);
  593. err1:
  594. if (auto_close)
  595. cdlopen_close_ignore_errors(dlopen_libhandle);
  596. return NULL;
  597. }
  598. static PyObject* try_extract_directfnptr(PyObject *x)
  599. {
  600. /* returns: borrowed ref or NULL */
  601. LibObject *lib;
  602. PyObject *ct;
  603. struct CPyExtFunc_s *exf = _cpyextfunc_get(x);
  604. if (exf == NULL)
  605. return NULL; /* wrong type */
  606. if (exf->direct_fn_cdata != NULL)
  607. return exf->direct_fn_cdata; /* common case: cached */
  608. if (exf->direct_fn == NULL)
  609. return x; /* backward compatibility: no direct_fn */
  610. lib = (LibObject *)PyCFunction_GET_SELF(x);
  611. ct = _cpyextfunc_type(lib, exf);
  612. if (ct == NULL)
  613. return NULL; /* error */
  614. x = new_simple_cdata(exf->direct_fn, (CTypeDescrObject *)ct);
  615. Py_DECREF(ct);
  616. exf->direct_fn_cdata = x; /* caches x, which becomes immortal like exf */
  617. return x;
  618. }
  619. static PyObject *address_of_global_var(PyObject *args)
  620. {
  621. LibObject *lib;
  622. PyObject *x, *o_varname;
  623. char *varname;
  624. if (!PyArg_ParseTuple(args, "O!s", &Lib_Type, &lib, &varname))
  625. return NULL;
  626. /* rebuild a string from 'varname', to do typechecks and to force
  627. a unicode back to a plain string (on python 2) */
  628. o_varname = PyText_FromString(varname);
  629. if (o_varname == NULL)
  630. return NULL;
  631. LIB_GET_OR_CACHE_ADDR(x, lib, o_varname, goto error);
  632. Py_DECREF(o_varname);
  633. if (GlobSupport_Check(x)) {
  634. return cg_addressof_global_var((GlobSupportObject *)x);
  635. }
  636. else {
  637. PyObject *func_cdata = try_extract_directfnptr(x);
  638. if (func_cdata != NULL) {
  639. /* an OP_CPYTHON_BLTN: '&func' returns a cdata */
  640. Py_INCREF(func_cdata);
  641. return func_cdata;
  642. }
  643. if (PyErr_Occurred())
  644. return NULL;
  645. if (CData_Check(x) && /* a constant functionptr cdata: 'f == &f' */
  646. (((CDataObject *)x)->c_type->ct_flags & CT_FUNCTIONPTR) != 0) {
  647. Py_INCREF(x);
  648. return x;
  649. }
  650. else {
  651. PyErr_Format(PyExc_AttributeError,
  652. "cannot take the address of the constant '%.200s'",
  653. varname);
  654. return NULL;
  655. }
  656. }
  657. error:
  658. Py_DECREF(o_varname);
  659. return NULL;
  660. }