1 /* GObject - GLib Type, Object, Parameter and Signal Library
2 * Copyright (C) 1998, 1999, 2000 Tim Janik and Red Hat, Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General
15 * Public License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
17 * Boston, MA 02111-1307, USA.
23 #define FIXME_DISABLE_PREALLOCATIONS
25 /* NOTE: some functions (some internal variants and exported ones)
26 * invalidate data portions of the TypeNodes. if external functions/callbacks
27 * are called, pointers to memory maintained by TypeNodes have to be looked up
28 * again. this affects most of the struct TypeNode fields, e.g. ->children or
29 * ->iface_entries (not ->supers[] as of recently), as all those memory portions can
30 * get realloc()ed during callback invocation.
33 * - g_type_from_name() should do an ordered array lookup after fetching the
34 * the quark, instead of a second hashtable lookup.
37 * - force interface initialization for already existing classes
40 #define G_TYPE_FLAG_MASK (G_TYPE_FLAG_CLASSED | \
41 G_TYPE_FLAG_INSTANTIATABLE | \
42 G_TYPE_FLAG_DERIVABLE | \
43 G_TYPE_FLAG_DEEP_DERIVABLE)
44 #define g_type_plugin_ref(p) ((p)->vtable->plugin_ref (p))
45 #define g_type_plugin_unref(p) ((p)->vtable->plugin_unref (p))
46 #define g_type_plugin_complete_type_info(p,t,i,v) ((p)->vtable->complete_type_info ((p), (t), (i), (v)))
47 #define g_type_plugin_complete_interface_info(p,f,t,i) ((p)->vtable->complete_interface_info ((p), (f), (t), (i)))
49 typedef struct _TypeNode TypeNode;
50 typedef struct _CommonData CommonData;
51 typedef struct _IFaceData IFaceData;
52 typedef struct _ClassData ClassData;
53 typedef struct _InstanceData InstanceData;
54 typedef union _TypeData TypeData;
55 typedef struct _IFaceEntry IFaceEntry;
56 typedef struct _IFaceHolder IFaceHolder;
59 /* --- prototypes --- */
60 static inline GTypeFundamentalInfo* type_node_fundamental_info (TypeNode *node);
61 static void type_data_make (TypeNode *node,
62 const GTypeInfo *info,
63 const GTypeValueTable *value_table);
64 static inline void type_data_ref (TypeNode *node);
65 static inline void type_data_unref (TypeNode *node,
67 static void type_data_last_unref (GType type,
71 /* --- structures --- */
75 guint n_children : 12;
79 guint is_instantiatable : 1;
86 IFaceEntry *iface_entries;
87 IFaceHolder *iface_conformants;
89 GType supers[1]; /* flexible array */
91 #define SIZEOF_BASE_TYPE_NODE() (G_STRUCT_OFFSET (TypeNode, supers))
92 #define MAX_N_SUPERS (255)
93 #define MAX_N_CHILDREN (4095)
94 #define MAX_N_IFACES (511)
106 GTypeInterface *vtable;
111 GTypeValueTable *value_table;
117 GBaseInitFunc vtable_init_base;
118 GBaseFinalizeFunc vtable_finalize_base;
124 GBaseInitFunc class_init_base;
125 GBaseFinalizeFunc class_finalize_base;
126 GClassInitFunc class_init;
127 GClassFinalizeFunc class_finalize;
128 gconstpointer class_data;
135 GBaseInitFunc class_init_base;
136 GBaseFinalizeFunc class_finalize_base;
137 GClassInitFunc class_init;
138 GClassFinalizeFunc class_finalize;
139 gconstpointer class_data;
141 guint16 instance_size;
143 GInstanceInitFunc instance_init;
144 GMemChunk *mem_chunk;
151 InstanceData instance;
155 GTypeClassCacheFunc cache_func;
159 /* --- variables --- */
160 static guint n_class_cache_funcs = 0;
161 static ClassCacheFunc *class_cache_funcs = NULL;
164 /* --- externs --- */
165 const char *g_log_domain_gobject = "GLib-Object";
166 GOBJECT_VAR GType _g_type_fundamental_last = 0;
169 /* --- type nodes --- */
170 static GHashTable *g_type_nodes_ht = NULL;
171 static GType *g_branch_seqnos = NULL;
172 static TypeNode ***g_type_nodes = NULL;
174 static inline TypeNode*
175 LOOKUP_TYPE_NODE (register GType utype)
177 register GType ftype = G_TYPE_FUNDAMENTAL (utype);
178 register GType b_seqno = G_TYPE_BRANCH_SEQNO (utype);
180 if (ftype < G_TYPE_FUNDAMENTAL_LAST && b_seqno < g_branch_seqnos[ftype])
181 return g_type_nodes[ftype][b_seqno];
185 #define NODE_TYPE(node) (node->supers[0])
186 #define NODE_PARENT_TYPE(node) (node->supers[1])
187 #define NODE_NAME(node) (g_quark_to_string (node->qname))
190 type_node_any_new (TypeNode *pnode,
194 GTypeFlags type_flags)
196 guint branch_last, n_supers = pnode ? pnode->n_supers + 1 : 0;
199 guint i, node_size = 0;
201 branch_last = g_branch_seqnos[ftype]++;
202 type = G_TYPE_DERIVE_ID (ftype, branch_last);
203 if (!branch_last || g_bit_storage (branch_last - 1) < g_bit_storage (g_branch_seqnos[ftype] - 1))
204 g_type_nodes[ftype] = g_renew (TypeNode*, g_type_nodes[ftype], 1 << g_bit_storage (g_branch_seqnos[ftype] - 1));
207 node_size += sizeof (GTypeFundamentalInfo); /* fundamental type info */
208 node_size += SIZEOF_BASE_TYPE_NODE (); /* TypeNode structure */
209 node_size += (sizeof (GType) * (1 + n_supers + 1)); /* self + ancestors + 0 for ->supers[] */
210 node = g_malloc0 (node_size);
211 if (!pnode) /* fundamental type */
212 node = G_STRUCT_MEMBER_P (node, sizeof (GTypeFundamentalInfo));
213 g_type_nodes[ftype][branch_last] = node;
215 node->n_supers = n_supers;
218 node->supers[0] = type;
221 node->is_classed = (type_flags & G_TYPE_FLAG_CLASSED) != 0;
222 node->is_instantiatable = (type_flags & G_TYPE_FLAG_INSTANTIATABLE) != 0;
223 node->is_iface = G_TYPE_IS_INTERFACE (type);
227 node->private.iface_conformants = NULL;
229 node->private.iface_entries = NULL;
233 node->supers[0] = type;
234 memcpy (node->supers + 1, pnode->supers, sizeof (GType) * (1 + pnode->n_supers + 1));
236 node->is_classed = pnode->is_classed;
237 node->is_instantiatable = pnode->is_instantiatable;
238 node->is_iface = pnode->is_iface;
243 node->private.iface_conformants = NULL;
247 node->n_ifaces = pnode->n_ifaces;
248 node->private.iface_entries = g_memdup (pnode->private.iface_entries,
249 sizeof (pnode->private.iface_entries[0]) * node->n_ifaces);
252 i = pnode->n_children++;
253 pnode->children = g_renew (GType, pnode->children, pnode->n_children);
254 pnode->children[i] = type;
257 node->plugin = plugin;
258 node->n_children = 0;
259 node->children = NULL;
261 node->qname = g_quark_from_string (name);
262 node->static_gdata = NULL;
264 g_hash_table_insert (g_type_nodes_ht,
265 GUINT_TO_POINTER (node->qname),
266 GUINT_TO_POINTER (type));
271 static inline GTypeFundamentalInfo*
272 type_node_fundamental_info (TypeNode *node)
274 GType ftype = G_TYPE_FUNDAMENTAL (NODE_TYPE (node));
276 if (ftype != NODE_TYPE (node))
277 node = LOOKUP_TYPE_NODE (ftype);
279 return node ? G_STRUCT_MEMBER_P (node, - sizeof (GTypeFundamentalInfo)) : NULL;
283 type_node_fundamental_new (GType ftype,
285 GTypeFlags type_flags)
287 GTypeFundamentalInfo *finfo;
289 guint i, flast = G_TYPE_FUNDAMENTAL_LAST;
291 g_assert (ftype == G_TYPE_FUNDAMENTAL (ftype));
293 type_flags &= G_TYPE_FLAG_MASK;
295 _g_type_fundamental_last = MAX (_g_type_fundamental_last, ftype + 1);
296 if (G_TYPE_FUNDAMENTAL_LAST > flast)
298 g_type_nodes = g_renew (TypeNode**, g_type_nodes, G_TYPE_FUNDAMENTAL_LAST);
299 g_branch_seqnos = g_renew (GType, g_branch_seqnos, G_TYPE_FUNDAMENTAL_LAST);
300 for (i = flast; i < G_TYPE_FUNDAMENTAL_LAST; i++)
302 g_type_nodes[i] = NULL;
303 g_branch_seqnos[i] = 0;
306 g_assert (g_branch_seqnos[ftype] == 0);
308 node = type_node_any_new (NULL, ftype, name, NULL, type_flags);
309 finfo = type_node_fundamental_info (node);
310 finfo->type_flags = type_flags;
316 type_node_new (TypeNode *pnode,
322 g_assert (pnode->n_supers < MAX_N_SUPERS);
323 g_assert (pnode->n_children < MAX_N_CHILDREN);
325 return type_node_any_new (pnode, G_TYPE_FUNDAMENTAL (NODE_TYPE (pnode)), name, plugin, 0);
328 static inline IFaceEntry*
329 type_lookup_iface_entry (TypeNode *node,
332 if (iface->is_iface && node->n_ifaces)
334 IFaceEntry *ifaces = node->private.iface_entries - 1;
335 guint n_ifaces = node->n_ifaces;
336 GType iface_type = NODE_TYPE (iface);
338 do /* FIXME: should optimize iface lookups for <= 4 */
343 i = (n_ifaces + 1) / 2;
345 if (iface_type == check->iface_type)
347 else if (iface_type > check->iface_type)
352 else /* if (iface_type < check->iface_type) */
362 type_descriptive_name (GType type)
366 gchar *name = g_type_name (type);
368 return name ? name : "<unknown>";
375 /* --- type consistency checks --- */
377 check_plugin (GTypePlugin *plugin,
378 gboolean need_complete_type_info,
379 gboolean need_complete_interface_info,
380 const gchar *type_name)
384 g_warning ("plugin handle for type `%s' is NULL",
390 g_warning ("plugin for type `%s' has no function table",
394 if (!plugin->vtable->plugin_ref)
396 g_warning ("plugin for type `%s' has no plugin_ref() implementation",
400 if (!plugin->vtable->plugin_unref)
402 g_warning ("plugin for type `%s' has no plugin_unref() implementation",
406 if (need_complete_type_info && !plugin->vtable->complete_type_info)
408 g_warning ("plugin for type `%s' has no complete_type_info() implementation",
412 if (need_complete_interface_info && !plugin->vtable->complete_interface_info)
414 g_warning ("plugin for type `%s' has no complete_interface_info() implementation",
422 check_type_name (const gchar *type_name)
424 static const gchar *extra_chars = "-_+";
425 const gchar *p = type_name;
428 if (!type_name[0] || !type_name[1] || !type_name[2])
430 g_warning ("type name `%s' is too short", type_name);
433 /* check the first letter */
434 name_valid = (p[0] >= 'A' && p[0] <= 'Z') || (p[0] >= 'a' && p[0] <= 'z') || p[0] == '_';
435 for (p = type_name + 1; *p; p++)
436 name_valid &= ((p[0] >= 'A' && p[0] <= 'Z') ||
437 (p[0] >= 'a' && p[0] <= 'z') ||
438 (p[0] >= '0' && p[0] <= '9') ||
439 strchr (extra_chars, p[0]));
442 g_warning ("type name `%s' contains invalid characters", type_name);
445 if (g_type_from_name (type_name))
447 g_warning ("cannot register existing type `%s'", type_name);
455 check_derivation (GType parent_type,
456 const gchar *type_name)
458 TypeNode *pnode = LOOKUP_TYPE_NODE (parent_type);
459 GTypeFundamentalInfo* finfo = type_node_fundamental_info (pnode);
463 g_warning ("cannot derive type `%s' from invalid parent type `%s'",
465 type_descriptive_name (parent_type));
468 /* ensure flat derivability */
469 if (!(finfo->type_flags & G_TYPE_FLAG_DERIVABLE))
471 g_warning ("cannot derive `%s' from non-derivable parent type `%s'",
476 /* ensure deep derivability */
477 if (parent_type != G_TYPE_FUNDAMENTAL (parent_type) &&
478 !(finfo->type_flags & G_TYPE_FLAG_DEEP_DERIVABLE))
480 g_warning ("cannot derive `%s' from non-fundamental parent type `%s'",
490 check_value_table (const gchar *type_name,
491 const GTypeValueTable *value_table)
495 else if (value_table->value_init == NULL)
497 if (value_table->value_free || value_table->value_copy ||
498 value_table->collect_type || value_table->collect_value ||
499 value_table->lcopy_type || value_table->lcopy_value)
500 g_warning ("cannot handle uninitializable values of type `%s'",
505 else /* value_table->value_init != NULL */
507 if (!value_table->value_free)
510 * g_warning ("missing `value_free()' for type `%s'", type_name);
514 if (!value_table->value_copy)
516 g_warning ("missing `value_copy()' for type `%s'", type_name);
519 if ((value_table->collect_type || value_table->collect_value) &&
520 (!value_table->collect_type || !value_table->collect_value))
522 g_warning ("one of `collect_type' and `collect_value()' is unspecified for type `%s'",
526 if ((value_table->lcopy_type || value_table->lcopy_value) &&
527 (!value_table->lcopy_type || !value_table->lcopy_value))
529 g_warning ("one of `lcopy_type' and `lcopy_value()' is unspecified for type `%s'",
539 check_type_info (TypeNode *pnode,
541 const gchar *type_name,
542 const GTypeInfo *info)
544 GTypeFundamentalInfo *finfo = type_node_fundamental_info (LOOKUP_TYPE_NODE (ftype));
545 gboolean is_interface = G_TYPE_IS_INTERFACE (ftype);
547 /* check instance members */
548 if (!(finfo->type_flags & G_TYPE_FLAG_INSTANTIATABLE) &&
549 (info->instance_size || info->n_preallocs || info->instance_init))
552 g_warning ("cannot instantiate `%s', derived from non-instantiatable parent type `%s'",
556 g_warning ("cannot instantiate `%s' as non-instantiatable fundamental",
560 /* check class & interface members */
561 if (!(finfo->type_flags & G_TYPE_FLAG_CLASSED) &&
562 (info->class_init || info->class_finalize || info->class_data ||
563 (!is_interface && (info->class_size || info->base_init || info->base_finalize))))
566 g_warning ("cannot create class for `%s', derived from non-classed parent type `%s'",
570 g_warning ("cannot create class for `%s' as non-classed fundamental",
574 /* check interface size */
575 if (is_interface && info->class_size < sizeof (GTypeInterface))
577 g_warning ("specified interface size for type `%s' is smaller than `GTypeInterface' size",
581 /* check class size */
582 if (finfo->type_flags & G_TYPE_FLAG_CLASSED)
584 if (info->class_size < sizeof (GTypeClass))
586 g_warning ("specified class size for type `%s' is smaller than `GTypeClass' size",
590 if (pnode && info->class_size < pnode->data->class.class_size)
592 g_warning ("specified class size for type `%s' is smaller "
593 "than the parent type's `%s' class size",
599 /* check instance size */
600 if (finfo->type_flags & G_TYPE_FLAG_INSTANTIATABLE)
602 if (info->instance_size < sizeof (GTypeInstance))
604 g_warning ("specified instance size for type `%s' is smaller than `GTypeInstance' size",
608 if (pnode && info->instance_size < pnode->data->instance.instance_size)
610 g_warning ("specified instance size for type `%s' is smaller "
611 "than the parent type's `%s' instance size",
622 find_conforming_type (TypeNode *pnode,
625 TypeNode *node = NULL;
628 if (type_lookup_iface_entry (pnode, iface))
631 for (i = 0; i < pnode->n_children && !node; i++)
632 node = find_conforming_type (LOOKUP_TYPE_NODE (pnode->children[i]), iface);
638 check_add_interface (GType instance_type,
641 TypeNode *node = LOOKUP_TYPE_NODE (instance_type);
642 TypeNode *iface = LOOKUP_TYPE_NODE (iface_type);
645 if (!node || !node->is_instantiatable)
647 g_warning ("cannot add interfaces to invalid (non-instantiatable) type `%s'",
648 type_descriptive_name (instance_type));
651 if (!iface || !iface->is_iface)
653 g_warning ("cannot add invalid (non-interface) type `%s' to type `%s'",
654 type_descriptive_name (iface_type),
658 tnode = LOOKUP_TYPE_NODE (NODE_PARENT_TYPE (iface));
659 if (NODE_PARENT_TYPE (tnode) && !type_lookup_iface_entry (node, tnode))
661 g_warning ("cannot add sub-interface `%s' to type `%s' which does not conform to super-interface `%s'",
667 tnode = find_conforming_type (node, iface);
670 g_warning ("cannot add interface type `%s' to type `%s', since type `%s' already conforms to interface",
681 check_interface_info (TypeNode *iface,
683 const GInterfaceInfo *info)
685 if ((info->interface_finalize || info->interface_data) && !info->interface_init)
687 g_warning ("interface type `%s' for type `%s' comes without initializer",
689 type_descriptive_name (instance_type));
697 /* --- type info (type node data) --- */
699 type_data_make (TypeNode *node,
700 const GTypeInfo *info,
701 const GTypeValueTable *value_table)
704 GTypeValueTable *vtable = NULL;
705 guint vtable_size = 0;
707 g_assert (node->data == NULL && info != NULL);
711 TypeNode *pnode = LOOKUP_TYPE_NODE (NODE_PARENT_TYPE (node));
714 vtable = pnode->data->common.value_table;
717 static const GTypeValueTable zero_vtable = { NULL, };
719 value_table = &zero_vtable;
723 vtable_size = sizeof (GTypeValueTable);
725 if (node->is_instantiatable) /* carefull, is_instantiatable is also is_classed */
727 data = g_malloc0 (sizeof (InstanceData) + vtable_size);
729 vtable = G_STRUCT_MEMBER_P (data, sizeof (InstanceData));
730 data->instance.class_size = info->class_size;
731 data->instance.class_init_base = info->base_init;
732 data->instance.class_finalize_base = info->base_finalize;
733 data->instance.class_init = info->class_init;
734 data->instance.class_finalize = info->class_finalize;
735 data->instance.class_data = info->class_data;
736 data->instance.class = NULL;
737 data->instance.instance_size = info->instance_size;
738 data->instance.n_preallocs = MIN (info->n_preallocs, 1024);
739 #ifdef FIXME_DISABLE_PREALLOCATIONS
740 data->instance.n_preallocs = 0;
742 data->instance.instance_init = info->instance_init;
743 data->instance.mem_chunk = NULL;
745 else if (node->is_classed) /* only classed */
747 data = g_malloc0 (sizeof (ClassData) + vtable_size);
749 vtable = G_STRUCT_MEMBER_P (data, sizeof (ClassData));
750 data->class.class_size = info->class_size;
751 data->class.class_init_base = info->base_init;
752 data->class.class_finalize_base = info->base_finalize;
753 data->class.class_init = info->class_init;
754 data->class.class_finalize = info->class_finalize;
755 data->class.class_data = info->class_data;
756 data->class.class = NULL;
758 else if (node->is_iface)
760 data = g_malloc0 (sizeof (IFaceData) + vtable_size);
762 vtable = G_STRUCT_MEMBER_P (data, sizeof (IFaceData));
763 data->iface.vtable_size = info->class_size;
764 data->iface.vtable_init_base = info->base_init;
765 data->iface.vtable_finalize_base = info->base_finalize;
769 data = g_malloc0 (sizeof (CommonData) + vtable_size);
771 vtable = G_STRUCT_MEMBER_P (data, sizeof (CommonData));
775 node->data->common.ref_count = 1;
778 *vtable = *value_table;
779 node->data->common.value_table = vtable;
781 g_assert (node->data->common.value_table != NULL); // FIXME: paranoid
785 type_data_ref (TypeNode *node)
789 TypeNode *pnode = LOOKUP_TYPE_NODE (NODE_PARENT_TYPE (node));
791 GTypeValueTable tmp_value_table;
793 g_assert (node->plugin != NULL);
796 type_data_ref (pnode);
798 memset (&tmp_info, 0, sizeof (tmp_info));
799 memset (&tmp_value_table, 0, sizeof (tmp_value_table));
800 g_type_plugin_ref (node->plugin);
801 g_type_plugin_complete_type_info (node->plugin, NODE_TYPE (node), &tmp_info, &tmp_value_table);
802 check_type_info (pnode, G_TYPE_FUNDAMENTAL (NODE_TYPE (node)), NODE_NAME (node), &tmp_info);
803 type_data_make (node, &tmp_info,
804 check_value_table (NODE_NAME (node), &tmp_value_table) ? &tmp_value_table : NULL);
808 g_assert (node->data->common.ref_count > 0);
810 node->data->common.ref_count += 1;
815 type_data_unref (TypeNode *node,
818 g_assert (node->data && node->data->common.ref_count);
820 if (node->data->common.ref_count > 1)
821 node->data->common.ref_count -= 1;
826 g_warning ("static type `%s' unreferenced too often",
831 type_data_last_unref (NODE_TYPE (node), uncached);
836 type_node_add_iface_entry (TypeNode *node,
842 g_assert (node->is_instantiatable && node->n_ifaces < MAX_N_IFACES);
845 node->private.iface_entries = g_renew (IFaceEntry, node->private.iface_entries, node->n_ifaces);
846 entries = node->private.iface_entries;
847 for (i = 0; i < node->n_ifaces - 1; i++)
848 if (entries[i].iface_type > iface_type)
850 g_memmove (entries + i + 1, entries + i, sizeof (entries[0]) * (node->n_ifaces - i - 1));
851 entries[i].iface_type = iface_type;
852 entries[i].vtable = NULL;
854 for (i = 0; i < node->n_children; i++)
855 type_node_add_iface_entry (LOOKUP_TYPE_NODE (node->children[i]), iface_type);
859 type_add_interface (TypeNode *node,
861 GInterfaceInfo *info,
864 IFaceHolder *iholder = g_new0 (IFaceHolder, 1);
866 /* we must not call any functions of GInterfaceInfo from within here, since
867 * we got most probably called from _within_ a type registration function
869 g_assert (node->is_instantiatable && iface->is_iface && ((info && !plugin) || (!info && plugin)));
871 iholder->next = iface->private.iface_conformants;
872 iface->private.iface_conformants = iholder;
873 iholder->instance_type = NODE_TYPE (node);
874 iholder->info = info ? g_memdup (info, sizeof (*info)) : NULL;
875 iholder->plugin = plugin;
877 type_node_add_iface_entry (node, NODE_TYPE (iface));
881 type_iface_retrive_holder_info (TypeNode *iface,
884 IFaceHolder *iholder = iface->private.iface_conformants;
886 g_assert (iface->is_iface);
888 while (iholder->instance_type != instance_type)
889 iholder = iholder->next;
893 GInterfaceInfo tmp_info;
895 g_assert (iholder->plugin != NULL);
897 type_data_ref (iface);
899 memset (&tmp_info, 0, sizeof (tmp_info));
900 g_type_plugin_ref (iholder->plugin);
901 g_type_plugin_complete_interface_info (iholder->plugin, NODE_TYPE (iface), instance_type, &tmp_info);
902 check_interface_info (iface, instance_type, &tmp_info);
903 iholder->info = g_memdup (&tmp_info, sizeof (tmp_info));
910 type_iface_blow_holder_info (TypeNode *iface,
913 IFaceHolder *iholder = iface->private.iface_conformants;
915 g_assert (iface->is_iface);
917 while (iholder->instance_type != instance_type)
918 iholder = iholder->next;
920 if (iholder->info && iholder->plugin)
922 g_free (iholder->info);
923 iholder->info = NULL;
924 g_type_plugin_unref (iholder->plugin);
926 type_data_unref (iface, FALSE);
931 /* --- type structure creation/destruction --- */
933 g_type_create_instance (GType type)
935 TypeNode *node = LOOKUP_TYPE_NODE (type);
936 GTypeInstance *instance;
940 if (!node || !node->is_instantiatable)
942 g_warning ("cannot create new instance of invalid (non-instantiatable) type `%s'",
943 type_descriptive_name (type));
947 class = g_type_class_ref (type);
949 if (node->data->instance.n_preallocs)
951 if (!node->data->instance.mem_chunk)
952 node->data->instance.mem_chunk = g_mem_chunk_new (NODE_NAME (node),
953 node->data->instance.instance_size,
954 (node->data->instance.instance_size *
955 node->data->instance.n_preallocs),
957 instance = g_chunk_new0 (GTypeInstance, node->data->instance.mem_chunk);
960 instance = g_malloc0 (node->data->instance.instance_size);
962 for (i = node->n_supers; i > 0; i--)
964 TypeNode *pnode = LOOKUP_TYPE_NODE (node->supers[i]);
966 if (pnode->data->instance.instance_init)
968 instance->g_class = pnode->data->instance.class;
969 pnode->data->instance.instance_init (instance, class);
972 instance->g_class = class;
973 if (node->data->instance.instance_init)
974 node->data->instance.instance_init (instance, class);
980 g_type_free_instance (GTypeInstance *instance)
985 g_return_if_fail (instance != NULL && instance->g_class != NULL);
987 class = instance->g_class;
988 node = LOOKUP_TYPE_NODE (class->g_type);
989 if (!node || !node->is_instantiatable || !node->data || node->data->class.class != (gpointer) class)
991 g_warning ("cannot free instance of invalid (non-instantiatable) type `%s'",
992 type_descriptive_name (class->g_type));
996 instance->g_class = NULL;
997 if (node->data->instance.n_preallocs)
998 g_chunk_free (instance, node->data->instance.mem_chunk);
1002 g_type_class_unref (class);
1006 type_propagate_iface_vtable (TypeNode *pnode,
1008 GTypeInterface *vtable)
1010 IFaceEntry *entry = type_lookup_iface_entry (pnode, iface);
1013 entry->vtable = vtable;
1014 for (i = 0; i < pnode->n_children; i++)
1016 TypeNode *node = LOOKUP_TYPE_NODE (pnode->children[i]);
1018 type_propagate_iface_vtable (node, iface, vtable);
1023 type_iface_vtable_init (TypeNode *iface,
1026 IFaceEntry *entry = type_lookup_iface_entry (node, iface);
1027 IFaceHolder *iholder = type_iface_retrive_holder_info (iface, NODE_TYPE (node));
1028 GTypeInterface *vtable;
1030 g_assert (iface->data && entry && entry->vtable == NULL && iholder && iholder->info);
1032 vtable = g_malloc0 (iface->data->iface.vtable_size);
1033 type_propagate_iface_vtable (node, iface, vtable);
1034 vtable->g_type = NODE_TYPE (iface);
1035 vtable->g_instance_type = NODE_TYPE (node);
1037 if (iface->data->iface.vtable_init_base)
1038 iface->data->iface.vtable_init_base (vtable);
1039 if (iholder->info->interface_init)
1040 iholder->info->interface_init (vtable, iholder->info->interface_data);
1044 type_iface_vtable_finalize (TypeNode *iface,
1046 GTypeInterface *vtable)
1048 IFaceEntry *entry = type_lookup_iface_entry (node, iface);
1049 IFaceHolder *iholder = iface->private.iface_conformants;
1051 g_assert (entry && entry->vtable == vtable);
1053 while (iholder->instance_type != NODE_TYPE (node))
1054 iholder = iholder->next;
1055 g_assert (iholder && iholder->info);
1057 type_propagate_iface_vtable (node, iface, NULL);
1058 if (iholder->info->interface_finalize)
1059 iholder->info->interface_finalize (vtable, iholder->info->interface_data);
1060 if (iface->data->iface.vtable_finalize_base)
1061 iface->data->iface.vtable_finalize_base (vtable);
1064 vtable->g_instance_type = 0;
1067 type_iface_blow_holder_info (iface, NODE_TYPE (node));
1071 type_class_init (TypeNode *node,
1074 GSList *slist, *init_slist = NULL;
1080 g_assert (node->is_classed && node->data &&
1081 node->data->class.class_size &&
1082 !node->data->class.class);
1084 class = g_malloc0 (node->data->class.class_size);
1085 node->data->class.class = class;
1089 TypeNode *pnode = LOOKUP_TYPE_NODE (pclass->g_type);
1091 memcpy (class, pclass, pnode->data->class.class_size);
1094 class->g_type = NODE_TYPE (node);
1096 /* stack all base class initialization functions, so we
1097 * call them in ascending order.
1099 for (bnode = node; bnode; bnode = LOOKUP_TYPE_NODE (NODE_PARENT_TYPE (bnode)))
1100 if (bnode->data->class.class_init_base)
1101 init_slist = g_slist_prepend (init_slist, bnode->data->class.class_init_base);
1102 for (slist = init_slist; slist; slist = slist->next)
1104 GBaseInitFunc class_init_base = slist->data;
1106 class_init_base (class);
1108 g_slist_free (init_slist);
1110 if (node->data->class.class_init)
1111 node->data->class.class_init (class, (gpointer) node->data->class.class_data);
1113 /* ok, we got the class done, now initialize all interfaces */
1114 for (entry = NULL, i = 0; i < node->n_ifaces; i++)
1115 if (!node->private.iface_entries[i].vtable)
1116 entry = node->private.iface_entries + i;
1119 type_iface_vtable_init (LOOKUP_TYPE_NODE (entry->iface_type), node);
1121 for (entry = NULL, i = 0; i < node->n_ifaces; i++)
1122 if (!node->private.iface_entries[i].vtable)
1123 entry = node->private.iface_entries + i;
1128 type_data_finalize_class_ifaces (TypeNode *node)
1133 g_assert (node->is_instantiatable && node->data && node->data->class.class && node->data->common.ref_count == 0);
1135 g_message ("finalizing interfaces for %sClass `%s'",
1136 type_descriptive_name (G_TYPE_FUNDAMENTAL (NODE_TYPE (node))),
1137 type_descriptive_name (NODE_TYPE (node)));
1139 for (entry = NULL, i = 0; i < node->n_ifaces; i++)
1140 if (node->private.iface_entries[i].vtable &&
1141 node->private.iface_entries[i].vtable->g_instance_type == NODE_TYPE (node))
1142 entry = node->private.iface_entries + i;
1145 type_iface_vtable_finalize (LOOKUP_TYPE_NODE (entry->iface_type), node, entry->vtable);
1147 for (entry = NULL, i = 0; i < node->n_ifaces; i++)
1148 if (node->private.iface_entries[i].vtable &&
1149 node->private.iface_entries[i].vtable->g_instance_type == NODE_TYPE (node))
1150 entry = node->private.iface_entries + i;
1155 type_data_finalize_class (TypeNode *node,
1158 GTypeClass *class = cdata->class;
1161 g_assert (cdata->class && cdata->common.ref_count == 0);
1163 g_message ("finalizing %sClass `%s'",
1164 type_descriptive_name (G_TYPE_FUNDAMENTAL (NODE_TYPE (node))),
1165 type_descriptive_name (NODE_TYPE (node)));
1167 if (cdata->class_finalize)
1168 cdata->class_finalize (class, (gpointer) cdata->class_data);
1170 /* call all base class destruction functions in descending order
1172 if (cdata->class_finalize_base)
1173 cdata->class_finalize_base (class);
1174 for (bnode = LOOKUP_TYPE_NODE (NODE_PARENT_TYPE (node)); bnode; bnode = LOOKUP_TYPE_NODE (NODE_PARENT_TYPE (bnode)))
1175 if (bnode->data->class.class_finalize_base)
1176 bnode->data->class.class_finalize_base (class);
1179 g_free (cdata->class);
1183 type_data_last_unref (GType type,
1186 TypeNode *node = LOOKUP_TYPE_NODE (type);
1188 g_return_if_fail (node != NULL && node->plugin != NULL);
1190 if (!node->data || node->data->common.ref_count == 0)
1192 g_warning ("cannot drop last reference to unreferenced type `%s'",
1193 type_descriptive_name (type));
1197 if (node->is_classed && node->data && node->data->class.class)
1201 for (i = 0; i < n_class_cache_funcs; i++)
1202 if (class_cache_funcs[i].cache_func (class_cache_funcs[i].cache_data, node->data->class.class))
1206 if (node->data->common.ref_count > 1) /* may have been re-referenced meanwhile */
1207 node->data->common.ref_count -= 1;
1210 GType ptype = NODE_PARENT_TYPE (node);
1213 node->data->common.ref_count = 0;
1215 if (node->is_instantiatable && node->data->instance.mem_chunk)
1217 g_mem_chunk_destroy (node->data->instance.mem_chunk);
1218 node->data->instance.mem_chunk = NULL;
1222 if (node->is_classed && tdata->class.class)
1225 type_data_finalize_class_ifaces (node);
1227 type_data_finalize_class (node, &tdata->class);
1235 type_data_unref (LOOKUP_TYPE_NODE (ptype), FALSE);
1236 g_type_plugin_unref (node->plugin);
1241 g_type_add_class_cache_func (gpointer cache_data,
1242 GTypeClassCacheFunc cache_func)
1246 g_return_if_fail (cache_func != NULL);
1248 i = n_class_cache_funcs++;
1249 class_cache_funcs = g_renew (ClassCacheFunc, class_cache_funcs, n_class_cache_funcs);
1250 class_cache_funcs[i].cache_data = cache_data;
1251 class_cache_funcs[i].cache_func = cache_func;
1255 g_type_remove_class_cache_func (gpointer cache_data,
1256 GTypeClassCacheFunc cache_func)
1260 g_return_if_fail (cache_func != NULL);
1262 for (i = 0; i < n_class_cache_funcs; i++)
1263 if (class_cache_funcs[i].cache_data == cache_data &&
1264 class_cache_funcs[i].cache_func == cache_func)
1266 n_class_cache_funcs--;
1267 g_memmove (class_cache_funcs + i,
1268 class_cache_funcs + i + 1,
1269 sizeof (class_cache_funcs[0]) * (n_class_cache_funcs - i));
1270 class_cache_funcs = g_renew (ClassCacheFunc, class_cache_funcs, n_class_cache_funcs);
1275 g_warning (G_STRLOC ": cannot remove unregistered class cache func %p with data %p",
1276 cache_func, cache_data);
1280 /* --- type registration --- */
1282 g_type_register_fundamental (GType type_id,
1283 const gchar *type_name,
1284 const GTypeInfo *info,
1285 const GTypeFundamentalInfo *finfo)
1287 GTypeFundamentalInfo *node_finfo;
1290 g_return_val_if_fail (type_id > 0, 0);
1291 g_return_val_if_fail (type_name != NULL, 0);
1292 g_return_val_if_fail (info != NULL, 0);
1293 g_return_val_if_fail (finfo != NULL, 0);
1295 if (!check_type_name (type_name))
1297 if (G_TYPE_FUNDAMENTAL (type_id) != type_id)
1299 g_warning ("cannot register fundamental type `%s' with non-fundamental id (%u)",
1304 if (LOOKUP_TYPE_NODE (type_id))
1306 g_warning ("cannot register existing fundamental type `%s' (as `%s')",
1307 type_descriptive_name (type_id),
1311 if ((finfo->type_flags & G_TYPE_FLAG_INSTANTIATABLE) &&
1312 !(finfo->type_flags & G_TYPE_FLAG_CLASSED))
1314 g_warning ("cannot register instantiatable fundamental type `%s' as non-classed",
1319 node = type_node_fundamental_new (type_id, type_name, finfo->type_flags);
1320 node_finfo = type_node_fundamental_info (node);
1322 if (!check_type_info (NULL, G_TYPE_FUNDAMENTAL (NODE_TYPE (node)), type_name, info))
1323 return NODE_TYPE (node);
1324 type_data_make (node, info,
1325 check_value_table (type_name, info->value_table) ? info->value_table : NULL);
1327 return NODE_TYPE (node);
1331 g_type_register_static (GType parent_type,
1332 const gchar *type_name,
1333 const GTypeInfo *info)
1335 TypeNode *pnode, *node;
1338 g_return_val_if_fail (parent_type > 0, 0);
1339 g_return_val_if_fail (type_name != NULL, 0);
1340 g_return_val_if_fail (info != NULL, 0);
1342 if (!check_type_name (type_name))
1344 if (!check_derivation (parent_type, type_name))
1347 pnode = LOOKUP_TYPE_NODE (parent_type);
1348 type_data_ref (pnode);
1350 if (!check_type_info (pnode, G_TYPE_FUNDAMENTAL (parent_type), type_name, info))
1352 if (info->class_finalize)
1354 g_warning ("class destructor specified for static type `%s'",
1359 node = type_node_new (pnode, type_name, NULL);
1360 type = NODE_TYPE (node);
1361 type_data_make (node, info,
1362 check_value_table (type_name, info->value_table) ? info->value_table : NULL);
1368 g_type_register_dynamic (GType parent_type,
1369 const gchar *type_name,
1370 GTypePlugin *plugin)
1372 TypeNode *pnode, *node;
1375 g_return_val_if_fail (parent_type > 0, 0);
1376 g_return_val_if_fail (type_name != NULL, 0);
1377 g_return_val_if_fail (plugin != NULL, 0);
1379 if (!check_type_name (type_name))
1381 if (!check_derivation (parent_type, type_name))
1383 if (!check_plugin (plugin, TRUE, FALSE, type_name))
1385 pnode = LOOKUP_TYPE_NODE (parent_type);
1387 node = type_node_new (pnode, type_name, plugin);
1388 type = NODE_TYPE (node);
1394 g_type_add_interface_static (GType instance_type,
1395 GType interface_type,
1396 GInterfaceInfo *info)
1401 g_return_if_fail (G_TYPE_IS_INSTANTIATABLE (instance_type));
1402 g_return_if_fail (g_type_parent (interface_type) == G_TYPE_INTERFACE);
1404 if (!check_add_interface (instance_type, interface_type))
1406 node = LOOKUP_TYPE_NODE (instance_type);
1407 iface = LOOKUP_TYPE_NODE (interface_type);
1408 if (!check_interface_info (iface, NODE_TYPE (node), info))
1410 type_add_interface (node, iface, info, NULL);
1414 g_type_add_interface_dynamic (GType instance_type,
1415 GType interface_type,
1416 GTypePlugin *plugin)
1421 g_return_if_fail (G_TYPE_IS_INSTANTIATABLE (instance_type));
1422 g_return_if_fail (g_type_parent (interface_type) == G_TYPE_INTERFACE);
1424 if (!check_add_interface (instance_type, interface_type))
1426 node = LOOKUP_TYPE_NODE (instance_type);
1427 iface = LOOKUP_TYPE_NODE (interface_type);
1428 if (!check_plugin (plugin, FALSE, TRUE, NODE_NAME (node)))
1430 type_add_interface (node, iface, NULL, plugin);
1434 /* --- public API functions --- */
1436 g_type_class_ref (GType type)
1438 TypeNode *node = LOOKUP_TYPE_NODE (type);
1440 /* optimize for common code path
1442 if (node && node->is_classed && node->data &&
1443 node->data->class.class && node->data->common.ref_count > 0)
1445 type_data_ref (node);
1447 return node->data->class.class;
1450 if (!node || !node->is_classed ||
1451 (node->data && node->data->common.ref_count < 1))
1453 g_warning ("cannot retrive class for invalid (unclassed) type `%s'",
1454 type_descriptive_name (type));
1458 type_data_ref (node);
1460 if (!node->data->class.class)
1462 GType ptype = NODE_PARENT_TYPE (node);
1463 GTypeClass *pclass = ptype ? g_type_class_ref (ptype) : NULL;
1465 type_class_init (node, pclass);
1468 return node->data->class.class;
1472 g_type_class_unref (gpointer g_class)
1475 GTypeClass *class = g_class;
1477 g_return_if_fail (g_class != NULL);
1479 node = LOOKUP_TYPE_NODE (class->g_type);
1480 if (node && node->is_classed && node->data &&
1481 node->data->class.class == class && node->data->common.ref_count > 0)
1482 type_data_unref (node, FALSE);
1484 g_warning ("cannot unreference class of invalid (unclassed) type `%s'",
1485 type_descriptive_name (class->g_type));
1489 g_type_class_unref_uncached (gpointer g_class)
1492 GTypeClass *class = g_class;
1494 g_return_if_fail (g_class != NULL);
1496 node = LOOKUP_TYPE_NODE (class->g_type);
1497 if (node && node->is_classed && node->data &&
1498 node->data->class.class == class && node->data->common.ref_count > 0)
1499 type_data_unref (node, TRUE);
1501 g_warning ("cannot unreference class of invalid (unclassed) type `%s'",
1502 type_descriptive_name (class->g_type));
1506 g_type_class_peek (GType type)
1508 TypeNode *node = LOOKUP_TYPE_NODE (type);
1510 if (node && node->is_classed && node->data && node->data->class.class) /* common.ref_count _may_ be 0 */
1511 return node->data->class.class;
1517 g_type_class_peek_parent (gpointer g_class)
1521 g_return_val_if_fail (g_class != NULL, NULL);
1523 node = LOOKUP_TYPE_NODE (G_TYPE_FROM_CLASS (g_class));
1524 if (node && node->is_classed && node->data && NODE_PARENT_TYPE (node))
1526 node = LOOKUP_TYPE_NODE (NODE_PARENT_TYPE (node));
1528 return node->data->class.class;
1535 g_type_interface_peek (gpointer instance_class,
1540 GTypeClass *class = instance_class;
1542 g_return_val_if_fail (instance_class != NULL, NULL);
1544 node = LOOKUP_TYPE_NODE (class->g_type);
1545 iface = LOOKUP_TYPE_NODE (iface_type);
1546 if (node && node->is_instantiatable && iface)
1548 IFaceEntry *entry = type_lookup_iface_entry (node, iface);
1550 if (entry && entry->vtable)
1551 return entry->vtable;
1558 g_type_value_table_peek (GType type)
1560 TypeNode *node = LOOKUP_TYPE_NODE (type);
1562 if (node && node->data && node->data->common.ref_count > 0)
1563 return node->data->common.value_table->value_init ? node->data->common.value_table : NULL;
1569 g_type_name (GType type)
1571 TypeNode *node = LOOKUP_TYPE_NODE (type);
1573 return node ? NODE_NAME (node) : NULL;
1577 g_type_qname (GType type)
1579 TypeNode *node = LOOKUP_TYPE_NODE (type);
1581 return node ? node->qname : 0;
1585 g_type_from_name (const gchar *name)
1589 g_return_val_if_fail (name != NULL, 0);
1591 quark = g_quark_try_string (name);
1594 GType type = GPOINTER_TO_UINT (g_hash_table_lookup (g_type_nodes_ht, GUINT_TO_POINTER (quark)));
1604 g_type_parent (GType type)
1606 TypeNode *node = LOOKUP_TYPE_NODE (type);
1608 return node ? NODE_PARENT_TYPE (node) : 0;
1612 g_type_next_base (GType type,
1615 TypeNode *node = LOOKUP_TYPE_NODE (type);
1619 TypeNode *base_node = LOOKUP_TYPE_NODE (base_type);
1621 if (base_node && base_node->n_supers < node->n_supers)
1623 guint n = node->n_supers - base_node->n_supers;
1625 if (node->supers[n] == base_type)
1626 return node->supers[n - 1];
1634 g_type_is_a (GType type,
1637 if (type != is_a_type)
1639 TypeNode *node = LOOKUP_TYPE_NODE (type);
1643 TypeNode *a_node = LOOKUP_TYPE_NODE (is_a_type);
1645 if (a_node && a_node->n_supers <= node->n_supers)
1646 return node->supers[node->n_supers - a_node->n_supers] == is_a_type;
1650 return LOOKUP_TYPE_NODE (type) != NULL;
1656 g_type_conforms_to (GType type,
1659 if (type != iface_type)
1661 TypeNode *node = LOOKUP_TYPE_NODE (type);
1665 TypeNode *iface_node = LOOKUP_TYPE_NODE (iface_type);
1669 if (iface_node->is_iface && node->is_instantiatable)
1670 return type_lookup_iface_entry (node, iface_node) != NULL;
1671 else if (iface_node->n_supers <= node->n_supers)
1672 return node->supers[node->n_supers - iface_node->n_supers] == iface_type;
1678 TypeNode *node = LOOKUP_TYPE_NODE (type);
1680 return node && (node->is_iface || node->is_instantiatable);
1687 g_type_fundamental_branch_last (GType type)
1689 GType ftype = G_TYPE_FUNDAMENTAL (type);
1691 return ftype < G_TYPE_FUNDAMENTAL_LAST ? g_branch_seqnos[ftype] : 0;
1694 GType* /* free result */
1695 g_type_children (GType type,
1698 TypeNode *node = LOOKUP_TYPE_NODE (type);
1702 GType *children = g_new (GType, node->n_children + 1);
1704 memcpy (children, node->children, sizeof (GType) * node->n_children);
1705 children[node->n_children] = 0;
1708 *n_children = node->n_children;
1721 GType* /* free result */
1722 g_type_interfaces (GType type,
1723 guint *n_interfaces)
1725 TypeNode *node = LOOKUP_TYPE_NODE (type);
1727 if (node && node->is_instantiatable)
1729 GType *ifaces = g_new (GType, node->n_ifaces + 1);
1732 for (i = 0; i < node->n_ifaces; i++)
1733 ifaces[i] = node->private.iface_entries[i].iface_type;
1737 *n_interfaces = node->n_ifaces;
1750 typedef struct _QData QData;
1763 g_type_get_qdata (GType type,
1766 TypeNode *node = LOOKUP_TYPE_NODE (type);
1769 g_return_val_if_fail (node != NULL, NULL);
1771 gdata = node->static_gdata;
1772 if (quark && gdata && gdata->n_qdatas)
1774 QData *qdatas = gdata->qdatas - 1;
1775 guint n_qdatas = gdata->n_qdatas;
1777 do /* FIXME: should optimize qdata lookups for <= 4 */
1782 i = (n_qdatas + 1) / 2;
1784 if (quark == check->quark)
1786 else if (quark > check->quark)
1791 else /* if (quark < check->quark) */
1801 g_type_set_qdata (GType type,
1805 TypeNode *node = LOOKUP_TYPE_NODE (type);
1810 g_return_if_fail (node != NULL);
1811 g_return_if_fail (quark != 0);
1813 /* setup qdata list if necessary */
1814 if (!node->static_gdata)
1815 node->static_gdata = g_new0 (GData, 1);
1816 gdata = node->static_gdata;
1818 /* try resetting old data */
1819 qdata = gdata->qdatas;
1820 for (i = 0; i < gdata->n_qdatas; i++)
1821 if (qdata[i].quark == quark)
1823 qdata[i].data = data;
1829 gdata->qdatas = g_renew (QData, gdata->qdatas, gdata->n_qdatas);
1830 qdata = gdata->qdatas;
1831 for (i = 0; i < gdata->n_qdatas - 1; i++)
1832 if (qdata[i].quark > quark)
1834 g_memmove (qdata + i + 1, qdata + i, sizeof (qdata[0]) * (gdata->n_qdatas - i - 1));
1835 qdata[i].quark = quark;
1836 qdata[i].data = data;
1840 /* --- implementation details --- */
1842 g_type_check_flags (GType type,
1845 TypeNode *node = LOOKUP_TYPE_NODE (type);
1847 flags &= G_TYPE_FLAG_MASK;
1850 GTypeFundamentalInfo *finfo = type_node_fundamental_info (node);
1852 return (finfo->type_flags & flags) != 0;
1859 g_type_get_plugin (GType type)
1861 TypeNode *node = LOOKUP_TYPE_NODE (type);
1863 return node && node->plugin;
1867 g_type_instance_conforms_to (GTypeInstance *type_instance,
1870 return (type_instance && type_instance->g_class &&
1871 g_type_conforms_to (type_instance->g_class->g_type, iface_type));
1875 g_type_class_is_a (GTypeClass *type_class,
1878 return (type_class && g_type_is_a (type_class->g_type, is_a_type));
1882 g_type_check_instance_cast (GTypeInstance *type_instance,
1887 g_warning ("invalid cast from (NULL) pointer to `%s'",
1888 type_descriptive_name (iface_type));
1889 return type_instance;
1891 if (!type_instance->g_class)
1893 g_warning ("invalid unclassed pointer in cast to `%s'",
1894 type_descriptive_name (iface_type));
1895 return type_instance;
1897 if (!G_TYPE_IS_CLASSED (type_instance->g_class->g_type))
1899 g_warning ("invalid unclassed type `%s' in cast to `%s'",
1900 type_descriptive_name (type_instance->g_class->g_type),
1901 type_descriptive_name (iface_type));
1902 return type_instance;
1904 if (!g_type_conforms_to (type_instance->g_class->g_type, iface_type))
1906 g_warning ("invalid cast from `%s' to `%s'",
1907 type_descriptive_name (type_instance->g_class->g_type),
1908 type_descriptive_name (iface_type));
1909 return type_instance;
1912 return type_instance;
1916 g_type_check_class_cast (GTypeClass *type_class,
1921 g_warning ("invalid class cast from (NULL) pointer to `%s'",
1922 type_descriptive_name (is_a_type));
1925 if (!G_TYPE_IS_CLASSED (type_class->g_type))
1927 g_warning ("invalid unclassed type `%s' in class cast to `%s'",
1928 type_descriptive_name (type_class->g_type),
1929 type_descriptive_name (is_a_type));
1932 if (!g_type_is_a (type_class->g_type, is_a_type))
1934 g_warning ("invalid class cast from `%s' to `%s'",
1935 type_descriptive_name (type_class->g_type),
1936 type_descriptive_name (is_a_type));
1944 /* --- foreign prototypes --- */
1945 extern void g_value_types_init (void); /* sync with gvaluetypes.c */
1946 extern void g_enum_types_init (void); /* sync with genums.c */
1947 extern void g_param_type_init (void); /* sync with gparam.c */
1948 extern void g_object_type_init (void); /* sync with gobject.c */
1949 extern void g_param_spec_types_init (void); /* sync with gparamspecs.c */
1952 /* --- initialization --- */
1956 static TypeNode *type0_node = NULL;
1961 if (G_TYPE_FUNDAMENTAL_LAST)
1964 /* type qname hash table */
1965 g_type_nodes_ht = g_hash_table_new (g_direct_hash, g_direct_equal);
1967 /* invalid type G_TYPE_INVALID (0)
1969 _g_type_fundamental_last = 1;
1970 g_type_nodes = g_renew (TypeNode**, g_type_nodes, G_TYPE_FUNDAMENTAL_LAST);
1971 g_type_nodes[0] = &type0_node;
1972 g_branch_seqnos = g_renew (GType, g_branch_seqnos, G_TYPE_FUNDAMENTAL_LAST);
1973 g_branch_seqnos[0] = 1;
1975 /* void type G_TYPE_NONE
1977 node = type_node_fundamental_new (G_TYPE_NONE, "void", 0);
1978 type = NODE_TYPE (node);
1979 g_assert (type == G_TYPE_NONE);
1981 /* interface fundamental type G_TYPE_INTERFACE (!classed)
1983 memset (&info, 0, sizeof (info));
1984 node = type_node_fundamental_new (G_TYPE_INTERFACE, "GInterface", G_TYPE_FLAG_DERIVABLE);
1985 type = NODE_TYPE (node);
1986 type_data_make (node, &info, NULL); // FIXME
1987 g_assert (type == G_TYPE_INTERFACE);
1989 /* G_TYPE_* value types
1991 g_value_types_init ();
1993 /* G_TYPE_ENUM & G_TYPE_FLAGS
1995 g_enum_types_init ();
1999 g_param_type_init ();
2003 g_object_type_init ();
2005 /* G_TYPE_PARAM_* pspec types
2007 g_param_spec_types_init ();