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