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
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
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
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
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