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(builder_c_t * builder,_cffi_opcode_t opcodes[],int index)416 realize_c_type_or_func(builder_c_t *builder,
417 _cffi_opcode_t opcodes[], int index)
418 {
419 PyObject *x, *y, *z;
420 _cffi_opcode_t op = opcodes[index];
421 Py_ssize_t length = -1;
422
423 if ((((uintptr_t)op) & 1) == 0) {
424 x = (PyObject *)op;
425 Py_INCREF(x);
426 return x;
427 }
428
429 switch (_CFFI_GETOP(op)) {
430
431 case _CFFI_OP_PRIMITIVE:
432 x = get_primitive_type(_CFFI_GETARG(op));
433 Py_XINCREF(x);
434 break;
435
436 case _CFFI_OP_POINTER:
437 y = realize_c_type_or_func(builder, opcodes, _CFFI_GETARG(op));
438 if (y == NULL)
439 return NULL;
440 if (CTypeDescr_Check(y)) {
441 x = new_pointer_type((CTypeDescrObject *)y);
442 }
443 else {
444 assert(PyTuple_Check(y)); /* from _CFFI_OP_FUNCTION */
445 x = PyTuple_GET_ITEM(y, 0);
446 Py_INCREF(x);
447 }
448 Py_DECREF(y);
449 break;
450
451 case _CFFI_OP_ARRAY:
452 length = (Py_ssize_t)opcodes[index + 1];
453 /* fall-through */
454 case _CFFI_OP_OPEN_ARRAY:
455 y = (PyObject *)realize_c_type(builder, opcodes, _CFFI_GETARG(op));
456 if (y == NULL)
457 return NULL;
458 z = new_pointer_type((CTypeDescrObject *)y);
459 Py_DECREF(y);
460 if (z == NULL)
461 return NULL;
462 x = new_array_type((CTypeDescrObject *)z, length);
463 Py_DECREF(z);
464 break;
465
466 case _CFFI_OP_STRUCT_UNION:
467 x = _realize_c_struct_or_union(builder, _CFFI_GETARG(op));
468 break;
469
470 case _CFFI_OP_ENUM:
471 {
472 const struct _cffi_enum_s *e;
473 _cffi_opcode_t op2;
474
475 e = &builder->ctx.enums[_CFFI_GETARG(op)];
476 op2 = builder->ctx.types[e->type_index];
477 if ((((uintptr_t)op2) & 1) == 0) {
478 x = (PyObject *)op2;
479 Py_INCREF(x);
480 }
481 else {
482 PyObject *enumerators = NULL, *enumvalues = NULL, *tmp;
483 Py_ssize_t i, j, n = 0;
484 const char *p;
485 int gindex;
486 PyObject *args;
487 PyObject *basetd = get_primitive_type(e->type_prim);
488 if (basetd == NULL)
489 return NULL;
490
491 if (*e->enumerators != '\0') {
492 n++;
493 for (p = e->enumerators; *p != '\0'; p++)
494 n += (*p == ',');
495 }
496 enumerators = PyTuple_New(n);
497 if (enumerators == NULL)
498 return NULL;
499
500 enumvalues = PyTuple_New(n);
501 if (enumvalues == NULL) {
502 Py_DECREF(enumerators);
503 return NULL;
504 }
505
506 p = e->enumerators;
507 for (i = 0; i < n; i++) {
508 j = 0;
509 while (p[j] != ',' && p[j] != '\0')
510 j++;
511 tmp = PyText_FromStringAndSize(p, j);
512 if (tmp == NULL)
513 break;
514 PyTuple_SET_ITEM(enumerators, i, tmp);
515
516 gindex = search_in_globals(&builder->ctx, p, j);
517 assert(gindex >= 0);
518 assert(builder->ctx.globals[gindex].type_op ==
519 _CFFI_OP(_CFFI_OP_ENUM, -1));
520
521 tmp = realize_global_int(builder, gindex);
522 if (tmp == NULL)
523 break;
524 PyTuple_SET_ITEM(enumvalues, i, tmp);
525
526 p += j + 1;
527 }
528
529 args = NULL;
530 if (!PyErr_Occurred()) {
531 char *name = alloca(6 + strlen(e->name));
532 _realize_name(name, "enum ", e->name);
533 args = Py_BuildValue("(sOOO)", name, enumerators,
534 enumvalues, basetd);
535 }
536 Py_DECREF(enumerators);
537 Py_DECREF(enumvalues);
538 if (args == NULL)
539 return NULL;
540
541 x = b_new_enum_type(NULL, args);
542 Py_DECREF(args);
543 if (x == NULL)
544 return NULL;
545
546 /* Update the "primary" _CFFI_OP_ENUM slot, which
547 may be the same or a different slot than the "current" one */
548 assert((((uintptr_t)x) & 1) == 0);
549 assert(builder->ctx.types[e->type_index] == op2);
550 Py_INCREF(x);
551 builder->ctx.types[e->type_index] = x;
552
553 /* Done, leave without updating the "current" slot because
554 it may be done already above. If not, never mind, the
555 next call to realize_c_type() will do it. */
556 return x;
557 }
558 break;
559 }
560
561 case _CFFI_OP_FUNCTION:
562 {
563 PyObject *fargs;
564 int i, base_index, num_args, ellipsis, abi;
565
566 y = (PyObject *)realize_c_type(builder, opcodes, _CFFI_GETARG(op));
567 if (y == NULL)
568 return NULL;
569
570 base_index = index + 1;
571 num_args = 0;
572 /* note that if the arguments are already built, they have a
573 pointer in the 'opcodes' array, and GETOP() returns a
574 random even value. But OP_FUNCTION_END is odd, so the
575 condition below still works correctly. */
576 while (_CFFI_GETOP(opcodes[base_index + num_args]) !=
577 _CFFI_OP_FUNCTION_END)
578 num_args++;
579
580 ellipsis = _CFFI_GETARG(opcodes[base_index + num_args]) & 0x01;
581 abi = _CFFI_GETARG(opcodes[base_index + num_args]) & 0xFE;
582 switch (abi) {
583 case 0:
584 abi = FFI_DEFAULT_ABI;
585 break;
586 case 2:
587 #if defined(MS_WIN32) && !defined(_WIN64)
588 abi = FFI_STDCALL;
589 #else
590 abi = FFI_DEFAULT_ABI;
591 #endif
592 break;
593 default:
594 PyErr_Format(FFIError, "abi number %d not supported", abi);
595 Py_DECREF(y);
596 return NULL;
597 }
598
599 fargs = PyTuple_New(num_args);
600 if (fargs == NULL) {
601 Py_DECREF(y);
602 return NULL;
603 }
604
605 for (i = 0; i < num_args; i++) {
606 z = (PyObject *)realize_c_type(builder, opcodes, base_index + i);
607 if (z == NULL) {
608 Py_DECREF(fargs);
609 Py_DECREF(y);
610 return NULL;
611 }
612 PyTuple_SET_ITEM(fargs, i, z);
613 }
614
615 z = new_function_type(fargs, (CTypeDescrObject *)y, ellipsis, abi);
616 Py_DECREF(fargs);
617 Py_DECREF(y);
618 if (z == NULL)
619 return NULL;
620
621 x = PyTuple_Pack(1, z); /* hack: hide the CT_FUNCTIONPTR. it will
622 be revealed again by the OP_POINTER */
623 Py_DECREF(z);
624 break;
625 }
626
627 case _CFFI_OP_NOOP:
628 x = realize_c_type_or_func(builder, opcodes, _CFFI_GETARG(op));
629 break;
630
631 case _CFFI_OP_TYPENAME:
632 {
633 /* essential: the TYPENAME opcode resolves the type index looked
634 up in the 'ctx->typenames' array, but it does so in 'ctx->types'
635 instead of in 'opcodes'! */
636 int type_index = builder->ctx.typenames[_CFFI_GETARG(op)].type_index;
637 x = realize_c_type_or_func(builder, builder->ctx.types, type_index);
638 break;
639 }
640
641 default:
642 PyErr_Format(PyExc_NotImplementedError, "op=%d", (int)_CFFI_GETOP(op));
643 return NULL;
644 }
645
646 if (x != NULL && opcodes == builder->ctx.types && opcodes[index] != x) {
647 assert((((uintptr_t)x) & 1) == 0);
648 assert((((uintptr_t)opcodes[index]) & 1) == 1);
649 Py_INCREF(x);
650 opcodes[index] = x;
651 }
652 return x;
653 };
654
655 static CTypeDescrObject *
realize_c_func_return_type(builder_c_t * builder,_cffi_opcode_t opcodes[],int index)656 realize_c_func_return_type(builder_c_t *builder,
657 _cffi_opcode_t opcodes[], int index)
658 {
659 PyObject *x;
660 _cffi_opcode_t op = opcodes[index];
661
662 if ((((uintptr_t)op) & 1) == 0) {
663 /* already built: assert that it is a function and fish
664 for the return type */
665 x = (PyObject *)op;
666 assert(PyTuple_Check(x)); /* from _CFFI_OP_FUNCTION */
667 x = PyTuple_GET_ITEM(x, 0);
668 assert(CTypeDescr_Check(x));
669 assert(((CTypeDescrObject *)x)->ct_flags & CT_FUNCTIONPTR);
670 x = PyTuple_GET_ITEM(((CTypeDescrObject *)x)->ct_stuff, 1);
671 assert(CTypeDescr_Check(x));
672 Py_INCREF(x);
673 return (CTypeDescrObject *)x;
674 }
675 else {
676 assert(_CFFI_GETOP(op) == _CFFI_OP_FUNCTION);
677 return realize_c_type(builder, opcodes, _CFFI_GETARG(opcodes[index]));
678 }
679 }
680
do_realize_lazy_struct(CTypeDescrObject * ct)681 static int do_realize_lazy_struct(CTypeDescrObject *ct)
682 {
683 /* This is called by force_lazy_struct() in _cffi_backend.c */
684 assert(ct->ct_flags & (CT_STRUCT | CT_UNION));
685
686 if (ct->ct_flags & CT_LAZY_FIELD_LIST) {
687 builder_c_t *builder;
688 char *p;
689 int n, i, sflags;
690 const struct _cffi_struct_union_s *s;
691 const struct _cffi_field_s *fld;
692 PyObject *fields, *args, *res;
693
694 assert(!(ct->ct_flags & CT_IS_OPAQUE));
695
696 builder = ct->ct_extra;
697 assert(builder != NULL);
698
699 p = alloca(2 + strlen(ct->ct_name));
700 _unrealize_name(p, ct->ct_name);
701
702 n = search_in_struct_unions(&builder->ctx, p, strlen(p));
703 if (n < 0)
704 Py_FatalError("lost a struct/union!");
705
706 s = &builder->ctx.struct_unions[n];
707 fld = &builder->ctx.fields[s->first_field_index];
708
709 /* XXX painfully build all the Python objects that are the args
710 to b_complete_struct_or_union() */
711
712 fields = PyList_New(s->num_fields);
713 if (fields == NULL)
714 return -1;
715
716 for (i = 0; i < s->num_fields; i++, fld++) {
717 _cffi_opcode_t op = fld->field_type_op;
718 int fbitsize = -1;
719 PyObject *f;
720 CTypeDescrObject *ctf;
721
722 switch (_CFFI_GETOP(op)) {
723
724 case _CFFI_OP_BITFIELD:
725 assert(fld->field_size >= 0);
726 fbitsize = (int)fld->field_size;
727 /* fall-through */
728 case _CFFI_OP_NOOP:
729 ctf = realize_c_type(builder, builder->ctx.types,
730 _CFFI_GETARG(op));
731 break;
732
733 default:
734 Py_DECREF(fields);
735 PyErr_Format(PyExc_NotImplementedError, "field op=%d",
736 (int)_CFFI_GETOP(op));
737 return -1;
738 }
739
740 if (ctf != NULL && fld->field_offset == (size_t)-1) {
741 /* unnamed struct, with field positions and sizes entirely
742 determined by complete_struct_or_union() and not checked.
743 Or, bitfields (field_size >= 0), similarly not checked. */
744 assert(fld->field_size == (size_t)-1 || fbitsize >= 0);
745 }
746 else if (ctf == NULL || detect_custom_layout(ct, SF_STD_FIELD_POS,
747 ctf->ct_size, fld->field_size,
748 "wrong size for field '",
749 fld->name, "'") < 0) {
750 Py_DECREF(fields);
751 return -1;
752 }
753
754 f = Py_BuildValue("(sOin)", fld->name, ctf,
755 fbitsize, (Py_ssize_t)fld->field_offset);
756 if (f == NULL) {
757 Py_DECREF(fields);
758 return -1;
759 }
760 PyList_SET_ITEM(fields, i, f);
761 }
762
763 sflags = 0;
764 if (s->flags & _CFFI_F_CHECK_FIELDS)
765 sflags |= SF_STD_FIELD_POS;
766 if (s->flags & _CFFI_F_PACKED)
767 sflags |= SF_PACKED;
768
769 args = Py_BuildValue("(OOOnii)", ct, fields, Py_None,
770 (Py_ssize_t)s->size,
771 s->alignment,
772 sflags);
773 Py_DECREF(fields);
774 if (args == NULL)
775 return -1;
776
777 ct->ct_extra = NULL;
778 ct->ct_flags |= CT_IS_OPAQUE;
779 res = b_complete_struct_or_union(NULL, args);
780 ct->ct_flags &= ~CT_IS_OPAQUE;
781 Py_DECREF(args);
782
783 if (res == NULL) {
784 ct->ct_extra = builder;
785 return -1;
786 }
787
788 assert(ct->ct_stuff != NULL);
789 ct->ct_flags &= ~CT_LAZY_FIELD_LIST;
790 Py_DECREF(res);
791 return 1;
792 }
793 else {
794 assert(ct->ct_flags & CT_IS_OPAQUE);
795 return 0;
796 }
797 }
798