def do_realize_lazy_struct(w_ctype): """This is called by W_CTypeStructOrUnion.force_lazy_struct(). """ assert isinstance(w_ctype, ctypestruct.W_CTypeStructOrUnion) space = w_ctype.space ffi = w_ctype._lazy_ffi s = w_ctype._lazy_s assert w_ctype.size != -1 # not an opaque (but may be -2) assert ffi is not None # still lazy first_field = rffi.getintfield(s, 'c_first_field_index') num_fields = rffi.getintfield(s, 'c_num_fields') fields_w = [None] * num_fields for i in range(num_fields): fld = ffi.ctxobj.ctx.c_fields[first_field + i] field_name = rffi.charp2str(fld.c_name) field_size = rffi.getintfield(fld, 'c_field_size') field_offset = rffi.getintfield(fld, 'c_field_offset') op = rffi.getintfield(fld, 'c_field_type_op') case = getop(op) if case == cffi_opcode.OP_NOOP: fbitsize = -1 # standard field elif case == cffi_opcode.OP_BITFIELD: assert field_size >= 0 fbitsize = field_size else: raise oefmt(space.w_NotImplementedError, "field op=%d", case) w_ctf = realize_c_type(ffi, ffi.ctxobj.ctx.c_types, getarg(op)) if field_offset == -1: # unnamed struct, with field positions and sizes entirely # determined by complete_struct_or_union() and not checked. # Or, bitfields (field_size >= 0), similarly not checked. assert field_size == -1 or fbitsize >= 0 else: newtype.detect_custom_layout(w_ctype, newtype.SF_STD_FIELD_POS, w_ctf.size, field_size, "wrong size for field '", field_name, "'") fields_w[i] = space.newtuple([ space.wrap(field_name), w_ctf, space.wrap(fbitsize), space.wrap(field_offset)]) sflags = 0 c_flags = rffi.getintfield(s, 'c_flags') if c_flags & cffi_opcode.F_CHECK_FIELDS: sflags |= newtype.SF_STD_FIELD_POS if c_flags & cffi_opcode.F_PACKED: sflags |= newtype.SF_PACKED assert w_ctype.size == rffi.getintfield(s, 'c_size') assert w_ctype.alignment == rffi.getintfield(s, 'c_alignment') try: w_ctype.size = -1 # make opaque again newtype.complete_struct_or_union( space, w_ctype, space.newlist(fields_w), space.w_None, totalsize = rffi.getintfield(s, 'c_size'), totalalignment = rffi.getintfield(s, 'c_alignment'), sflags = sflags) except: w_ctype.size = rffi.getintfield(s, 'c_size') # restore w_ctype.alignment = rffi.getintfield(s, 'c_alignment') # restore raise if rffi.getintfield(s, 'c_size') >= 0: assert w_ctype.size == rffi.getintfield(s, 'c_size') assert w_ctype.alignment > 0 if rffi.getintfield(s, 'c_alignment') != -1: assert w_ctype.alignment == rffi.getintfield(s, 'c_alignment') assert w_ctype._fields_list is not None # not lazy any more w_ctype._lazy_ffi = None w_ctype._lazy_s = lltype.nullptr(parse_c_type.STRUCT_UNION_S)
elif case == cffi_opcode.OP_BITFIELD: assert field_size >= 0 fbitsize = field_size else: raise oefmt(space.w_NotImplementedError, "field op=%d", case) w_ctf = realize_c_type(ffi, ffi.ctxobj.ctx.c_types, getarg(op)) if field_offset == -1: # unnamed struct, with field positions and sizes entirely # determined by complete_struct_or_union() and not checked. # Or, bitfields (field_size >= 0), similarly not checked. assert field_size == -1 or fbitsize >= 0 else: newtype.detect_custom_layout(w_ctype, newtype.SF_STD_FIELD_POS, w_ctf.size, field_size, "wrong size for field '", field_name, "'") fields_w[i] = space.newtuple([ space.wrap(field_name), w_ctf, space.wrap(fbitsize), space.wrap(field_offset)]) sflags = 0 c_flags = rffi.getintfield(s, 'c_flags') if c_flags & cffi_opcode.F_CHECK_FIELDS: sflags |= newtype.SF_STD_FIELD_POS if c_flags & cffi_opcode.F_PACKED: sflags |= newtype.SF_PACKED