def _call(self, funcaddr, args_w): space = self.space cif_descr = self.cif_descr size = cif_descr.exchange_size mustfree_max_plus_1 = 0 buffer = lltype.malloc(rffi.CCHARP.TO, size, flavor="raw") try: for i in range(len(args_w)): data = rffi.ptradd(buffer, cif_descr.exchange_args[i]) w_obj = args_w[i] argtype = self.fargs[i] if argtype.convert_argument_from_object(data, w_obj): # argtype is a pointer type, and w_obj a list/tuple/str mustfree_max_plus_1 = i + 1 ec = cerrno.get_errno_container(space) cerrno.restore_errno_from(ec) jit_libffi.jit_ffi_call(cif_descr, rffi.cast(rffi.VOIDP, funcaddr), buffer) e = cerrno.get_real_errno() cerrno.save_errno_into(ec, e) resultdata = rffi.ptradd(buffer, cif_descr.exchange_result) w_res = self.ctitem.copy_and_convert_to_object(resultdata) finally: for i in range(mustfree_max_plus_1): argtype = self.fargs[i] if isinstance(argtype, W_CTypePointer): data = rffi.ptradd(buffer, cif_descr.exchange_args[i]) flag = get_mustfree_flag(data) if flag == 1: raw_string = rffi.cast(rffi.CCHARPP, data)[0] lltype.free(raw_string, flavor="raw") lltype.free(buffer, flavor="raw") return w_res
must_leave = False ec = None space = callback.space try: must_leave = space.threadlocals.try_enter_thread(space) ec = cerrno.get_errno_container(space) cerrno.save_errno_into(ec, e) extra_line = '' try: w_res = callback.invoke(ll_args) extra_line = "Trying to convert the result back to C:\n" callback.convert_result(ll_res, w_res) except OperationError, e: # got an app-level exception callback.print_error(e, extra_line) callback.write_error_return_value(ll_res) # except Exception, e: # oups! last-level attempt to recover. try: os.write(STDERR, "SystemError: callback raised ") os.write(STDERR, str(e)) os.write(STDERR, "\n") except OSError: pass callback.write_error_return_value(ll_res) if must_leave: space.threadlocals.leave_thread(space) if ec is not None: cerrno.restore_errno_from(ec)