Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
 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
Ejemplo n.º 5
0
 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
Ejemplo n.º 6
0
    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