Exemple #1
0
def ffi_prep_callback(tp, f):
    """(ffi-prep-callback callback-tp fn)
       Prepares a Pixie function for use as a c callback. callback-tp is a ffi callback type,
       fn is a pixie function (can be a closure, native fn or any object that implements -invoke.
       Returns a function pointer that can be passed to c and invoked as a callback."""
    affirm(isinstance(tp, CFunctionType),
           u"First argument to ffi-prep-callback must be a CFunctionType")
    raw_closure = rffi.cast(rffi.VOIDP, clibffi.closureHeap.alloc())

    if not we_are_translated():
        unique_id = id_generator.get_next()
    else:
        unique_id = rffi.cast(lltype.Signed, raw_closure)

    res = clibffi.c_ffi_prep_closure(
        rffi.cast(clibffi.FFI_CLOSUREP, raw_closure),
        tp.get_cd().cif, invoke_callback, rffi.cast(rffi.VOIDP, unique_id))

    if rffi.cast(lltype.Signed, res) != clibffi.FFI_OK:
        registered_callbacks[unique_id] = None
        runtime_error(u"libffi failed to build this callback")

    cb = CCallback(tp, raw_closure, unique_id, f)
    registered_callbacks[unique_id] = cb

    return cb
Exemple #2
0
def ffi_prep_callback(tp, f):
    """(ffi-prep-callback callback-tp fn)
       Prepares a Pixie function for use as a c callback. callback-tp is a ffi callback type,
       fn is a pixie function (can be a closure, native fn or any object that implements -invoke.
       Returns a function pointer that can be passed to c and invoked as a callback."""
    affirm(isinstance(tp, CFunctionType), u"First argument to ffi-prep-callback must be a CFunctionType")
    raw_closure = rffi.cast(rffi.VOIDP, clibffi.closureHeap.alloc())

    if not we_are_translated():
        unique_id = id_generator.get_next()
    else:
        unique_id = rffi.cast(lltype.Signed, raw_closure)

    res = clibffi.c_ffi_prep_closure(rffi.cast(clibffi.FFI_CLOSUREP, raw_closure), tp.get_cd().cif,
                             invoke_callback,
                             rffi.cast(rffi.VOIDP, unique_id))


    if rffi.cast(lltype.Signed, res) != clibffi.FFI_OK:
        registered_callbacks[unique_id] = None
        runtime_error(u"libffi failed to build this callback")

    cb = CCallback(tp, raw_closure, unique_id, f)
    registered_callbacks[unique_id] = cb

    return cb
Exemple #3
0
    def __init__(self, cfunc, callback):
        self.cfunc = cfunc
        self.callback = callback
        pointer = rffi.cast(rffi.VOIDP, clibffi.closureHeap.alloc())
        if cfunc.notready:
            cfunc.prepare_cif()
            cfunc.notready = False
        Mem.__init__(self, cfunc, pointer)

        closure_ptr = rffi.cast(clibffi.FFI_CLOSUREP, self.pointer)
        # hide the object
        gcref = rgc.cast_instance_to_gcref(self)
        raw = rgc.hide_nonmovable_gcref(gcref)
        unique_id = rffi.cast(rffi.VOIDP, raw)

        res = clibffi.c_ffi_prep_closure(closure_ptr, cfunc.cif.cif,
            invoke_callback, unique_id)

        if rffi.cast(lltype.Signed, res) != clibffi.FFI_OK:
            raise unwind(LError(u"libffi failed to build this callback"))
        if closure_ptr.c_user_data != unique_id:
            raise unwind(LError(u"ffi_prep_closure(): bad user_data"))

        # The function might be called in separate thread,
        # so allocate GIL here, just in case.
        rgil.allocate()
Exemple #4
0
 def __init__(self, space, ctype, w_callable, w_error, w_onerror):
     raw_closure = rffi.cast(rffi.CCHARP, clibffi.closureHeap.alloc())
     self._closure = Closure(raw_closure)
     W_ExternPython.__init__(self, space, raw_closure, ctype,
                             w_callable, w_error, w_onerror)
     self.key_pycode = space._try_fetch_pycode(w_callable)
     #
     cif_descr = self.getfunctype().cif_descr
     if not cif_descr:
         raise oefmt(space.w_NotImplementedError,
                     "%s: callback with unsupported argument or "
                     "return type or with '...'", self.getfunctype().name)
     with self as ptr:
         closure_ptr = rffi.cast(clibffi.FFI_CLOSUREP, ptr)
         unique_id = self.hide_object()
         res = clibffi.c_ffi_prep_closure(closure_ptr, cif_descr.cif,
                                          invoke_callback,
                                          unique_id)
     if rffi.cast(lltype.Signed, res) != clibffi.FFI_OK:
         raise oefmt(space.w_SystemError,
                     "libffi failed to build this callback")
     if closure_ptr.c_user_data != unique_id:
         raise oefmt(space.w_SystemError,
             "ffi_prep_closure(): bad user_data (it seems that the "
             "version of the libffi library seen at runtime is "
             "different from the 'ffi.h' file seen at compile-time)")
Exemple #5
0
 def __init__(self, space, ctype, w_callable, w_error, w_onerror):
     raw_closure = rffi.cast(rffi.CCHARP, clibffi.closureHeap.alloc())
     self._closure = Closure(raw_closure)
     W_ExternPython.__init__(self, space, raw_closure, ctype, w_callable,
                             w_error, w_onerror)
     self.key_pycode = space._try_fetch_pycode(w_callable)
     #
     cif_descr = self.getfunctype().cif_descr
     if not cif_descr:
         raise oefmt(
             space.w_NotImplementedError,
             "%s: callback with unsupported argument or "
             "return type or with '...'",
             self.getfunctype().name)
     with self as ptr:
         closure_ptr = rffi.cast(clibffi.FFI_CLOSUREP, ptr)
         unique_id = self.hide_object()
         res = clibffi.c_ffi_prep_closure(closure_ptr, cif_descr.cif,
                                          invoke_callback, unique_id)
     if rffi.cast(lltype.Signed, res) != clibffi.FFI_OK:
         raise oefmt(space.w_SystemError,
                     "libffi failed to build this callback")
     if closure_ptr.c_user_data != unique_id:
         raise oefmt(
             space.w_SystemError,
             "ffi_prep_closure(): bad user_data (it seems that the "
             "version of the libffi library seen at runtime is "
             "different from the 'ffi.h' file seen at compile-time)")
Exemple #6
0
 def __init__(self, space, ctype, w_callable, w_error):
     raw_closure = rffi.cast(rffi.CCHARP, clibffi.closureHeap.alloc())
     W_CData.__init__(self, space, raw_closure, ctype)
     #
     if not space.is_true(space.callable(w_callable)):
         raise operationerrfmt(space.w_TypeError,
                               "expected a callable object, not %T",
                               w_callable)
     self.w_callable = w_callable
     #
     fresult = self.getfunctype().ctitem
     size = fresult.size
     if size > 0:
         if fresult.is_primitive_integer and size < SIZE_OF_FFI_ARG:
             size = SIZE_OF_FFI_ARG
         self.ll_error = lltype.malloc(rffi.CCHARP.TO, size, flavor='raw',
                                       zero=True)
     if not space.is_none(w_error):
         convert_from_object_fficallback(fresult, self.ll_error, w_error)
     #
     self.unique_id = compute_unique_id(self)
     global_callback_mapping.set(self.unique_id, self)
     #
     cif_descr = self.getfunctype().cif_descr
     if not cif_descr:
         raise OperationError(space.w_NotImplementedError,
                              space.wrap("callbacks with '...'"))
     res = clibffi.c_ffi_prep_closure(self.get_closure(), cif_descr.cif,
                                      invoke_callback,
                                      rffi.cast(rffi.VOIDP, self.unique_id))
     if rffi.cast(lltype.Signed, res) != clibffi.FFI_OK:
         raise OperationError(space.w_SystemError,
             space.wrap("libffi failed to build this callback"))
Exemple #7
0
 def __init__(self, space, ctype, w_callable, w_error, w_onerror):
     raw_closure = rffi.cast(rffi.CCHARP, clibffi.closureHeap.alloc())
     W_CData.__init__(self, space, raw_closure, ctype)
     #
     if not space.is_true(space.callable(w_callable)):
         raise oefmt(space.w_TypeError,
                     "expected a callable object, not %T", w_callable)
     self.w_callable = w_callable
     if not space.is_none(w_onerror):
         if not space.is_true(space.callable(w_onerror)):
             raise oefmt(
                 space.w_TypeError,
                 "expected a callable object for 'onerror', not %T",
                 w_onerror)
         self.w_onerror = w_onerror
     #
     fresult = self.getfunctype().ctitem
     size = fresult.size
     if size > 0:
         if fresult.is_primitive_integer and size < SIZE_OF_FFI_ARG:
             size = SIZE_OF_FFI_ARG
         self.ll_error = lltype.malloc(rffi.CCHARP.TO,
                                       size,
                                       flavor='raw',
                                       zero=True)
     if not space.is_none(w_error):
         convert_from_object_fficallback(fresult, self.ll_error, w_error)
     #
     self.unique_id = compute_unique_id(self)
     global_callback_mapping.set(self.unique_id, self)
     #
     cif_descr = self.getfunctype().cif_descr
     if not cif_descr:
         raise oefmt(
             space.w_NotImplementedError,
             "%s: callback with unsupported argument or "
             "return type or with '...'",
             self.getfunctype().name)
     with self as ptr:
         closure_ptr = rffi.cast(clibffi.FFI_CLOSUREP, ptr)
         unique_id = rffi.cast(rffi.VOIDP, self.unique_id)
         res = clibffi.c_ffi_prep_closure(closure_ptr, cif_descr.cif,
                                          invoke_callback, unique_id)
     if rffi.cast(lltype.Signed, res) != clibffi.FFI_OK:
         raise OperationError(
             space.w_SystemError,
             space.wrap("libffi failed to build this callback"))
     #
     # We must setup the GIL here, in case the callback is invoked in
     # some other non-Pythonic thread.  This is the same as cffi on
     # CPython.
     if space.config.translation.thread:
         from pypy.module.thread.os_thread import setup_threads
         setup_threads(space)
Exemple #8
0
 def __init__(self, space, ctype, w_callable, w_error, w_onerror):
     raw_closure = rffi.cast(rffi.CCHARP, clibffi.closureHeap.alloc())
     W_CData.__init__(self, space, raw_closure, ctype)
     #
     if not space.is_true(space.callable(w_callable)):
         raise oefmt(space.w_TypeError,
                     "expected a callable object, not %T", w_callable)
     self.w_callable = w_callable
     if not space.is_none(w_onerror):
         if not space.is_true(space.callable(w_onerror)):
             raise oefmt(space.w_TypeError,
                         "expected a callable object for 'onerror', not %T",
                         w_onerror)
         self.w_onerror = w_onerror
     #
     fresult = self.getfunctype().ctitem
     size = fresult.size
     if size > 0:
         if fresult.is_primitive_integer and size < SIZE_OF_FFI_ARG:
             size = SIZE_OF_FFI_ARG
         self.ll_error = lltype.malloc(rffi.CCHARP.TO, size, flavor='raw',
                                       zero=True)
     if not space.is_none(w_error):
         convert_from_object_fficallback(fresult, self.ll_error, w_error)
     #
     self.unique_id = compute_unique_id(self)
     global_callback_mapping.set(self.unique_id, self)
     #
     cif_descr = self.getfunctype().cif_descr
     if not cif_descr:
         raise oefmt(space.w_NotImplementedError,
                     "%s: callback with unsupported argument or "
                     "return type or with '...'", self.getfunctype().name)
     with self as ptr:
         closure_ptr = rffi.cast(clibffi.FFI_CLOSUREP, ptr)
         unique_id = rffi.cast(rffi.VOIDP, self.unique_id)
         res = clibffi.c_ffi_prep_closure(closure_ptr, cif_descr.cif,
                                          invoke_callback,
                                          unique_id)
     if rffi.cast(lltype.Signed, res) != clibffi.FFI_OK:
         raise OperationError(space.w_SystemError,
             space.wrap("libffi failed to build this callback"))
     #
     # We must setup the GIL here, in case the callback is invoked in
     # some other non-Pythonic thread.  This is the same as cffi on
     # CPython.
     if space.config.translation.thread:
         from pypy.module.thread.os_thread import setup_threads
         setup_threads(space)
Exemple #9
0
 def __init__(self, callback_data):
     self.heap = clibffi.closureHeap.alloc()
     self.callback_data = callback_data
     w_callback_info = self.callback_data.w_callback_info
     space = self.callback_data.space
     self.uid = compute_unique_id(self)
     registration[self.uid] = self
     cls_ptr = rffi.cast(clibffi.FFI_CLOSUREP, self.heap)
     status = clibffi.c_ffi_prep_closure(cls_ptr,
                                         w_callback_info.cif_descr.cif,
                                         invoke,
                                         rffi.cast(rffi.VOIDP, self.uid))
     if rffi.cast(lltype.Signed, status) != clibffi.FFI_OK:
         space = self.callback_data.space
         raise space.error(space.w_RuntimeError,
                           "libffi failed to build this callback type")
Exemple #10
0
 def __init__(self, callback_data):
     self.heap = clibffi.closureHeap.alloc()
     self.callback_data = callback_data
     w_callback_info = self.callback_data.w_callback_info
     space = self.callback_data.space
     self.uid = compute_unique_id(self)
     registration[self.uid] = self
     cls_ptr = rffi.cast(clibffi.FFI_CLOSUREP, self.heap)
     status = clibffi.c_ffi_prep_closure(cls_ptr,
                                         w_callback_info.cif_descr.cif,
                                         invoke,
                                         rffi.cast(rffi.VOIDP, self.uid))
     if rffi.cast(lltype.Signed, status) != clibffi.FFI_OK:
         space = self.callback_data.space
         raise space.error(space.w_RuntimeError,
                           "libffi failed to build this callback type")
Exemple #11
0
 def __init__(self, space, ctype, w_callable, w_error, w_onerror):
     raw_closure = rffi.cast(rffi.CCHARP, clibffi.closureHeap.alloc())
     self._closure = Closure(raw_closure)
     W_ExternPython.__init__(self, space, raw_closure, ctype,
                             w_callable, w_error, w_onerror)
     self.key_pycode = space._try_fetch_pycode(w_callable)
     #
     cif_descr = self.getfunctype().cif_descr
     if not cif_descr:
         raise oefmt(space.w_NotImplementedError,
                     "%s: callback with unsupported argument or "
                     "return type or with '...'", self.getfunctype().name)
     with self as ptr:
         closure_ptr = rffi.cast(clibffi.FFI_CLOSUREP, ptr)
         unique_id = self.hide_object()
         res = clibffi.c_ffi_prep_closure(closure_ptr, cif_descr.cif,
                                          invoke_callback,
                                          unique_id)
     if rffi.cast(lltype.Signed, res) != clibffi.FFI_OK:
         raise OperationError(space.w_SystemError,
             space.wrap("libffi failed to build this callback"))