gtype: Allow g_type_query() to be called on dynamic types

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 <pwithnall@endlessos.org>

Fixes: #623
This commit is contained in:
Philip Withnall 2023-07-30 11:25:42 +03:00
parent 43cec2d622
commit d9b23c5466
2 changed files with 30 additions and 4 deletions

View File

@ -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);

View File

@ -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 ();
}