Пример #1
0
def invoke_callback(ffi_cif, ll_res, ll_args, ll_userdata):
    """ Callback specification.
    ffi_cif - something ffi specific, don't care
    ll_args - rffi.VOIDPP - pointer to array of pointers to args
    ll_res - rffi.VOIDP - pointer to result
    ll_userdata - a special structure which holds necessary information
                  (what the real callback is for example), casted to VOIDP
    """
    cerrno._errno_after(rffi.RFFI_ERR_ALL | rffi.RFFI_ALT_ERRNO)
    ll_res = rffi.cast(rffi.CCHARP, ll_res)
    callback = reveal_callback(ll_userdata)
    if callback is None:
        # oups!
        try:
            os.write(
                STDERR, "SystemError: invoking a callback "
                "that was already freed\n")
        except:
            pass
        # In this case, we don't even know how big ll_res is.  Let's assume
        # it is just a 'ffi_arg', and store 0 there.
        misc._raw_memclear(ll_res, SIZE_OF_FFI_ARG)
    else:
        callback.invoke(ll_res, rffi.cast(rffi.CCHARP, ll_args))
    cerrno._errno_before(rffi.RFFI_ERR_ALL | rffi.RFFI_ALT_ERRNO)
Пример #2
0
def _cffi_call_python(ll_externpy, ll_args):
    """Invoked by the helpers generated from extern "Python" in the cdef.

       'externpy' is a static structure that describes which of the
       extern "Python" functions is called.  It has got fields 'name' and
       'type_index' describing the function, and more reserved fields
       that are initially zero.  These reserved fields are set up by
       ffi.def_extern(), which invokes externpy_deco() below.

       'args' is a pointer to an array of 8-byte entries.  Each entry
       contains an argument.  If an argument is less than 8 bytes, only
       the part at the beginning of the entry is initialized.  If an
       argument is 'long double' or a struct/union, then it is passed
       by reference.

       'args' is also used as the place to write the result to
       (directly, even if more than 8 bytes).  In all cases, 'args' is
       at least 8 bytes in size.
    """
    from pypy.module._cffi_backend.ccallback import reveal_callback
    from rpython.rlib import rgil

    rgil.acquire()
    rffi.stackcounter.stacks_counter += 1
    llop.gc_stack_bottom(lltype.Void)  # marker for trackgcroot.py

    cerrno._errno_after(rffi.RFFI_ERR_ALL | rffi.RFFI_ALT_ERRNO)

    if not ll_externpy.c_reserved1:
        # Not initialized!  We don't have a space at all.
        # Write the error to the file descriptor stderr.
        try:
            funcname = rffi.charp2str(ll_externpy.c_name)
            msg = (
                'extern "Python": function %s() called, but no code was '
                "attached to it yet with @ffi.def_extern().  "
                "Returning 0.\n" % (funcname,)
            )
            os.write(STDERR, msg)
        except:
            pass
        for i in range(intmask(ll_externpy.c_size_of_result)):
            ll_args[i] = "\x00"
    else:
        externpython = reveal_callback(ll_externpy.c_reserved1)
        # the same buffer is used both for passing arguments and
        # the result value
        externpython.invoke(ll_args, ll_args)

    cerrno._errno_before(rffi.RFFI_ERR_ALL | rffi.RFFI_ALT_ERRNO)

    rffi.stackcounter.stacks_counter -= 1
    rgil.release()
Пример #3
0
def _cffi_call_python(ll_externpy, ll_args):
    """Invoked by the helpers generated from extern "Python" in the cdef.

       'externpy' is a static structure that describes which of the
       extern "Python" functions is called.  It has got fields 'name' and
       'type_index' describing the function, and more reserved fields
       that are initially zero.  These reserved fields are set up by
       ffi.def_extern(), which invokes externpy_deco() below.

       'args' is a pointer to an array of 8-byte entries.  Each entry
       contains an argument.  If an argument is less than 8 bytes, only
       the part at the beginning of the entry is initialized.  If an
       argument is 'long double' or a struct/union, then it is passed
       by reference.

       'args' is also used as the place to write the result to
       (directly, even if more than 8 bytes).  In all cases, 'args' is
       at least 8 bytes in size.
    """
    from pypy.module._cffi_backend.ccallback import reveal_callback
    from rpython.rlib import rgil

    rgil.acquire()
    rffi.stackcounter.stacks_counter += 1
    llop.gc_stack_bottom(lltype.Void)   # marker for trackgcroot.py

    cerrno._errno_after(rffi.RFFI_ERR_ALL | rffi.RFFI_ALT_ERRNO)

    if not ll_externpy.c_reserved1:
        # Not initialized!  We don't have a space at all.
        # Write the error to the file descriptor stderr.
        try:
            funcname = rffi.charp2str(ll_externpy.c_name)
            msg = ("extern \"Python\": function %s() called, but no code was "
                   "attached to it yet with @ffi.def_extern().  "
                   "Returning 0.\n" % (funcname,))
            os.write(STDERR, msg)
        except:
            pass
        for i in range(intmask(ll_externpy.c_size_of_result)):
            ll_args[i] = '\x00'
    else:
        externpython = reveal_callback(ll_externpy.c_reserved1)
        # the same buffer is used both for passing arguments and
        # the result value
        externpython.invoke(ll_args, ll_args)

    cerrno._errno_before(rffi.RFFI_ERR_ALL | rffi.RFFI_ALT_ERRNO)

    rffi.stackcounter.stacks_counter -= 1
    rgil.release()
Пример #4
0
def invoke_callback(ffi_cif, ll_res, ll_args, ll_userdata):
    """ Callback specification.
    ffi_cif - something ffi specific, don't care
    ll_args - rffi.VOIDPP - pointer to array of pointers to args
    ll_res - rffi.VOIDP - pointer to result
    ll_userdata - a special structure which holds necessary information
                  (what the real callback is for example), casted to VOIDP
    """
    cerrno._errno_after(rffi.RFFI_ERR_ALL | rffi.RFFI_ALT_ERRNO)
    ll_res = rffi.cast(rffi.CCHARP, ll_res)
    callback = reveal_callback(ll_userdata)
    if callback is None:
        # oups!
        try:
            os.write(STDERR, "SystemError: invoking a callback "
                             "that was already freed\n")
        except:
            pass
        # In this case, we don't even know how big ll_res is.  Let's assume
        # it is just a 'ffi_arg', and store 0 there.
        misc._raw_memclear(ll_res, SIZE_OF_FFI_ARG)
    else:
        callback.invoke(ll_res, rffi.cast(rffi.CCHARP, ll_args))
    cerrno._errno_before(rffi.RFFI_ERR_ALL | rffi.RFFI_ALT_ERRNO)
Пример #5
0
def invoke_callback(ffi_cif, ll_res, ll_args, ll_userdata):
    cerrno._errno_after(rffi.RFFI_ERR_ALL | rffi.RFFI_ALT_ERRNO)
    _invoke_callback(ffi_cif, ll_res, ll_args, ll_userdata)
    cerrno._errno_before(rffi.RFFI_ERR_ALL | rffi.RFFI_ALT_ERRNO)
Пример #6
0
def invoke_callback(ffi_cif, ll_res, ll_args, ll_userdata):
    cerrno._errno_after(rffi.RFFI_ERR_ALL | rffi.RFFI_ALT_ERRNO)
    _invoke_callback(ffi_cif, ll_res, ll_args, ll_userdata)
    cerrno._errno_before(rffi.RFFI_ERR_ALL | rffi.RFFI_ALT_ERRNO)