[perl-Glib-Object-Introspection] interface → SV: correctly marshal class struct args of functions



commit ac5409fff68705e144a16f973cce0e180dae1f6a
Author: Torsten Schönfeld <kaffeetisch gmx de>
Date:   Mon Oct 2 13:48:33 2017 +0200

    interface → SV: correctly marshal class struct args of functions
    
    Class structs were already handled correctly when they are instance args of
    methods.  Extend the special treatment to function args.  Occurs, e.g., with
    GooCanvas::CanvasItem::class_list_child_properties.

 gperl-i11n-marshal-interface.c |  107 +++++++++++++++++++++-------------------
 1 files changed, 57 insertions(+), 50 deletions(-)
---
diff --git a/gperl-i11n-marshal-interface.c b/gperl-i11n-marshal-interface.c
index 7faa4ad..851b9b9 100644
--- a/gperl-i11n-marshal-interface.c
+++ b/gperl-i11n-marshal-interface.c
@@ -1,34 +1,8 @@
 /* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; -*- */
 
-void _store_enum (GIEnumInfo * info, gint value, GIArgument * arg);
-gint _retrieve_enum (GIEnumInfo * info, GIArgument * arg);
-
-static gpointer
-instance_sv_to_class_struct_pointer (SV *sv, GPerlI11nInvocationInfo *iinfo)
-{
-       gpointer pointer = NULL;
-       GType class_type = 0;
-       dwarn ("  -> gtype struct?\n");
-       if (gperl_sv_is_ref (sv)) { /* instance? */
-               const char *package = sv_reftype (SvRV (sv), TRUE);
-               class_type = gperl_type_from_package (package);
-       } else { /* package? */
-               class_type = gperl_type_from_package (SvPV_nolen (sv));
-       }
-       dwarn ("     class_type = %s (%lu), is_classed = %d\n",
-              g_type_name (class_type), class_type, G_TYPE_IS_CLASSED (class_type));
-       if (G_TYPE_IS_CLASSED (class_type)) {
-               pointer = g_type_class_peek (class_type);
-               if (!pointer) {
-                       /* If peek() produced NULL, the class has not been
-                        * instantiated yet and needs to be created. */
-                       pointer = g_type_class_ref (class_type);
-                       free_after_call (iinfo, (GFunc) g_type_class_unref, pointer);
-               }
-               dwarn ("     type class = %p\n", pointer);
-       }
-       return pointer;
-}
+static gpointer _sv_to_class_struct_pointer (SV *sv, GPerlI11nInvocationInfo *iinfo);
+static void _store_enum (GIEnumInfo * info, gint value, GIArgument * arg);
+static gint _retrieve_enum (GIEnumInfo * info, GIArgument * arg);
 
 static gpointer
 instance_sv_to_pointer (GICallableInfo *info, SV *sv, GPerlI11nInvocationInfo *iinfo)
@@ -58,7 +32,7 @@ instance_sv_to_pointer (GICallableInfo *info, SV *sv, GPerlI11nInvocationInfo *i
                GType type = get_gtype ((GIRegisteredTypeInfo *) container);
                if (!type || type == G_TYPE_NONE) {
                        if (g_struct_info_is_gtype_struct (container)) {
-                               pointer = instance_sv_to_class_struct_pointer (sv, iinfo);
+                               pointer = _sv_to_class_struct_pointer (sv, iinfo);
                        }
                        if (!pointer) {
                                dwarn ("  -> untyped record\n");
@@ -200,29 +174,33 @@ sv_to_interface (GIArgInfo * arg_info,
                        && !g_type_info_is_pointer (type_info);
                GType type = get_gtype ((GIRegisteredTypeInfo *) interface);
                if (!type || type == G_TYPE_NONE) {
-                       const gchar *namespace, *name, *package;
-                       GType parent_type;
                        dwarn ("  -> untyped record\n");
                        g_assert (!need_value_semantics);
-                       /* Find out whether this untyped record is a member of
-                        * a boxed union before using raw hash-to-struct
-                        * conversion. */
-                       name = g_base_info_get_name (interface);
-                       namespace = g_base_info_get_namespace (interface);
-                       package = get_package_for_basename (namespace);
-                       parent_type = package ? find_union_member_gtype (package, name) : 0;
-                       if (parent_type && parent_type != G_TYPE_NONE) {
-                               arg->v_pointer = gperl_get_boxed_check (
-                                                  sv, parent_type);
-                               if (GI_TRANSFER_EVERYTHING == transfer)
-                                       arg->v_pointer =
-                                               g_boxed_copy (parent_type,
-                                                             arg->v_pointer);
+                       if (g_struct_info_is_gtype_struct (interface)) {
+                               arg->v_pointer = _sv_to_class_struct_pointer (sv, invocation_info);
                        } else {
-                               arg->v_pointer = sv_to_struct (transfer,
-                                                              interface,
-                                                              info_type,
-                                                              sv);
+                               const gchar *namespace, *name, *package;
+                               GType parent_type;
+                               /* Find out whether this untyped record is a member of
+                                * a boxed union before using raw hash-to-struct
+                                * conversion. */
+                               name = g_base_info_get_name (interface);
+                               namespace = g_base_info_get_namespace (interface);
+                               package = get_package_for_basename (namespace);
+                               parent_type = package ? find_union_member_gtype (package, name) : 0;
+                               if (parent_type && parent_type != G_TYPE_NONE) {
+                                       arg->v_pointer = gperl_get_boxed_check (
+                                                          sv, parent_type);
+                                       if (GI_TRANSFER_EVERYTHING == transfer)
+                                               arg->v_pointer =
+                                                       g_boxed_copy (parent_type,
+                                                                     arg->v_pointer);
+                               } else {
+                                       arg->v_pointer = sv_to_struct (transfer,
+                                                                      interface,
+                                                                      info_type,
+                                                                      sv);
+                               }
                        }
                }
 
@@ -465,6 +443,35 @@ interface_to_sv (GITypeInfo* info, GIArgument *arg, gboolean own, GPerlI11nInvoc
 
 /* ------------------------------------------------------------------------- */
 
+static gpointer
+_sv_to_class_struct_pointer (SV *sv, GPerlI11nInvocationInfo *iinfo)
+{
+       gpointer pointer = NULL;
+       GType class_type = 0;
+       dwarn ("  -> gtype struct?\n");
+       if (gperl_sv_is_ref (sv)) { /* instance? */
+               const char *package = sv_reftype (SvRV (sv), TRUE);
+               class_type = gperl_type_from_package (package);
+       } else { /* package? */
+               class_type = gperl_type_from_package (SvPV_nolen (sv));
+       }
+       dwarn ("     class_type = %s (%lu), is_classed = %d\n",
+              g_type_name (class_type), class_type, G_TYPE_IS_CLASSED (class_type));
+       if (G_TYPE_IS_CLASSED (class_type)) {
+               pointer = g_type_class_peek (class_type);
+               if (!pointer) {
+                       /* If peek() produced NULL, the class has not been
+                        * instantiated yet and needs to be created. */
+                       pointer = g_type_class_ref (class_type);
+                       free_after_call (iinfo, (GFunc) g_type_class_unref, pointer);
+               }
+               dwarn ("     type class = %p\n", pointer);
+       }
+       return pointer;
+}
+
+/* ------------------------------------------------------------------------- */
+
 void
 _store_enum (GIEnumInfo * info, gint value, GIArgument * arg)
 {


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