diff options
Diffstat (limited to 'gi/pygi-marshal-from-py.c')
-rw-r--r-- | gi/pygi-marshal-from-py.c | 160 |
1 files changed, 0 insertions, 160 deletions
diff --git a/gi/pygi-marshal-from-py.c b/gi/pygi-marshal-from-py.c index c6fe1c21..92c89c84 100644 --- a/gi/pygi-marshal-from-py.c +++ b/gi/pygi-marshal-from-py.c @@ -140,166 +140,6 @@ _is_union_member (GIInterfaceInfo *interface_info, PyObject *py_arg) { return is_member; } -/* _pygi_destroy_notify_dummy: - * - * Dummy method used in the occasion when a method has a GDestroyNotify - * argument without user data. - */ -static void -_pygi_destroy_notify_dummy (gpointer data) { -} - -static PyGICClosure *global_destroy_notify; - -static void -_pygi_destroy_notify_callback_closure (ffi_cif *cif, - void *result, - void **args, - void *data) -{ - PyGICClosure *info = * (void**) (args[0]); - - g_assert (info); - - _pygi_invoke_closure_free (info); -} - -/* _pygi_destroy_notify_create: - * - * Method used in the occasion when a method has a GDestroyNotify - * argument with user data. - */ -static PyGICClosure* -_pygi_destroy_notify_create (void) -{ - if (!global_destroy_notify) { - - PyGICClosure *destroy_notify = g_slice_new0 (PyGICClosure); - GIBaseInfo* glib_destroy_notify; - - g_assert (destroy_notify); - - glib_destroy_notify = g_irepository_find_by_name (NULL, "GLib", "DestroyNotify"); - g_assert (glib_destroy_notify != NULL); - g_assert (g_base_info_get_type (glib_destroy_notify) == GI_INFO_TYPE_CALLBACK); - - destroy_notify->closure = g_callable_info_prepare_closure ( (GICallableInfo*) glib_destroy_notify, - &destroy_notify->cif, - _pygi_destroy_notify_callback_closure, - NULL); - - global_destroy_notify = destroy_notify; - } - - return global_destroy_notify; -} - -gboolean -_pygi_marshal_from_py_interface_callback (PyGIInvokeState *state, - PyGICallableCache *callable_cache, - PyGIArgCache *arg_cache, - PyObject *py_arg, - GIArgument *arg, - gpointer *cleanup_data) -{ - GICallableInfo *callable_info; - PyGICClosure *closure; - PyGIArgCache *user_data_cache = NULL; - PyGIArgCache *destroy_cache = NULL; - PyGICallbackCache *callback_cache; - PyObject *py_user_data = NULL; - - callback_cache = (PyGICallbackCache *)arg_cache; - - if (callback_cache->user_data_index > 0) { - user_data_cache = _pygi_callable_cache_get_arg (callable_cache, callback_cache->user_data_index); - if (user_data_cache->py_arg_index < state->n_py_in_args) { - /* py_user_data is a borrowed reference. */ - py_user_data = PyTuple_GetItem (state->py_in_args, user_data_cache->py_arg_index); - if (!py_user_data) - return FALSE; - /* NULL out user_data if it was not supplied and the default arg placeholder - * was used instead. - */ - if (py_user_data == _PyGIDefaultArgPlaceholder) { - py_user_data = NULL; - } else if (callable_cache->user_data_varargs_index < 0) { - /* For non-variable length user data, place the user data in a - * single item tuple which is concatenated to the callbacks arguments. - * This allows callback input arg marshaling to always expect a - * tuple for user data. Note the - */ - py_user_data = Py_BuildValue("(O)", py_user_data, NULL); - } else { - /* increment the ref borrowed from PyTuple_GetItem above */ - Py_INCREF (py_user_data); - } - } - } - - if (py_arg == Py_None) { - return TRUE; - } - - if (!PyCallable_Check (py_arg)) { - PyErr_Format (PyExc_TypeError, - "Callback needs to be a function or method not %s", - py_arg->ob_type->tp_name); - - return FALSE; - } - - callable_info = (GICallableInfo *)callback_cache->interface_info; - - closure = _pygi_make_native_closure (callable_info, callback_cache->scope, py_arg, py_user_data); - arg->v_pointer = closure->closure; - - /* always decref the user data as _pygi_make_native_closure adds its own ref */ - Py_XDECREF (py_user_data); - - /* The PyGICClosure instance is used as user data passed into the C function. - * The return trip to python will marshal this back and pull the python user data out. - */ - if (user_data_cache != NULL) { - state->in_args[user_data_cache->c_arg_index].v_pointer = closure; - } - - /* Setup a GDestroyNotify callback if this method supports it along with - * a user data field. The user data field is a requirement in order - * free resources and ref counts associated with this arguments closure. - * In case a user data field is not available, show a warning giving - * explicit information and setup a dummy notification to avoid a crash - * later on in _pygi_destroy_notify_callback_closure. - */ - if (callback_cache->destroy_notify_index > 0) { - destroy_cache = _pygi_callable_cache_get_arg (callable_cache, callback_cache->destroy_notify_index); - } - - if (destroy_cache) { - if (user_data_cache != NULL) { - PyGICClosure *destroy_notify = _pygi_destroy_notify_create (); - state->in_args[destroy_cache->c_arg_index].v_pointer = destroy_notify->closure; - } else { - gchar *msg = g_strdup_printf("Callables passed to %s will leak references because " - "the method does not support a user_data argument. " - "See: https://bugzilla.gnome.org/show_bug.cgi?id=685598", - callable_cache->name); - if (PyErr_WarnEx(PyExc_RuntimeWarning, msg, 2)) { - g_free(msg); - _pygi_invoke_closure_free(closure); - return FALSE; - } - g_free(msg); - state->in_args[destroy_cache->c_arg_index].v_pointer = _pygi_destroy_notify_dummy; - } - } - - /* Use the PyGIClosure as data passed to cleanup for GI_SCOPE_TYPE_CALL. */ - *cleanup_data = closure; - - return TRUE; -} - gboolean _pygi_marshal_from_py_interface_enum (PyGIInvokeState *state, PyGICallableCache *callable_cache, |