static GPerlI11nPerlCallbackInfo * create_perl_callback_closure (GICallableInfo *cb_info, SV *code) { GPerlI11nPerlCallbackInfo *info; info = g_new0 (GPerlI11nPerlCallbackInfo, 1); if (!gperl_sv_is_defined (code)) return info; info->interface = g_base_info_ref (cb_info); info->cif = g_new0 (ffi_cif, 1); info->closure = g_callable_info_prepare_closure (info->interface, info->cif, invoke_perl_code, info); /* FIXME: This should most likely use SvREFCNT_inc instead of * newSVsv. */ info->code = newSVsv (code); info->sub_name = NULL; /* These are only relevant for signal marshalling; if needed, they get * set in invoke_perl_signal_handler. */ info->swap_data = FALSE; info->args_converter = NULL; #ifdef PERL_IMPLICIT_CONTEXT info->priv = aTHX; #endif return info; }
PyGICClosure* _pygi_make_native_closure (GICallableInfo* info, GIArgInfo* arg_info, PyObject *py_function, gpointer py_user_data) { PyGICClosure *closure; ffi_closure *fficlosure; /* Begin by cleaning up old async functions */ g_slist_foreach(async_free_list, (GFunc)_pygi_invoke_closure_free, NULL); g_slist_free(async_free_list); async_free_list = NULL; /* Build the closure itself */ closure = g_slice_new0(PyGICClosure); closure->info = (GICallableInfo *) g_base_info_ref ((GIBaseInfo *) info); closure->function = py_function; closure->user_data = py_user_data; Py_INCREF(py_function); if (closure->user_data) Py_INCREF(closure->user_data); fficlosure = g_callable_info_prepare_closure (info, &closure->cif, _pygi_closure_handle, closure); closure->closure = fficlosure; /* Give the closure the information it needs to determine when to free itself later */ closure->scope = g_arg_info_get_scope(arg_info); return closure; }
/* assumes ownership of sub_name */ static GPerlI11nPerlCallbackInfo * create_perl_callback_closure_for_named_sub (GICallableInfo *cb_info, gchar *sub_name) { GPerlI11nPerlCallbackInfo *info; info = g_new0 (GPerlI11nPerlCallbackInfo, 1); info->interface = g_base_info_ref (cb_info); info->cif = g_new0 (ffi_cif, 1); info->closure = g_callable_info_prepare_closure (info->interface, info->cif, invoke_perl_code, info); info->sub_name = sub_name; info->code = NULL; info->data = NULL; #ifdef PERL_IMPLICIT_CONTEXT info->priv = aTHX; #endif return info; }
PyGICClosure* _pygi_destroy_notify_create (void) { if (!global_destroy_notify) { PyGICClosure *destroy_notify = g_slice_new0 (PyGICClosure); g_assert (destroy_notify); GIBaseInfo* 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; }
static void in_callback_argument_from_ruby(RBGIArgMetadata *metadata, GArray *in_args) { gpointer callback_function; GIArgInfo *arg_info; GIArgument *callback_argument; GIArgument *closure_argument = NULL; GIArgument *destroy_argument = NULL; RBGICallback *callback = NULL; arg_info = &(metadata->arg_info); callback_argument = &(g_array_index(in_args, GIArgument, metadata->in_arg_index)); if (metadata->closure_in_arg_index != -1) { closure_argument = &(g_array_index(in_args, GIArgument, metadata->closure_in_arg_index)); } if (metadata->destroy_in_arg_index != -1) { destroy_argument = &(g_array_index(in_args, GIArgument, metadata->destroy_in_arg_index)); } if (!rb_block_given_p() && g_arg_info_may_be_null(arg_info)) { callback_argument->v_pointer = NULL; if (closure_argument) { closure_argument->v_pointer = NULL; } if (destroy_argument) { destroy_argument->v_pointer = NULL; } return; } callback_function = find_callback_function(arg_info); if (callback_function) { callback_argument->v_pointer = callback_function; } else { callback = RB_ZALLOC(RBGICallback); callback->type_info = g_arg_info_get_type(arg_info); callback->callback_info = g_type_info_get_interface(callback->type_info); callback->closure = g_callable_info_prepare_closure(callback->callback_info, &(callback->cif), ffi_closure_callback, callback); callback_argument->v_pointer = callback->closure; } if (closure_argument) { RBGICallbackData *callback_data; callback_data = ALLOC(RBGICallbackData); callback_data->callback = callback; callback_data->metadata = metadata; callback_data->rb_callback = rb_block_proc(); callback_data_guard_from_gc(callback_data); closure_argument->v_pointer = callback_data; } if (destroy_argument) { destroy_argument->v_pointer = destroy_notify; } }
static void create_native_closure (GType interface_type, GIInterfaceInfo *iface_info, GIVFuncInfo *vfunc_info, MethodImpl *impl) { GIFunctionInfo *invoker_info; GIStructInfo *struct_info; GIFieldInfo *field_info; GITypeInfo *type_info; GICallbackInfo *callback_info; guint n_fields, i; gboolean found_field_info; invoker_info = g_vfunc_info_get_invoker (vfunc_info); if (invoker_info == NULL) { g_debug ("No invoker for VFunc '%s.%s'", g_base_info_get_name (iface_info), g_base_info_get_name (vfunc_info)); return; } struct_info = g_interface_info_get_iface_struct (iface_info); n_fields = g_struct_info_get_n_fields (struct_info); found_field_info = FALSE; for (i = 0; i < n_fields; i++) { field_info = g_struct_info_get_field (struct_info, i); if (strcmp (g_base_info_get_name (field_info), g_base_info_get_name (vfunc_info)) == 0) { found_field_info = TRUE; break; } g_base_info_unref (field_info); } if (!found_field_info) { g_debug ("No struct field for VFunc '%s.%s'", g_base_info_get_name (iface_info), g_base_info_get_name (vfunc_info)); g_base_info_unref (struct_info); g_base_info_unref (invoker_info); return; } type_info = g_field_info_get_type (field_info); g_assert (g_type_info_get_tag (type_info) == GI_TYPE_TAG_INTERFACE); callback_info = g_type_info_get_interface (type_info); g_assert (g_base_info_get_type (callback_info) == GI_INFO_TYPE_CALLBACK); impl->interface_type = interface_type; impl->invoker_info = invoker_info; impl->method_name = g_base_info_get_name (invoker_info); impl->closure = g_callable_info_prepare_closure (callback_info, &impl->cif, handle_method_impl, impl); impl->struct_offset = g_field_info_get_offset (field_info); g_base_info_unref (callback_info); g_base_info_unref (type_info); g_base_info_unref (field_info); g_base_info_unref (struct_info); }