def _realize_c_struct_or_union(ffi, sindex): s = ffi.ctxobj.ctx.c_struct_unions[sindex] type_index = rffi.getintfield(s, 'c_type_index') if ffi.cached_types[type_index] is not None: return ffi.cached_types[type_index] #found already in the "primary" slot space = ffi.space w_ctype = None c_flags = rffi.getintfield(s, 'c_flags') c_first_field_index = rffi.getintfield(s, 'c_first_field_index') if (c_flags & cffi_opcode.F_EXTERNAL) == 0: if (c_flags & cffi_opcode.F_UNION) != 0: name = _realize_name("union ", s.c_name) x = ctypestruct.W_CTypeUnion(space, name) else: name = _realize_name("struct ", s.c_name) x = ctypestruct.W_CTypeStruct(space, name) if (c_flags & cffi_opcode.F_OPAQUE) == 0: assert c_first_field_index >= 0 w_ctype = x w_ctype.size = rffi.getintfield(s, 'c_size') w_ctype.alignment = rffi.getintfield(s, 'c_alignment') # w_ctype._field_list and other underscore fields are still # None, making it a "lazy" (i.e. "non-forced") kind of struct w_ctype._lazy_ffi = ffi w_ctype._lazy_s = s else: assert c_first_field_index < 0 else: assert c_first_field_index < 0 x = _fetch_external_struct_or_union(s, ffi.included_ffis_libs) if x is None: raise oefmt(ffi.w_FFIError, "'%s %s' should come from ffi.include() but was not found", "union" if c_flags & cffi_opcode.F_UNION else "struct", rffi.charp2str(s.c_name)) assert isinstance(x, ctypestruct.W_CTypeStructOrUnion) if (c_flags & cffi_opcode.F_OPAQUE) == 0 and x.size < 0: prefix = "union" if c_flags & cffi_opcode.F_UNION else "struct" name = rffi.charp2str(s.c_name) raise oefmt(space.w_NotImplementedError, "'%s %s' is opaque in the ffi.include(), but no " "longer in the ffi doing the include (workaround: don't " "use ffi.include() but duplicate the declarations of " "everything using %s %s)", prefix, name, prefix, name) # Update the "primary" OP_STRUCT_UNION slot ffi.cached_types[type_index] = x if w_ctype is not None and rffi.getintfield(s, 'c_size') == -2: # oops, this struct is unnamed and we couldn't generate # a C expression to get its size. We have to rely on # complete_struct_or_union() to compute it now. try: do_realize_lazy_struct(w_ctype) except: ffi.cached_types[type_index] = None raise return x
def new_union_type(space, name): return ctypestruct.W_CTypeUnion(space, name)