[glib: 1/2] glib-genmarshal: Avoid a param ref for static param valist arguments
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib: 1/2] glib-genmarshal: Avoid a param ref for static param valist arguments
- Date: Mon, 29 Jul 2019 11:45:22 +0000 (UTC)
commit 3f411a36af8295e282740adddf4cfb9d50c6c9d8
Author: Philip Withnall <withnall endlessm com>
Date: Tue Jun 18 11:59:11 2019 +0100
glib-genmarshal: Avoid a param ref for static param valist arguments
When building a valist marshaller, we can avoid reffing a GParamSpec
if the argument is known to always be static. The marshaller we ship in
`gmarshal.c` got this right, but marshallers generated by
glib-genmarshal were missing the optimisation. Fix that, and add a unit
test.
Signed-off-by: Philip Withnall <withnall endlessm com>
Fixes: #1792
gobject/glib-genmarshal.in | 1 +
gobject/tests/genmarshal.py | 133 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 134 insertions(+)
---
diff --git a/gobject/glib-genmarshal.in b/gobject/glib-genmarshal.in
index 1ea2ad9e8..7380f24a8 100755
--- a/gobject/glib-genmarshal.in
+++ b/gobject/glib-genmarshal.in
@@ -337,6 +337,7 @@ IN_ARGS = {
'ctype': 'gpointer',
'getter': 'g_marshal_value_peek_param',
'box': ['g_param_spec_ref', 'g_param_spec_unref'],
+ 'static-check': True,
},
'BOXED': {
'signal': 'BOXED',
diff --git a/gobject/tests/genmarshal.py b/gobject/tests/genmarshal.py
index 0da61f3a2..190a1a69a 100644
--- a/gobject/tests/genmarshal.py
+++ b/gobject/tests/genmarshal.py
@@ -594,6 +594,139 @@ class TestGenmarshal(unittest.TestCase):
''').strip().format(**body_result.subs),
body_result.out.strip())
+ def test_void_param_nostdinc(self):
+ """Test running with a basic VOID:PARAM list, but without the
+ standard marshallers, and with valist support enabled. This checks that
+ the valist marshaller for PARAM correctly skips a param copy if the
+ argument is static.
+
+ See issue #1792.
+ """
+ self.maxDiff = None # TODO
+ (header_result, body_result) = \
+ self.runGenmarshalWithList('VOID:PARAM', '--quiet', '--nostdinc',
+ '--valist-marshaller')
+
+ self.assertEqual('', header_result.err)
+ self.assertEqual('', body_result.err)
+
+ self.assertEqual(dedent(
+ '''
+ /* {standard_top_comment} */
+ {standard_top_pragma}
+
+ G_BEGIN_DECLS
+
+ /* VOID:PARAM ({list_path}:1) */
+ extern
+ void g_cclosure_user_marshal_VOID__PARAM (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+ extern
+ void g_cclosure_user_marshal_VOID__PARAMv (GClosure *closure,
+ GValue *return_value,
+ gpointer instance,
+ va_list args,
+ gpointer marshal_data,
+ int n_params,
+ GType *param_types);
+
+
+ G_END_DECLS
+
+ {standard_bottom_pragma}
+ ''').strip().format(**header_result.subs),
+ header_result.out.strip())
+
+ self.assertEqual(dedent(
+ '''
+ /* {standard_top_comment} */
+ {standard_marshal_peek_defines}
+
+ /* VOID:PARAM ({list_path}:1) */
+ void
+ g_cclosure_user_marshal_VOID__PARAM (GClosure *closure,
+ GValue *return_value G_GNUC_UNUSED,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint G_GNUC_UNUSED,
+ gpointer marshal_data)
+ {{
+ typedef void (*GMarshalFunc_VOID__PARAM) (gpointer data1,
+ gpointer arg1,
+ gpointer data2);
+ GCClosure *cc = (GCClosure *) closure;
+ gpointer data1, data2;
+ GMarshalFunc_VOID__PARAM callback;
+
+ g_return_if_fail (n_param_values == 2);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {{
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }}
+ else
+ {{
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }}
+ callback = (GMarshalFunc_VOID__PARAM) (marshal_data ? marshal_data : cc->callback);
+
+ callback (data1,
+ g_marshal_value_peek_param (param_values + 1),
+ data2);
+ }}
+
+ void
+ g_cclosure_user_marshal_VOID__PARAMv (GClosure *closure,
+ GValue *return_value G_GNUC_UNUSED,
+ gpointer instance,
+ va_list args,
+ gpointer marshal_data,
+ int n_params,
+ GType *param_types)
+ {{
+ typedef void (*GMarshalFunc_VOID__PARAM) (gpointer data1,
+ gpointer arg1,
+ gpointer data2);
+ GCClosure *cc = (GCClosure *) closure;
+ gpointer data1, data2;
+ GMarshalFunc_VOID__PARAM callback;
+ gpointer arg0;
+ va_list args_copy;
+
+ G_VA_COPY (args_copy, args);
+ arg0 = (gpointer) va_arg (args_copy, gpointer);
+ if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL)
+ arg0 = g_param_spec_ref (arg0);
+ va_end (args_copy);
+
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {{
+ data1 = closure->data;
+ data2 = instance;
+ }}
+ else
+ {{
+ data1 = instance;
+ data2 = closure->data;
+ }}
+ callback = (GMarshalFunc_VOID__PARAM) (marshal_data ? marshal_data : cc->callback);
+
+ callback (data1,
+ arg0,
+ data2);
+ if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL)
+ g_param_spec_unref (arg0);
+ }}
+ ''').strip().format(**body_result.subs),
+ body_result.out.strip())
+
if __name__ == '__main__':
unittest.main(testRunner=taptestrunner.TAPTestRunner())
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]