[perl-Glib-Object-Introspection] Adjust the stack-saving guards



commit ea38b0ee6f62d1464b4a905cc157760acb930eb7
Author: Torsten SchÃnfeld <kaffeetisch gmx de>
Date:   Tue Jul 3 23:07:37 2012 +0200

    Adjust the stack-saving guards
    
    Use a more general macro wrapper to save the stack pointer.

 GObjectIntrospection.xs        |   25 +++++++++++++------------
 gperl-i11n-invoke-c.c          |   18 ++++++++----------
 gperl-i11n-invoke-perl.c       |    2 +-
 gperl-i11n-marshal-arg.c       |    5 +++--
 gperl-i11n-marshal-interface.c |    5 +++--
 5 files changed, 28 insertions(+), 27 deletions(-)
---
diff --git a/GObjectIntrospection.xs b/GObjectIntrospection.xs
index 0c18758..6979913 100644
--- a/GObjectIntrospection.xs
+++ b/GObjectIntrospection.xs
@@ -226,16 +226,15 @@ static void generic_class_init (GIObjectInfo *info, const gchar *target_package,
 static void call_carp_croak (const char *msg);
 
 /* interface_to_sv and its callers might invoke Perl code, so any xsub invoking
- * them needs to save the stack.  these wrappers do this automatically. */
-#define SS_arg_to_sv(sv, arg, info, transfer, iinfo)	\
-	PUTBACK;					\
-	sv = arg_to_sv (arg, info, transfer, iinfo);	\
-	SPAGAIN;
-
-#define SS_get_field(sv, field_info, mem, transfer)	\
-	PUTBACK;					\
-	sv = get_field (field_info, mem, transfer);	\
-	SPAGAIN;
+ * them needs to save the stack.  this wrapper does this automatically. */
+#define SAVED_STACK_SV(expr)			\
+	({					\
+		SV *_saved_stack_sv;		\
+		PUTBACK;			\
+		_saved_stack_sv = expr;		\
+		SPAGAIN;			\
+		_saved_stack_sv;		\
+	})
 
 /* #define NOISY */
 #ifdef NOISY
@@ -436,7 +435,8 @@ _fetch_constant (class, basename, constant)
 	type_info = g_constant_info_get_type (info);
 	/* FIXME: What am I suppossed to do with the return value? */
 	g_constant_info_get_value (info, &value);
-	SS_arg_to_sv (RETVAL, &value, type_info, GI_TRANSFER_NOTHING, NULL);
+	/* No PUTBACK/SPAGAIN needed here. */
+	RETVAL = arg_to_sv (&value, type_info, GI_TRANSFER_NOTHING, NULL);
 #if GI_CHECK_VERSION (1, 30, 1)
 	g_constant_info_free_value (info, &value);
 #endif
@@ -472,7 +472,8 @@ _get_field (class, basename, namespace, field, invocant)
 		ccroak ("Unable to handle field access for type '%s'",
 		        g_type_name (invocant_type));
 	boxed_mem = gperl_get_boxed_check (invocant, invocant_type);
-	SS_get_field (RETVAL, field_info, boxed_mem, GI_TRANSFER_NOTHING);
+	/* No PUTBACK/SPAGAIN needed here. */
+	RETVAL = get_field (field_info, boxed_mem, GI_TRANSFER_NOTHING);
 	g_base_info_unref (field_info);
 	g_base_info_unref (namespace_info);
     OUTPUT:
diff --git a/gperl-i11n-invoke-c.c b/gperl-i11n-invoke-c.c
index 1b3d57f..ba33609 100644
--- a/gperl-i11n-invoke-c.c
+++ b/gperl-i11n-invoke-c.c
@@ -183,11 +183,10 @@ invoke_callable (GICallableInfo *info,
 	   )
 	{
 		SV *value;
-		SS_arg_to_sv (value,
-		              &return_value,
-		              iinfo.return_type_info,
-		              iinfo.return_type_transfer,
-		              &iinfo);
+		value = SAVED_STACK_SV (arg_to_sv (&return_value,
+		                                   iinfo.return_type_info,
+		                                   iinfo.return_type_transfer,
+		                                   &iinfo));
 		if (value) {
 			XPUSHs (sv_2mortal (value));
 			n_return_values++;
@@ -216,11 +215,10 @@ invoke_callable (GICallableInfo *info,
 			transfer = g_arg_info_is_caller_allocates (arg_info)
 			         ? GI_TRANSFER_CONTAINER
 			         : g_arg_info_get_ownership_transfer (arg_info);
-			SS_arg_to_sv (sv,
-			              iinfo.out_args[i].v_pointer,
-			              iinfo.out_arg_infos[i],
-			              transfer,
-			              &iinfo);
+			sv = SAVED_STACK_SV (arg_to_sv (iinfo.out_args[i].v_pointer,
+			                                iinfo.out_arg_infos[i],
+			                                transfer,
+			                                &iinfo));
 			if (sv) {
 				XPUSHs (sv_2mortal (sv));
 				n_return_values++;
diff --git a/gperl-i11n-invoke-perl.c b/gperl-i11n-invoke-perl.c
index d59139b..b739c16 100644
--- a/gperl-i11n-invoke-perl.c
+++ b/gperl-i11n-invoke-perl.c
@@ -75,7 +75,7 @@ invoke_callback (ffi_cif* cif, gpointer resp, gpointer* args, gpointer userdata)
 			GIArgument arg;
 			SV *sv;
 			raw_to_arg (args[i], &arg, arg_type);
-			SS_arg_to_sv (sv, &arg, arg_type, transfer, &iinfo);
+			sv = SAVED_STACK_SV (arg_to_sv (&arg, arg_type, transfer, &iinfo));
 			/* If arg_to_sv returns NULL, we take that as 'skip
 			 * this argument'; happens for GDestroyNotify, for
 			 * example. */
diff --git a/gperl-i11n-marshal-arg.c b/gperl-i11n-marshal-arg.c
index c468675..4e679a6 100644
--- a/gperl-i11n-marshal-arg.c
+++ b/gperl-i11n-marshal-arg.c
@@ -128,8 +128,9 @@ sv_to_arg (SV * sv,
 	}
 }
 
-/* This may call Perl code (via interface_to_sv), so it needs to be wrapped
- * with PUTBACK/SPAGAIN by the caller. */
+/* This may call Perl code (via interface_to_sv, glist_to_sv, ghash_to_sv or
+ * array_to_sv), so it needs to be wrapped with PUTBACK/SPAGAIN by the
+ * caller. */
 static SV *
 arg_to_sv (GIArgument * arg,
            GITypeInfo * info,
diff --git a/gperl-i11n-marshal-interface.c b/gperl-i11n-marshal-interface.c
index 8017f66..7d399f5 100644
--- a/gperl-i11n-marshal-interface.c
+++ b/gperl-i11n-marshal-interface.c
@@ -158,8 +158,9 @@ sv_to_interface (GIArgInfo * arg_info,
 	g_base_info_unref ((GIBaseInfo *) interface);
 }
 
-/* This may call Perl code, so it needs to be wrapped with PUTBACK/SPAGAIN by
- * the caller. */
+/* This may call Perl code (via gperl_new_boxed, gperl_sv_from_value,
+ * struct_to_sv), so it needs to be wrapped with PUTBACK/SPAGAIN by the
+ * caller. */
 static SV *
 interface_to_sv (GITypeInfo* info, GIArgument *arg, gboolean own, GPerlI11nInvocationInfo *iinfo)
 {



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