Merge branch 'gtype-guintptr' into 'main'

GType: Use guintptr as the underlying storage if larger than gsize

See merge request GNOME/glib!3578
This commit is contained in:
Philip Withnall 2023-10-25 11:58:59 +00:00
commit cf2c2ed444
10 changed files with 66 additions and 27 deletions

View File

@ -48,6 +48,8 @@ G_TYPE_CHECK_CLASS_TYPE
G_TYPE_CHECK_VALUE
G_TYPE_CHECK_VALUE_TYPE
G_TYPE_FLAG_RESERVED_ID_BIT
GPOINTER_TO_TYPE
GTYPE_TO_POINTER
g_type_init
GTypeDebugFlags
g_type_init_with_debug_flags

View File

@ -5160,12 +5160,12 @@ class CodeGenerator:
)
for i in self.ifaces:
self.outfile.write(
' g_hash_table_insert (lookup_hash, (gpointer) "%s", GSIZE_TO_POINTER (%sTYPE_%s_PROXY));\n'
' g_hash_table_insert (lookup_hash, (gpointer) "%s", (gpointer) (guintptr) (%sTYPE_%s_PROXY));\n'
% (i.name, i.ns_upper, i.name_upper)
)
self.outfile.write(" g_once_init_leave (&once_init_value, 1);\n" " }\n")
self.outfile.write(
" ret = (GType) GPOINTER_TO_SIZE (g_hash_table_lookup (lookup_hash, interface_name));\n"
" ret = (GType) (guintptr) (g_hash_table_lookup (lookup_hash, interface_name));\n"
" if (ret == (GType) 0)\n"
" ret = G_TYPE_DBUS_PROXY;\n"
)

View File

@ -1108,6 +1108,12 @@
* @s: #gsize to stuff into the pointer
*
* Stuffs a #gsize into a pointer type.
*
* Remember, you may not store pointers in integers. This is not portable
* in any way, shape or form. These macros only allow storing integers in
* pointers, and preserve all bits of a pointer (e.g. on CHERI systems).
* The only types that can store pointers as well as integers are #guintptr
* and #gintptr.
*/
/**
@ -1116,6 +1122,14 @@
*
* Extracts a #gsize from a pointer. The #gsize must have
* been stored in the pointer with GSIZE_TO_POINTER().
*
* Remember, you may not store pointers in integers. This is not portable
* in any way, shape or form. These macros only allow storing integers in
* pointers, and preserve all bits of a pointer (e.g. on CHERI systems).
* The only types that can store pointers as well as integers are #guintptr
* and #gintptr.
*
* See also GPOINTER_TO_TYPE() for #gsize.
*/
/* Byte order {{{1 */

View File

@ -1175,7 +1175,7 @@ g_signal_type_cclosure_new (GType itype,
g_return_val_if_fail (G_TYPE_IS_CLASSED (itype) || G_TYPE_IS_INTERFACE (itype), NULL);
g_return_val_if_fail (struct_offset >= sizeof (GTypeClass), NULL);
closure = g_closure_new_simple (sizeof (GClosure), (gpointer) itype);
closure = g_closure_new_simple (sizeof (GClosure), GTYPE_TO_POINTER (itype));
if (G_TYPE_IS_INTERFACE (itype))
{
g_closure_set_meta_marshal (closure, GUINT_TO_POINTER (struct_offset), g_type_iface_meta_marshal);

View File

@ -1234,7 +1234,7 @@ g_param_spec_pool_list_owned (GParamSpecPool *pool,
g_mutex_lock (&pool->mutex);
data[0] = NULL;
data[1] = (gpointer) owner_type;
data[1] = GTYPE_TO_POINTER (owner_type);
g_hash_table_foreach (pool->hash_table, pool_list, &data);
g_mutex_unlock (&pool->mutex);
@ -1373,7 +1373,7 @@ g_param_spec_pool_list (GParamSpecPool *pool,
d = g_type_depth (owner_type);
slists = g_new0 (GSList*, d);
data[0] = slists;
data[1] = (gpointer) owner_type;
data[1] = GTYPE_TO_POINTER (owner_type);
data[2] = pool->hash_table;
data[3] = &n_pspecs;

View File

@ -1222,7 +1222,7 @@ param_gtype_set_default (GParamSpec *pspec,
{
GParamSpecGType *tspec = G_PARAM_SPEC_GTYPE (pspec);
value->data[0].v_pointer = GSIZE_TO_POINTER (tspec->is_a_type);
value->data[0].v_pointer = GTYPE_TO_POINTER (tspec->is_a_type);
}
static gboolean
@ -1230,7 +1230,7 @@ param_gtype_is_valid (GParamSpec *pspec,
const GValue *value)
{
GParamSpecGType *tspec = G_PARAM_SPEC_GTYPE (pspec);
GType gtype = GPOINTER_TO_SIZE (value->data[0].v_pointer);
GType gtype = GPOINTER_TO_TYPE (value->data[0].v_pointer);
return tspec->is_a_type == G_TYPE_NONE ||
g_type_is_a (gtype, tspec->is_a_type);
@ -1241,12 +1241,12 @@ param_gtype_validate (GParamSpec *pspec,
GValue *value)
{
GParamSpecGType *tspec = G_PARAM_SPEC_GTYPE (pspec);
GType gtype = GPOINTER_TO_SIZE (value->data[0].v_pointer);
GType gtype = GPOINTER_TO_TYPE (value->data[0].v_pointer);
guint changed = 0;
if (tspec->is_a_type != G_TYPE_NONE && !g_type_is_a (gtype, tspec->is_a_type))
{
value->data[0].v_pointer = GSIZE_TO_POINTER (tspec->is_a_type);
value->data[0].v_pointer = GTYPE_TO_POINTER (tspec->is_a_type);
changed++;
}
@ -1258,8 +1258,8 @@ param_gtype_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2)
{
GType p1 = GPOINTER_TO_SIZE (value1->data[0].v_pointer);
GType p2 = GPOINTER_TO_SIZE (value2->data[0].v_pointer);
GType p1 = GPOINTER_TO_TYPE (value1->data[0].v_pointer);
GType p2 = GPOINTER_TO_TYPE (value2->data[0].v_pointer);
/* not much to compare here, try to at least provide stable lesser/greater result */

View File

@ -1233,8 +1233,8 @@ g_signal_lookup (const gchar *name,
{
/* give elaborate warnings */
if (!g_type_name (itype))
g_critical (G_STRLOC ": unable to look up signal \"%s\" for invalid type id '%"G_GSIZE_FORMAT"'",
name, itype);
g_critical (G_STRLOC ": unable to look up signal \"%s\" for invalid type id '%"G_GUINTPTR_FORMAT"'",
name, (guintptr) itype);
else if (!g_signal_is_valid_name (name))
g_critical (G_STRLOC ": unable to look up invalid signal name \"%s\" on type '%s'",
name, g_type_name (itype));
@ -1282,8 +1282,8 @@ g_signal_list_ids (GType itype,
{
/* give elaborate warnings */
if (!g_type_name (itype))
g_critical (G_STRLOC ": unable to list signals for invalid type id '%"G_GSIZE_FORMAT"'",
itype);
g_critical (G_STRLOC ": unable to list signals for invalid type id '%"G_GUINTPTR_FORMAT"'",
(guintptr) itype);
else if (!G_TYPE_IS_INSTANTIATABLE (itype) && !G_TYPE_IS_INTERFACE (itype))
g_critical (G_STRLOC ": unable to list signals of non instantiatable type '%s'",
g_type_name (itype));
@ -2034,8 +2034,8 @@ g_signal_override_class_handler (const gchar *signal_name,
g_signal_override_class_closure (signal_id, instance_type,
g_cclosure_new (class_handler, NULL, NULL));
else
g_critical ("%s: signal name '%s' is invalid for type id '%"G_GSIZE_FORMAT"'",
G_STRLOC, signal_name, instance_type);
g_critical ("%s: signal name '%s' is invalid for type id '%"G_GUINTPTR_FORMAT"'",
G_STRLOC, signal_name, (guintptr) instance_type);
}

View File

@ -422,7 +422,7 @@ type_node_any_new_W (TypeNode *pnode,
#endif
}
else
type = (GType) node;
type = GPOINTER_TO_TYPE (node);
g_assert ((type & TYPE_ID_MASK) == 0);
@ -497,7 +497,7 @@ type_node_any_new_W (TypeNode *pnode,
node->global_gdata = NULL;
g_hash_table_insert (static_type_nodes_ht,
(gpointer) g_quark_to_string (node->qname),
(gpointer) type);
GTYPE_TO_POINTER (type));
g_atomic_int_inc ((gint *)&type_registration_serial);
@ -2721,9 +2721,9 @@ g_type_register_fundamental (GType type_id,
if ((type_id & TYPE_ID_MASK) ||
type_id > G_TYPE_FUNDAMENTAL_MAX)
{
g_critical ("attempt to register fundamental type '%s' with invalid type id (%" G_GSIZE_FORMAT ")",
g_critical ("attempt to register fundamental type '%s' with invalid type id (%" G_GUINTPTR_FORMAT ")",
type_name,
type_id);
(guintptr) type_id);
return 0;
}
if ((finfo->type_flags & G_TYPE_FLAG_INSTANTIATABLE) &&
@ -3444,7 +3444,7 @@ g_type_from_name (const gchar *name)
g_return_val_if_fail (name != NULL, 0);
G_READ_LOCK (&type_rw_lock);
type = (GType) g_hash_table_lookup (static_type_nodes_ht, name);
type = GPOINTER_TO_TYPE (g_hash_table_lookup (static_type_nodes_ht, name));
G_READ_UNLOCK (&type_rw_lock);
return type;
@ -4390,7 +4390,7 @@ g_type_value_table_peek (GType type)
return vtable;
if (!node)
g_critical (G_STRLOC ": type id '%" G_GSIZE_FORMAT "' is invalid", type);
g_critical (G_STRLOC ": type id '%" G_GUINTPTR_FORMAT "' is invalid", (guintptr) type);
if (!has_refed_data)
g_critical ("can't peek value table for type '%s' which is not currently referenced",
type_descriptive_name_I (type));

View File

@ -421,9 +421,11 @@ G_BEGIN_DECLS
* A numerical value which represents the unique identifier of a registered
* type.
*/
#if GLIB_SIZEOF_SIZE_T != GLIB_SIZEOF_LONG || !defined (G_CXX_STD_VERSION)
#if GLIB_SIZEOF_VOID_P > GLIB_SIZEOF_SIZE_T
typedef guintptr GType;
#elif GLIB_SIZEOF_SIZE_T != GLIB_SIZEOF_LONG || !defined (G_CXX_STD_VERSION)
typedef gsize GType;
#else /* for historic reasons, C++ links against gulong GTypes */
#else /* for historic reasons, C++ on non-Morello/CHERI systems links against gulong GTypes */
typedef gulong GType;
#endif
typedef struct _GValue GValue;
@ -2708,6 +2710,27 @@ const gchar * g_type_name_from_class (GTypeClass *g_class);
*/
#define G_TYPE_FLAG_RESERVED_ID_BIT ((GType) (1 << 0))
/**
* GPOINTER_TO_TYPE:
* @p: The pointer to convert to a #GType
*
* This macro should be used instead of GPOINTER_TO_SIZE() to ensure
* portability since #GType is not guaranteed to be the same as #gsize.
*
* Since: 2.80
*/
#define GPOINTER_TO_TYPE(p) ((GType) (guintptr) (p)) GOBJECT_AVAILABLE_MACRO_IN_2_80
/**
* GTYPE_TO_POINTER:
* @t: The #GType to convert to a pointer
*
* This macro should be used instead of GSIZE_TO_POINTER() to ensure
* portability since #GType is not guaranteed to be the same as #gsize.
*
* Since: 2.80
*/
#define GTYPE_TO_POINTER(t) ((gpointer) (guintptr) (t)) GOBJECT_AVAILABLE_MACRO_IN_2_80
G_END_DECLS
#endif /* __G_TYPE_H__ */

View File

@ -1208,7 +1208,7 @@ g_value_set_gtype (GValue *value,
{
g_return_if_fail (G_VALUE_HOLDS_GTYPE (value));
value->data[0].v_pointer = GSIZE_TO_POINTER (v_gtype);
value->data[0].v_pointer = GTYPE_TO_POINTER (v_gtype);
}
@ -1227,7 +1227,7 @@ g_value_get_gtype (const GValue *value)
{
g_return_val_if_fail (G_VALUE_HOLDS_GTYPE (value), 0);
return GPOINTER_TO_SIZE (value->data[0].v_pointer);
return GPOINTER_TO_TYPE (value->data[0].v_pointer);
}
/**