Beispiel #1
0
def new_function_type(space, w_fargs, w_fresult, ellipsis=0):
    from pypy.module._cffi_backend import ctypefunc
    fargs = []
    for w_farg in space.fixedview(w_fargs):
        if not isinstance(w_farg, ctypeobj.W_CType):
            raise OperationError(
                space.w_TypeError,
                space.wrap("first arg must be a tuple of ctype objects"))
        if isinstance(w_farg, ctypearray.W_CTypeArray):
            w_farg = w_farg.ctptr
        fargs.append(w_farg)
    #
    if ((w_fresult.size < 0
         and not isinstance(w_fresult, ctypevoid.W_CTypeVoid))
            or isinstance(w_fresult, ctypearray.W_CTypeArray)):
        if (isinstance(w_fresult, ctypestruct.W_CTypeStructOrUnion)
                and w_fresult.size < 0):
            raise oefmt(space.w_TypeError, "result type '%s' is opaque",
                        w_fresult.name)
        else:
            raise oefmt(space.w_TypeError, "invalid result type: '%s'",
                        w_fresult.name)
    #
    fct = ctypefunc.W_CTypeFunc(space, fargs, w_fresult, ellipsis)
    return fct
Beispiel #2
0
def _build_function_type(space, fargs, fresult, ellipsis, abi):
    from pypy.module._cffi_backend import ctypefunc
    #
    if ((fresult.size < 0 and not isinstance(fresult, ctypevoid.W_CTypeVoid))
            or isinstance(fresult, ctypearray.W_CTypeArray)):
        if (isinstance(fresult, ctypestruct.W_CTypeStructOrUnion)
                and fresult.size < 0):
            raise oefmt(space.w_TypeError, "result type '%s' is opaque",
                        fresult.name)
        else:
            raise oefmt(space.w_TypeError, "invalid result type: '%s'",
                        fresult.name)
    #
    fct = ctypefunc.W_CTypeFunc(space, fargs, fresult, ellipsis, abi)
    unique_cache = space.fromcache(UniqueCache)
    func_hash = _func_key_hash(unique_cache, fargs, fresult, ellipsis, abi)
    for weakdict in unique_cache.functions:
        if weakdict.get(func_hash) is None:
            weakdict.set(func_hash, fct)
            break
    else:
        weakdict = rweakref.RWeakValueDictionary(int, ctypefunc.W_CTypeFunc)
        unique_cache.functions.append(weakdict)
        weakdict.set(func_hash, fct)
    return fct
Beispiel #3
0
def _build_function_type(space, fargs, fresult, ellipsis, abi):
    from pypy.module._cffi_backend import ctypefunc
    #
    if ((fresult.size < 0 and not isinstance(fresult, ctypevoid.W_CTypeVoid))
            or isinstance(fresult, ctypearray.W_CTypeArray)):
        if (isinstance(fresult, ctypestruct.W_CTypeStructOrUnion)
                and fresult.size < 0):
            raise oefmt(space.w_TypeError, "result type '%s' is opaque",
                        fresult.name)
        else:
            raise oefmt(space.w_TypeError, "invalid result type: '%s'",
                        fresult.name)
    #
    fct = ctypefunc.W_CTypeFunc(space, fargs, fresult, ellipsis, abi)
    unique_cache = space.fromcache(UniqueCache)
    _record_function_type(unique_cache, fct)
    return fct
Beispiel #4
0
def _new_function_type(space, fargs, w_fresult, ellipsis=False):
    from pypy.module._cffi_backend import ctypefunc
    #
    unique_cache = space.fromcache(UniqueCache)
    unique_key = (fargs, w_fresult, ellipsis)
    try:
        return unique_cache.functions[unique_key]
    except KeyError:
        pass
    #
    if ((w_fresult.size < 0
         and not isinstance(w_fresult, ctypevoid.W_CTypeVoid))
            or isinstance(w_fresult, ctypearray.W_CTypeArray)):
        if (isinstance(w_fresult, ctypestruct.W_CTypeStructOrUnion)
                and w_fresult.size < 0):
            raise oefmt(space.w_TypeError, "result type '%s' is opaque",
                        w_fresult.name)
        else:
            raise oefmt(space.w_TypeError, "invalid result type: '%s'",
                        w_fresult.name)
    #
    fct = ctypefunc.W_CTypeFunc(space, fargs, w_fresult, ellipsis)
    unique_cache.functions[unique_key] = fct
    return fct
Beispiel #5
0
def tf1_tf1(space, w_self, args_w):
    """Pythonized version of TF1 constructor:
    takes functions and callable objects, and allows a callback into them."""

    from pypy.module.cppyy import interp_cppyy
    tf1_class = interp_cppyy.scope_byname(space, "TF1")

    # expected signature:
    #  1. (char* name, pyfunc, double xmin, double xmax, int npar = 0)
    argc = len(args_w)

    try:
        if argc < 4 or 5 < argc:
            raise TypeError("wrong number of arguments")

        # first argument must be a name
        funcname = space.str_w(args_w[0])

        # last (optional) argument is number of parameters
        npar = 0
        if argc == 5: npar = space.int_w(args_w[4])

        # second argument must be a callable python object
        w_callable = args_w[1]
        if not space.is_true(space.callable(w_callable)):
            raise TypeError("2nd argument is not a valid python callable")

        # generate a pointer to function
        from pypy.module._cffi_backend import newtype, ctypefunc, func

        c_double = newtype.new_primitive_type(space, 'double')
        c_doublep = newtype.new_pointer_type(space, c_double)

        # wrap the callable as the signature needs modifying
        w_ifunc = interp_cppyy.get_interface_func(space, w_callable, npar)

        w_cfunc = ctypefunc.W_CTypeFunc(space, [c_doublep, c_doublep],
                                        c_double, False)
        w_callback = func.callback(space, w_cfunc, w_ifunc, None)
        funcaddr = rffi.cast(rffi.ULONG, w_callback.get_closure())

        # so far, so good; leaves on issue: CINT is expecting a wrapper, but
        # we need the overload that takes a function pointer, which is not in
        # the dictionary, hence this helper:
        newinst = _create_tf1(space.str_w(args_w[0]), funcaddr,
                              space.float_w(args_w[2]),
                              space.float_w(args_w[3]), npar)

        # w_self is a null-ptr bound as TF1
        from pypy.module.cppyy.interp_cppyy import W_CPPInstance, memory_regulator
        cppself = space.interp_w(W_CPPInstance, w_self, can_be_None=False)
        cppself._rawobject = newinst
        memory_regulator.register(cppself)

        # tie all the life times to the TF1 instance
        space.setattr(w_self, space.wrap('_callback'), w_callback)

        # by definition for __init__
        return None

    except (OperationError, TypeError, IndexError), e:
        newargs_w = args_w[1:]  # drop class