[perl-Glib-Object-Introspection] Move some code around to decrease its visibility



commit 7a15b06ecdd215c46a2ac6a91d3bf119b49dc918
Author: Torsten SchÃnfeld <kaffeetisch gmx de>
Date:   Sun Jan 27 22:31:33 2013 +0100

    Move some code around to decrease its visibility

 GObjectIntrospection.xs       |   20 ---
 gperl-i11n-invoke-c.c         |  344 ++++++++++++++++++++++++++++++++++-------
 gperl-i11n-invoke-info.c      |  268 --------------------------------
 gperl-i11n-invoke-perl.c      |   72 +++++++++-
 gperl-i11n-marshal-array.c    |    2 +-
 gperl-i11n-marshal-callback.c |    2 +-
 6 files changed, 357 insertions(+), 351 deletions(-)
---
diff --git a/GObjectIntrospection.xs b/GObjectIntrospection.xs
index 3c34fdc..c38475f 100644
--- a/GObjectIntrospection.xs
+++ b/GObjectIntrospection.xs
@@ -160,27 +160,8 @@ static void invoke_c_code (GICallableInfo *info,
                            const gchar *package,
                            const gchar *namespace,
                            const gchar *function);
-static gpointer allocate_out_mem (GITypeInfo *arg_type);
-static void handle_automatic_arg (guint pos,
-                                  GIArgument * arg,
-                                  GPerlI11nInvocationInfo * invocation_info);
 static void free_after_call (GPerlI11nInvocationInfo *iinfo,
                              GFunc func, gpointer data);
-static void invoke_free_after_call_handlers (GPerlI11nInvocationInfo *iinfo);
-
-/* invocation info */
-static void prepare_c_invocation_info (GPerlI11nInvocationInfo *iinfo,
-                                       GICallableInfo *info,
-                                       IV items,
-                                       UV internal_stack_offset,
-                                       const gchar *package,
-                                       const gchar *namespace,
-                                       const gchar *function);
-static void clear_c_invocation_info (GPerlI11nInvocationInfo *iinfo);
-
-static void prepare_perl_invocation_info (GPerlI11nInvocationInfo *iinfo,
-                                          GICallableInfo *info);
-static void clear_perl_invocation_info (GPerlI11nInvocationInfo *iinfo);
 
 /* info finders */
 static GIFunctionInfo * get_function_info (GIRepository *repository,
@@ -296,7 +277,6 @@ static void call_carp_carp (const char *msg);
 #include "gperl-i11n-gvalue.c"
 #include "gperl-i11n-info.c"
 #include "gperl-i11n-invoke-c.c"
-#include "gperl-i11n-invoke-info.c"
 #include "gperl-i11n-invoke-perl.c"
 #include "gperl-i11n-marshal-arg.c"
 #include "gperl-i11n-marshal-array.c"
diff --git a/gperl-i11n-invoke-c.c b/gperl-i11n-invoke-c.c
index 1a94227..a377276 100644
--- a/gperl-i11n-invoke-c.c
+++ b/gperl-i11n-invoke-c.c
@@ -1,48 +1,19 @@
 /* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; -*- */
 
-static gchar *
-format_target (GPerlI11nInvocationInfo *iinfo)
-{
-	gchar *caller = NULL;
-	if (iinfo->target_package && iinfo->target_namespace && iinfo->target_function) {
-		caller = g_strconcat (iinfo->target_package, "::",
-		                      iinfo->target_namespace, "::",
-		                      iinfo->target_function,
-		                      NULL);
-	} else if (iinfo->target_package && iinfo->target_function) {
-		caller = g_strconcat (iinfo->target_package, "::",
-		                      iinfo->target_function,
-		                      NULL);
-	} else {
-		caller = g_strconcat ("Callable ",
-		                      g_base_info_get_name (iinfo->interface),
-		                      NULL);
-	}
-	return caller;
-}
-
-static void
-check_n_args (GPerlI11nInvocationInfo *iinfo)
-{
-	if (iinfo->n_expected_args != iinfo->n_given_args) {
-		/* Avoid the cost of formatting the target until we know we
-		 * need it. */
-		gchar *caller = NULL;
-		if (iinfo->n_given_args < (iinfo->n_expected_args - iinfo->n_nullable_args)) {
-			caller = format_target (iinfo);
-			ccroak ("%s: passed too few parameters "
-			        "(expected %d, got %d)",
-			        caller, iinfo->n_expected_args, iinfo->n_given_args);
-		} else if (iinfo->n_given_args > iinfo->n_expected_args) {
-			caller = format_target (iinfo);
-			cwarn ("*** %s: passed too many parameters "
-			       "(expected %d, got %d); ignoring excess",
-			       caller, iinfo->n_expected_args, iinfo->n_given_args);
-		}
-		if (caller)
-			g_free (caller);
-	}
-}
+static void _prepare_c_invocation_info (GPerlI11nInvocationInfo *iinfo,
+                                        GICallableInfo *info,
+                                        IV items,
+                                        UV internal_stack_offset,
+                                        const gchar *package,
+                                        const gchar *namespace,
+                                        const gchar *function);
+static void _clear_c_invocation_info (GPerlI11nInvocationInfo *iinfo);
+static void _check_n_args (GPerlI11nInvocationInfo *iinfo);
+static void _handle_automatic_arg (guint pos,
+                                   GIArgument * arg,
+                                   GPerlI11nInvocationInfo * invocation_info);
+static gpointer _allocate_out_mem (GITypeInfo *arg_type);
+static void _invoke_free_after_call_handlers (GPerlI11nInvocationInfo *iinfo);
 
 static void
 invoke_c_code (GICallableInfo *info,
@@ -64,10 +35,10 @@ invoke_c_code (GICallableInfo *info,
 
 	PERL_UNUSED_VAR (mark);
 
-	prepare_c_invocation_info (&iinfo, info, items, internal_stack_offset,
-	                           package, namespace, function);
+	_prepare_c_invocation_info (&iinfo, info, items, internal_stack_offset,
+	                            package, namespace, function);
 
-	check_n_args (&iinfo);
+	_check_n_args (&iinfo);
 
 	if (iinfo.is_method) {
 		instance = instance_sv_to_pointer (info, ST (0 + iinfo.stack_offset));
@@ -137,7 +108,7 @@ invoke_c_code (GICallableInfo *info,
 		    case GI_DIRECTION_OUT:
 			if (g_arg_info_is_caller_allocates (arg_info)) {
 				iinfo.aux_args[i].v_pointer =
-					allocate_out_mem (arg_type);
+					_allocate_out_mem (arg_type);
 				iinfo.out_args[i].v_pointer = &iinfo.aux_args[i];
 				iinfo.args[ffi_stack_pos] = &iinfo.aux_args[i];
 			} else {
@@ -184,10 +155,10 @@ invoke_c_code (GICallableInfo *info,
 		arg_info = g_callable_info_get_arg ((GICallableInfo *) info, i);
 		switch (g_arg_info_get_direction (arg_info)) {
 		    case GI_DIRECTION_IN:
-			handle_automatic_arg (i, &iinfo.in_args[i], &iinfo);
+			_handle_automatic_arg (i, &iinfo.in_args[i], &iinfo);
 			break;
 		    case GI_DIRECTION_INOUT:
-			handle_automatic_arg (i, &iinfo.aux_args[i], &iinfo);
+			_handle_automatic_arg (i, &iinfo.aux_args[i], &iinfo);
 			break;
 		    case GI_DIRECTION_OUT:
 			/* handled later */
@@ -205,14 +176,14 @@ invoke_c_code (GICallableInfo *info,
 	if (FFI_OK != ffi_prep_cif (&cif, FFI_DEFAULT_ABI, iinfo.n_invoke_args,
 	                            iinfo.return_type_ffi, iinfo.arg_types))
 	{
-		clear_c_invocation_info (&iinfo);
+		_clear_c_invocation_info (&iinfo);
 		ccroak ("Could not prepare a call interface");
 	}
 
 	ffi_call (&cif, func_pointer, &return_value, iinfo.args);
 
 	/* free call-scoped data */
-	invoke_free_after_call_handlers (&iinfo);
+	_invoke_free_after_call_handlers (&iinfo);
 
 	if (local_error) {
 		gperl_croak_gerror (NULL, local_error);
@@ -281,17 +252,270 @@ invoke_c_code (GICallableInfo *info,
 		g_base_info_unref ((GIBaseInfo *) arg_info);
 	}
 
-	clear_c_invocation_info (&iinfo);
+	_clear_c_invocation_info (&iinfo);
 
 	dwarn ("  number of return values: %d\n", n_return_values);
 
 	PUTBACK;
 }
 
+/* ------------------------------------------------------------------------- */
+
 static void
-handle_automatic_arg (guint pos,
-                      GIArgument * arg,
-                      GPerlI11nInvocationInfo * invocation_info)
+_prepare_c_invocation_info (GPerlI11nInvocationInfo *iinfo,
+                            GICallableInfo *info,
+                            IV items,
+                            UV internal_stack_offset,
+                            const gchar *package,
+                            const gchar *namespace,
+                            const gchar *function)
+{
+	guint i;
+
+	dwarn ("C invoke: %s::%s::%s => %s\n"
+	       "  n_args: %d\n",
+	       package, namespace, function,
+	       g_base_info_get_name (info),
+	       g_callable_info_get_n_args (info));
+
+	iinfo->interface = info;
+	iinfo->target_package = package;
+	iinfo->target_namespace = namespace;
+	iinfo->target_function = function;
+
+	iinfo->is_function = GI_IS_FUNCTION_INFO (info);
+	iinfo->is_vfunc = GI_IS_VFUNC_INFO (info);
+	iinfo->is_callback = (g_base_info_get_type (info) == GI_INFO_TYPE_CALLBACK);
+	dwarn ("  is_function = %d, is_vfunc = %d, is_callback = %d\n",
+	       iinfo->is_function, iinfo->is_vfunc, iinfo->is_callback);
+
+	iinfo->stack_offset = internal_stack_offset;
+
+	iinfo->is_constructor = FALSE;
+	if (iinfo->is_function) {
+		iinfo->is_constructor =
+			g_function_info_get_flags (info) & GI_FUNCTION_IS_CONSTRUCTOR;
+	}
+	if (iinfo->is_constructor) {
+		iinfo->stack_offset++;
+	}
+
+	iinfo->n_given_args = items - iinfo->stack_offset;
+
+	iinfo->n_invoke_args = iinfo->n_args =
+		g_callable_info_get_n_args ((GICallableInfo *) info);
+
+	/* FIXME: can a vfunc not throw? */
+	iinfo->throws = FALSE;
+	if (iinfo->is_function) {
+		iinfo->throws =
+			g_function_info_get_flags (info) & GI_FUNCTION_THROWS;
+	}
+	if (iinfo->throws) {
+		iinfo->n_invoke_args++;
+	}
+
+	if (iinfo->is_vfunc) {
+		iinfo->is_method = TRUE;
+	} else if (iinfo->is_callback) {
+		iinfo->is_method = FALSE;
+	} else {
+		iinfo->is_method =
+			(g_function_info_get_flags (info) & GI_FUNCTION_IS_METHOD)
+			&& !iinfo->is_constructor;
+	}
+	if (iinfo->is_method) {
+		iinfo->n_invoke_args++;
+	}
+
+	dwarn ("C invoke: %s\n"
+	       "  n_args: %d, n_invoke_args: %d, n_given_args: %d\n"
+	       "  is_constructor: %d, is_method: %d\n",
+	       iinfo->is_vfunc ? g_base_info_get_name (info) : g_function_info_get_symbol (info),
+	       iinfo->n_args, iinfo->n_invoke_args, iinfo->n_given_args,
+	       iinfo->is_constructor, iinfo->is_method);
+
+	iinfo->return_type_info =
+		g_callable_info_get_return_type ((GICallableInfo *) info);
+	iinfo->has_return_value =
+		GI_TYPE_TAG_VOID != g_type_info_get_tag (iinfo->return_type_info);
+	iinfo->return_type_ffi = g_type_info_get_ffi_type (iinfo->return_type_info);
+	iinfo->return_type_transfer = g_callable_info_get_caller_owns ((GICallableInfo *) info);
+
+	/* allocate enough space for all args in both the out and in lists.
+	 * we'll only use as much as we need.  since function argument lists
+	 * are typically small, this shouldn't be a big problem. */
+	if (iinfo->n_invoke_args) {
+		gint n = iinfo->n_invoke_args;
+		iinfo->in_args = gperl_alloc_temp (sizeof (GIArgument) * n);
+		iinfo->out_args = gperl_alloc_temp (sizeof (GIArgument) * n);
+		iinfo->out_arg_infos = gperl_alloc_temp (sizeof (GITypeInfo*) * n);
+		iinfo->arg_types = gperl_alloc_temp (sizeof (ffi_type *) * n);
+		iinfo->args = gperl_alloc_temp (sizeof (gpointer) * n);
+		iinfo->aux_args = gperl_alloc_temp (sizeof (GIArgument) * n);
+		iinfo->is_automatic_arg = gperl_alloc_temp (sizeof (gboolean) * n);
+	}
+
+	iinfo->method_offset = iinfo->is_method ? 1 : 0;
+	iinfo->dynamic_stack_offset = 0;
+
+	/* Make a first pass to mark args that are filled in automatically, and
+	 * thus have no counterpart on the Perl side. */
+	for (i = 0 ; i < iinfo->n_args ; i++) {
+		GIArgInfo * arg_info =
+			g_callable_info_get_arg ((GICallableInfo *) info, i);
+		GITypeInfo * arg_type = g_arg_info_get_type (arg_info);
+		GITypeTag arg_tag = g_type_info_get_tag (arg_type);
+
+		if (arg_tag == GI_TYPE_TAG_ARRAY) {
+			gint pos = g_type_info_get_array_length (arg_type);
+			if (pos >= 0) {
+				dwarn ("  pos %d is automatic (array length)\n", pos);
+				iinfo->is_automatic_arg[pos] = TRUE;
+			}
+		}
+
+		else if (arg_tag == GI_TYPE_TAG_INTERFACE) {
+			GIBaseInfo * interface = g_type_info_get_interface (arg_type);
+			GIInfoType info_type = g_base_info_get_type (interface);
+			if (info_type == GI_INFO_TYPE_CALLBACK) {
+				gint pos = g_arg_info_get_destroy (arg_info);
+				if (pos >= 0) {
+					dwarn ("  pos %d is automatic (callback destroy notify)\n", pos);
+					iinfo->is_automatic_arg[pos] = TRUE;
+				}
+			}
+			g_base_info_unref ((GIBaseInfo *) interface);
+		}
+
+		g_base_info_unref ((GIBaseInfo *) arg_type);
+		g_base_info_unref ((GIBaseInfo *) arg_info);
+	}
+
+	/* Make another pass to count the expected args. */
+	iinfo->n_expected_args = iinfo->method_offset;
+	iinfo->n_nullable_args = 0;
+	for (i = 0 ; i < iinfo->n_args ; i++) {
+		GIArgInfo * arg_info =
+			g_callable_info_get_arg ((GICallableInfo *) info, i);
+		GITypeInfo * arg_type = g_arg_info_get_type (arg_info);
+		GITypeTag arg_tag = g_type_info_get_tag (arg_type);
+		gboolean is_out = GI_DIRECTION_OUT == g_arg_info_get_direction (arg_info);
+		gboolean is_automatic = iinfo->is_automatic_arg[i];
+		gboolean is_skipped = FALSE;
+#if GI_CHECK_VERSION (1, 29, 0)
+		is_skipped = g_arg_info_is_skip (arg_info);
+#endif
+
+		if (!is_out && !is_automatic && !is_skipped)
+			iinfo->n_expected_args++;
+		/* Callback user data may always be NULL. */
+		if (g_arg_info_may_be_null (arg_info) || arg_tag == GI_TYPE_TAG_VOID)
+			iinfo->n_nullable_args++;
+
+		g_base_info_unref ((GIBaseInfo *) arg_type);
+		g_base_info_unref ((GIBaseInfo *) arg_info);
+	}
+
+	/* If the return value is an array which comes with an outbound length
+	 * arg, then mark that length arg as automatic, too. */
+	if (g_type_info_get_tag (iinfo->return_type_info) == GI_TYPE_TAG_ARRAY) {
+		gint pos = g_type_info_get_array_length (iinfo->return_type_info);
+		if (pos >= 0) {
+			GIArgInfo * arg_info =
+				g_callable_info_get_arg ((GICallableInfo *) info, pos);
+			if (GI_DIRECTION_OUT == g_arg_info_get_direction (arg_info)) {
+				dwarn ("  pos %d is automatic (array length)\n", pos);
+				iinfo->is_automatic_arg[pos] = TRUE;
+			}
+			g_base_info_unref (arg_info);
+		}
+	}
+
+	/* We need to undo the special handling that GInitiallyUnowned
+	 * descendants receive from gobject-introspection: values of this type
+	 * are always marked transfer=none, even for constructors. */
+	if (iinfo->is_constructor &&
+	    g_type_info_get_tag (iinfo->return_type_info) == GI_TYPE_TAG_INTERFACE)
+	{
+		GIBaseInfo * interface = g_type_info_get_interface (iinfo->return_type_info);
+		if (GI_IS_REGISTERED_TYPE_INFO (interface) &&
+		    g_type_is_a (get_gtype (interface),
+		                 G_TYPE_INITIALLY_UNOWNED))
+		{
+			iinfo->return_type_transfer = GI_TRANSFER_EVERYTHING;
+		}
+		g_base_info_unref ((GIBaseInfo *) interface);
+	}
+}
+
+static void
+_clear_c_invocation_info (GPerlI11nInvocationInfo *iinfo)
+{
+	g_slist_free (iinfo->free_after_call);
+
+	/* The actual callback infos might be needed later, so we cannot free
+	 * them here. */
+	g_slist_free (iinfo->callback_infos);
+
+	g_slist_foreach (iinfo->array_infos, (GFunc) g_free, NULL);
+	g_slist_free (iinfo->array_infos);
+
+	g_base_info_unref ((GIBaseInfo *) iinfo->return_type_info);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static gchar *
+_format_target (GPerlI11nInvocationInfo *iinfo)
+{
+	gchar *caller = NULL;
+	if (iinfo->target_package && iinfo->target_namespace && iinfo->target_function) {
+		caller = g_strconcat (iinfo->target_package, "::",
+		                      iinfo->target_namespace, "::",
+		                      iinfo->target_function,
+		                      NULL);
+	} else if (iinfo->target_package && iinfo->target_function) {
+		caller = g_strconcat (iinfo->target_package, "::",
+		                      iinfo->target_function,
+		                      NULL);
+	} else {
+		caller = g_strconcat ("Callable ",
+		                      g_base_info_get_name (iinfo->interface),
+		                      NULL);
+	}
+	return caller;
+}
+
+static void
+_check_n_args (GPerlI11nInvocationInfo *iinfo)
+{
+	if (iinfo->n_expected_args != iinfo->n_given_args) {
+		/* Avoid the cost of formatting the target until we know we
+		 * need it. */
+		gchar *caller = NULL;
+		if (iinfo->n_given_args < (iinfo->n_expected_args - iinfo->n_nullable_args)) {
+			caller = _format_target (iinfo);
+			ccroak ("%s: passed too few parameters "
+			        "(expected %d, got %d)",
+			        caller, iinfo->n_expected_args, iinfo->n_given_args);
+		} else if (iinfo->n_given_args > iinfo->n_expected_args) {
+			caller = _format_target (iinfo);
+			cwarn ("*** %s: passed too many parameters "
+			       "(expected %d, got %d); ignoring excess",
+			       caller, iinfo->n_expected_args, iinfo->n_given_args);
+		}
+		if (caller)
+			g_free (caller);
+	}
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void
+_handle_automatic_arg (guint pos,
+                       GIArgument * arg,
+                       GPerlI11nInvocationInfo * invocation_info)
 {
 	GSList *l;
 
@@ -326,7 +550,7 @@ handle_automatic_arg (guint pos,
 }
 
 static gpointer
-allocate_out_mem (GITypeInfo *arg_type)
+_allocate_out_mem (GITypeInfo *arg_type)
 {
 	GIBaseInfo *interface_info;
 	GIInfoType type;
@@ -368,6 +592,8 @@ allocate_out_mem (GITypeInfo *arg_type)
 	}
 }
 
+/* ------------------------------------------------------------------------- */
+
 typedef struct {
 	GFunc func;
 	gpointer data;
@@ -384,17 +610,17 @@ free_after_call (GPerlI11nInvocationInfo *iinfo, GFunc func, gpointer data)
 }
 
 static void
-invoke_free_closure (FreeClosure *closure)
+_invoke_free_closure (FreeClosure *closure)
 {
 	closure->func (closure->data, NULL);
 	g_free (closure);
 }
 
 static void
-invoke_free_after_call_handlers (GPerlI11nInvocationInfo *iinfo)
+_invoke_free_after_call_handlers (GPerlI11nInvocationInfo *iinfo)
 {
 	g_slist_foreach (iinfo->free_after_call,
-	                 (GFunc) invoke_free_closure, NULL);
+	                 (GFunc) _invoke_free_closure, NULL);
 	g_slist_free (iinfo->free_after_call);
 	iinfo->free_after_call = NULL;
 }
diff --git a/gperl-i11n-invoke-perl.c b/gperl-i11n-invoke-perl.c
index 4326847..e2828d8 100644
--- a/gperl-i11n-invoke-perl.c
+++ b/gperl-i11n-invoke-perl.c
@@ -1,5 +1,9 @@
 /* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; -*- */
 
+static void _prepare_perl_invocation_info (GPerlI11nInvocationInfo *iinfo,
+                                           GICallableInfo *info);
+static void _clear_perl_invocation_info (GPerlI11nInvocationInfo *iinfo);
+
 static void
 invoke_perl_code (ffi_cif* cif, gpointer resp, gpointer* args, gpointer userdata)
 {
@@ -19,7 +23,7 @@ invoke_perl_code (ffi_cif* cif, gpointer resp, gpointer* args, gpointer userdata
 	info = (GPerlI11nPerlCallbackInfo *) userdata;
 	cb_interface = (GICallableInfo *) info->interface;
 
-	prepare_perl_invocation_info (&iinfo, cb_interface);
+	_prepare_perl_invocation_info (&iinfo, cb_interface);
 
 	/* set perl context */
 	GPERL_CALLBACK_MARSHAL_INIT (info);
@@ -262,7 +266,7 @@ invoke_perl_code (ffi_cif* cif, gpointer resp, gpointer* args, gpointer userdata
 
 	PUTBACK;
 
-	clear_perl_invocation_info (&iinfo);
+	_clear_perl_invocation_info (&iinfo);
 
 	FREETMPS;
 	LEAVE;
@@ -328,3 +332,67 @@ invoke_perl_signal_handler (ffi_cif* cif, gpointer resp, gpointer* args, gpointe
 }
 
 #endif
+
+/* -------------------------------------------------------------------------- */
+
+static void
+_prepare_perl_invocation_info (GPerlI11nInvocationInfo *iinfo,
+                               GICallableInfo *info)
+{
+	dwarn ("Perl invoke: %s\n"
+	       "  n_args: %d\n",
+	       g_base_info_get_name (info),
+	       g_callable_info_get_n_args (info));
+
+	iinfo->interface = info;
+
+	/* When invoking Perl code, we currently always use a complete
+	 * description of the callable (from a record field or some callback
+	 * typedef) for functions, vfuncs and calllbacks.  This implies that
+	 * there is no implicit invocant; it always appears explicitly in the
+	 * arg list.  For signals, however, the invocant is implicit. */
+	iinfo->is_function = GI_IS_FUNCTION_INFO (info);
+	iinfo->is_vfunc = GI_IS_VFUNC_INFO (info);
+	iinfo->is_signal = GI_IS_SIGNAL_INFO (info);
+	iinfo->is_callback = (g_base_info_get_type (info) == GI_INFO_TYPE_CALLBACK);
+	dwarn ("  is_function = %d, is_vfunc = %d, is_callback = %d, is_signal = %d\n",
+	       iinfo->is_function, iinfo->is_vfunc, iinfo->is_callback, iinfo->is_signal);
+
+	iinfo->n_args = g_callable_info_get_n_args (info);
+
+	/* FIXME: 'throws'? */
+
+	iinfo->return_type_info = g_callable_info_get_return_type (info);
+	iinfo->has_return_value =
+		GI_TYPE_TAG_VOID != g_type_info_get_tag (iinfo->return_type_info);
+	iinfo->return_type_ffi = g_type_info_get_ffi_type (iinfo->return_type_info);
+	iinfo->return_type_transfer = g_callable_info_get_caller_owns (info);
+
+	iinfo->dynamic_stack_offset = 0;
+
+	/* If the callback is supposed to return a GInitiallyUnowned object
+	 * then we must enforce GI_TRANSFER_EVERYTHING.  Otherwise, if the Perl
+	 * code returns a newly created object, FREETMPS would finalize it. */
+	if (g_type_info_get_tag (iinfo->return_type_info) == GI_TYPE_TAG_INTERFACE &&
+	    iinfo->return_type_transfer == GI_TRANSFER_NOTHING)
+	{
+		GIBaseInfo *interface = g_type_info_get_interface (iinfo->return_type_info);
+		if (GI_IS_REGISTERED_TYPE_INFO (interface) &&
+		    g_type_is_a (get_gtype (interface),
+		                 G_TYPE_INITIALLY_UNOWNED))
+		{
+			iinfo->return_type_transfer = GI_TRANSFER_EVERYTHING;
+		}
+		g_base_info_unref (interface);
+	}
+}
+
+static void
+_clear_perl_invocation_info (GPerlI11nInvocationInfo *iinfo)
+{
+	/* The actual callback infos might be needed later, so we cannot free
+	 * them here. */
+	g_slist_free (iinfo->callback_infos);
+
+	g_base_info_unref ((GIBaseInfo *) iinfo->return_type_info);
+}
diff --git a/gperl-i11n-marshal-array.c b/gperl-i11n-marshal-array.c
index 77f1202..5509486 100644
--- a/gperl-i11n-marshal-array.c
+++ b/gperl-i11n-marshal-array.c
@@ -103,7 +103,7 @@ sv_to_array (GITransfer transfer,
 
 	/* Add an array info entry even before the undef check so that the
 	 * corresponding length arg is set to zero later by
-	 * handle_automatic_arg. */
+	 * _handle_automatic_arg. */
 	length_pos = g_type_info_get_array_length (type_info);
 	if (length_pos >= 0) {
 		array_info = g_new0 (GPerlI11nArrayInfo, 1);
diff --git a/gperl-i11n-marshal-callback.c b/gperl-i11n-marshal-callback.c
index 5e758a4..d00b8bf 100644
--- a/gperl-i11n-marshal-callback.c
+++ b/gperl-i11n-marshal-callback.c
@@ -10,7 +10,7 @@ sv_to_callback (GIArgInfo * arg_info,
 	GPerlI11nPerlCallbackInfo *callback_info;
 	GIScopeType scope;
 
-	/* the destroy notify func is handled by handle_automatic_arg */
+	/* the destroy notify func is handled by _handle_automatic_arg */
 
 	dwarn ("      Perl callback at %d (%s)\n",
 	       invocation_info->current_pos,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]