def __init__(self, name): self.w_ffitype = W_FFIType('struct %s' % name, clibffi.FFI_TYPE_NULL, w_structdescr=self) self.fields_w = None self.name2w_field = {} self._ffistruct_owner = None
class W__StructDescr(W_Root): def __init__(self, name): self.w_ffitype = W_FFIType('struct %s' % name, clibffi.FFI_TYPE_NULL, w_structdescr=self) self.fields_w = None self.name2w_field = {} self._ffistruct_owner = None 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 check_complete(self, space): if self.fields_w is None: raise oefmt(space.w_ValueError, "%s has an incomplete type", self.w_ffitype.name) def allocate(self, space): self.check_complete(space) return W__StructInstance(self) @unwrap_spec(addr=int) def fromaddress(self, space, addr): self.check_complete(space) rawmem = rffi.cast(rffi.VOIDP, addr) return W__StructInstance(self, allocate=False, autofree=True, rawmem=rawmem) @jit.elidable_promote('0') def get_type_and_offset_for_field(self, space, name): try: w_field = self.name2w_field[name] except KeyError: raise oefmt(space.w_AttributeError, '%s', name) return w_field.w_ffitype, w_field.offset
class W__StructDescr(W_Root): def __init__(self, name): self.w_ffitype = W_FFIType('struct %s' % name, clibffi.FFI_TYPE_NULL, w_structdescr=self) self.fields_w = None self.name2w_field = {} self._ffistruct_owner = None 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 check_complete(self, space): if self.fields_w is None: raise oefmt(space.w_ValueError, "%s has an incomplete type", self.w_ffitype.name) def allocate(self, space): self.check_complete(space) return W__StructInstance(self) @unwrap_spec(addr=int) def fromaddress(self, space, addr): self.check_complete(space) rawmem = rffi.cast(rffi.VOIDP, addr) return W__StructInstance(self, allocate=False, autofree=True, rawmem=rawmem) def get_type_and_offset_for_field(self, space, w_name): name = space.str_w(w_name) try: return self._get_type_and_offset_for_field(space, name) except KeyError: raise OperationError(space.w_AttributeError, w_name) @jit.elidable_promote('0') def _get_type_and_offset_for_field(self, space, name): w_field = self.name2w_field[name] return w_field.w_ffitype, w_field.offset
def setup_class(cls): BaseAppTestFFI.setup_class.im_func(cls) @unwrap_spec(addr=int, typename='text', length=int) def read_raw_mem(space, addr, typename, length): import ctypes addr = ctypes.cast(addr, ctypes.c_void_p) c_type = getattr(ctypes, typename) array_type = ctypes.POINTER(c_type * length) ptr_array = ctypes.cast(addr, array_type) array = ptr_array[0] lst = [array[i] for i in range(length)] return space.wrap(lst) if cls.runappdirect: cls.w_read_raw_mem = lambda self, *args: read_raw_mem( cls.space, *args) else: cls.w_read_raw_mem = cls.space.wrap(interp2app(read_raw_mem)) # from rpython.rlib import clibffi from rpython.rlib.rarithmetic import r_uint from rpython.rtyper.lltypesystem import lltype, rffi dummy_type = lltype.malloc(clibffi.FFI_TYPE_P.TO, flavor='raw') dummy_type.c_size = r_uint(123) dummy_type.c_alignment = rffi.cast(rffi.USHORT, 0) dummy_type.c_type = rffi.cast(rffi.USHORT, 0) cls.w_dummy_type = W_FFIType('dummy', dummy_type) cls.w_runappdirect = cls.space.wrap(cls.runappdirect)
def setup_class(cls): BaseAppTestFFI.setup_class.im_func(cls) if cls.runappdirect: cls.w_read_raw_mem = cls.read_raw_mem else: @unwrap_spec(addr=int, typename=str, length=int) def read_raw_mem_w(space, addr, typename, length): return space.wrap(cls.read_raw_mem(addr, typename, length)) cls.w_read_raw_mem = cls.space.wrap(interp2app(read_raw_mem_w)) # from rpython.rlib import clibffi from rpython.rlib.rarithmetic import r_uint from rpython.rtyper.lltypesystem import lltype, rffi dummy_type = lltype.malloc(clibffi.FFI_TYPE_P.TO, flavor='raw') dummy_type.c_size = r_uint(123) dummy_type.c_alignment = rffi.cast(rffi.USHORT, 0) dummy_type.c_type = rffi.cast(rffi.USHORT, 0) cls.w_dummy_type = W_FFIType('dummy', dummy_type) cls.w_runappdirect = cls.space.wrap(cls.runappdirect)
def descr_get_ffi_type(self, space): from pypy.module._rawffi.alt.interp_ffitype import W_FFIType return W_FFIType('<unknown>', self.get_basic_ffi_type(), self)