def __init__(self, space, w_vector): W_AbstractSeqIterObject.__init__(self, w_vector) # TODO: this should live in rpythonize.py or something so that the # imports can move to the top w/o getting circles from pypy.module.cppyy import interp_cppyy assert isinstance(w_vector, interp_cppyy.W_CPPInstance) vector = space.interp_w(interp_cppyy.W_CPPInstance, w_vector) self.overload = vector.cppclass.get_overload("__getitem__") from pypy.module.cppyy import capi v_type = capi.c_stdvector_valuetype(space, vector.cppclass.name) v_size = capi.c_stdvector_valuesize(space, vector.cppclass.name) if not v_type or not v_size: raise NotImplementedError # fallback on getitem w_arr = vector.cppclass.get_overload("data").call(w_vector, []) arr = space.interp_w(W_ArrayInstance, w_arr, can_be_None=True) if not arr: raise OperationError(space.w_StopIteration, space.w_None) self.data = rffi.cast(rffi.VOIDP, space.uint_w(arr.getbuffer(space))) from pypy.module.cppyy import converter self.converter = converter.get_converter(space, v_type, '') self.len = space.uint_w(vector.cppclass.get_overload("size").call(w_vector, [])) self.stride = v_size
def __init__(self, space, w_vector): W_AbstractSeqIterObject.__init__(self, w_vector) # TODO: this should live in rpythonize.py or something so that the # imports can move to the top w/o getting circles from pypy.module.cppyy import interp_cppyy assert isinstance(w_vector, interp_cppyy.W_CPPInstance) vector = space.interp_w(interp_cppyy.W_CPPInstance, w_vector) self.overload = vector.cppclass.get_overload("__getitem__") from pypy.module.cppyy import capi v_type = capi.c_stdvector_valuetype(space, vector.cppclass.name) v_size = capi.c_stdvector_valuesize(space, vector.cppclass.name) if not v_type or not v_size: raise NotImplementedError # fallback on getitem w_arr = vector.cppclass.get_overload("data").call(w_vector, []) arr = space.interp_w(W_ArrayInstance, w_arr, can_be_None=True) if not arr: raise OperationError(space.w_StopIteration, space.w_None) self.data = rffi.cast(rffi.VOIDP, space.uint_w(arr.getbuffer(space))) from pypy.module.cppyy import converter self.converter = converter.get_converter(space, v_type, '') self.len = space.uint_w( vector.cppclass.get_overload("size").call(w_vector, [])) self.stride = v_size
def _setup(self, cppthis): self.converters = [ converter.get_converter(self.space, arg_type, arg_dflt) for arg_type, arg_dflt in self.arg_defs ] self.executor = executor.get_executor(self.space, capi.c_method_result_type(self.scope, self.index)) # Each CPPMethod corresponds one-to-one to a C++ equivalent and cppthis # has been offset to the matching class. Hence, the libffi pointer is # uniquely defined and needs to be setup only once. methgetter = capi.c_get_methptr_getter(self.scope, self.index) if methgetter and cppthis: # methods only for now funcptr = methgetter(rffi.cast(capi.C_OBJECT, cppthis)) argtypes_libffi = [conv.libffitype for conv in self.converters if conv.libffitype] if len(argtypes_libffi) == len(self.converters) and self.executor.libffitype: # add c++ this to the arguments libffifunc = libffi.Func( "XXX", [libffi.types.pointer] + argtypes_libffi, self.executor.libffitype, funcptr ) self._libffifunc = libffifunc
def __init__(self, space, containing_scope, type_name, offset, is_static): self.space = space self.scope = containing_scope self.converter = converter.get_converter(self.space, type_name, "") self.offset = offset self._is_static = is_static
def __init__(self, space, containing_scope, type_name, offset): self.space = space self.scope = containing_scope self.converter = converter.get_converter(self.space, type_name, '') self.offset = offset
def _setup(self, cppthis): self.converters = [converter.get_converter(self.space, arg_type, arg_dflt) for arg_type, arg_dflt in self.arg_defs] self.executor = executor.get_executor( self.space, capi.c_method_result_type(self.space, self.scope, self.index)) for conv in self.converters: if conv.uses_local: self.uses_local = True break # Each CPPMethod corresponds one-to-one to a C++ equivalent and cppthis # has been offset to the matching class. Hence, the libffi pointer is # uniquely defined and needs to be setup only once. methgetter = capi.c_get_methptr_getter(self.space, self.scope, self.index) if methgetter and cppthis: # methods only for now cif_descr = lltype.nullptr(jit_libffi.CIF_DESCRIPTION) try: funcaddr = methgetter(rffi.cast(capi.C_OBJECT, cppthis)) self._funcaddr = rffi.cast(rffi.VOIDP, funcaddr) nargs = self.args_expected + 1 # +1: cppthis # memory block for CIF description (note: not tracked as the life # time of methods is normally the duration of the application) size = llmemory.sizeof(jit_libffi.CIF_DESCRIPTION, nargs) # allocate the buffer cif_descr = lltype.malloc(jit_libffi.CIF_DESCRIPTION_P.TO, llmemory.raw_malloc_usage(size), flavor='raw', track_allocation=False) # array of 'ffi_type*' values, one per argument size = rffi.sizeof(jit_libffi.FFI_TYPE_P) * nargs atypes = lltype.malloc(rffi.CCHARP.TO, llmemory.raw_malloc_usage(size), flavor='raw', track_allocation=False) cif_descr.atypes = rffi.cast(jit_libffi.FFI_TYPE_PP, atypes) # argument type specification cif_descr.atypes[0] = jit_libffi.types.pointer # cppthis for i, conv in enumerate(self.converters): if not conv.libffitype: raise FastCallNotPossible cif_descr.atypes[i+1] = conv.libffitype # result type specification cif_descr.rtype = self.executor.libffitype # exchange --- # first, enough room for an array of 'nargs' pointers exchange_offset = rffi.sizeof(rffi.CCHARP) * nargs exchange_offset = (exchange_offset + 7) & ~7 # alignment cif_descr.exchange_result = exchange_offset cif_descr.exchange_result_libffi = exchange_offset # TODO: left this out while testing (see ctypefunc.py) # For results of precisely these types, libffi has a # strange rule that they will be returned as a whole # 'ffi_arg' if they are smaller. The difference # only matters on big-endian. # then enough room for the result, rounded up to sizeof(ffi_arg) exchange_offset += max(rffi.getintfield(cif_descr.rtype, 'c_size'), jit_libffi.SIZE_OF_FFI_ARG) # loop over args for i in range(nargs): exchange_offset = (exchange_offset + 7) & ~7 # alignment cif_descr.exchange_args[i] = exchange_offset exchange_offset += rffi.getintfield(cif_descr.atypes[i], 'c_size') # store the exchange data size cif_descr.exchange_size = exchange_offset # --- exchange # extra cif_descr.abi = clibffi.FFI_DEFAULT_ABI cif_descr.nargs = self.args_expected + 1 # +1: cppthis res = jit_libffi.jit_ffi_prep_cif(cif_descr) if res != clibffi.FFI_OK: raise FastCallNotPossible except Exception, e: if cif_descr: lltype.free(cif_descr.atypes, flavor='raw', track_allocation=False) lltype.free(cif_descr, flavor='raw', track_allocation=False) cif_descr = lltype.nullptr(jit_libffi.CIF_DESCRIPTION) self._funcaddr = lltype.nullptr(rffi.VOIDP.TO) self.cif_descr = cif_descr