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()
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()
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)
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)
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)))
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)))