1
2 typedef struct {
3 struct _cffi_type_context_s ctx; /* inlined substructure */
4 PyObject *types_dict;
5 PyObject *included_ffis;
6 PyObject *included_libs;
7 PyObject *_keepalive1;
8 PyObject *_keepalive2;
9 } builder_c_t;
10
11
12 static PyObject *all_primitives[_CFFI__NUM_PRIM];
13 static CTypeDescrObject *g_ct_voidp, *g_ct_chararray;
14
15 static PyObject *build_primitive_type(int num); /* forward */
16
17 #define primitive_in_range(num) ((num) >= 0 && (num) < _CFFI__NUM_PRIM)
18 #define get_primitive_type(num) \
19 ((primitive_in_range(num) && all_primitives[num] != NULL) ? \
20 all_primitives[num] : build_primitive_type(num))
21
init_global_types_dict(PyObject * ffi_type_dict)22 static int init_global_types_dict(PyObject *ffi_type_dict)
23 {
24 int err;
25 PyObject *ct_void, *ct_char, *ct2, *pnull;
26 /* XXX some leaks in case these functions fail, but well,
27 MemoryErrors during importing an extension module are kind
28 of bad anyway */
29
30 ct_void = get_primitive_type(_CFFI_PRIM_VOID); // 'void'
31 if (ct_void == NULL)
32 return -1;
33
34 ct2 = new_pointer_type((CTypeDescrObject *)ct_void); // 'void *'
35 if (ct2 == NULL)
36 return -1;
37 g_ct_voidp = (CTypeDescrObject *)ct2;
38
39 ct_char = get_primitive_type(_CFFI_PRIM_CHAR); // 'char'
40 if (ct_char == NULL)
41 return -1;
42
43 ct2 = new_pointer_type((CTypeDescrObject *)ct_char); // 'char *'
44 if (ct2 == NULL)
45 return -1;
46
47 ct2 = new_array_type((CTypeDescrObject *)ct2, -1); // 'char[]'
48 if (ct2 == NULL)
49 return -1;
50 g_ct_chararray = (CTypeDescrObject *)ct2;
51
52 pnull = new_simple_cdata(NULL, g_ct_voidp);
53 if (pnull == NULL)
54 return -1;
55 err = PyDict_SetItemString(ffi_type_dict, "NULL", pnull);
56 Py_DECREF(pnull);
57 return err;
58 }
59
free_builder_c(builder_c_t * builder,int ctx_is_static)60 static void free_builder_c(builder_c_t *builder, int ctx_is_static)
61 {
62 if (!ctx_is_static) {
63 size_t i;
64 const void *mem[] = {builder->ctx.types,
65 builder->ctx.globals,
66 builder->ctx.struct_unions,
67 //builder->ctx.fields: allocated with struct_unions
68 builder->ctx.enums,
69 builder->ctx.typenames};
70 for (i = 0; i < sizeof(mem) / sizeof(*mem); i++) {
71 if (mem[i] != NULL)
72 PyMem_Free((void *)mem[i]);
73 }
74 }
75 Py_XDECREF(builder->included_ffis);
76 Py_XDECREF(builder->included_libs);
77 Py_XDECREF(builder->types_dict);
78 Py_XDECREF(builder->_keepalive1);
79 Py_XDECREF(builder->_keepalive2);
80 }
81
init_builder_c(builder_c_t * builder,const struct _cffi_type_context_s * ctx)82 static int init_builder_c(builder_c_t *builder,
83 const struct _cffi_type_context_s *ctx)
84 {
85 PyObject *ldict = PyDict_New();
86 if (ldict == NULL)
87 return -1;
88
89 if (ctx)
90 builder->ctx = *ctx;
91 else
92 memset(&builder->ctx, 0, sizeof(builder->ctx));
93
94 builder->types_dict = ldict;
95 builder->included_ffis = NULL;
96 builder->included_libs = NULL;
97 builder->_keepalive1 = NULL;
98 builder->_keepalive2 = NULL;
99 return 0;
100 }
101
build_primitive_type(int num)102 static PyObject *build_primitive_type(int num)
103 {
104 /* XXX too many translations between here and new_primitive_type() */
105 static const char *primitive_name[] = {
106 NULL,
107 "_Bool",
108 "char",
109 "signed char",
110 "unsigned char",
111 "short",
112 "unsigned short",
113 "int",
114 "unsigned int",
115 "long",
116 "unsigned long",
117 "long long",
118 "unsigned long long",
119 "float",
120 "double",
121 "long double",
122 "wchar_t",
123 "int8_t",
124 "uint8_t",
125 "int16_t",
126 "uint16_t",
127 "int32_t",
128 "uint32_t",
129 "int64_t",
130 "uint64_t",
131 "intptr_t",
132 "uintptr_t",
133 "ptrdiff_t",
134 "size_t",
135 "ssize_t",
136 "int_least8_t",
137 "uint_least8_t",
138 "int_least16_t",
139 "uint_least16_t",
140 "int_least32_t",
141 "uint_least32_t",
142 "int_least64_t",
143 "uint_least64_t",
144 "int_fast8_t",
145 "uint_fast8_t",
146 "int_fast16_t",
147 "uint_fast16_t",
148 "int_fast32_t",
149 "uint_fast32_t",
150 "int_fast64_t",
151 "uint_fast64_t",
152 "intmax_t",
153 "uintmax_t",
154 "float _Complex",
155 "double _Complex",
156 "char16_t",
157 "char32_t",
158 };
159 PyObject *x;
160
161 assert(sizeof(primitive_name) == sizeof(*primitive_name) * _CFFI__NUM_PRIM);
162 if (num == _CFFI_PRIM_VOID) {
163 x = new_void_type();
164 }
165 else if (primitive_in_range(num) && primitive_name[num] != NULL) {
166 x = new_primitive_type(primitive_name[num]);
167 }
168 else if (num == _CFFI__UNKNOWN_PRIM) {
169 PyErr_SetString(FFIError, "primitive integer type with an unexpected "
170 "size (or not an integer type at all)");
171 return NULL;
172 }
173 else if (num == _CFFI__UNKNOWN_FLOAT_PRIM) {
174 PyErr_SetString(FFIError, "primitive floating-point type with an "
175 "unexpected size (or not a float type at all)");
176 return NULL;
177 }
178 else if (num == _CFFI__UNKNOWN_LONG_DOUBLE) {
179 PyErr_SetString(FFIError, "primitive floating-point type is "
180 "'long double', not supported for now with "
181 "the syntax 'typedef double... xxx;'");
182 return NULL;
183 }
184 else {
185 PyErr_Format(PyExc_NotImplementedError, "prim=%d", num);
186 return NULL;
187 }
188
189 all_primitives[num] = x;
190 return x;
191 }
192
realize_global_int(builder_c_t * builder,int gindex)193 static PyObject *realize_global_int(builder_c_t *builder, int gindex)
194 {
195 int neg;
196 char got[64];
197 unsigned long long value;
198 struct _cffi_getconst_s gc;
199 const struct _cffi_global_s *g = &builder->ctx.globals[gindex];
200 gc.ctx = &builder->ctx;
201 gc.gindex = gindex;
202 /* note: we cast g->address to this function type; we do the same
203 in parse_c_type:parse_sequel() too. Note that the called function
204 may be declared simply with "unsigned long long *" as argument,
205 which is fine as it is the first field in _cffi_getconst_s. */
206 assert(&gc.value == (unsigned long long *)&gc);
207 neg = ((int(*)(struct _cffi_getconst_s *))g->address)(&gc);
208 value = gc.value;
209
210 switch (neg) {
211
212 case 0:
213 if (value <= (unsigned long long)LONG_MAX)
214 return PyInt_FromLong((long)value);
215 else
216 return PyLong_FromUnsignedLongLong(value);
217
218 case 1:
219 if ((long long)value >= (long long)LONG_MIN)
220 return PyInt_FromLong((long)value);
221 else
222 return PyLong_FromLongLong((long long)value);
223
224 default:
225 break;
226 }
227 if (neg == 2)
228 sprintf(got, "%llu (0x%llx)", value, value);
229 else
230 sprintf(got, "%lld", (long long)value);
231 PyErr_Format(FFIError, "the C compiler says '%.200s' is equal to %s, "
232 "but the cdef disagrees", g->name, got);
233 return NULL;
234 }
235
236 static CTypeDescrObject *
unwrap_fn_as_fnptr(PyObject * x)237 unwrap_fn_as_fnptr(PyObject *x)
238 {
239 assert(PyTuple_Check(x));
240 return (CTypeDescrObject *)PyTuple_GET_ITEM(x, 0);
241 }
242
243 static CTypeDescrObject *
unexpected_fn_type(PyObject * x)244 unexpected_fn_type(PyObject *x)
245 {
246 CTypeDescrObject *ct = unwrap_fn_as_fnptr(x);
247 char *text1 = ct->ct_name;
248 char *text2 = text1 + ct->ct_name_position + 1;
249 assert(text2[-3] == '(');
250 text2[-3] = '\0';
251 PyErr_Format(FFIError, "the type '%s%s' is a function type, not a "
252 "pointer-to-function type", text1, text2);
253 text2[-3] = '(';
254 return NULL;
255 }
256
257 static PyObject *
258 realize_c_type_or_func(builder_c_t *builder,
259 _cffi_opcode_t opcodes[], int index); /* forward */
260
261
262 /* Interpret an opcodes[] array. If opcodes == ctx->types, store all
263 the intermediate types back in the opcodes[]. Returns a new
264 reference.
265 */
266 static CTypeDescrObject *
realize_c_type(builder_c_t * builder,_cffi_opcode_t opcodes[],int index)267 realize_c_type(builder_c_t *builder, _cffi_opcode_t opcodes[], int index)
268 {
269 PyObject *x = realize_c_type_or_func(builder, opcodes, index);
270 if (x == NULL || CTypeDescr_Check(x))
271 return (CTypeDescrObject *)x;
272 else {
273 unexpected_fn_type(x);
274 Py_DECREF(x);
275 return NULL;
276 }
277 }
278
_realize_name(char * target,const char * prefix,const char * srcname)279 static void _realize_name(char *target, const char *prefix, const char *srcname)
280 {
281 /* "xyz" => "struct xyz"
282 "$xyz" => "xyz"
283 "$1" => "struct $1"
284 */
285 if (srcname[0] == '$' && srcname[1] != '$' &&
286 !('0' <= srcname[1] && srcname[1] <= '9')) {
287 strcpy(target, &srcname[1]);
288 }
289 else {
290 strcpy(target, prefix);
291 strcat(target, srcname);
292 }
293 }
294
_unrealize_name(char * target,const char * srcname)295 static void _unrealize_name(char *target, const char *srcname)
296 {
297 /* reverse of _realize_name() */
298 if (strncmp(srcname, "struct ", 7) == 0) {
299 strcpy(target, &srcname[7]);
300 }
301 else if (strncmp(srcname, "union ", 6) == 0) {
302 strcpy(target, &srcname[6]);
303 }
304 else if (strncmp(srcname, "enum ", 5) == 0) {
305 strcpy(target, &srcname[5]);
306 }
307 else {
308 strcpy(target, "$");
309 strcat(target, srcname);
310 }
311 }
312
313 static PyObject * /* forward */
314 _fetch_external_struct_or_union(const struct _cffi_struct_union_s *s,
315 PyObject *included_ffis, int recursion);
316
317 static PyObject *
_realize_c_struct_or_union(builder_c_t * builder,int sindex)318 _realize_c_struct_or_union(builder_c_t *builder, int sindex)
319 {
320 PyObject *x;
321 _cffi_opcode_t op2;
322 const struct _cffi_struct_union_s *s;
323
324 if (sindex == _CFFI__IO_FILE_STRUCT) {
325 /* returns a single global cached opaque type */
326 static PyObject *file_struct = NULL;
327 if (file_struct == NULL)
328 file_struct = new_struct_or_union_type("FILE",
329 CT_STRUCT | CT_IS_FILE);
330 Py_XINCREF(file_struct);
331 return file_struct;
332 }
333
334 s = &builder->ctx.struct_unions[sindex];
335 op2 = builder->ctx.types[s->type_index];
336 if ((((uintptr_t)op2) & 1) == 0) {
337 x = (PyObject *)op2; /* found already in the "primary" slot */
338 Py_INCREF(x);
339 }
340 else {
341 CTypeDescrObject *ct = NULL;
342
343 if (!(s->flags & _CFFI_F_EXTERNAL)) {
344 int flags = (s->flags & _CFFI_F_UNION) ? CT_UNION : CT_STRUCT;
345 char *name = alloca(8 + strlen(s->name));
346 _realize_name(name,
347 (s->flags & _CFFI_F_UNION) ? "union " : "struct ",
348 s->name);
349 if (strcmp(name, "struct _IO_FILE") == 0)
350 x = _realize_c_struct_or_union(builder, _CFFI__IO_FILE_STRUCT);
351 else
352 x = new_struct_or_union_type(name, flags);
353 if (x == NULL)
354 return NULL;
355
356 if (!(s->flags & _CFFI_F_OPAQUE)) {
357 assert(s->first_field_index >= 0);
358 ct = (CTypeDescrObject *)x;
359 ct->ct_size = (Py_ssize_t)s->size;
360 ct->ct_length = s->alignment; /* may be -1 */
361 ct->ct_flags &= ~CT_IS_OPAQUE;
362 ct->ct_flags |= CT_LAZY_FIELD_LIST;
363 ct->ct_extra = builder;
364 }
365 else
366 assert(s->first_field_index < 0);
367 }
368 else {
369 assert(s->first_field_index < 0);
370 x = _fetch_external_struct_or_union(s, builder->included_ffis, 0);
371 if (x == NULL) {
372 if (!PyErr_Occurred())
373 PyErr_Format(FFIError, "'%s %.200s' should come from "
374 "ffi.include() but was not found",
375 (s->flags & _CFFI_F_UNION) ? "union"
376 : "struct", s->name);
377 return NULL;
378 }
379 if (!(s->flags & _CFFI_F_OPAQUE)) {
380 if (((CTypeDescrObject *)x)->ct_flags & CT_IS_OPAQUE) {
381 const char *prefix = (s->flags & _CFFI_F_UNION) ? "union"
382 : "struct";
383 PyErr_Format(PyExc_NotImplementedError,
384 "'%s %.200s' is opaque in the ffi.include(), "
385 "but no longer in the ffi doing the include "
386 "(workaround: don't use ffi.include() but "
387 "duplicate the declarations of everything "
388 "using %s %.200s)",
389 prefix, s->name, prefix, s->name);
390 Py_DECREF(x);
391 return NULL;
392 }
393 }
394 }
395
396 /* Update the "primary" OP_STRUCT_UNION slot */
397 assert((((uintptr_t)x) & 1) == 0);
398 assert(builder->ctx.types[s->type_index] == op2);
399 Py_INCREF(x);
400 builder->ctx.types[s->type_index] = x;
401
402 if (ct != NULL && s->size == (size_t)-2) {
403 /* oops, this struct is unnamed and we couldn't generate
404 a C expression to get its size. We have to rely on
405 complete_struct_or_union() to compute it now. */
406 if (do_realize_lazy_struct(ct) < 0) {
407 builder->ctx.types[s->type_index] = op2;
408 return NULL;
409 }
410 }
411 }
412 return x;
413 }
414
415 static PyObject *
realize_c_type_or_func_now(builder_c_t * builder,_cffi_opcode_t op,_cffi_opcode_t opcodes[],int index)416 realize_c_type_or_func_now(builder_c_t *builder, _cffi_opcode_t op,
417 _cffi_opcode_t opcodes[], int index)
418 {
419 PyObject *x, *y, *z;
420 Py_ssize_t length = -1;
421
422 switch (_CFFI_GETOP(op)) {
423
424 case _CFFI_OP_PRIMITIVE:
425 x = get_primitive_type(_CFFI_GETARG(op));
426 Py_XINCREF(x);
427 break;
428
429 case _CFFI_OP_POINTER:
430 y = realize_c_type_or_func(builder, opcodes, _CFFI_GETARG(op));
431 if (y == NULL)
432 return NULL;
433 if (CTypeDescr_Check(y)) {
434 x = new_pointer_type((CTypeDescrObject *)y);
435 }
436 else {
437 assert(PyTuple_Check(y)); /* from _CFFI_OP_FUNCTION */
438 x = PyTuple_GET_ITEM(y, 0);
439 Py_INCREF(x);
440 }
441 Py_DECREF(y);
442 break;
443
444 case _CFFI_OP_ARRAY:
445 length = (Py_ssize_t)opcodes[index + 1];
446 /* fall-through */
447 case _CFFI_OP_OPEN_ARRAY:
448 y = (PyObject *)realize_c_type(builder, opcodes, _CFFI_GETARG(op));
449 if (y == NULL)
450 return NULL;
451 z = new_pointer_type((CTypeDescrObject *)y);
452 Py_DECREF(y);
453 if (z == NULL)
454 return NULL;
455 x = new_array_type((CTypeDescrObject *)z, length);
456 Py_DECREF(z);
457 break;
458
459 case _CFFI_OP_STRUCT_UNION:
460 x = _realize_c_struct_or_union(builder, _CFFI_GETARG(op));
461 break;
462
463 case _CFFI_OP_ENUM:
464 {
465 const struct _cffi_enum_s *e;
466 _cffi_opcode_t op2;
467
468 e = &builder->ctx.enums[_CFFI_GETARG(op)];
469 op2 = builder->ctx.types[e->type_index];
470 if ((((uintptr_t)op2) & 1) == 0) {
471 x = (PyObject *)op2;
472 Py_INCREF(x);
473 }
474 else {
475 PyObject *enumerators = NULL, *enumvalues = NULL, *tmp;
476 Py_ssize_t i, j, n = 0;
477 const char *p;
478 int gindex;
479 PyObject *args;
480 PyObject *basetd = get_primitive_type(e->type_prim);
481 if (basetd == NULL)
482 return NULL;
483
484 if (*e->enumerators != '\0') {
485 n++;
486 for (p = e->enumerators; *p != '\0'; p++)
487 n += (*p == ',');
488 }
489 enumerators = PyTuple_New(n);
490 if (enumerators == NULL)
491 return NULL;
492
493 enumvalues = PyTuple_New(n);
494 if (enumvalues == NULL) {
495 Py_DECREF(enumerators);
496 return NULL;
497 }
498
499 p = e->enumerators;
500 for (i = 0; i < n; i++) {
501 j = 0;
502 while (p[j] != ',' && p[j] != '\0')
503 j++;
504 tmp = PyText_FromStringAndSize(p, j);
505 if (tmp == NULL)
506 break;
507 PyTuple_SET_ITEM(enumerators, i, tmp);
508
509 gindex = search_in_globals(&builder->ctx, p, j);
510 assert(gindex >= 0);
511 assert(builder->ctx.globals[gindex].type_op ==
512 _CFFI_OP(_CFFI_OP_ENUM, -1));
513
514 tmp = realize_global_int(builder, gindex);
515 if (tmp == NULL)
516 break;
517 PyTuple_SET_ITEM(enumvalues, i, tmp);
518
519 p += j + 1;
520 }
521
522 args = NULL;
523 if (!PyErr_Occurred()) {
524 char *name = alloca(6 + strlen(e->name));
525 _realize_name(name, "enum ", e->name);
526 args = Py_BuildValue("(sOOO)", name, enumerators,
527 enumvalues, basetd);
528 }
529 Py_DECREF(enumerators);
530 Py_DECREF(enumvalues);
531 if (args == NULL)
532 return NULL;
533
534 x = b_new_enum_type(NULL, args);
535 Py_DECREF(args);
536 if (x == NULL)
537 return NULL;
538
539 /* Update the "primary" _CFFI_OP_ENUM slot, which
540 may be the same or a different slot than the "current" one */
541 assert((((uintptr_t)x) & 1) == 0);
542 assert(builder->ctx.types[e->type_index] == op2);
543 Py_INCREF(x);
544 builder->ctx.types[e->type_index] = x;
545
546 /* Done, leave without updating the "current" slot because
547 it may be done already above. If not, never mind, the
548 next call to realize_c_type() will do it. */
549 return x;
550 }
551 break;
552 }
553
554 case _CFFI_OP_FUNCTION:
555 {
556 PyObject *fargs;
557 int i, base_index, num_args, ellipsis, abi;
558
559 y = (PyObject *)realize_c_type(builder, opcodes, _CFFI_GETARG(op));
560 if (y == NULL)
561 return NULL;
562
563 base_index = index + 1;
564 num_args = 0;
565 /* note that if the arguments are already built, they have a
566 pointer in the 'opcodes' array, and GETOP() returns a
567 random even value. But OP_FUNCTION_END is odd, so the
568 condition below still works correctly. */
569 while (_CFFI_GETOP(opcodes[base_index + num_args]) !=
570 _CFFI_OP_FUNCTION_END)
571 num_args++;
572
573 ellipsis = _CFFI_GETARG(opcodes[base_index + num_args]) & 0x01;
574 abi = _CFFI_GETARG(opcodes[base_index + num_args]) & 0xFE;
575 switch (abi) {
576 case 0:
577 abi = FFI_DEFAULT_ABI;
578 break;
579 case 2:
580 #if defined(MS_WIN32) && !defined(_WIN64)
581 abi = FFI_STDCALL;
582 #else
583 abi = FFI_DEFAULT_ABI;
584 #endif
585 break;
586 default:
587 PyErr_Format(FFIError, "abi number %d not supported", abi);
588 Py_DECREF(y);
589 return NULL;
590 }
591
592 fargs = PyTuple_New(num_args);
593 if (fargs == NULL) {
594 Py_DECREF(y);
595 return NULL;
596 }
597
598 for (i = 0; i < num_args; i++) {
599 z = (PyObject *)realize_c_type(builder, opcodes, base_index + i);
600 if (z == NULL) {
601 Py_DECREF(fargs);
602 Py_DECREF(y);
603 return NULL;
604 }
605 PyTuple_SET_ITEM(fargs, i, z);
606 }
607
608 z = new_function_type(fargs, (CTypeDescrObject *)y, ellipsis, abi);
609 Py_DECREF(fargs);
610 Py_DECREF(y);
611 if (z == NULL)
612 return NULL;
613
614 x = PyTuple_Pack(1, z); /* hack: hide the CT_FUNCTIONPTR. it will
615 be revealed again by the OP_POINTER */
616 Py_DECREF(z);
617 break;
618 }
619
620 case _CFFI_OP_NOOP:
621 x = realize_c_type_or_func(builder, opcodes, _CFFI_GETARG(op));
622 break;
623
624 case _CFFI_OP_TYPENAME:
625 {
626 /* essential: the TYPENAME opcode resolves the type index looked
627 up in the 'ctx->typenames' array, but it does so in 'ctx->types'
628 instead of in 'opcodes'! */
629 int type_index = builder->ctx.typenames[_CFFI_GETARG(op)].type_index;
630 x = realize_c_type_or_func(builder, builder->ctx.types, type_index);
631 break;
632 }
633
634 default:
635 PyErr_Format(PyExc_NotImplementedError, "op=%d", (int)_CFFI_GETOP(op));
636 return NULL;
637 }
638
639 return x;
640 }
641
642 static int _realize_recursion_level;
643
644 static PyObject *
realize_c_type_or_func(builder_c_t * builder,_cffi_opcode_t opcodes[],int index)645 realize_c_type_or_func(builder_c_t *builder,
646 _cffi_opcode_t opcodes[], int index)
647 {
648 PyObject *x;
649 _cffi_opcode_t op = opcodes[index];
650
651 if ((((uintptr_t)op) & 1) == 0) {
652 x = (PyObject *)op;
653 Py_INCREF(x);
654 return x;
655 }
656
657 if (_realize_recursion_level >= 1000) {
658 PyErr_Format(PyExc_RuntimeError,
659 "type-building recursion too deep or infinite. "
660 "This is known to occur e.g. in ``struct s { void(*callable)"
661 "(struct s); }''. Please report if you get this error and "
662 "really need support for your case.");
663 return NULL;
664 }
665 _realize_recursion_level++;
666 x = realize_c_type_or_func_now(builder, op, opcodes, index);
667 _realize_recursion_level--;
668
669 if (x != NULL && opcodes == builder->ctx.types && opcodes[index] != x) {
670 assert((((uintptr_t)x) & 1) == 0);
671 assert((((uintptr_t)opcodes[index]) & 1) == 1);
672 Py_INCREF(x);
673 opcodes[index] = x;
674 }
675 return x;
676 }
677
678 static CTypeDescrObject *
realize_c_func_return_type(builder_c_t * builder,_cffi_opcode_t opcodes[],int index)679 realize_c_func_return_type(builder_c_t *builder,
680 _cffi_opcode_t opcodes[], int index)
681 {
682 PyObject *x;
683 _cffi_opcode_t op = opcodes[index];
684
685 if ((((uintptr_t)op) & 1) == 0) {
686 /* already built: assert that it is a function and fish
687 for the return type */
688 x = (PyObject *)op;
689 assert(PyTuple_Check(x)); /* from _CFFI_OP_FUNCTION */
690 x = PyTuple_GET_ITEM(x, 0);
691 assert(CTypeDescr_Check(x));
692 assert(((CTypeDescrObject *)x)->ct_flags & CT_FUNCTIONPTR);
693 x = PyTuple_GET_ITEM(((CTypeDescrObject *)x)->ct_stuff, 1);
694 assert(CTypeDescr_Check(x));
695 Py_INCREF(x);
696 return (CTypeDescrObject *)x;
697 }
698 else {
699 assert(_CFFI_GETOP(op) == _CFFI_OP_FUNCTION);
700 return realize_c_type(builder, opcodes, _CFFI_GETARG(opcodes[index]));
701 }
702 }
703
do_realize_lazy_struct(CTypeDescrObject * ct)704 static int do_realize_lazy_struct(CTypeDescrObject *ct)
705 {
706 /* This is called by force_lazy_struct() in _cffi_backend.c */
707 assert(ct->ct_flags & (CT_STRUCT | CT_UNION));
708
709 if (ct->ct_flags & CT_LAZY_FIELD_LIST) {
710 builder_c_t *builder;
711 char *p;
712 int n, i, sflags;
713 const struct _cffi_struct_union_s *s;
714 const struct _cffi_field_s *fld;
715 PyObject *fields, *args, *res;
716
717 assert(!(ct->ct_flags & CT_IS_OPAQUE));
718
719 builder = ct->ct_extra;
720 assert(builder != NULL);
721
722 p = alloca(2 + strlen(ct->ct_name));
723 _unrealize_name(p, ct->ct_name);
724
725 n = search_in_struct_unions(&builder->ctx, p, strlen(p));
726 if (n < 0)
727 Py_FatalError("lost a struct/union!");
728
729 s = &builder->ctx.struct_unions[n];
730 fld = &builder->ctx.fields[s->first_field_index];
731
732 /* XXX painfully build all the Python objects that are the args
733 to b_complete_struct_or_union() */
734
735 fields = PyList_New(s->num_fields);
736 if (fields == NULL)
737 return -1;
738
739 for (i = 0; i < s->num_fields; i++, fld++) {
740 _cffi_opcode_t op = fld->field_type_op;
741 int fbitsize = -1;
742 PyObject *f;
743 CTypeDescrObject *ctf;
744
745 switch (_CFFI_GETOP(op)) {
746
747 case _CFFI_OP_BITFIELD:
748 assert(fld->field_size >= 0);
749 fbitsize = (int)fld->field_size;
750 /* fall-through */
751 case _CFFI_OP_NOOP:
752 ctf = realize_c_type(builder, builder->ctx.types,
753 _CFFI_GETARG(op));
754 break;
755
756 default:
757 Py_DECREF(fields);
758 PyErr_Format(PyExc_NotImplementedError, "field op=%d",
759 (int)_CFFI_GETOP(op));
760 return -1;
761 }
762
763 if (ctf != NULL && fld->field_offset == (size_t)-1) {
764 /* unnamed struct, with field positions and sizes entirely
765 determined by complete_struct_or_union() and not checked.
766 Or, bitfields (field_size >= 0), similarly not checked. */
767 assert(fld->field_size == (size_t)-1 || fbitsize >= 0);
768 }
769 else if (ctf == NULL || detect_custom_layout(ct, SF_STD_FIELD_POS,
770 ctf->ct_size, fld->field_size,
771 "wrong size for field '",
772 fld->name, "'") < 0) {
773 Py_DECREF(fields);
774 return -1;
775 }
776
777 f = Py_BuildValue("(sOin)", fld->name, ctf,
778 fbitsize, (Py_ssize_t)fld->field_offset);
779 if (f == NULL) {
780 Py_DECREF(fields);
781 return -1;
782 }
783 PyList_SET_ITEM(fields, i, f);
784 }
785
786 sflags = 0;
787 if (s->flags & _CFFI_F_CHECK_FIELDS)
788 sflags |= SF_STD_FIELD_POS;
789 if (s->flags & _CFFI_F_PACKED)
790 sflags |= SF_PACKED;
791
792 args = Py_BuildValue("(OOOnii)", ct, fields, Py_None,
793 (Py_ssize_t)s->size,
794 s->alignment,
795 sflags);
796 Py_DECREF(fields);
797 if (args == NULL)
798 return -1;
799
800 ct->ct_extra = NULL;
801 ct->ct_flags |= CT_IS_OPAQUE;
802 res = b_complete_struct_or_union(NULL, args);
803 ct->ct_flags &= ~CT_IS_OPAQUE;
804 Py_DECREF(args);
805
806 if (res == NULL) {
807 ct->ct_extra = builder;
808 return -1;
809 }
810
811 assert(ct->ct_stuff != NULL);
812 ct->ct_flags &= ~CT_LAZY_FIELD_LIST;
813 Py_DECREF(res);
814 return 1;
815 }
816 else {
817 assert(ct->ct_flags & CT_IS_OPAQUE);
818 return 0;
819 }
820 }
821