def cast_to_ffitype(self): if not self.ffitype: field_types = [] for name, field in self.fields: field_types.append(field.cast_to_ffitype()) self.ffitype = clibffi.make_struct_ffitype_e(self.size, self.align, field_types) return self.ffitype.ffistruct
def define_fields(self, space, w_fields): if self.fields_w is not None: raise oefmt(space.w_ValueError, "%s's fields has already been defined", self.w_ffitype.name) fields_w = space.fixedview(w_fields) # note that the fields_w returned by compute_size_and_alignement has a # different annotation than the original: list(W_Root) vs list(W_Field) size, alignment, fields_w = compute_size_and_alignement( space, fields_w) self.fields_w = fields_w field_types = [] # clibffi's types for w_field in fields_w: field_types.append(w_field.w_ffitype.get_ffitype()) self.name2w_field[w_field.name] = w_field # # on CPython, the FFIStructOwner might go into gc.garbage and thus the # __del__ never be called. Thus, we don't track the allocation of the # malloc done inside this function, else the leakfinder might complain ffistruct = clibffi.make_struct_ffitype_e(size, alignment, field_types, track_allocation=False) self.w_ffitype.set_ffitype(ffistruct.ffistruct) self._ffistruct_owner = FFIStructOwner(ffistruct)
def cast_to_ffitype(self): if self.fields is None: raise OldError(u"Struct not initialized") if not self.ffitype: field_types = [] for name, field in self.fields: field_types.append(field.cast_to_ffitype()) self.ffitype = clibffi.make_struct_ffitype_e( self.size, self.align, field_types) return self.ffitype.ffistruct
def ensure_allocated(self, space): if not self.ffi_struct: layout = self.ensure_layout(space) # Repeated fields are delicate. Consider for example # struct { int a[5]; } # or struct { struct {int x;} a[5]; } # Seeing no corresponding doc in clibffi, let's just repeat # the field 5 times... fieldtypes = [] for w_field in layout.fields: w_type = space.send(w_field, 'type') assert isinstance(w_type, W_TypeObject) fieldtypes.append(ffi_types[w_type.typeindex]) self.ffi_struct = clibffi.make_struct_ffitype_e(layout.size, layout.alignment, fieldtypes)
def get_basic_ffi_type(self): if not self.ffi_struct: # Repeated fields are delicate. Consider for example # struct { int a[5]; } # or struct { struct {int x;} a[5]; } # Seeing no corresponding doc in clibffi, let's just repeat # the field 5 times... fieldtypes = [] for name, tp, bitsize in self.fields: basic_ffi_type = tp.get_basic_ffi_type() basic_size, _ = size_alignment(basic_ffi_type) total_size = tp.size count = 0 while count + basic_size <= total_size: fieldtypes.append(basic_ffi_type) count += basic_size if basic_size == 0: # corner case. get out of this infinite break # loop after 1 iteration ("why not") self.ffi_struct = clibffi.make_struct_ffitype_e( self.size, self.alignment, fieldtypes) return self.ffi_struct.ffistruct
def define_fields(self, space, w_fields): if self.fields_w is not None: raise oefmt(space.w_ValueError, "%s's fields has already been defined", self.w_ffitype.name) fields_w = space.fixedview(w_fields) # note that the fields_w returned by compute_size_and_alignement has a # different annotation than the original: list(W_Root) vs list(W_Field) size, alignment, fields_w = compute_size_and_alignement(space, fields_w) self.fields_w = fields_w field_types = [] # clibffi's types for w_field in fields_w: field_types.append(w_field.w_ffitype.get_ffitype()) self.name2w_field[w_field.name] = w_field # # on CPython, the FFIStructOwner might go into gc.garbage and thus the # __del__ never be called. Thus, we don't track the allocation of the # malloc done inside this function, else the leakfinder might complain ffistruct = clibffi.make_struct_ffitype_e(size, alignment, field_types, track_allocation=False) self.w_ffitype.set_ffitype(ffistruct.ffistruct) self._ffistruct_owner = FFIStructOwner(ffistruct)
def get_basic_ffi_type(self): if not self.ffi_struct: # Repeated fields are delicate. Consider for example # struct { int a[5]; } # or struct { struct {int x;} a[5]; } # Seeing no corresponding doc in clibffi, let's just repeat # the field 5 times... fieldtypes = [] for name, tp, bitsize in self.fields: basic_ffi_type = tp.get_basic_ffi_type() basic_size, _ = size_alignment(basic_ffi_type) total_size = tp.size count = 0 while count + basic_size <= total_size: fieldtypes.append(basic_ffi_type) count += basic_size if basic_size == 0: # corner case. get out of this infinite break # loop after 1 iteration ("why not") self.ffi_struct = clibffi.make_struct_ffitype_e(self.size, self.alignment, fieldtypes) return self.ffi_struct.ffistruct
def __init__(self, tys): self.struct = ffi.make_struct_ffitype_e(0, 0, tys) self.ty = self.struct.ffistruct