示例#1
0
 def prepare_nostruct_fnptr(self, ffi):
     # tweaked version: instead of returning the ctfuncptr
     # corresponding exactly to the OP_FUNCTION ... OP_FUNCTION_END
     # opcodes, this builds in self.nostruct_ctype another one in
     # which the struct args are replaced with ptr-to- struct, and
     # a struct return value is replaced with a hidden first arg of
     # type ptr-to-struct.  This is how recompiler.py produces
     # trampoline functions for PyPy.
     if self.nostruct_ctype is None:
         fargs, fret, ellipsis, abi = self._unpack(ffi)
         # 'locs' will be a string of the same length as the final fargs,
         # containing 'A' where a struct argument was detected, and 'R'
         # in first position if a struct return value was detected
         locs = ['\x00'] * len(fargs)
         for i in range(len(fargs)):
             farg = fargs[i]
             if isinstance(farg, ctypestruct.W_CTypeStructOrUnion):
                 farg = newtype.new_pointer_type(ffi.space, farg)
                 fargs[i] = farg
                 locs[i] = 'A'
         if isinstance(fret, ctypestruct.W_CTypeStructOrUnion):
             fret = newtype.new_pointer_type(ffi.space, fret)
             fargs = [fret] + fargs
             locs = ['R'] + locs
             fret = newtype.new_void_type(ffi.space)
         ctfuncptr = newtype._new_function_type(
             ffi.space, fargs, fret, ellipsis, abi)
         if locs == ['\x00'] * len(locs):
             locs = None
         else:
             locs = ''.join(locs)
         self.nostruct_ctype = ctfuncptr
         self.nostruct_locs = locs
         self.nostruct_nargs = len(ctfuncptr.fargs) - (locs is not None and
                                                       locs[0] == 'R')
示例#2
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
示例#3
0
def realize_c_type_or_func(ffi, opcodes, index):
    op = opcodes[index]

    from_ffi = (opcodes == ffi.ctxobj.ctx.c_types)
    if from_ffi and ffi.cached_types[index] is not None:
        return ffi.cached_types[index]

    case = getop(op)

    if case == cffi_opcode.OP_PRIMITIVE:
        x = get_primitive_type(ffi, getarg(op))

    elif case == cffi_opcode.OP_POINTER:
        y = realize_c_type_or_func(ffi, opcodes, getarg(op))
        if isinstance(y, W_CType):
            x = newtype.new_pointer_type(ffi.space, y)
        elif isinstance(y, W_RawFuncType):
            x = y.unwrap_as_fnptr(ffi)
        else:
            raise NotImplementedError

    elif case == cffi_opcode.OP_ARRAY:
        x = get_array_type(ffi, opcodes, getarg(op),
                           rffi.cast(rffi.SIGNED, opcodes[index + 1]))

    elif case == cffi_opcode.OP_OPEN_ARRAY:
        x = get_array_type(ffi, opcodes, getarg(op), -1)

    elif case == cffi_opcode.OP_STRUCT_UNION:
        x = _realize_c_struct_or_union(ffi, getarg(op))

    elif case == cffi_opcode.OP_ENUM:
        x = _realize_c_enum(ffi, getarg(op))

    elif case == cffi_opcode.OP_FUNCTION:
        x = W_RawFuncType(opcodes, index)

    elif case == cffi_opcode.OP_NOOP:
        x = realize_c_type_or_func(ffi, opcodes, getarg(op))

    elif case == cffi_opcode.OP_TYPENAME:
        # essential: the TYPENAME opcode resolves the type index looked
        # up in the 'ctx.c_typenames' array, but it does so in 'ctx.c_types'
        # instead of in 'opcodes'!
        type_index = rffi.getintfield(ffi.ctxobj.ctx.c_typenames[getarg(op)],
                                      'c_type_index')
        x = realize_c_type_or_func(ffi, ffi.ctxobj.ctx.c_types, type_index)

    else:
        raise oefmt(ffi.space.w_NotImplementedError, "op=%d", case)

    if from_ffi:
        assert ffi.cached_types[index] is None or ffi.cached_types[index] is x
        ffi.cached_types[index] = x

    return x
示例#4
0
文件: ffi_obj.py 项目: Qointum/pypy
    def descr_addressof(self, w_arg, args_w):
        """\
Limited equivalent to the '&' operator in C:

1. ffi.addressof(<cdata 'struct-or-union'>) returns a cdata that is a
pointer to this struct or union.

2. ffi.addressof(<cdata>, field-or-index...) returns the address of a
field or array item inside the given structure or array, recursively
in case of nested structures or arrays.

3. ffi.addressof(<library>, "name") returns the address of the named
function or global variable."""
        #
        from pypy.module._cffi_backend.lib_obj import W_LibObject

        space = self.space
        if isinstance(w_arg, W_LibObject) and len(args_w) == 1:
            # case 3 in the docstring
            return w_arg.address_of_func_or_global_var(space.str_w(args_w[0]))
        #
        w_ctype = self.ffi_type(w_arg, ACCEPT_CDATA)
        if len(args_w) == 0:
            # case 1 in the docstring
            if not isinstance(w_ctype, ctypestruct.W_CTypeStructOrUnion) and not isinstance(
                w_ctype, ctypearray.W_CTypeArray
            ):
                raise oefmt(space.w_TypeError, "expected a cdata struct/union/array object")
            offset = 0
        else:
            # case 2 in the docstring
            if (
                not isinstance(w_ctype, ctypestruct.W_CTypeStructOrUnion)
                and not isinstance(w_ctype, ctypearray.W_CTypeArray)
                and not isinstance(w_ctype, ctypeptr.W_CTypePointer)
            ):
                raise oefmt(space.w_TypeError, "expected a cdata struct/union/array/pointer object")
            if len(args_w) == 1:
                w_ctype, offset = w_ctype.direct_typeoffsetof(args_w[0], False)
            else:
                w_ctype, offset = self._more_addressof(args_w, w_ctype)
        #
        assert isinstance(w_arg, W_CData)
        cdata = w_arg.unsafe_escaping_ptr()
        cdata = rffi.ptradd(cdata, offset)
        w_ctypeptr = newtype.new_pointer_type(space, w_ctype)
        return W_CData(space, cdata, w_ctypeptr)
示例#5
0
    def descr_addressof(self, w_arg, args_w):
        """\
Limited equivalent to the '&' operator in C:

1. ffi.addressof(<cdata 'struct-or-union'>) returns a cdata that is a
pointer to this struct or union.

2. ffi.addressof(<cdata>, field-or-index...) returns the address of a
field or array item inside the given structure or array, recursively
in case of nested structures or arrays.

3. ffi.addressof(<library>, "name") returns the address of the named
function or global variable."""
        #
        from pypy.module._cffi_backend.lib_obj import W_LibObject
        space = self.space
        if isinstance(w_arg, W_LibObject) and len(args_w) == 1:
            # case 3 in the docstring
            return w_arg.address_of_func_or_global_var(space.text_w(args_w[0]))
        #
        w_ctype = self.ffi_type(w_arg, ACCEPT_CDATA)
        if len(args_w) == 0:
            # case 1 in the docstring
            if (not isinstance(w_ctype, ctypestruct.W_CTypeStructOrUnion)
                    and not isinstance(w_ctype, ctypearray.W_CTypeArray)):
                raise oefmt(space.w_TypeError,
                            "expected a cdata struct/union/array object")
            offset = 0
        else:
            # case 2 in the docstring
            if (not isinstance(w_ctype, ctypestruct.W_CTypeStructOrUnion)
                    and not isinstance(w_ctype, ctypearray.W_CTypeArray)
                    and not isinstance(w_ctype, ctypeptr.W_CTypePointer)):
                raise oefmt(
                    space.w_TypeError,
                    "expected a cdata struct/union/array/pointer object")
            if len(args_w) == 1:
                w_ctype, offset = w_ctype.direct_typeoffsetof(args_w[0], False)
            else:
                w_ctype, offset = self._more_addressof(args_w, w_ctype)
        #
        assert isinstance(w_arg, W_CData)
        cdata = w_arg.unsafe_escaping_ptr()
        cdata = rffi.ptradd(cdata, offset)
        w_ctypeptr = newtype.new_pointer_type(space, w_ctype)
        return W_CData(space, cdata, w_ctypeptr)
示例#6
0
def get_array_type(ffi, opcodes, itemindex, length):
    w_ctitem = realize_c_type(ffi, opcodes, itemindex)
    w_ctitemptr = newtype.new_pointer_type(ffi.space, w_ctitem)
    return newtype._new_array_type(ffi.space, w_ctitemptr, length)
示例#7
0
def realize_c_type_or_func(ffi, opcodes, index):
    op = opcodes[index]

    from_ffi = (opcodes == ffi.ctxobj.ctx.c_types)
    if from_ffi and ffi.cached_types[index] is not None:
        return ffi.cached_types[index]

    case = getop(op)

    if case == cffi_opcode.OP_PRIMITIVE:
        x = get_primitive_type(ffi, getarg(op))

    elif case == cffi_opcode.OP_POINTER:
        y = realize_c_type_or_func(ffi, opcodes, getarg(op))
        if isinstance(y, W_CType):
            x = newtype.new_pointer_type(ffi.space, y)
        elif isinstance(y, W_RawFuncType):
            x = y.unwrap_as_fnptr(ffi)
        else:
            raise NotImplementedError

    elif case == cffi_opcode.OP_ARRAY:
        x = get_array_type(ffi, opcodes, getarg(op),
                           rffi.cast(rffi.SIGNED, opcodes[index + 1]))

    elif case == cffi_opcode.OP_OPEN_ARRAY:
        x = get_array_type(ffi, opcodes, getarg(op), -1)

    elif case == cffi_opcode.OP_STRUCT_UNION:
        x = _realize_c_struct_or_union(ffi, getarg(op))
示例#8
0
    def __init__(self, space):
        self.library = None
        self.capi_calls = {}

        import pypy.module._cffi_backend.newtype as nt

        # TODO: the following need to match up with the globally defined C_XYZ low-level
        # types (see capi/__init__.py), but by using strings here, that isn't guaranteed
        c_opaque_ptr = nt.new_primitive_type(space, 'unsigned long')
 
        c_scope  = c_opaque_ptr
        c_type   = c_scope
        c_object = c_opaque_ptr
        c_method = c_opaque_ptr
        c_index  = nt.new_primitive_type(space, 'long')

        c_void   = nt.new_void_type(space)
        c_char   = nt.new_primitive_type(space, 'char')
        c_uchar  = nt.new_primitive_type(space, 'unsigned char')
        c_short  = nt.new_primitive_type(space, 'short')
        c_int    = nt.new_primitive_type(space, 'int')
        c_long   = nt.new_primitive_type(space, 'long')
        c_llong  = nt.new_primitive_type(space, 'long long')
        c_ullong = nt.new_primitive_type(space, 'unsigned long long')
        c_float  = nt.new_primitive_type(space, 'float')
        c_double = nt.new_primitive_type(space, 'double')

        c_ccharp = nt.new_pointer_type(space, c_char)
        c_index_array = nt.new_pointer_type(space, c_void)

        c_voidp  = nt.new_pointer_type(space, c_void)
        c_size_t = nt.new_primitive_type(space, 'size_t')

        c_ptrdiff_t = nt.new_primitive_type(space, 'ptrdiff_t')

        self.capi_call_ifaces = {
            # name to opaque C++ scope representation
            'num_scopes'               : ([c_scope],                  c_int),
            'scope_name'               : ([c_scope, c_int],           c_ccharp),

            'resolve_name'             : ([c_ccharp],                 c_ccharp),
            'get_scope'                : ([c_ccharp],                 c_scope),
            'get_template'             : ([c_ccharp],                 c_type),
            'actual_class'             : ([c_type, c_object],         c_type),

            # memory management
            'allocate'                 : ([c_type],                   c_object),
            'deallocate'               : ([c_type, c_object],         c_void),
            'destruct'                 : ([c_type, c_object],         c_void),

            # method/function dispatching
            'call_v'       : ([c_method, c_object, c_int, c_voidp],   c_void),
            'call_b'       : ([c_method, c_object, c_int, c_voidp],   c_uchar),
            'call_c'       : ([c_method, c_object, c_int, c_voidp],   c_char),

            'call_h'       : ([c_method, c_object, c_int, c_voidp],   c_short),
            'call_i'       : ([c_method, c_object, c_int, c_voidp],   c_int),
            'call_l'       : ([c_method, c_object, c_int, c_voidp],   c_long),
            'call_ll'      : ([c_method, c_object, c_int, c_voidp],   c_llong),
            'call_f'       : ([c_method, c_object, c_int, c_voidp],   c_float),
            'call_d'       : ([c_method, c_object, c_int, c_voidp],   c_double),

            'call_r'       : ([c_method, c_object, c_int, c_voidp],   c_voidp),
            'call_s'       : ([c_method, c_object, c_int, c_voidp],   c_ccharp),

            'constructor'  : ([c_method, c_object, c_int, c_voidp],   c_object),
            'call_o'       : ([c_method, c_object, c_int, c_voidp, c_type],     c_object),

            'get_methptr_getter'       : ([c_scope, c_index],         c_voidp), # TODO: verify

            # handling of function argument buffer
            'allocate_function_args'   : ([c_int],                    c_voidp),
            'deallocate_function_args' : ([c_voidp],                  c_void),
            'function_arg_sizeof'      : ([],                         c_size_t),
            'function_arg_typeoffset'  : ([],                         c_size_t),

            # scope reflection information
            'is_namespace'             : ([c_scope],                  c_int),
            'is_enum'                  : ([c_ccharp],                 c_int),

            # type/class reflection information
            'final_name'               : ([c_type],                   c_ccharp),
            'scoped_final_name'        : ([c_type],                   c_ccharp),
            'has_complex_hierarchy'    : ([c_type],                   c_int),
            'num_bases'                : ([c_type],                   c_int),
            'base_name'                : ([c_type, c_int],            c_ccharp),
            'is_subtype'               : ([c_type, c_type],           c_int),

            'base_offset'              : ([c_type, c_type, c_object, c_int],    c_ptrdiff_t),

            # method/function reflection information
            'num_methods'              : ([c_scope],                  c_int),
            'method_index_at'          : ([c_scope, c_int],           c_index),
            'method_indices_from_name' : ([c_scope, c_ccharp],        c_index_array),

            'method_name'              : ([c_scope, c_index],         c_ccharp),
            'method_result_type'       : ([c_scope, c_index],         c_ccharp),
            'method_num_args'          : ([c_scope, c_index],         c_int),
            'method_req_args'          : ([c_scope, c_index],         c_int),
            'method_arg_type'          : ([c_scope, c_index, c_int],  c_ccharp),
            'method_arg_default'       : ([c_scope, c_index, c_int],  c_ccharp),
            'method_signature'         : ([c_scope, c_index],         c_ccharp),

            'method_is_template'       : ([c_scope, c_index],         c_int),
            'method_num_template_args' : ([c_scope, c_index],         c_int),
            'method_template_arg_name' : ([c_scope, c_index, c_index],          c_ccharp),

            'get_method'               : ([c_scope, c_index],         c_method),
            'get_global_operator'      : ([c_scope, c_scope, c_scope, c_ccharp],   c_index),

            # method properties
            'is_constructor'           : ([c_type, c_index],          c_int),
            'is_staticmethod'          : ([c_type, c_index],          c_int),

            # data member reflection information
            'num_datamembers'          : ([c_scope],                  c_int),
            'datamember_name'          : ([c_scope, c_int],           c_ccharp),
            'datamember_type'          : ([c_scope, c_int],           c_ccharp),
            'datamember_offset'        : ([c_scope, c_int],           c_ptrdiff_t),

            'datamember_index'         : ([c_scope, c_ccharp],        c_int),

            # data member properties
            'is_publicdata'            : ([c_scope, c_int],           c_int),
            'is_staticdata'            : ([c_scope, c_int],           c_int),

            # misc helpers
            'strtoll'                  : ([c_ccharp],                 c_llong),
            'strtoull'                 : ([c_ccharp],                 c_ullong),
            'free'                     : ([c_voidp],                  c_void),

            'charp2stdstring'          : ([c_ccharp],                 c_object),
            'stdstring2stdstring'      : ([c_object],                 c_object),
        }

        # size/offset are backend-specific but fixed after load
        self.c_sizeof_farg = 0
        self.c_offset_farg = 0
示例#9
0
    def __init__(self, space):
        self.library = None
        self.capi_calls = {}

        import pypy.module._cffi_backend.newtype as nt

        # TODO: the following need to match up with the globally defined C_XYZ low-level
        # types (see capi/__init__.py), but by using strings here, that isn't guaranteed
        c_opaque_ptr = nt.new_primitive_type(space, 'unsigned long')

        c_scope = c_opaque_ptr
        c_type = c_scope
        c_object = c_opaque_ptr
        c_method = c_opaque_ptr
        c_index = nt.new_primitive_type(space, 'long')

        c_void = nt.new_void_type(space)
        c_char = nt.new_primitive_type(space, 'char')
        c_uchar = nt.new_primitive_type(space, 'unsigned char')
        c_short = nt.new_primitive_type(space, 'short')
        c_int = nt.new_primitive_type(space, 'int')
        c_long = nt.new_primitive_type(space, 'long')
        c_llong = nt.new_primitive_type(space, 'long long')
        c_ullong = nt.new_primitive_type(space, 'unsigned long long')
        c_float = nt.new_primitive_type(space, 'float')
        c_double = nt.new_primitive_type(space, 'double')

        c_ccharp = nt.new_pointer_type(space, c_char)
        c_index_array = nt.new_pointer_type(space, c_void)

        c_voidp = nt.new_pointer_type(space, c_void)
        c_size_t = nt.new_primitive_type(space, 'size_t')

        c_ptrdiff_t = nt.new_primitive_type(space, 'ptrdiff_t')

        self.capi_call_ifaces = {
            # name to opaque C++ scope representation
            'num_scopes': ([c_scope], c_int),
            'scope_name': ([c_scope, c_int], c_ccharp),
            'resolve_name': ([c_ccharp], c_ccharp),
            'get_scope': ([c_ccharp], c_scope),
            'get_template': ([c_ccharp], c_type),
            'actual_class': ([c_type, c_object], c_type),

            # memory management
            'allocate': ([c_type], c_object),
            'deallocate': ([c_type, c_object], c_void),
            'destruct': ([c_type, c_object], c_void),

            # method/function dispatching
            'call_v': ([c_method, c_object, c_int, c_voidp], c_void),
            'call_b': ([c_method, c_object, c_int, c_voidp], c_uchar),
            'call_c': ([c_method, c_object, c_int, c_voidp], c_char),
            'call_h': ([c_method, c_object, c_int, c_voidp], c_short),
            'call_i': ([c_method, c_object, c_int, c_voidp], c_int),
            'call_l': ([c_method, c_object, c_int, c_voidp], c_long),
            'call_ll': ([c_method, c_object, c_int, c_voidp], c_llong),
            'call_f': ([c_method, c_object, c_int, c_voidp], c_float),
            'call_d': ([c_method, c_object, c_int, c_voidp], c_double),
            'call_r': ([c_method, c_object, c_int, c_voidp], c_voidp),
            'call_s': ([c_method, c_object, c_int, c_voidp], c_ccharp),
            'constructor': ([c_method, c_object, c_int, c_voidp], c_object),
            'call_o': ([c_method, c_object, c_int, c_voidp, c_type], c_object),
            'get_methptr_getter': ([c_scope,
                                    c_index], c_voidp),  # TODO: verify

            # handling of function argument buffer
            'allocate_function_args': ([c_int], c_voidp),
            'deallocate_function_args': ([c_voidp], c_void),
            'function_arg_sizeof': ([], c_size_t),
            'function_arg_typeoffset': ([], c_size_t),

            # scope reflection information
            'is_namespace': ([c_scope], c_int),
            'is_enum': ([c_ccharp], c_int),

            # type/class reflection information
            'final_name': ([c_type], c_ccharp),
            'scoped_final_name': ([c_type], c_ccharp),
            'has_complex_hierarchy': ([c_type], c_int),
            'num_bases': ([c_type], c_int),
            'base_name': ([c_type, c_int], c_ccharp),
            'is_subtype': ([c_type, c_type], c_int),
            'base_offset': ([c_type, c_type, c_object, c_int], c_ptrdiff_t),

            # method/function reflection information
            'num_methods': ([c_scope], c_int),
            'method_index_at': ([c_scope, c_int], c_index),
            'method_indices_from_name': ([c_scope, c_ccharp], c_index_array),
            'method_name': ([c_scope, c_index], c_ccharp),
            'method_result_type': ([c_scope, c_index], c_ccharp),
            'method_num_args': ([c_scope, c_index], c_int),
            'method_req_args': ([c_scope, c_index], c_int),
            'method_arg_type': ([c_scope, c_index, c_int], c_ccharp),
            'method_arg_default': ([c_scope, c_index, c_int], c_ccharp),
            'method_signature': ([c_scope, c_index], c_ccharp),
            'method_is_template': ([c_scope, c_index], c_int),
            'method_num_template_args': ([c_scope, c_index], c_int),
            'method_template_arg_name': ([c_scope, c_index,
                                          c_index], c_ccharp),
            'get_method': ([c_scope, c_index], c_method),
            'get_global_operator': ([c_scope, c_scope, c_scope,
                                     c_ccharp], c_index),

            # method properties
            'is_constructor': ([c_type, c_index], c_int),
            'is_staticmethod': ([c_type, c_index], c_int),

            # data member reflection information
            'num_datamembers': ([c_scope], c_int),
            'datamember_name': ([c_scope, c_int], c_ccharp),
            'datamember_type': ([c_scope, c_int], c_ccharp),
            'datamember_offset': ([c_scope, c_int], c_ptrdiff_t),
            'datamember_index': ([c_scope, c_ccharp], c_int),

            # data member properties
            'is_publicdata': ([c_scope, c_int], c_int),
            'is_staticdata': ([c_scope, c_int], c_int),

            # misc helpers
            'strtoll': ([c_ccharp], c_llong),
            'strtoull': ([c_ccharp], c_ullong),
            'free': ([c_voidp], c_void),
            'charp2stdstring': ([c_ccharp], c_object),
            'stdstring2stdstring': ([c_object], c_object),
        }

        # size/offset are backend-specific but fixed after load
        self.c_sizeof_farg = 0
        self.c_offset_farg = 0
示例#10
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
示例#11
0
文件: cglob.py 项目: pypyjs/pypy
 def address(self):
     w_ctypeptr = newtype.new_pointer_type(self.space, self.w_ctype)
     return W_CData(self.space, self.ptr, w_ctypeptr)
示例#12
0
 def address(self):
     w_ctypeptr = newtype.new_pointer_type(self.space, self.w_ctype)
     return W_CData(self.space, self.fetch_global_var_addr(), w_ctypeptr)
示例#13
0
 def address(self):
     w_ctypeptr = newtype.new_pointer_type(self.space, self.w_ctype)
     return W_CData(self.space, self.fetch_global_var_addr(), w_ctypeptr)