diff --git a/girepository/girepository-private.h b/girepository/girepository-private.h index 19a77262e..6e48e1ee4 100644 --- a/girepository/girepository-private.h +++ b/girepository/girepository-private.h @@ -57,8 +57,15 @@ struct _GIBaseInfo uint32_t offset; uint32_t type_is_embedded : 1; /* Used by GITypeInfo */ + + /* A copy of GIBaseInfo is exposed publicly for stack-allocated derivatives + * such as GITypeInfo, so its size is now ABI. */ + void *padding[6]; }; +G_STATIC_ASSERT (sizeof (GIBaseInfo) == sizeof (GIBaseInfoStack)); +G_STATIC_ASSERT (G_ALIGNOF (GIBaseInfo) == G_ALIGNOF (GIBaseInfoStack)); + /* Subtypes */ struct _GICallableInfo { @@ -196,18 +203,15 @@ struct _GIFieldInfo void gi_field_info_class_init (gpointer g_class, gpointer class_data); -struct _GIArgInfo -{ - GIBaseInfo parent; -}; +/* GIArgInfo is stack-allocatable so it can be used with + * gi_callable_info_load_return_type() and gi_callable_info_load_arg(), so its + * definition is actually public in gitypes.h. */ void gi_arg_info_class_init (gpointer g_class, gpointer class_data); -struct _GITypeInfo -{ - GIBaseInfo parent; -}; +/* GITypeInfo is stack-allocatable so it can be used with + * gi_arg_info_load_type(), so its definition is actually public in gitypes.h. */ void gi_type_info_class_init (gpointer g_class, gpointer class_data); diff --git a/girepository/gitypes.h b/girepository/gitypes.h index 658043e2b..12a8048bd 100644 --- a/girepository/gitypes.h +++ b/girepository/gitypes.h @@ -41,6 +41,17 @@ G_BEGIN_DECLS typedef struct _GIBaseInfo GIBaseInfo; typedef struct _GIBaseInfoClass GIBaseInfoClass; +typedef struct +{ + /*< private >*/ + GTypeInstance parent_instance; + + int dummy0; + void *dummy1[3]; + uint32_t dummy2[2]; + void *dummy3[6]; +} GIBaseInfoStack; + /* Documented in gicallableinfo.c */ typedef struct _GICallableInfo GICallableInfo; GI_AVAILABLE_IN_ALL GType gi_callable_info_get_type (void); @@ -110,11 +121,23 @@ typedef struct _GIFieldInfo GIFieldInfo; GI_AVAILABLE_IN_ALL GType gi_field_info_get_type (void); /* Documented in giarginfo.c */ -typedef struct _GIArgInfo GIArgInfo; +typedef struct +{ + /*< private >*/ + GIBaseInfoStack parent; + + void *padding[6]; +} GIArgInfo; GI_AVAILABLE_IN_ALL GType gi_arg_info_get_type (void); /* Documented in gitypeinfo.c */ -typedef struct _GITypeInfo GITypeInfo; +typedef struct +{ + /*< private >*/ + GIBaseInfoStack parent; + + void *padding[6]; +} GITypeInfo; GI_AVAILABLE_IN_ALL GType gi_type_info_get_type (void); /* Documented in giunresolvedinfo.c */ diff --git a/girepository/tests/repository.c b/girepository/tests/repository.c index f8d8c3085..48c1def31 100644 --- a/girepository/tests/repository.c +++ b/girepository/tests/repository.c @@ -152,6 +152,7 @@ test_repository_arg_info (RepositoryFixture *fx, GIFunctionInfo *method_info = NULL; GIArgInfo *arg_info = NULL; GITypeInfo *type_info = NULL; + GITypeInfo type_info_stack; unsigned int idx; g_test_summary ("Test retrieving GIArgInfos from a typelib"); @@ -188,7 +189,13 @@ test_repository_arg_info (RepositoryFixture *fx, g_assert_true (gi_type_info_is_pointer (type_info)); g_assert_cmpint (gi_type_info_get_tag (type_info), ==, GI_TYPE_TAG_UTF8); + gi_arg_info_load_type (arg_info, &type_info_stack); + g_assert_true (gi_type_info_is_pointer (&type_info_stack) == gi_type_info_is_pointer (type_info)); + g_assert_cmpint (gi_type_info_get_tag (&type_info_stack), ==, gi_type_info_get_tag (type_info)); + + gi_base_info_clear (&type_info_stack); g_clear_pointer (&type_info, gi_base_info_unref); + g_clear_pointer (&arg_info, gi_base_info_unref); g_clear_pointer (&method_info, gi_base_info_unref); g_clear_pointer (&object_info, gi_base_info_unref); @@ -237,9 +244,11 @@ test_repository_callable_info (RepositoryFixture *fx, GIFunctionInfo *method_info = NULL; GICallableInfo *callable_info; GITypeInfo *type_info = NULL; + GITypeInfo type_info_stack; GIAttributeIter iter = GI_ATTRIBUTE_ITER_INIT; const char *name, *value; GIArgInfo *arg_info = NULL; + GIArgInfo arg_info_stack; g_test_summary ("Test retrieving GICallableInfos from a typelib"); @@ -260,6 +269,12 @@ test_repository_callable_info (RepositoryFixture *fx, g_assert_nonnull (type_info); g_assert_true (gi_type_info_is_pointer (type_info)); g_assert_cmpint (gi_type_info_get_tag (type_info), ==, GI_TYPE_TAG_VOID); + + gi_callable_info_load_return_type (callable_info, &type_info_stack); + g_assert_true (gi_type_info_is_pointer (&type_info_stack) == gi_type_info_is_pointer (type_info)); + g_assert_cmpint (gi_type_info_get_tag (&type_info_stack), ==, gi_type_info_get_tag (type_info)); + + gi_base_info_clear (&type_info_stack); g_clear_pointer (&type_info, gi_base_info_unref); /* This method has no attributes */ @@ -275,6 +290,12 @@ test_repository_callable_info (RepositoryFixture *fx, arg_info = gi_callable_info_get_arg (callable_info, 0); g_assert_nonnull (arg_info); + + gi_callable_info_load_arg (callable_info, 0, &arg_info_stack); + g_assert_cmpint (gi_arg_info_get_direction (&arg_info_stack), ==, gi_arg_info_get_direction (arg_info)); + g_assert_true (gi_arg_info_may_be_null (&arg_info_stack) == gi_arg_info_may_be_null (arg_info)); + + gi_base_info_clear (&arg_info_stack); g_clear_pointer (&arg_info, gi_base_info_unref); g_assert_cmpint (gi_callable_info_get_instance_ownership_transfer (callable_info), ==, GI_TRANSFER_NOTHING);