From d9b23c5466bbd8d3c637c983d412860766927636 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Sun, 30 Jul 2023 11:25:42 +0300 Subject: [PATCH] gtype: Allow g_type_query() to be called on dynamic types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There’s no reason that anyone can think of that this should be disallowed. It’s useful for language runtimes like GJS to be able to find out the allocation size of dynamic GObjects. Signed-off-by: Philip Withnall Fixes: #623 --- gobject/gtype.c | 8 ++++++-- gobject/tests/dynamictype.c | 26 ++++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/gobject/gtype.c b/gobject/gtype.c index 72ef32cfc..e2e0c3873 100644 --- a/gobject/gtype.c +++ b/gobject/gtype.c @@ -3929,11 +3929,15 @@ type_add_flags_W (TypeNode *node, * filled in with constant values upon success * * Queries the type system for information about a specific type. + * * This function will fill in a user-provided structure to hold * type-specific information. If an invalid #GType is passed in, the * @type member of the #GTypeQuery is 0. All members filled into the * #GTypeQuery structure should be considered constant and have to be * left untouched. + * + * Since GLib 2.78, this function allows queries on dynamic types. Previously + * it only supported static types. */ void g_type_query (GType type, @@ -3943,10 +3947,10 @@ g_type_query (GType type, g_return_if_fail (query != NULL); - /* if node is not static and classed, we won't allow query */ + /* if node is not classed, we won't allow query */ query->type = 0; node = lookup_type_node_I (type); - if (node && node->is_classed && !node->plugin) + if (node && node->is_classed) { /* type is classed and probably even instantiatable */ G_READ_LOCK (&type_rw_lock); diff --git a/gobject/tests/dynamictype.c b/gobject/tests/dynamictype.c index cb33cb690..214211816 100644 --- a/gobject/tests/dynamictype.c +++ b/gobject/tests/dynamictype.c @@ -109,8 +109,6 @@ test_dynamic_type (void) { DynamicObjectClass *class; - test_module_new (module_register); - /* Not loaded until we call ref for the first time */ class = g_type_class_peek (DYNAMIC_OBJECT_TYPE); g_assert_null (class); @@ -165,6 +163,27 @@ test_dynamic_type (void) #endif } +static void +test_dynamic_type_query (void) +{ + DynamicObjectClass *class; + GTypeQuery query_result; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/623"); + + class = g_type_class_ref (DYNAMIC_OBJECT_TYPE); + g_assert_nonnull (class); + + g_type_query (DYNAMIC_OBJECT_TYPE, &query_result); + + g_assert_cmpuint (query_result.type, !=, 0); + g_assert_cmpstr (query_result.type_name, ==, "DynamicObject"); + g_assert_cmpuint (query_result.class_size, >=, sizeof (DynamicObjectClass)); + g_assert_cmpuint (query_result.instance_size, >=, sizeof (DynamicObject)); + + g_type_class_unref (class); +} + int main (int argc, char *argv[]) @@ -175,7 +194,10 @@ main (int argc, g_test_init (&argc, &argv, NULL); + test_module_new (module_register); + g_test_add_func ("/gobject/dynamic-type", test_dynamic_type); + g_test_add_func ("/gobject/dynamic-type/query", test_dynamic_type_query); return g_test_run (); }