[perl-Glib-Object-Introspection] Support caller-allocated out args in callbacks
- From: Torsten SchÃnfeld <tsch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [perl-Glib-Object-Introspection] Support caller-allocated out args in callbacks
- Date: Wed, 12 Oct 2011 17:41:58 +0000 (UTC)
commit 16239095cb4e6e9d2bf252ff5eeec853a048f00a
Author: Torsten SchÃnfeld <kaffeetisch gmx de>
Date: Wed Oct 12 16:18:59 2011 +0200
Support caller-allocated out args in callbacks
The GtkCellRenderer vfunc get_aligned_area is an example.
gperl-i11n-invoke-perl.c | 8 +++++++-
gperl-i11n-marshal-arg.c | 2 --
gperl-i11n-marshal-interface.c | 24 +++++++++++++++++++-----
3 files changed, 26 insertions(+), 8 deletions(-)
---
diff --git a/gperl-i11n-invoke-perl.c b/gperl-i11n-invoke-perl.c
index 97dbfa8..aa8fa91 100644
--- a/gperl-i11n-invoke-perl.c
+++ b/gperl-i11n-invoke-perl.c
@@ -157,10 +157,16 @@ invoke_callback (ffi_cif* cif, gpointer resp, gpointer* args, gpointer userdata)
GIArgument tmp_arg;
GITransfer transfer = g_arg_info_get_ownership_transfer (arg_info);
gboolean may_be_null = g_arg_info_may_be_null (arg_info);
+ gboolean is_caller_allocated = g_arg_info_is_caller_allocates (arg_info);
+ if (is_caller_allocated) {
+ tmp_arg.v_pointer = out_pointer;
+ }
sv_to_arg (returned_values[out_index], &tmp_arg,
arg_info, arg_type,
transfer, may_be_null, NULL);
- arg_to_raw (&tmp_arg, out_pointer, arg_type);
+ if (!is_caller_allocated) {
+ arg_to_raw (&tmp_arg, out_pointer, arg_type);
+ }
out_index++;
}
diff --git a/gperl-i11n-marshal-arg.c b/gperl-i11n-marshal-arg.c
index 7d0e6ca..bbf8c70 100644
--- a/gperl-i11n-marshal-arg.c
+++ b/gperl-i11n-marshal-arg.c
@@ -11,8 +11,6 @@ sv_to_arg (SV * sv,
{
GITypeTag tag = g_type_info_get_tag (type_info);
- memset (arg, 0, sizeof (GIArgument));
-
if (!gperl_sv_is_defined (sv))
/* Interfaces and void types need to be able to handle undef
* separately. */
diff --git a/gperl-i11n-marshal-interface.c b/gperl-i11n-marshal-interface.c
index 773e0ee..7dea8c0 100644
--- a/gperl-i11n-marshal-interface.c
+++ b/gperl-i11n-marshal-interface.c
@@ -76,7 +76,9 @@ sv_to_interface (GIArgInfo * arg_info,
case GI_INFO_TYPE_STRUCT:
case GI_INFO_TYPE_BOXED:
{
- /* FIXME: What about pass-by-value here? */
+ gboolean need_value_semantics =
+ arg_info && g_arg_info_is_caller_allocates (arg_info)
+ && !g_type_info_is_pointer (type_info);
GType type = g_registered_type_info_get_g_type (
(GIRegisteredTypeInfo *) interface);
if (!type || type == G_TYPE_NONE) {
@@ -84,6 +86,7 @@ sv_to_interface (GIArgInfo * arg_info,
? g_arg_info_get_ownership_transfer (arg_info)
: GI_TRANSFER_NOTHING;
dwarn (" unboxed type\n");
+ g_assert (!need_value_semantics);
arg->v_pointer = sv_to_struct (transfer,
interface,
info_type,
@@ -91,17 +94,28 @@ sv_to_interface (GIArgInfo * arg_info,
} else if (type == G_TYPE_CLOSURE) {
/* FIXME: User cannot supply user data. */
dwarn (" closure type\n");
+ g_assert (!need_value_semantics);
arg->v_pointer = gperl_closure_new (sv, NULL, FALSE);
} else if (type == G_TYPE_VALUE) {
dwarn (" value type\n");
+ g_assert (!need_value_semantics);
arg->v_pointer = SvGValueWrapper (sv);
if (!arg->v_pointer)
ccroak ("Cannot convert arbitrary SV to GValue");
} else {
- dwarn (" boxed type: %s (%d)\n",
- g_type_name (type), type);
- /* FIXME: Check transfer setting. */
- arg->v_pointer = gperl_get_boxed_check (sv, type);
+ dwarn (" boxed type: %s, name=%s, caller-allocates=%d, is-pointer=%d\n",
+ g_type_name (type),
+ g_base_info_get_name (interface),
+ g_arg_info_is_caller_allocates (arg_info),
+ g_type_info_is_pointer (type_info));
+ if (need_value_semantics) {
+ gsize n_bytes = g_struct_info_get_size (interface);
+ gpointer mem = gperl_get_boxed_check (sv, type);
+ g_memmove (arg->v_pointer, mem, n_bytes);
+ } else {
+ /* FIXME: Check transfer setting. */
+ arg->v_pointer = gperl_get_boxed_check (sv, type);
+ }
}
break;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]