Esempio n. 1
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()
Esempio n. 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()
Esempio n. 3
0
def _new_runfn(h, _):
    # Here, we are in a fresh new stacklet.
    llop.gc_stack_bottom(lltype.Void)  # marker for trackgcroot.py
    #
    # There is a fresh suspstack object waiting on the gcrootfinder,
    # so populate it with data that represents the parent suspended
    # stacklet and detach the suspstack object from gcrootfinder.
    suspstack = gcrootfinder.attach_handle_on_suspstack(h)
    #
    # Call the main function provided by the (RPython) user.
    suspstack = gcrootfinder.runfn(suspstack, gcrootfinder.arg)
    #
    # Here, suspstack points to the target stacklet to which we want
    # to jump to next.  Read the 'handle' and forget about the
    # suspstack object.
    return _consume_suspstack(suspstack)
Esempio n. 4
0
def _new_runfn(h, _):
    # Here, we are in a fresh new stacklet.
    llop.gc_stack_bottom(lltype.Void)   # marker for trackgcroot.py
    #
    # There is a fresh suspstack object waiting on the gcrootfinder,
    # so populate it with data that represents the parent suspended
    # stacklet and detach the suspstack object from gcrootfinder.
    suspstack = gcrootfinder.attach_handle_on_suspstack(h)
    #
    # Call the main function provided by the (RPython) user.
    suspstack = gcrootfinder.runfn(suspstack, gcrootfinder.arg)
    #
    # Here, suspstack points to the target stacklet to which we want
    # to jump to next.  Read the 'handle' and forget about the
    # suspstack object.
    return _consume_suspstack(suspstack)
Esempio n. 5
0
File: api.py Progetto: Darriall/pypy
 def wrapper(*args):
     from pypy.module.cpyext.pyobject import make_ref, from_ref
     from pypy.module.cpyext.pyobject import Reference
     # we hope that malloc removal removes the newtuple() that is
     # inserted exactly here by the varargs specializer
     if gil_acquire:
         after = rffi.aroundstate.after
         if after:
             after()
     rffi.stackcounter.stacks_counter += 1
     llop.gc_stack_bottom(lltype.Void)   # marker for trackgcroot.py
     retval = fatal_value
     boxed_args = ()
     try:
         if not we_are_translated() and DEBUG_WRAPPER:
             print >>sys.stderr, callable,
         assert len(args) == len(callable.api_func.argtypes)
         for i, (typ, is_wrapped) in argtypes_enum_ui:
             arg = args[i]
             if is_PyObject(typ) and is_wrapped:
                 if arg:
                     arg_conv = from_ref(space, rffi.cast(PyObject, arg))
                 else:
                     arg_conv = None
             else:
                 arg_conv = arg
             boxed_args += (arg_conv, )
         state = space.fromcache(State)
         try:
             result = callable(space, *boxed_args)
             if not we_are_translated() and DEBUG_WRAPPER:
                 print >>sys.stderr, " DONE"
         except OperationError, e:
             failed = True
             state.set_exception(e)
         except BaseException, e:
             failed = True
             if not we_are_translated():
                 message = repr(e)
                 import traceback
                 traceback.print_exc()
             else:
                 message = str(e)
             state.set_exception(OperationError(space.w_SystemError,
                                                space.wrap(message)))
Esempio n. 6
0
File: api.py Progetto: juokaz/pypy
 def wrapper(*args):
     from pypy.module.cpyext.pyobject import make_ref, from_ref
     from pypy.module.cpyext.pyobject import Reference
     # we hope that malloc removal removes the newtuple() that is
     # inserted exactly here by the varargs specializer
     rffi.stackcounter.stacks_counter += 1
     llop.gc_stack_bottom(lltype.Void)   # marker for trackgcroot.py
     retval = fatal_value
     boxed_args = ()
     try:
         if not we_are_translated() and DEBUG_WRAPPER:
             print >>sys.stderr, callable,
         assert len(args) == len(callable.api_func.argtypes)
         for i, (typ, is_wrapped) in argtypes_enum_ui:
             arg = args[i]
             if is_PyObject(typ) and is_wrapped:
                 if arg:
                     arg_conv = from_ref(space, rffi.cast(PyObject, arg))
                 else:
                     arg_conv = None
             else:
                 arg_conv = arg
             boxed_args += (arg_conv, )
         state = space.fromcache(State)
         try:
             result = callable(space, *boxed_args)
             if not we_are_translated() and DEBUG_WRAPPER:
                 print >>sys.stderr, " DONE"
         except OperationError, e:
             failed = True
             state.set_exception(e)
         except BaseException, e:
             failed = True
             if not we_are_translated():
                 message = repr(e)
                 import traceback
                 traceback.print_exc()
             else:
                 message = str(e)
             state.set_exception(OperationError(space.w_SystemError,
                                                space.wrap(message)))