Example #1
0
 def delitem(self, space, i, j):
     if i < 0:
         i += self.len
     if i < 0:
         i = 0
     if j < 0:
         j += self.len
     if j < 0:
         j = 0
     if j > self.len:
         j = self.len
     if i >= j:
         return None
     oldbuffer = self.buffer
     self.buffer = lltype.malloc(
         mytype.arraytype, max(self.len - (j - i), 0), flavor='raw',
         add_memory_pressure=True)
     if i:
         rffi.c_memcpy(
             rffi.cast(rffi.VOIDP, self.buffer),
             rffi.cast(rffi.VOIDP, oldbuffer),
             i * mytype.bytes
         )
     if j < self.len:
         rffi.c_memcpy(
             rffi.cast(rffi.VOIDP, rffi.ptradd(self.buffer, i)),
             rffi.cast(rffi.VOIDP, rffi.ptradd(oldbuffer, j)),
             (self.len - j) * mytype.bytes
         )
     self.len -= j - i
     self.allocated = self.len
     if oldbuffer:
         lltype.free(oldbuffer, flavor='raw')
Example #2
0
    def _call(self, funcaddr, args_w):
        space = self.space
        cif_descr = self.cif_descr
        size = cif_descr.exchange_size
        mustfree_max_plus_1 = 0
        buffer = lltype.malloc(rffi.CCHARP.TO, size, flavor='raw')
        try:
            for i in range(len(args_w)):
                data = rffi.ptradd(buffer, cif_descr.exchange_args[i])
                w_obj = args_w[i]
                argtype = self.fargs[i]
                if argtype.convert_argument_from_object(data, w_obj):
                    # argtype is a pointer type, and w_obj a list/tuple/str
                    mustfree_max_plus_1 = i + 1

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

            resultdata = rffi.ptradd(buffer, cif_descr.exchange_result)
            w_res = self.ctitem.copy_and_convert_to_object(resultdata)
        finally:
            for i in range(mustfree_max_plus_1):
                argtype = self.fargs[i]
                if isinstance(argtype, W_CTypePointer):
                    data = rffi.ptradd(buffer, cif_descr.exchange_args[i])
                    flag = get_mustfree_flag(data)
                    if flag == 1:
                        raw_cdata = rffi.cast(rffi.CCHARPP, data)[0]
                        lltype.free(raw_cdata, flavor='raw')
            lltype.free(buffer, flavor='raw')
            keepalive_until_here(args_w)
        return w_res
Example #3
0
    def _call(self, funcaddr, args_w):
        space = self.space
        cif_descr = self.cif_descr
        size = cif_descr.exchange_size
        mustfree_max_plus_1 = 0
        buffer = lltype.malloc(rffi.CCHARP.TO, size, flavor="raw")
        try:
            for i in range(len(args_w)):
                data = rffi.ptradd(buffer, cif_descr.exchange_args[i])
                w_obj = args_w[i]
                argtype = self.fargs[i]
                if argtype.convert_argument_from_object(data, w_obj):
                    # argtype is a pointer type, and w_obj a list/tuple/str
                    mustfree_max_plus_1 = i + 1

            ec = cerrno.get_errno_container(space)
            cerrno.restore_errno_from(ec)
            jit_libffi.jit_ffi_call(cif_descr, rffi.cast(rffi.VOIDP, funcaddr), buffer)
            e = cerrno.get_real_errno()
            cerrno.save_errno_into(ec, e)

            resultdata = rffi.ptradd(buffer, cif_descr.exchange_result)
            w_res = self.ctitem.copy_and_convert_to_object(resultdata)
        finally:
            for i in range(mustfree_max_plus_1):
                argtype = self.fargs[i]
                if isinstance(argtype, W_CTypePointer):
                    data = rffi.ptradd(buffer, cif_descr.exchange_args[i])
                    flag = get_mustfree_flag(data)
                    if flag == 1:
                        raw_string = rffi.cast(rffi.CCHARPP, data)[0]
                        lltype.free(raw_string, flavor="raw")
            lltype.free(buffer, flavor="raw")
        return w_res
Example #4
0
    def invoke(self, space, ptr, args_w, block=None):
        self = jit.promote(self)

        if block is not None:
            args_w.append(block)
        nargs = len(args_w)
        assert nargs == self.cif_descr.nargs
        #
        size = self.cif_descr.exchange_size
        buffer = lltype.malloc(rffi.CCHARP.TO, size, flavor='raw')
        try:
            for i in range(len(args_w)):
                data = rffi.ptradd(buffer, self.cif_descr.exchange_args[i])
                w_obj = args_w[i]
                self._put_arg(space, data, i, w_obj)

            # ec = cerrno.get_errno_container(space)
            # cerrno.restore_errno_from(ec)
            jit_ffi_call(self.cif_descr, rffi.cast(rffi.VOIDP, ptr), buffer)
            # e = cerrno.get_real_errno()
            # cerrno.save_errno_into(ec, e)

            resultdata = rffi.ptradd(buffer, self.cif_descr.exchange_result)
            w_res = self._get_result(space, resultdata)
        finally:
            lltype.free(buffer, flavor='raw')
        return w_res
Example #5
0
def array_getitem(ffitype, width, addr, index, offset):
    for TYPE, ffitype2 in clibffi.ffitype_map:
        if ffitype is ffitype2:
            addr = rffi.ptradd(addr, index * width)
            addr = rffi.ptradd(addr, offset)
            return rffi.cast(rffi.CArrayPtr(TYPE), addr)[0]
    assert False
Example #6
0
 def ccall(self, pointer, argv):
     argc = len(argv)
     if argc != len(self.argtypes):
         raise unwind(LCallError(len(self.argtypes), len(self.argtypes), False, argc))
     if self.notready:
         self.prepare_cif()
         self.notready = False
     cif = self.cif
     # String objects need to be converted and stored during the call.
     # Also, there are many things that are better treated like this.
     pool = Pool()
     #sbuf = []
     # Exchange buffer is built for every call. Filled with arguments that are passed to the function.
     exc = lltype.malloc(rffi.VOIDP.TO, cif.exchange_size, flavor='raw')
     try:
         for i in range(argc):
             offset = rffi.ptradd(exc, cif.exchange_args[i])
             arg = argv[i]
             arg_t = self.argtypes[i]
             # TODO: fixme
             arg_t.store(pool, offset, arg)
         jit_libffi.jit_ffi_call(cif, pointer, exc)
         val = null
         if isinstance(self.restype, Type):
             offset = rffi.ptradd(exc, cif.exchange_result)
             val = self.restype.load(offset, True)
     finally:
         lltype.free(exc, flavor='raw')
         pool.free_noreuse()
     return val
Example #7
0
 def method_put_bytes(self, space, start, string, str_offset, nbytes):
     with rffi.scoped_view_charp(string) as cstring:
         rffi.c_memcpy(
             rffi.ptradd(self.ptr, start),
             rffi.cast(rffi.VOIDP, rffi.ptradd(cstring, str_offset)),
             nbytes
         )
Example #8
0
 def _do_setslice(self, w_slice, w_value):
     ctptr, start, length = self._do_getslicearg(w_slice)
     ctitem = ctptr.ctitem
     ctitemsize = ctitem.size
     cdata = rffi.ptradd(self._cdata, start * ctitemsize)
     #
     if isinstance(w_value, W_CData):
         from pypy.module._cffi_backend import ctypearray
         ctv = w_value.ctype
         if (isinstance(ctv, ctypearray.W_CTypeArray) and
             ctv.ctitem is ctitem and
             w_value.get_array_length() == length):
             # fast path: copying from exactly the correct type
             s = w_value._cdata
             for i in range(ctitemsize * length):
                 cdata[i] = s[i]
             keepalive_until_here(w_value)
             return
     #
     space = self.space
     w_iter = space.iter(w_value)
     for i in range(length):
         try:
             w_item = space.next(w_iter)
         except OperationError, e:
             if not e.match(space, space.w_StopIteration):
                 raise
             raise operationerrfmt(space.w_ValueError,
                                   "need %d values to unpack, got %d",
                                   length, i)
         ctitem.convert_from_object(cdata, w_item)
         cdata = rffi.ptradd(cdata, ctitemsize)
Example #9
0
 def ccall(self, pointer, argv):
     argc = len(argv)
     if argc != len(self.argtypes):
         raise Error(u"ffi call expects %d arguments" % argc)
     if self.notready:
         self.prepare_cif()
         self.notready = False
     cif = self.cif
     # String objects need to be converted and stored during the call.
     # I assume it's not a good idea to just generated some and expect them to
     # stick around.
     sbuf = []
     # Exchange buffer is built for every call. Filled with arguments that are passed to the function.
     exc = lltype.malloc(rffi.VOIDP.TO, cif.exchange_size, flavor='raw')
     try:
         for i in range(argc):
             offset = rffi.ptradd(exc, cif.exchange_args[i])
             arg = argv[i]
             arg_t = self.argtypes[i]
             if isinstance(arg, String) and isinstance(arg_t, Pointer):
                 arg = rffi.str2charp(as_cstring(arg))
                 sbuf.append(arg)
                 arg_t.store_string(offset, arg)
             else:
                 arg_t.store(offset, arg)
         jit_libffi.jit_ffi_call(cif, pointer, exc)
         val = null
         if isinstance(self.restype, Type):
             offset = rffi.ptradd(exc, cif.exchange_result)
             val = self.restype.load(offset)
     finally:
         lltype.free(exc, flavor='raw')
         for sb in sbuf:
             lltype.free(sb, flavor='raw')
     return val
Example #10
0
 def fake_call_impl_any(cif_description, func_addr, exchange_buffer):
     ofs = 16
     for avalue in unroll_avalues:
         TYPE = rffi.CArray(lltype.typeOf(avalue))
         data = rffi.ptradd(exchange_buffer, ofs)
         got = rffi.cast(lltype.Ptr(TYPE), data)[0]
         if lltype.typeOf(avalue) is lltype.SingleFloat:
             got = float(got)
             avalue = float(avalue)
         elif (lltype.typeOf(avalue) is rffi.SIGNEDCHAR or
               lltype.typeOf(avalue) is rffi.UCHAR):
             got = intmask(got)
             avalue = intmask(avalue)
         assert got == avalue
         ofs += 16
     write_to_ofs = 0
     if rvalue is not None:
         write_rvalue = rvalue
         if BIG_ENDIAN:
             if (lltype.typeOf(write_rvalue) is rffi.SIGNEDCHAR or
                 lltype.typeOf(write_rvalue) is rffi.UCHAR):
                 # 'write_rvalue' is an int type smaller than Signed
                 write_to_ofs = rffi.sizeof(rffi.LONG) - 1
     else:
         write_rvalue = 12923  # ignored
     TYPE = rffi.CArray(lltype.typeOf(write_rvalue))
     data = rffi.ptradd(exchange_buffer, ofs)
     rffi.cast(lltype.Ptr(TYPE), data)[write_to_ofs] = write_rvalue
Example #11
0
 def force_words(self, start, stop):
     assert start > 0 and stop > 0 and self.size() >= stop and self.pixelbuffer_words >= stop and stop >= start
     pixbuf = rffi.ptradd(self.display().get_pixelbuffer(), start)
     realbuf = rffi.ptradd(self._real_depth_buffer, start)
     rffi.c_memcpy(
         rffi.cast(rffi.VOIDP, pixbuf),
         rffi.cast(rffi.VOIDP, realbuf),
         (stop - start) * constants.BYTES_PER_WORD)  # VOIDP is char*, we want to copy word*
Example #12
0
 def _invoke(self, args):
     exb = lltype.malloc(rffi.CCHARP.TO, self._transfer_size, flavor="raw")
     offset_p = rffi.ptradd(exb, self._arg0_offset)
     self.pack_args(offset_p, args, self._arg_types)
     jit_ffi_call(self._cd, self._f_ptr, exb)
     offset_p = rffi.ptradd(exb, self._ret_offset)
     ret_val = get_ret_val(offset_p, self._ret_type)
     lltype.free(exb, flavor="raw")
     return ret_val
Example #13
0
 def copy_pixels(self, pixels, start, stop):
     offset = start * self.bpp
     assert offset >= 0
     remaining_size = (self.width * self.height * self.bpp) - offset
     if remaining_size <= 0 or start >= stop:
         return
     nbytes = rffi.r_size_t(min((stop - start) * self.bpp, remaining_size))
     pixbuf = rffi.ptradd(PIXELVOIDPP[0], offset)
     surfacebuf = rffi.ptradd(rffi.cast(rffi.VOIDP, pixels), offset)
     rffi.c_memcpy(pixbuf, surfacebuf, nbytes)
Example #14
0
def set_native_value(ptr, val, tp):
    if tp is Integer._type:
        pnt = rffi.cast(rffi.LONGP, ptr)
        pnt[0] = rffi.cast(rffi.LONG, val.int_val())
        return rffi.cast(rffi.CCHARP, rffi.ptradd(pnt, rffi.sizeof(rffi.LONG)))
    if tp is String._type:
        pnt = rffi.cast(rffi.CCHARPP, ptr)
        pnt[0] = rffi.str2charp(str(rt.name(val)))
        return rffi.cast(rffi.CCHARP, rffi.ptradd(pnt, rffi.sizeof(rffi.CCHARP)))
    assert False
Example #15
0
 def do_call(n):
     func_ptr = llhelper(lltype.Ptr(FUNC), fn)
     exbuf = lltype.malloc(rffi.CCHARP.TO, 48, flavor='raw', zero=True)
     data_in = rffi.ptradd(exbuf, 16)
     rffi.cast(ARRAY, data_in)[0] = n
     jit_ffi_call(cif_description, func_ptr, exbuf)
     data_out = rffi.ptradd(exbuf, 32)
     res = rffi.cast(ARRAY, data_out)[0]
     lltype.free(exbuf, flavor='raw')
     return res
Example #16
0
        def get_indices(w_start, w_stop, w_step, length):
            w_slice = space.newslice(w_start, w_stop, w_step)
            values = lltype.malloc(Py_ssize_tP.TO, 3, flavor='raw')

            res = api.PySlice_GetIndices(w_slice, 100, values,
                rffi.ptradd(values, 1),
                rffi.ptradd(values, 2))
            assert res == 0
            rv = values[0], values[1], values[2]
            lltype.free(values, flavor='raw')
            return rv
Example #17
0
File: ffi.py Project: Xsan-21/pixie
    def prep_exb(self, args):
        if not self._is_inited:
            self.thaw()
        exb = lltype.malloc(rffi.CCHARP.TO, self._transfer_size, flavor="raw")
        offset_p = rffi.ptradd(exb, self._arg0_offset)
        tokens = [None] * len(args)

        for x in range(len(self._arg_types)):
            tokens[x] = self._arg_types[x].ffi_set_value(offset_p, args[x])
            offset_p = rffi.ptradd(offset_p, self._arg_types[x].ffi_size())

        return exb, tokens
Example #18
0
 def fake_call_impl_any(cif_description, func_addr, exchange_buffer):
     # read the args from the buffer
     data_in = rffi.ptradd(exchange_buffer, 16)
     n = rffi.cast(ARRAY, data_in)[0]
     #
     # logic of the function
     func_ptr = rffi.cast(lltype.Ptr(FUNC), func_addr)
     n = func_ptr(n)
     #
     # write the result to the buffer
     data_out = rffi.ptradd(exchange_buffer, 32)
     rffi.cast(ARRAY, data_out)[0] = n
Example #19
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
Example #20
0
def jit_ffi_call_impl_any(cif_description, func_addr, exchange_buffer):
    """
    This is the function which actually calls libffi. All the rest if just
    infrastructure to convince the JIT to pass a typed result box to
    jit_ffi_save_result
    """
    buffer_array = rffi.cast(rffi.VOIDPP, exchange_buffer)
    for i in range(cif_description.nargs):
        data = rffi.ptradd(exchange_buffer, cif_description.exchange_args[i])
        buffer_array[i] = data
    resultdata = rffi.ptradd(exchange_buffer,
                             cif_description.exchange_result)
    clibffi.c_ffi_call(cif_description.cif, func_addr,
                       rffi.cast(rffi.VOIDP, resultdata),
                       buffer_array)
Example #21
0
 def setitem(self, index, value):
     if not isinstance(index, Integer):
         return Object.setitem(self, index, value)
     index = index.value
     ctype = self.ctype
     if isinstance(ctype, Pointer):
         ctype = ctype.to
         if isinstance(ctype, Array):
             pointer = rffi.ptradd(self.pointer, ctype.ctype.size*index)
             # TODO: could do length check if length present.
             return ctype.ctype.store(self.pool, pointer, value)
         elif isinstance(ctype, Type):
             pointer = rffi.ptradd(self.pointer, ctype.size*index)
             return ctype.store(self.pool, pointer, value)
     return Object.setitem(self, Integer(index), value)
Example #22
0
File: ffi.py Project: kidaa/pixie
def unpack(ptr, offset, tp):
    """(unpack ptr offset tp)
       Reads a value of type tp from offset of ptr."""
    affirm(isinstance(ptr, VoidP) or isinstance(ptr, Buffer) or isinstance(ptr, CStruct), u"Type is not unpackable")
    affirm(isinstance(tp, CType), u"Packing type must be a CType")
    ptr = rffi.ptradd(ptr.raw_data(), offset.int_val())
    return tp.ffi_get_value(ptr)
Example #23
0
 def decode_float(self, i):
     from rpython.rlib import rdtoa
     start = rffi.ptradd(self.ll_chars, i)
     floatval = rdtoa.dg_strtod(start, self.end_ptr)
     diff = rffi.cast(rffi.LONG, self.end_ptr[0]) - rffi.cast(rffi.LONG, start)
     self.pos = i + diff
     return self.space.wrap(floatval)
Example #24
0
 def call(self, space, w_self, w_args, w_kw):
     func_to_call = self.func
     if self.offset:
         pto = as_pyobj(space, self.w_objclass)
         # make ptr the equivalent of this, using the offsets
         #func_to_call = rffi.cast(rffi.VOIDP, ptr.c_tp_as_number.c_nb_multiply)
         if pto:
             cptr = rffi.cast(rffi.CCHARP, pto)
             for o in self.offset:
                 ptr = rffi.cast(rffi.VOIDPP, rffi.ptradd(cptr, o))[0]
                 cptr = rffi.cast(rffi.CCHARP, ptr)
             func_to_call = rffi.cast(rffi.VOIDP, cptr)
         else:
             # Should never happen, assert to get a traceback
             assert False, "failed to convert w_type %s to PyObject" % str(
                                                           self.w_objclass)
     assert func_to_call
     if self.wrapper_func is None:
         assert self.wrapper_func_kwds is not None
         return self.wrapper_func_kwds(space, w_self, w_args, func_to_call,
                                       w_kw)
     if space.is_true(w_kw):
         raise oefmt(space.w_TypeError,
                     "wrapper %s doesn't take any keyword arguments",
                     self.method_name)
     return self.wrapper_func(space, w_self, w_args, func_to_call)
Example #25
0
 def test_rawfuncptr(self):
     libm = self.get_libm()
     pow = libm.getrawpointer('pow', [ffi_type_double, ffi_type_double],
                              ffi_type_double)
     buffer = lltype.malloc(rffi.DOUBLEP.TO, 3, flavor='raw')
     buffer[0] = 2.0
     buffer[1] = 3.0
     buffer[2] = 43.5
     pow.call([rffi.cast(rffi.VOIDP, buffer),
               rffi.cast(rffi.VOIDP, rffi.ptradd(buffer, 1))],
              rffi.cast(rffi.VOIDP, rffi.ptradd(buffer, 2)))
     assert buffer[2] == 8.0
     lltype.free(buffer, flavor='raw')
     del pow
     del libm
     assert not ALLOCATED
Example #26
0
    def rawallocate(self, ctypefunc):
        space = ctypefunc.space
        self.space = space

        # compute the total size needed in the CIF_DESCRIPTION buffer
        self.nb_bytes = 0
        self.bufferp = lltype.nullptr(rffi.CCHARP.TO)
        self.fb_build()

        # allocate the buffer
        if we_are_translated():
            rawmem = lltype.malloc(rffi.CCHARP.TO, self.nb_bytes, flavor="raw")
            rawmem = rffi.cast(CIF_DESCRIPTION_P, rawmem)
        else:
            # gross overestimation of the length below, but too bad
            rawmem = lltype.malloc(CIF_DESCRIPTION_P.TO, self.nb_bytes, flavor="raw")

        # the buffer is automatically managed from the W_CTypeFunc instance
        ctypefunc.cif_descr = rawmem

        # call again fb_build() to really build the libffi data structures
        self.bufferp = rffi.cast(rffi.CCHARP, rawmem)
        self.fb_build()
        assert self.bufferp == rffi.ptradd(rffi.cast(rffi.CCHARP, rawmem), self.nb_bytes)

        # fill in the 'exchange_*' fields
        self.fb_build_exchange(rawmem)

        # fill in the extra fields
        self.fb_extra_fields(rawmem)

        # call libffi's ffi_prep_cif() function
        res = jit_libffi.jit_ffi_prep_cif(rawmem)
        if res != clibffi.FFI_OK:
            raise OperationError(space.w_SystemError, space.wrap("libffi failed to build this function type"))
Example #27
0
 def _do_call(self, funcsym, ll_args, RESULT):
     # XXX: check len(args)?
     ll_result = lltype.nullptr(rffi.VOIDP.TO)
     if self.restype != types.void:
         size = adjust_return_size(intmask(self.restype.c_size))
         ll_result = lltype.malloc(rffi.VOIDP.TO, size,
                                   flavor='raw')
     ffires = c_ffi_call(self.ll_cif,
                         self.funcsym,
                         rffi.cast(rffi.VOIDP, ll_result),
                         rffi.cast(rffi.VOIDPP, ll_args))
     if RESULT is not lltype.Void:
         TP = lltype.Ptr(rffi.CArray(RESULT))
         if types.is_struct(self.restype):
             assert RESULT == rffi.SIGNED
             # for structs, we directly return the buffer and transfer the
             # ownership
             buf = rffi.cast(TP, ll_result)
             res = rffi.cast(RESULT, buf)
         else:
             if _BIG_ENDIAN and types.getkind(self.restype) in ('i','u'):
                 ptr = ll_result
                 n = rffi.sizeof(lltype.Signed) - self.restype.c_size
                 ptr = rffi.ptradd(ptr, n)
                 res = rffi.cast(TP, ptr)[0]
             else:
                 res = rffi.cast(TP, ll_result)[0]
     else:
         res = None
     self._free_buffers(ll_result, ll_args)
     clibffi.check_fficall_result(ffires, self.flags)
     return res
Example #28
0
 def __init__(self, space, ctitem, cdata):
     self.space = space
     self.ctitem = ctitem
     self.cdata = cdata
     length = cdata.get_array_length()
     self._next = cdata.unsafe_escaping_ptr()
     self._stop = rffi.ptradd(self._next, length * ctitem.size)
Example #29
0
    def test_cdll_life_time(self):
        from rpython.translator.tool.cbuild import ExternalCompilationInfo
        from rpython.translator.platform import platform
        from rpython.tool.udir import udir

        c_file = udir.ensure("test_libffi", dir=1).join("xlib.c")
        c_file.write(py.code.Source('''
        long fun(long i) {
            return i + 42;
        }
        '''))
        eci = ExternalCompilationInfo(export_symbols=['fun'])
        lib_name = str(platform.compile([c_file], eci, 'x', standalone=False))

        lib = CDLL(lib_name)
        slong = cast_type_to_ffitype(rffi.LONG)
        fun = lib.getrawpointer('fun', [slong], slong)
        del lib     # already delete here

        buffer = lltype.malloc(rffi.LONGP.TO, 2, flavor='raw')
        buffer[0] = 200
        buffer[1] = -1
        fun.call([rffi.cast(rffi.VOIDP, buffer)],
                 rffi.cast(rffi.VOIDP, rffi.ptradd(buffer, 1)))
        assert buffer[1] == 242

        lltype.free(buffer, flavor='raw')
        del fun

        assert not ALLOCATED
Example #30
0
 def _more(self):
     chunk = rffi.cast(CLOSURES, alloc(CHUNK))
     count = CHUNK//rffi.sizeof(FFI_CLOSUREP.TO)
     for i in range(count):
         rffi.cast(rffi.VOIDPP, chunk)[0] = self.free_list
         self.free_list = rffi.cast(rffi.VOIDP, chunk)
         chunk = rffi.ptradd(chunk, 1)
Example #31
0
 def _do_getitem(self, ctype, i):
     ctitem = ctype.ctitem
     with self as ptr:
         return ctitem.convert_to_object(
             rffi.ptradd(ptr, i * ctitem.size))
Example #32
0
 def extract_str(bc, off, size):
     assert off > 0 and size >= 0
     return rffi.charpsize2str(rffi.ptradd(bc, off), size)
Example #33
0
def array_setitem_T(TYPE, width, addr, index, offset, value):
    addr = rffi.ptradd(addr, index * width)
    addr = rffi.ptradd(addr, offset)
    rffi.cast(rffi.CArrayPtr(TYPE), addr)[0] = value
Example #34
0
 def get_method(self, space, offset):
     offset_ptr = rffi.ptradd(rffi.cast(rffi.CCHARP, self.ptr), offset)
     raise_if_out_of_bounds(space, offset, self.sizeof_memory, sizeof_type)
     return rw_strategy.read(space, offset_ptr)
Example #35
0
 def execute_libffi(self, space, cif_descr, funcaddr, buffer):
     jit_libffi.jit_ffi_call(cif_descr, funcaddr, buffer)
     result = rffi.ptradd(buffer, cif_descr.exchange_result)
     from pypy.module._cppyy import interp_cppyy
     ptr_result = rffi.cast(capi.C_OBJECT, rffi.cast(rffi.VOIDPP, result)[0])
     return interp_cppyy.wrap_cppinstance(space, ptr_result, self.cppclass)
Example #36
0
File: ffi.py Project: kgann/pixie
 def get_ret_val_from_buffer(self, exb):
     offset_p = rffi.ptradd(exb,
                            jit.promote(self._cd.exchange_result_libffi))
     ret_val = self._ret_type.ffi_get_value(offset_p)
     return ret_val
Example #37
0
def direct_readinto(self, w_rwbuffer):
    rwbuffer = self.space.writebuf_w(w_rwbuffer)
    stream = self.getstream()
    size = rwbuffer.getlength()
    target_address = lltype.nullptr(rffi.CCHARP.TO)
    fd = -1
    target_pos = 0

    if size > 64:
        try:
            target_address = rwbuffer.get_raw_address()
        except ValueError:
            pass
        else:
            fd = stream.try_to_find_file_descriptor()

    if fd < 0 or not target_address:
        # fall-back
        MAX_PART = 1024 * 1024    # 1 MB
        while size > MAX_PART:
            data = self.direct_read(MAX_PART)
            output_slice(self.space, rwbuffer, target_pos, data)
            target_pos += len(data)
            size -= len(data)
            if len(data) != MAX_PART:
                break
        else:
            data = self.direct_read(size)
            output_slice(self.space, rwbuffer, target_pos, data)
            target_pos += len(data)

    else:
        # optimized case: reading more than 64 bytes into a rwbuffer
        # with a valid raw address
        self.check_readable()

        # first "read" the part that is already sitting in buffers, if any
        initial_size = min(size, stream.count_buffered_bytes())
        if initial_size > 0:
            data = stream.read(initial_size)
            output_slice(self.space, rwbuffer, target_pos, data)
            target_pos += len(data)
            size -= len(data)

        # then call c_read() to get the rest
        if size > 0:
            stream.flush()
            while True:
                got = c_read(fd, rffi.ptradd(target_address, target_pos), size)
                got = rffi.cast(lltype.Signed, got)
                if got > 0:
                    target_pos += got
                    size -= got
                    if size <= 0:
                        break
                elif got == 0:
                    break
                else:
                    err = rposix.get_saved_errno()
                    if err == errno.EINTR:
                        signal_checker(self.space)()
                        continue
                    if is_wouldblock_error(err) and target_pos > 0:
                        break
                    raise OSError(err, "read error")
            keepalive_until_here(rwbuffer)

    return self.space.newint(target_pos)
Example #38
0
File: ffi.py Project: kgann/pixie
def pack(ptr, offset):
    affirm(
        isinstance(ptr, VoidP) or isinstance(ptr, Buffer)
        or isinstance(ptr, CStruct), u"Type is not unpackable")
    ptr = rffi.ptradd(ptr.raw_data(), offset.int_val())
    return VoidP(ptr)
Example #39
0
 def next_w(self):
     result = self._next
     if result == self._stop:
         raise OperationError(self.space.w_StopIteration, self.space.w_None)
     self._next = rffi.ptradd(result, self.ctitem.size)
     return self.ctitem.convert_to_object(result)
Example #40
0
 def add(self, cdata, i):
     p = rffi.ptradd(cdata, i * self.ctitem.size)
     return cdataobj.W_CData(self.space, p, self.ctptr)
Example #41
0
def ffiobj_init(ffi, module_name, version, types, w_globals, w_struct_unions,
                w_enums, w_typenames, w_includes):
    space = ffi.space

    # xxx force ll2ctypes conversion here.  This appears to be needed,
    # otherwise ll2ctypes explodes.  I don't want to know :-(
    rffi.cast(lltype.Signed, ffi.ctxobj)

    if version == -1 and not types:
        return
    if not (cffi1_module.VERSION_MIN <= version <= cffi1_module.VERSION_MAX):
        raise oefmt(
            space.w_ImportError,
            "cffi out-of-line Python module '%s' has unknown version %s",
            module_name, hex(version))

    if types:
        # unpack a string of 4-byte entries into an array of _cffi_opcode_t
        n = len(types) // 4
        ntypes = allocate_array(ffi, _CFFI_OPCODE_T, n)
        decoder = StringDecoder(ffi, types)
        for i in range(n):
            ntypes[i] = decoder.next_opcode()
        ffi.ctxobj.ctx.c_types = ntypes
        rffi.setintfield(ffi.ctxobj.ctx, 'c_num_types', n)
        ffi.cached_types = [None] * n

    if w_globals is not None:
        # unpack a tuple alternating strings and ints, each two together
        # describing one global_s entry with no specified address or size.
        # The int is only used with integer constants.
        globals_w = space.fixedview(w_globals)
        n = len(globals_w) // 2
        size = n * rffi.sizeof(GLOBAL_S) + n * rffi.sizeof(CDL_INTCONST_S)
        p = allocate(ffi, size)
        nglobs = rffi.cast(rffi.CArrayPtr(GLOBAL_S), p)
        p = rffi.ptradd(p,
                        llmemory.raw_malloc_usage(n * rffi.sizeof(GLOBAL_S)))
        nintconsts = rffi.cast(rffi.CArrayPtr(CDL_INTCONST_S), p)
        for i in range(n):
            decoder = StringDecoder(ffi, space.bytes_w(globals_w[i * 2]))
            nglobs[i].c_type_op = decoder.next_opcode()
            nglobs[i].c_name = decoder.next_name()
            op = getop(nglobs[i].c_type_op)
            if op == cffi_opcode.OP_CONSTANT_INT or op == cffi_opcode.OP_ENUM:
                w_integer = globals_w[i * 2 + 1]
                ll_set_cdl_realize_global_int(nglobs[i])
                bigint = space.bigint_w(w_integer)
                ullvalue = bigint.ulonglongmask()
                rffi.setintfield(nintconsts[i], 'neg', int(bigint.sign <= 0))
                rffi.setintfield(nintconsts[i], 'value', ullvalue)
        ffi.ctxobj.ctx.c_globals = nglobs
        rffi.setintfield(ffi.ctxobj.ctx, 'c_num_globals', n)

    if w_struct_unions is not None:
        # unpack a tuple of struct/unions, each described as a sub-tuple;
        # the item 0 of each sub-tuple describes the struct/union, and
        # the items 1..N-1 describe the fields, if any
        struct_unions_w = space.fixedview(w_struct_unions)
        n = len(struct_unions_w)
        nftot = 0  # total number of fields
        for i in range(n):
            nftot += space.len_w(struct_unions_w[i]) - 1
        nstructs = allocate_array(ffi, STRUCT_UNION_S, n)
        nfields = allocate_array(ffi, FIELD_S, nftot)
        nf = 0
        for i in range(n):
            # 'desc' is the tuple of strings (desc_struct, desc_field_1, ..)
            desc = space.fixedview(struct_unions_w[i])
            nf1 = len(desc) - 1
            decoder = StringDecoder(ffi, space.bytes_w(desc[0]))
            rffi.setintfield(nstructs[i], 'c_type_index',
                             decoder.next_4bytes())
            flags = decoder.next_4bytes()
            rffi.setintfield(nstructs[i], 'c_flags', flags)
            nstructs[i].c_name = decoder.next_name()
            if flags & (cffi_opcode.F_OPAQUE | cffi_opcode.F_EXTERNAL):
                rffi.setintfield(nstructs[i], 'c_size', -1)
                rffi.setintfield(nstructs[i], 'c_alignment', -1)
                rffi.setintfield(nstructs[i], 'c_first_field_index', -1)
                rffi.setintfield(nstructs[i], 'c_num_fields', 0)
                assert nf1 == 0
            else:
                rffi.setintfield(nstructs[i], 'c_size', -2)
                rffi.setintfield(nstructs[i], 'c_alignment', -2)
                rffi.setintfield(nstructs[i], 'c_first_field_index', nf)
                rffi.setintfield(nstructs[i], 'c_num_fields', nf1)
            for j in range(nf1):
                decoder = StringDecoder(ffi, space.bytes_w(desc[j + 1]))
                # this 'decoder' is for one of the other strings beyond
                # the first one, describing one field each
                type_op = decoder.next_opcode()
                nfields[nf].c_field_type_op = type_op
                rffi.setintfield(nfields[nf], 'c_field_offset', -1)
                if getop(type_op) != cffi_opcode.OP_NOOP:
                    field_size = decoder.next_4bytes()
                else:
                    field_size = -1
                rffi.setintfield(nfields[nf], 'c_field_size', field_size)
                nfields[nf].c_name = decoder.next_name()
                nf += 1
        assert nf == nftot
        ffi.ctxobj.ctx.c_struct_unions = nstructs
        ffi.ctxobj.ctx.c_fields = nfields
        rffi.setintfield(ffi.ctxobj.ctx, 'c_num_struct_unions', n)

    if w_enums:
        # unpack a tuple of strings, each of which describes one enum_s entry
        enums_w = space.fixedview(w_enums)
        n = len(enums_w)
        nenums = allocate_array(ffi, ENUM_S, n)
        for i in range(n):
            decoder = StringDecoder(ffi, space.bytes_w(enums_w[i]))
            rffi.setintfield(nenums[i], 'c_type_index', decoder.next_4bytes())
            rffi.setintfield(nenums[i], 'c_type_prim', decoder.next_4bytes())
            nenums[i].c_name = decoder.next_name()
            nenums[i].c_enumerators = decoder.next_name()
        ffi.ctxobj.ctx.c_enums = nenums
        rffi.setintfield(ffi.ctxobj.ctx, 'c_num_enums', n)

    if w_typenames:
        # unpack a tuple of strings, each of which describes one typename_s
        # entry
        typenames_w = space.fixedview(w_typenames)
        n = len(typenames_w)
        ntypenames = allocate_array(ffi, TYPENAME_S, n)
        for i in range(n):
            decoder = StringDecoder(ffi, space.bytes_w(typenames_w[i]))
            rffi.setintfield(ntypenames[i], 'c_type_index',
                             decoder.next_4bytes())
            ntypenames[i].c_name = decoder.next_name()
        ffi.ctxobj.ctx.c_typenames = ntypenames
        rffi.setintfield(ffi.ctxobj.ctx, 'c_num_typenames', n)

    if w_includes:
        from pypy.module._cffi_backend.ffi_obj import W_FFIObject
        #
        for w_parent_ffi in space.fixedview(w_includes):
            parent_ffi = space.interp_w(W_FFIObject, w_parent_ffi)
            ffi.included_ffis_libs.append((parent_ffi, None))
Example #42
0
 def setslice(self, start, string):
     raw_cdata = rffi.ptradd(self.raw_cdata, start)
     copy_string_to_raw(llstr(string), raw_cdata, 0, len(string))
Example #43
0
 def in_map(m, offset):
     return rffi.ptradd(m.data, offset)
Example #44
0
 def put_method(self, space, offset, w_value):
     offset_ptr = rffi.ptradd(rffi.cast(rffi.CCHARP, self.ptr), offset)
     raise_if_out_of_bounds(space, offset, self.sizeof_memory, sizeof_type)
     rw_strategy.write(space, offset_ptr, w_value)
Example #45
0
 def execute_libffi(self, space, cif_descr, funcaddr, buffer):
     if hasattr(space, "fake"):
         raise NotImplementedError
     jit_libffi.jit_ffi_call(cif_descr, funcaddr, buffer)
     result = rffi.ptradd(buffer, cif_descr.exchange_result)
     return self.wrap_result(space, rffi.cast(rffi.LONGP, result)[0])
Example #46
0
 def getslice(self, start, stop, step, size):
     if step == 1:
         return rffi.charpsize2str(rffi.ptradd(self.raw_cdata, start), size)
     return RawBuffer.getslice(self, start, stop, step, size)
Example #47
0
 def get_raw_address(self):
     ba = self.ba
     p = nonmoving_raw_ptr_for_resizable_list(ba._data)
     p = rffi.ptradd(p, ba._offset)
     return p
Example #48
0
 def execute_libffi(self, space, cif_descr, funcaddr, buffer):
     jit_libffi.jit_ffi_call(cif_descr, funcaddr, buffer)
     result = rffi.ptradd(buffer, cif_descr.exchange_result)
     return self._wrap_object(space, rffi.cast(self.c_ptrtype, result)[0])
Example #49
0
 def f(p):
     c(rffi.ptradd(p, 0))
     lltype.free(p, flavor='raw')
Example #50
0
def _operate(stream, data, flush, max_length, cfunc, while_doing):
    """Common code for compress() and decompress().
    """
    # Prepare the input buffer for the stream
    assert data is not None
    with rffi.scoped_nonmovingbuffer(data) as inbuf:
        stream.c_next_in = rffi.cast(Bytefp, inbuf)
        end_inbuf = rffi.ptradd(stream.c_next_in, len(data))

        # Prepare the output buffer
        with lltype.scoped_alloc(rffi.CCHARP.TO, OUTPUT_BUFFER_SIZE) as outbuf:
            # Strategy: we call deflate() to get as much output data as fits in
            # the buffer, then accumulate all output into a StringBuffer
            # 'result'.
            result = StringBuilder()

            while True:
                avail_in = ptrdiff(end_inbuf, stream.c_next_in)
                if avail_in > INPUT_BUFFER_MAX:
                    avail_in = INPUT_BUFFER_MAX
                rffi.setintfield(stream, 'c_avail_in', avail_in)

                stream.c_next_out = rffi.cast(Bytefp, outbuf)
                bufsize = OUTPUT_BUFFER_SIZE
                if max_length < bufsize:
                    if max_length <= 0:
                        err = Z_OK
                        break
                    bufsize = max_length
                max_length -= bufsize
                rffi.setintfield(stream, 'c_avail_out', bufsize)

                err = cfunc(stream, flush)

                if err == Z_OK or err == Z_STREAM_END:
                    # accumulate data into 'result'
                    avail_out = rffi.cast(lltype.Signed, stream.c_avail_out)
                    result.append_charpsize(outbuf, bufsize - avail_out)
                    # if the output buffer is full, there might be more data
                    # so we need to try again.  Otherwise, we're done.
                    if avail_out > 0:
                        break
                    # We're also done if we got a Z_STREAM_END (which should
                    # only occur when flush == Z_FINISH).
                    if err == Z_STREAM_END:
                        break
                    else:
                        continue
                elif err == Z_BUF_ERROR:
                    avail_out = rffi.cast(lltype.Signed, stream.c_avail_out)
                    # When compressing, we will only get Z_BUF_ERROR if
                    # the output buffer was full but there wasn't more
                    # output when we tried again, so it is not an error
                    # condition.
                    if avail_out == bufsize:
                        break

                # fallback case: report this error
                raise RZlibError.fromstream(stream, err, while_doing)

    # When decompressing, if the compressed stream of data was truncated,
    # then the zlib simply returns Z_OK and waits for more.  If it is
    # complete it returns Z_STREAM_END.
    avail_in = ptrdiff(end_inbuf, stream.c_next_in)
    return (result.build(), err, avail_in)
Example #51
0
def array_getitem_T(TYPE, width, addr, index, offset):
    addr = rffi.ptradd(addr, index * width)
    addr = rffi.ptradd(addr, offset)
    return rffi.cast(rffi.CArrayPtr(TYPE), addr)[0]
Example #52
0
 def buffer_advance(self, n):
     self.ll_buffer = rffi.ptradd(self.ll_buffer, n)
Example #53
0
 def get_raw_address(self):
     from rpython.rtyper.lltypesystem import rffi
     ptr = self.buffer.get_raw_address()
     return rffi.ptradd(ptr, self.offset)
Example #54
0
 def get_raw_address(self):
     from rpython.rtyper.lltypesystem import rffi
     offset = self.start * self.parent.getstrides()[0]
     return rffi.ptradd(self.parent.get_raw_address(), offset)
Example #55
0
 def execute_libffi(self, space, cif_descr, funcaddr, buffer):
     jit_libffi.jit_ffi_call(cif_descr, funcaddr, buffer)
     presult = rffi.ptradd(buffer, cif_descr.exchange_result)
     obj = rffi.cast(capi.C_OBJECT, rffi.cast(rffi.VOIDPP, presult)[0])
     return self._wrap_result(space, obj)
Example #56
0
 def setslice(self, index, s):
     assert s is not None
     ptr = rffi.ptradd(cts.cast('char *', self.view.ptr), index)
     rffi.str2chararray(s, ptr, len(s))
Example #57
0
 def write_raw_complex_data(self, real, imag):
     with self as ptr:
         halfsize = self.ctype.size >> 1
         ptr2 = rffi.ptradd(ptr, halfsize)
         misc.write_raw_float_data(ptr, real, halfsize)
         misc.write_raw_float_data(ptr2, imag, halfsize)
Example #58
0
 def getslice(self, start, stop, step, size):
     assert step == 1
     assert stop - start == size
     ptr = rffi.ptradd(cts.cast('char *', self.view.ptr), start)
     return rffi.charpsize2str(ptr, size)
Example #59
0
def exchange_address(ptr, cif_descr, index):
    return rffi.ptradd(ptr, cif_descr.exchange_args[index])
Example #60
0
File: ffi.py Project: kgann/pixie
 def get_item(self, nm):
     (tp, offset) = self._type.get_desc(nm)
     ptr = rffi.ptradd(self._buffer, offset)
     return tp.ffi_load_from(ptr)