Exemplo n.º 1
0
 def convert_bitfield_from_object(self, cdata, w_ob):
     ctype = self.ctype
     space = ctype.space
     #
     value = misc.as_long_long(space, w_ob)
     if isinstance(ctype, ctypeprim.W_CTypePrimitiveSigned):
         is_signed = True
         fmin = -(r_longlong(1) << (self.bitsize - 1))
         fmax = (r_longlong(1) << (self.bitsize - 1)) - 1
         if fmax == 0:
             fmax = 1      # special case to let "int x:1" receive "1"
     else:
         is_signed = False
         fmin = r_longlong(0)
         fmax = r_longlong((r_ulonglong(1) << self.bitsize) - 1)
     if value < fmin or value > fmax:
         raise oefmt(space.w_OverflowError,
                     "value %d outside the range allowed by the bit field "
                     "width: %d <= x <= %d", value, fmin, fmax)
     rawmask = ((r_ulonglong(1) << self.bitsize) - 1) << self.bitshift
     rawvalue = r_ulonglong(value) << self.bitshift
     rawfielddata = misc.read_raw_unsigned_data(cdata, ctype.size)
     rawfielddata = (rawfielddata & ~rawmask) | (rawvalue & rawmask)
     if is_signed:
         misc.write_raw_signed_data(cdata, rawfielddata, ctype.size)
     else:
         misc.write_raw_unsigned_data(cdata, rawfielddata, ctype.size)
Exemplo n.º 2
0
 def convert_bitfield_from_object(self, cdata, w_ob):
     ctype = self.ctype
     space = ctype.space
     #
     value = misc.as_long_long(space, w_ob)
     if isinstance(ctype, ctypeprim.W_CTypePrimitiveSigned):
         is_signed = True
         fmin = -(r_longlong(1) << (self.bitsize - 1))
         fmax = (r_longlong(1) << (self.bitsize - 1)) - 1
         if fmax == 0:
             fmax = 1  # special case to let "int x:1" receive "1"
     else:
         is_signed = False
         fmin = r_longlong(0)
         fmax = r_longlong((r_ulonglong(1) << self.bitsize) - 1)
     if value < fmin or value > fmax:
         raise oefmt(
             space.w_OverflowError,
             "value %d outside the range allowed by the bit field "
             "width: %d <= x <= %d", value, fmin, fmax)
     rawmask = ((r_ulonglong(1) << self.bitsize) - 1) << self.bitshift
     rawvalue = r_ulonglong(value) << self.bitshift
     rawfielddata = misc.read_raw_unsigned_data(cdata, ctype.size)
     rawfielddata = (rawfielddata & ~rawmask) | (rawvalue & rawmask)
     if is_signed:
         misc.write_raw_signed_data(cdata, rawfielddata, ctype.size)
     else:
         misc.write_raw_unsigned_data(cdata, rawfielddata, ctype.size)
Exemplo n.º 3
0
 def test_it_writes_nothing_and_returns_None(self, space):
     data = lltype.malloc(rffi.CCHARP.TO, 1, flavor='raw')
     misc.write_raw_signed_data(data, 11, 1)
     w_void_type = ffitype.VoidRWStrategy()
     res = w_void_type.write(space, data, 0)
     assert misc.read_raw_signed_data(data, 1) == 11
     assert res is None
     lltype.free(data, flavor='raw')
Exemplo n.º 4
0
 def test_it_writes_nothing_and_returns_None(self, space):
     data = lltype.malloc(rffi.CCHARP.TO, 1, flavor='raw')
     misc.write_raw_signed_data(data, 11, 1)
     w_void_type = ffitype.VoidRWStrategy()
     res = w_void_type.write(space, data, 0)
     assert misc.read_raw_signed_data(data, 1) == 11
     assert res is None
     lltype.free(data, flavor='raw')
Exemplo n.º 5
0
 def convert_from_object(self, cdata, w_ob):
     if self.value_fits_long:
         value = misc.as_long(self.space, w_ob)
         if self.value_smaller_than_long:
             if value != misc.signext(value, self.size):
                 self._overflow(w_ob)
         misc.write_raw_signed_data(cdata, value, self.size)
     else:
         self._convert_from_object_longlong(cdata, w_ob)
Exemplo n.º 6
0
 def convert_from_object(self, cdata, w_ob):
     if self.value_fits_long:
         value = misc.as_long(self.space, w_ob)
         if self.value_smaller_than_long:
             if value != misc.signext(value, self.size):
                 self._overflow(w_ob)
         misc.write_raw_signed_data(cdata, value, self.size)
     else:
         self._convert_from_object_longlong(cdata, w_ob)
Exemplo n.º 7
0
    def rcall(self, funcaddr, args):
        assert self.cif_descr
        self = jit.promote(self)
        # no checking of len(args) needed, as calls in this context are not dynamic

        # The following code is functionally similar to W_CTypeFunc._call, but its
        # implementation is tailored to the restricted use (include memory handling)
        # of the CAPI calls.
        space = self.space
        cif_descr = self.cif_descr
        size = cif_descr.exchange_size
        raw_string = rffi.cast(rffi.CCHARP,
                               0)  # only ever have one in the CAPI
        buffer = lltype.malloc(rffi.CCHARP.TO, size, flavor='raw')
        try:
            for i in range(len(args)):
                data = rffi.ptradd(buffer, cif_descr.exchange_args[i])
                obj = args[i]
                argtype = self.fargs[i]
                # the following is clumsy, but the data types used as arguments are
                # very limited, so it'll do for now
                if obj.tc == 'l':
                    assert isinstance(argtype,
                                      ctypeprim.W_CTypePrimitiveSigned)
                    misc.write_raw_signed_data(data,
                                               rffi.cast(rffi.LONG, obj._long),
                                               argtype.size)
                elif obj.tc == 'h':
                    assert isinstance(argtype,
                                      ctypeprim.W_CTypePrimitiveUnsigned)
                    misc.write_raw_unsigned_data(
                        data, rffi.cast(rffi.ULONG, obj._handle), argtype.size)
                elif obj.tc == 'p':
                    assert obj._voidp != rffi.cast(rffi.VOIDP, 0)
                    data = rffi.cast(rffi.VOIDPP, data)
                    data[0] = obj._voidp
                else:  # only other use is sring
                    assert obj.tc == 's'
                    n = len(obj._string)
                    assert raw_string == rffi.cast(rffi.CCHARP, 0)
                    # XXX could use rffi.get_nonmovingbuffer_final_null()
                    raw_string = rffi.str2charp(obj._string)
                    data = rffi.cast(rffi.CCHARPP, data)
                    data[0] = raw_string

            jit_libffi.jit_ffi_call(cif_descr, rffi.cast(rffi.VOIDP, funcaddr),
                                    buffer)

            resultdata = rffi.ptradd(buffer, cif_descr.exchange_result)
            # this wrapping is unnecessary, but the assumption is that given the
            # immediate unwrapping, the round-trip is removed
            w_res = self.ctitem.copy_and_convert_to_object(resultdata)
        finally:
            if raw_string != rffi.cast(rffi.CCHARP, 0):
                rffi.free_charp(raw_string)
            lltype.free(buffer, flavor='raw')
        return w_res
Exemplo n.º 8
0
 def convert_from_object(self, cdata, w_ob):
     if self.value_fits_long:
         value = misc.as_long(self.space, w_ob)
         if self.size < rffi.sizeof(lltype.Signed):
             if r_uint(value) - self.vmin > self.vrangemax:
                 self._overflow(w_ob)
         misc.write_raw_signed_data(cdata, value, self.size)
     else:
         value = misc.as_long_long(self.space, w_ob)
         misc.write_raw_signed_data(cdata, value, self.size)
Exemplo n.º 9
0
    def rcall(self, funcaddr, args):
        assert self.cif_descr
        self = jit.promote(self)
        # no checking of len(args) needed, as calls in this context are not dynamic

        # The following code is functionally similar to W_CTypeFunc._call, but its
        # implementation is tailored to the restricted use (include memory handling)
        # of the CAPI calls.
        space = self.space
        cif_descr = self.cif_descr
        size = cif_descr.exchange_size
        raw_string = rffi.cast(rffi.CCHARP, 0)    # only ever have one in the CAPI
        buffer = lltype.malloc(rffi.CCHARP.TO, size, flavor='raw')
        try:
            for i in range(len(args)):
                data = rffi.ptradd(buffer, cif_descr.exchange_args[i])
                obj = args[i]
                argtype = self.fargs[i]
                # the following is clumsy, but the data types used as arguments are
                # very limited, so it'll do for now
                if obj.tc == 'l':
                    assert isinstance(argtype, ctypeprim.W_CTypePrimitiveSigned)
                    misc.write_raw_signed_data(data, rffi.cast(rffi.LONG, obj._long), argtype.size)
                elif obj.tc == 'h':
                    assert isinstance(argtype, ctypeprim.W_CTypePrimitiveUnsigned)
                    misc.write_raw_unsigned_data(data, rffi.cast(rffi.ULONG, obj._handle), argtype.size)
                elif obj.tc == 'p':
                    assert obj._voidp != rffi.cast(rffi.VOIDP, 0)
                    data = rffi.cast(rffi.VOIDPP, data)
                    data[0] = obj._voidp
                else:    # only other use is sring
                    assert obj.tc == 's'
                    n = len(obj._string)
                    assert raw_string == rffi.cast(rffi.CCHARP, 0)
                    # XXX could use rffi.get_nonmovingbuffer_final_null()
                    raw_string = rffi.str2charp(obj._string)
                    data = rffi.cast(rffi.CCHARPP, data)
                    data[0] = raw_string

            jit_libffi.jit_ffi_call(cif_descr,
                                    rffi.cast(rffi.VOIDP, funcaddr),
                                    buffer)

            resultdata = rffi.ptradd(buffer, cif_descr.exchange_result)
            # this wrapping is unnecessary, but the assumption is that given the
            # immediate unwrapping, the round-trip is removed
            w_res = self.ctitem.copy_and_convert_to_object(resultdata)
        finally:
            if raw_string != rffi.cast(rffi.CCHARP, 0):
                rffi.free_charp(raw_string)
            lltype.free(buffer, flavor='raw')
        return w_res
Exemplo n.º 10
0
 def test_it_reads_signed_types_to_buffer(self, space):
     for t in [
             ffitype.INT8, ffitype.INT16, ffitype.INT32, ffitype.INT64,
             ffitype.LONG
     ]:
         w_signed_type = ffitype.SignedRWStrategy(t)
         size = w_signed_type.typesize
         # make new buffer for every t
         data = lltype.malloc(rffi.CCHARP.TO, size, flavor='raw')
         misc.write_raw_signed_data(data, -88, size)
         w_res = w_signed_type.read(space, data)
         assert self.unwrap(space, w_res) == -88
         lltype.free(data, flavor='raw')
Exemplo n.º 11
0
 def test_it_reads_signed_types_to_buffer(self, space):
     for t in [ffitype.INT8,
               ffitype.INT16,
               ffitype.INT32,
               ffitype.INT64,
               ffitype.LONG]:
         w_signed_type = ffitype.SignedRWStrategy(t)
         size = w_signed_type.typesize
         # make new buffer for every t
         data = lltype.malloc(rffi.CCHARP.TO, size, flavor='raw')
         misc.write_raw_signed_data(data, -88, size)
         w_res = w_signed_type.read(space, data)
         assert self.unwrap(space, w_res) == -88
         lltype.free(data, flavor='raw')
Exemplo n.º 12
0
 def convert_from_object(self, cdata, w_ob):
     if self.value_fits_long:
         value = misc.as_long(self.space, w_ob)
         if self.value_smaller_than_long:
             size = self.size
             if size == 1:
                 signextended = misc.signext(value, 1)
             elif size == 2:
                 signextended = misc.signext(value, 2)
             elif size == 4:
                 signextended = misc.signext(value, 4)
             else:
                 raise AssertionError("unsupported size")
             if value != signextended:
                 self._overflow(w_ob)
         misc.write_raw_signed_data(cdata, value, self.size)
     else:
         self._convert_from_object_longlong(cdata, w_ob)
Exemplo n.º 13
0
def convert_from_object_fficallback(fresult, ll_res, w_res,
                                    encode_result_for_libffi):
    space = fresult.space
    if isinstance(fresult, W_CTypeVoid):
        if not space.is_w(w_res, space.w_None):
            raise oefmt(
                space.w_TypeError,
                "callback with the return type 'void' must return "
                "None")
        return
    #
    small_result = encode_result_for_libffi and fresult.size < SIZE_OF_FFI_ARG
    if small_result and fresult.is_primitive_integer:
        # work work work around a libffi irregularity: for integer return
        # types we have to fill at least a complete 'ffi_arg'-sized result
        # buffer.
        if type(fresult) is W_CTypePrimitiveSigned:
            # It's probably fine to always zero-extend, but you never
            # know: maybe some code somewhere expects a negative
            # 'short' result to be returned into EAX as a 32-bit
            # negative number.  Better safe than sorry.  This code
            # is about that case.  Let's ignore this for enums.
            #
            # do a first conversion only to detect overflows.  This
            # conversion produces stuff that is otherwise ignored.
            fresult.convert_from_object(ll_res, w_res)
            #
            # manual inlining and tweaking of
            # W_CTypePrimitiveSigned.convert_from_object() in order
            # to write a whole 'ffi_arg'.
            value = misc.as_long(space, w_res)
            misc.write_raw_signed_data(ll_res, value, SIZE_OF_FFI_ARG)
            return
        else:
            # zero extension: fill the '*result' with zeros, and (on big-
            # endian machines) correct the 'result' pointer to write to
            misc._raw_memclear(ll_res, SIZE_OF_FFI_ARG)
            if BIG_ENDIAN:
                diff = SIZE_OF_FFI_ARG - fresult.size
                ll_res = rffi.ptradd(ll_res, diff)
    #
    fresult.convert_from_object(ll_res, w_res)
Exemplo n.º 14
0
def convert_from_object_fficallback(fresult, ll_res, w_res,
                                    encode_result_for_libffi):
    space = fresult.space
    if isinstance(fresult, W_CTypeVoid):
        if not space.is_w(w_res, space.w_None):
            raise oefmt(space.w_TypeError,
                        "callback with the return type 'void' must return "
                        "None")
        return
    #
    small_result = encode_result_for_libffi and fresult.size < SIZE_OF_FFI_ARG
    if small_result and fresult.is_primitive_integer:
        # work work work around a libffi irregularity: for integer return
        # types we have to fill at least a complete 'ffi_arg'-sized result
        # buffer.
        if type(fresult) is W_CTypePrimitiveSigned:
            # It's probably fine to always zero-extend, but you never
            # know: maybe some code somewhere expects a negative
            # 'short' result to be returned into EAX as a 32-bit
            # negative number.  Better safe than sorry.  This code
            # is about that case.  Let's ignore this for enums.
            #
            # do a first conversion only to detect overflows.  This
            # conversion produces stuff that is otherwise ignored.
            fresult.convert_from_object(ll_res, w_res)
            #
            # manual inlining and tweaking of
            # W_CTypePrimitiveSigned.convert_from_object() in order
            # to write a whole 'ffi_arg'.
            value = misc.as_long(space, w_res)
            misc.write_raw_signed_data(ll_res, value, SIZE_OF_FFI_ARG)
            return
        else:
            # zero extension: fill the '*result' with zeros, and (on big-
            # endian machines) correct the 'result' pointer to write to
            misc._raw_memclear(ll_res, SIZE_OF_FFI_ARG)
            if BIG_ENDIAN:
                diff = SIZE_OF_FFI_ARG - fresult.size
                ll_res = rffi.ptradd(ll_res, diff)
    #
    fresult.convert_from_object(ll_res, w_res)
Exemplo n.º 15
0
 def _convert_from_object_longlong(self, cdata, w_ob):
     # in its own function: LONGLONG may make the whole function jit-opaque
     value = misc.as_long_long(self.space, w_ob)
     misc.write_raw_signed_data(cdata, value, self.size)
Exemplo n.º 16
0
    def rcall(self, funcaddr, args):
        assert self.cif_descr
        self = jit.promote(self)
        # no checking of len(args) needed, as calls in this context are not dynamic

        # The following code is functionally similar to W_CTypeFunc._call, but its
        # implementation is tailored to the restricted use (include memory handling)
        # of the CAPI calls.
        space = self.space
        cif_descr = self.cif_descr
        size = cif_descr.exchange_size
        raw_string1 = rffi.cast(rffi.CCHARP, 0)
        raw_string2 = rffi.cast(rffi.CCHARP, 0)  # have max two in any CAPI
        buffer = lltype.malloc(rffi.CCHARP.TO, size, flavor='raw')
        try:
            for i in range(len(args)):
                data = rffi.ptradd(buffer, cif_descr.exchange_args[i])
                obj = args[i]
                argtype = self.fargs[i]
                # the following is clumsy, but the data types used as arguments are
                # very limited, so it'll do for now
                if obj.tc == 'h':
                    misc.write_raw_unsigned_data(
                        data, rffi.cast(rffi.SIZE_T, obj._scope), argtype.size)
                elif obj.tc == 'm':
                    misc.write_raw_signed_data(
                        data, rffi.cast(rffi.INTPTR_T, obj._method),
                        argtype.size)
                elif obj.tc == 'o':
                    # additional cast of void* to intptr_t required for 32b (or intmask fails)
                    misc.write_raw_signed_data(
                        data,
                        rffi.cast(rffi.INTPTR_T,
                                  rffi.cast(rffi.VOIDP, obj._object)),
                        argtype.size)
                elif obj.tc == 'u':
                    misc.write_raw_unsigned_data(
                        data, rffi.cast(rffi.SIZE_T, obj._index), argtype.size)
                elif obj.tc == 'i':
                    misc.write_raw_signed_data(data,
                                               rffi.cast(rffi.INT, obj._int),
                                               argtype.size)
                elif obj.tc == 'd':
                    misc.write_raw_float_data(
                        data, rffi.cast(rffi.DOUBLE, obj._double),
                        argtype.size)
                elif obj.tc == 'p':
                    assert obj._voidp != rffi.cast(rffi.VOIDP, 0)
                    data = rffi.cast(rffi.VOIDPP, data)
                    data[0] = obj._voidp
                elif obj.tc == 's':
                    n = len(obj._string)
                    data = rffi.cast(rffi.CCHARPP, data)
                    if raw_string1 == rffi.cast(rffi.CCHARP, 0):
                        # XXX could use rffi.get_nonmovingbuffer_final_null()
                        raw_string1 = rffi.str2charp(obj._string)
                        data[0] = raw_string1
                    else:
                        assert raw_string2 == rffi.cast(rffi.CCHARP, 0)
                        raw_string2 = rffi.str2charp(obj._string)
                        data[0] = raw_string2
                else:  # only other use is voidp
                    assert obj.tc == 'p'
                    assert obj._voidp != rffi.cast(rffi.VOIDP, 0)
                    data = rffi.cast(rffi.VOIDPP, data)
                    data[0] = obj._voidp

            jit_libffi.jit_ffi_call(cif_descr, rffi.cast(rffi.VOIDP, funcaddr),
                                    buffer)

            resultdata = rffi.ptradd(buffer, cif_descr.exchange_result)
            # this wrapping is unnecessary, but the assumption is that given the
            # immediate unwrapping, the round-trip is removed
            w_res = self.ctitem.copy_and_convert_to_object(resultdata)
        finally:
            if raw_string1 != rffi.cast(rffi.CCHARP, 0):
                rffi.free_charp(raw_string1)
            if raw_string2 != rffi.cast(rffi.CCHARP, 0):
                rffi.free_charp(raw_string2)
            lltype.free(buffer, flavor='raw')
        return w_res
Exemplo n.º 17
0
 def write_raw_signed_data(self, source):
     with self as ptr:
         misc.write_raw_signed_data(ptr, source, self.ctype.size)
Exemplo n.º 18
0
Arquivo: type.py Projeto: mswart/topaz
 def write(self, space, data, w_arg):
     arg = space.int_w(w_arg)
     misc.write_raw_signed_data(data, arg, self.typesize)
Exemplo n.º 19
0
 def write_raw_signed_data(self, source):
     misc.write_raw_signed_data(self._cdata, source, self.ctype.size)
     keepalive_until_here(self)
Exemplo n.º 20
0
 def write_raw_signed_data(self, source):
     with self as ptr:
         misc.write_raw_signed_data(ptr, source, self.ctype.size)
Exemplo n.º 21
0
 def write_raw_signed_data(self, source):
     misc.write_raw_signed_data(self._cdata, source, self.ctype.size)
     keepalive_until_here(self)