Exemplo n.º 1
0
 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
Exemplo n.º 2
0
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
Exemplo n.º 3
0
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
Exemplo n.º 4
0
    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)
Exemplo n.º 5
0
    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)
Exemplo n.º 6
0
 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)
Exemplo n.º 7
0
 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