Exemple #1
0
    def _invoke(self, args):
        arity = len(args)
        tp_arity = len(self._c_fn_type._arg_types)
        if self._c_fn_type._is_variadic:
            if arity < tp_arity:
                runtime_error(u"Wrong number of args to fn: got " +
                              unicode(str(arity)) + u", expected at least " +
                              unicode(str(tp_arity)))
        else:
            if arity != tp_arity:
                runtime_error(u"Wrong number of args to fn: got " +
                              unicode(str(arity)) + u", expected " +
                              unicode(str(tp_arity)))

        exb, tokens = self.prep_exb(args)
        cd = jit.promote(self._c_fn_type.get_cd())
        #fp = jit.promote(self._f_ptr)
        jit_ffi_call(cd, self._f_ptr, exb)
        ret_val = self.get_ret_val_from_buffer(exb)

        for x in range(len(args)):
            t = tokens[x]
            if t is not None:
                t.finalize_token()

        lltype.free(exb, flavor="raw")
        keepalive_until_here(args)
        return ret_val
Exemple #2
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
Exemple #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

            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
Exemple #4
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_cppobject(space, ptr_result, self.cppclass)
Exemple #5
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?
             # array handling is wrong.
             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
Exemple #6
0
    def _invoke(self, args):
        arity = len(args)
        tp_arity = len(self._c_fn_type._arg_types)
        if self._c_fn_type._is_variadic:
            if arity < tp_arity:
                runtime_error(u"Wrong number of args to fn: got " + unicode(str(arity)) +
                    u", expected at least " + unicode(str(tp_arity)))
        else:
            if arity != tp_arity:
                runtime_error(u"Wrong number of args to fn: got " + unicode(str(arity)) +
                    u", expected " + unicode(str(tp_arity)))

        exb, tokens = self.prep_exb(args)
        cd = jit.promote(self._c_fn_type.get_cd())
        #fp = jit.promote(self._f_ptr)
        jit_ffi_call(cd,
                     self._f_ptr,
                     exb)
        ret_val = self.get_ret_val_from_buffer(exb)

        for x in range(len(args)):
            t = tokens[x]
            if t is not None:
                t.finalize_token()

        lltype.free(exb, flavor="raw")
        keepalive_until_here(args)
        return ret_val
Exemple #7
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
Exemple #8
0
def test_jit_ffi_call():
    cd = lltype.malloc(CIF_DESCRIPTION, 1, flavor='raw')
    cd.abi = clibffi.FFI_DEFAULT_ABI
    cd.nargs = 1
    cd.rtype = clibffi.cast_type_to_ffitype(rffi.DOUBLE)
    atypes = lltype.malloc(clibffi.FFI_TYPE_PP.TO, 1, flavor='raw')
    atypes[0] = clibffi.cast_type_to_ffitype(rffi.DOUBLE)
    cd.atypes = atypes
    cd.exchange_size = 64  # 64 bytes of exchange data
    cd.exchange_result = 24
    cd.exchange_args[0] = 16
    #
    jit_ffi_prep_cif(cd)
    #
    assert rffi.sizeof(rffi.DOUBLE) == 8
    exb = lltype.malloc(rffi.DOUBLEP.TO, 8, flavor='raw')
    exb[2] = 1.23
    jit_ffi_call(cd, math_sin, rffi.cast(rffi.CCHARP, exb))
    res = exb[3]
    lltype.free(exb, flavor='raw')
    #
    lltype.free(atypes, flavor='raw')
    lltype.free(cd, flavor='raw')
    #
    assert res == math.sin(1.23)
Exemple #9
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
Exemple #10
0
def test_jit_ffi_call():
    cd = lltype.malloc(CIF_DESCRIPTION, 1, flavor='raw')
    cd.abi = clibffi.FFI_DEFAULT_ABI
    cd.nargs = 1
    cd.rtype = clibffi.cast_type_to_ffitype(rffi.DOUBLE)
    atypes = lltype.malloc(clibffi.FFI_TYPE_PP.TO, 1, flavor='raw')
    atypes[0] = clibffi.cast_type_to_ffitype(rffi.DOUBLE)
    cd.atypes = atypes
    cd.exchange_size = 64    # 64 bytes of exchange data
    cd.exchange_result = 24
    cd.exchange_args[0] = 16
    #
    jit_ffi_prep_cif(cd)
    #
    assert rffi.sizeof(rffi.DOUBLE) == 8
    exb = lltype.malloc(rffi.DOUBLEP.TO, 8, flavor='raw')
    exb[2] = 1.23
    jit_ffi_call(cd, math_sin, rffi.cast(rffi.CCHARP, exb))
    res = exb[3]
    lltype.free(exb, flavor='raw')
    #
    lltype.free(atypes, flavor='raw')
    lltype.free(cd, flavor='raw')
    #
    assert res == math.sin(1.23)
Exemple #11
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
Exemple #12
0
    def _invoke(self, args):

        exb = self.prep_exb(args)
        jit_ffi_call(self._cd, self._f_ptr, exb)
        ret_val = self.get_ret_val_from_buffer(exb)
        lltype.free(exb, flavor="raw")
        return ret_val
Exemple #13
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
Exemple #14
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
Exemple #15
0
    def _call(self, funcaddr, args_w):
        space = self.space
        cif_descr = self.cif_descr  # 'self' should have been promoted here
        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
Exemple #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_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
Exemple #17
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
Exemple #18
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
 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
 def f():
     #
     jit_ffi_prep_cif(cd)
     #
     assert rffi.sizeof(rffi.DOUBLE) == 8
     exb = lltype.malloc(rffi.DOUBLEP.TO, 8, flavor='raw')
     exb[2] = 1.23
     jit_ffi_call(cd, math_sin, rffi.cast(rffi.CCHARP, exb))
     res = exb[3]
     lltype.free(exb, flavor='raw')
     #
     return res
Exemple #21
0
 def f():
     #
     jit_ffi_prep_cif(cd)
     #
     assert rffi.sizeof(rffi.DOUBLE) == 8
     exb = lltype.malloc(rffi.DOUBLEP.TO, 8, flavor='raw')
     exb[2] = 1.23
     jit_ffi_call(cd, math_sin, rffi.cast(rffi.CCHARP, exb))
     res = exb[3]
     lltype.free(exb, flavor='raw')
     #
     return res
Exemple #22
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
Exemple #23
0
    def _invoke(self, args):

        exb, tokens = self.prep_exb(args)
        jit_ffi_call(self._cd, self._f_ptr, exb)
        ret_val = self.get_ret_val_from_buffer(exb)

        for x in range(len(args)):
            t = tokens[x]
            if t is not None:
                t.finalize_token()

        lltype.free(exb, flavor="raw")
        return ret_val
Exemple #24
0
    def _invoke(self, args):

        exb, tokens = self.prep_exb(args)
        jit_ffi_call(self._cd, self._f_ptr, exb)
        ret_val = self.get_ret_val_from_buffer(exb)

        for x in range(len(args)):
            t = tokens[x]
            if t is not None:
                t.finalize_token()

        lltype.free(exb, flavor="raw")
        return ret_val
Exemple #25
0
    def _call(self, funcaddr, args_w):
        space = self.space
        cif_descr = self.cif_descr   # 'self' should have been promoted here
        size = cif_descr.exchange_size
        mustfree_max_plus_1 = 0
        buffer = lltype.malloc(rffi.CCHARP.TO, size, flavor='raw')
        try:
            keepalives = [None] * len(args_w)    # None or strings
            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,
                                                        keepalives, i):
                    # 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)
                    raw_cdata = rffi.cast(rffi.CCHARPP, data)[0]
                    if flag == 1:
                        lltype.free(raw_cdata, flavor='raw')
                    elif flag >= 4:
                        value = keepalives[i]
                        assert value is not None
                        rffi.free_nonmovingbuffer(value, raw_cdata, chr(flag))
            lltype.free(buffer, flavor='raw')
            keepalive_until_here(args_w)
        return w_res
Exemple #26
0
        def f():
            exbuf = lltype.malloc(rffi.CCHARP.TO, (len(avalues)+2) * 16,
                                  flavor='raw', zero=True)
            ofs = 16
            for avalue in unroll_avalues:
                TYPE = rffi.CArray(lltype.typeOf(avalue))
                data = rffi.ptradd(exbuf, ofs)
                rffi.cast(lltype.Ptr(TYPE), data)[0] = avalue
                ofs += 16

            jit_ffi_call(cif_description, func_addr, exbuf)

            if rvalue is None:
                res = 654321
            else:
                TYPE = rffi.CArray(lltype.typeOf(rvalue))
                data = rffi.ptradd(exbuf, ofs)
                res = rffi.cast(lltype.Ptr(TYPE), data)[0]
            lltype.free(exbuf, flavor='raw')
            if lltype.typeOf(res) is lltype.SingleFloat:
                res = float(res)
            return res
Exemple #27
0
def builtin_ffi_call(ctx):
    # parameter validation
    assert len(ctx.params) == 3 and \
            ctx.params[0].type == 'str' and \
            ctx.params[1].type == 'str' and \
            ctx.params[2].type == 'array'

    # extract parameters
    libname = ctx.params[0].strvalue
    symname = ctx.params[1].strvalue
    args = ctx.params[2].arrayvalue
    lib = ctx.machine.space.ffi_libs[libname].lib
    ff = ctx.machine.space.ffi_functions[(libname, symname)]
    cif = ff.cif
    func = rdynload.dlsym(lib, rffi.str2charp(symname))

    # prepare exchange
    exc = lltype.malloc(rffi.VOIDP.TO, cif.exchange_size, flavor='raw')

    # cast ao val to ffi val
    ptr = exc
    for i in range(cif.nargs):
        ptr = rffi.ptradd(exc, cif.exchange_args[i])
        _cast_aovalue_to_ffivalue(ctx.machine.space, args[i], ff.atypes[i],
                                  ptr)

    # ffi call
    jit_libffi.jit_ffi_call(cif, func, exc)

    # cast ffi val back to ao val
    ptr = rffi.ptradd(exc, cif.exchange_result)
    val = _cast_ffivalue_to_aovalue(ctx.machine.space, ptr, ff.rtype)

    # free exc
    lltype.free(exc, flavor='raw')

    # return val
    ctx.tos.push(val)
Exemple #28
0
        def f(i):
            exbuf = lltype.malloc(rffi.CCHARP.TO, (len(avalues)+2) * 16,
                                  flavor='raw')

            targetptr = rffi.ptradd(exbuf, 16)
            for avalue in unroll_avalues:
                TYPE = rffi.CArray(lltype.typeOf(avalue))
                if i >= 9:    # a guard that can fail
                    pass
                rffi.cast(lltype.Ptr(TYPE), targetptr)[0] = avalue
                targetptr = rffi.ptradd(targetptr, 16)

            jit_ffi_call(cif_description, func_addr, exbuf)

            if rvalue is None:
                res = 654321
            else:
                TYPE = rffi.CArray(lltype.typeOf(rvalue))
                res = rffi.cast(lltype.Ptr(TYPE), targetptr)[0]
            lltype.free(exbuf, flavor='raw')
            if lltype.typeOf(res) is lltype.SingleFloat:
                res = float(res)
            return res
        def f(i):
            exbuf = lltype.malloc(rffi.CCHARP.TO, (len(avalues) + 2) * 16,
                                  flavor='raw')

            targetptr = rffi.ptradd(exbuf, 16)
            for avalue in unroll_avalues:
                TYPE = rffi.CArray(lltype.typeOf(avalue))
                if i >= 9:  # a guard that can fail
                    pass
                rffi.cast(lltype.Ptr(TYPE), targetptr)[0] = avalue
                targetptr = rffi.ptradd(targetptr, 16)

            jit_ffi_call(cif_description, func_addr, exbuf)

            if rvalue is None:
                res = 654321
            else:
                TYPE = rffi.CArray(lltype.typeOf(rvalue))
                res = rffi.cast(lltype.Ptr(TYPE), targetptr)[0]
            lltype.free(exbuf, flavor='raw')
            if lltype.typeOf(res) is lltype.SingleFloat:
                res = float(res)
            return res
Exemple #30
0
 def execute_libffi(self, space, cif_descr, funcaddr, buffer):
     jit_libffi.jit_ffi_call(cif_descr, funcaddr, buffer)
     return space.w_None
Exemple #31
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])
Exemple #32
0
 def execute_libffi(self, space, cif_descr, funcaddr, buf):
     jit_libffi.jit_ffi_call(cif_descr, funcaddr, buf)
     result = rffi.ptradd(buf, cif_descr.exchange_result)
     return self._convert2complex(
         space, rffi.cast(capi.C_OBJECT,
                          rffi.cast(rffi.VOIDPP, result)[0]))
Exemple #33
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])
Exemple #34
0
 def execute_libffi(self, space, cif_descr, funcaddr, buffer):
     jit_libffi.jit_ffi_call(cif_descr, funcaddr, buffer)
     return space.w_None
Exemple #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_cppobject(space, ptr_result, self.cppclass)
Exemple #36
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)
Exemple #37
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
Exemple #38
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])
Exemple #39
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])
Exemple #40
0
 def execute_libffi(self, space, cif_descr, funcaddr, buf):
     jit_libffi.jit_ffi_call(cif_descr, funcaddr, buf)
     result = rffi.ptradd(buf, cif_descr.exchange_result)
     return self._wrap_reference(
         space, rffi.cast(self.c_ptrtype,
                          rffi.cast(rffi.VOIDPP, result)[0]))
Exemple #41
0
 def execute_libffi(self, space, cif_descr, funcaddr, buf):
     jit_libffi.jit_ffi_call(cif_descr, funcaddr, buf)
     vptr = rffi.ptradd(buf, cif_descr.exchange_result)
     lres = rffi.cast(rffi.LONG, rffi.cast(rffi.LONGP, vptr)[0])
     return self._wrap_object(space, lres)