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