added newly added gobject/ headers.
[platform/upstream/glib.git] / gobject / gtype.c
1 /* GObject - GLib Type, Object, Parameter and Signal Library
2  * Copyright (C) 1998, 1999, 2000 Tim Janik and Red Hat, Inc.
3  *
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.
8  *
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.
13  *
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.
18  */
19 #include        "gtype.h"
20
21 #include        <string.h>
22
23 #define FIXME_DISABLE_PREALLOCATIONS
24
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.
31  *
32  * TODO:
33  * - g_type_from_name() should do an ordered array lookup after fetching the
34  *   the quark, instead of a second hashtable lookup.
35  * - speedup checks for virtual types, steal a bit somewhere
36  *
37  * FIXME:
38  * - force interface initialization for already existing classes
39  * - make things threadsafe
40  */
41
42 #define TYPE_FUNDAMENTAL_FLAG_MASK (G_TYPE_FLAG_CLASSED | \
43                                     G_TYPE_FLAG_INSTANTIATABLE | \
44                                     G_TYPE_FLAG_DERIVABLE | \
45                                     G_TYPE_FLAG_DEEP_DERIVABLE)
46 #define TYPE_FLAG_MASK             (G_TYPE_FLAG_ABSTRACT)
47
48 #define g_type_plugin_ref(p)                            ((p)->vtable->plugin_ref (p))
49 #define g_type_plugin_unref(p)                          ((p)->vtable->plugin_unref (p))
50 #define g_type_plugin_complete_type_info(p,t,i,v)       ((p)->vtable->complete_type_info ((p), (t), (i), (v)))
51 #define g_type_plugin_complete_interface_info(p,f,t,i)  ((p)->vtable->complete_interface_info ((p), (f), (t), (i)))
52
53
54 /* --- typedefs --- */
55 typedef struct _TypeNode        TypeNode;
56 typedef struct _CommonData      CommonData;
57 typedef struct _IFaceData       IFaceData;
58 typedef struct _ClassData       ClassData;
59 typedef struct _InstanceData    InstanceData;
60 typedef union  _TypeData        TypeData;
61 typedef struct _IFaceEntry      IFaceEntry;
62 typedef struct _IFaceHolder     IFaceHolder;
63
64
65 /* --- prototypes --- */
66 static inline GTypeFundamentalInfo*     type_node_fundamental_info      (TypeNode               *node);
67 static        void                      type_add_flags                  (TypeNode               *node,
68                                                                          GTypeFlags              flags);
69 static        void                      type_data_make                  (TypeNode               *node,
70                                                                          const GTypeInfo        *info,
71                                                                          const GTypeValueTable  *value_table);
72 static inline void                      type_data_ref                   (TypeNode               *node);
73 static inline void                      type_data_unref                 (TypeNode               *node,
74                                                                          gboolean                uncached);
75 static        void                      type_data_last_unref            (GType                   type,
76                                                                          gboolean                uncached);
77
78
79 /* --- structures --- */
80 struct _GValue  /* kludge, keep in sync with gvalue.h */
81 {
82   GType g_type;
83 };
84 struct _TypeNode
85 {
86   GTypePlugin *plugin;
87   guint        n_children : 12;
88   guint        n_supers : 8;
89   guint        n_ifaces : 9;
90   guint        is_classed : 1;
91   guint        is_instantiatable : 1;
92   guint        is_iface : 1;
93   GType       *children;
94   TypeData    *data;
95   GQuark       qname;
96   GData       *static_gdata;
97   union {
98     IFaceEntry  *iface_entries;
99     IFaceHolder *iface_conformants;
100   } private;
101   GType        supers[1]; /* flexible array */
102 };
103 #define SIZEOF_BASE_TYPE_NODE() (G_STRUCT_OFFSET (TypeNode, supers))
104 #define MAX_N_SUPERS    (255)
105 #define MAX_N_CHILDREN  (4095)
106 #define MAX_N_IFACES    (511)
107
108 struct _IFaceHolder
109 {
110   GType           instance_type;
111   GInterfaceInfo *info;
112   GTypePlugin    *plugin;
113   IFaceHolder    *next;
114 };
115 struct _IFaceEntry
116 {
117   GType           iface_type;
118   GTypeInterface *vtable;
119 };
120 struct _CommonData
121 {
122   guint             ref_count;
123   GTypeValueTable  *value_table;
124 };
125 struct _IFaceData
126 {
127   CommonData         common;
128   guint16            vtable_size;
129   GBaseInitFunc      vtable_init_base;
130   GBaseFinalizeFunc  vtable_finalize_base;
131 };
132 struct _ClassData
133 {
134   CommonData         common;
135   guint16            class_size;
136   GBaseInitFunc      class_init_base;
137   GBaseFinalizeFunc  class_finalize_base;
138   GClassInitFunc     class_init;
139   GClassFinalizeFunc class_finalize;
140   gconstpointer      class_data;
141   gpointer           class;
142 };
143 struct _InstanceData
144 {
145   CommonData         common;
146   guint16            class_size;
147   GBaseInitFunc      class_init_base;
148   GBaseFinalizeFunc  class_finalize_base;
149   GClassInitFunc     class_init;
150   GClassFinalizeFunc class_finalize;
151   gconstpointer      class_data;
152   gpointer           class;
153   guint16            instance_size;
154   guint16            n_preallocs;
155   GInstanceInitFunc  instance_init;
156   GMemChunk        *mem_chunk;
157 };
158 union _TypeData
159 {
160   CommonData         common;
161   IFaceData          iface;
162   ClassData          class;
163   InstanceData       instance;
164 };
165 typedef struct {
166   gpointer            cache_data;
167   GTypeClassCacheFunc cache_func;
168 } ClassCacheFunc;
169
170
171 /* --- variables --- */
172 static guint           n_class_cache_funcs = 0;
173 static ClassCacheFunc *class_cache_funcs = NULL;
174 static GType           last_fundamental_id = 0;
175 static GQuark          quark_type_flags = 0;
176
177
178 /* --- externs --- */
179 const char  *g_log_domain_gobject = "GLib-Object";
180
181
182 /* --- type nodes --- */
183 static GHashTable       *g_type_nodes_ht = NULL;
184 static GType            *g_branch_seqnos = NULL;
185 static TypeNode       ***g_type_nodes = NULL;
186
187 static inline TypeNode*
188 LOOKUP_TYPE_NODE (register GType utype)
189 {
190   register GType ftype = G_TYPE_FUNDAMENTAL (utype);
191   register GType b_seqno = G_TYPE_BRANCH_SEQNO (utype);
192
193   if (ftype < last_fundamental_id && b_seqno < g_branch_seqnos[ftype])
194     return g_type_nodes[ftype][b_seqno];
195   else
196     return NULL;
197 }
198 #define NODE_TYPE(node)         (node->supers[0])
199 #define NODE_PARENT_TYPE(node)  (node->supers[1])
200 #define NODE_NAME(node)         (g_quark_to_string (node->qname))
201
202 static TypeNode*
203 type_node_any_new (TypeNode              *pnode,
204                    GType                  ftype,
205                    const gchar           *name,
206                    GTypePlugin           *plugin,
207                    GTypeFundamentalFlags  type_flags)
208 {
209   guint branch_last, n_supers = pnode ? pnode->n_supers + 1 : 0;
210   GType type;
211   TypeNode *node;
212   guint i, node_size = 0;
213
214   branch_last = g_branch_seqnos[ftype]++;
215   type = G_TYPE_DERIVE_ID (ftype, branch_last);
216   if (!branch_last || g_bit_storage (branch_last - 1) < g_bit_storage (g_branch_seqnos[ftype] - 1))
217     g_type_nodes[ftype] = g_renew (TypeNode*, g_type_nodes[ftype], 1 << g_bit_storage (g_branch_seqnos[ftype] - 1));
218
219   if (!pnode)
220     node_size += sizeof (GTypeFundamentalInfo);       /* fundamental type info */
221   node_size += SIZEOF_BASE_TYPE_NODE ();              /* TypeNode structure */
222   node_size += (sizeof (GType) * (1 + n_supers + 1)); /* self + ancestors + 0 for ->supers[] */
223   node = g_malloc0 (node_size);
224   if (!pnode)                                         /* offset fundamental types */
225     node = G_STRUCT_MEMBER_P (node, sizeof (GTypeFundamentalInfo));
226   g_type_nodes[ftype][branch_last] = node;
227
228   node->n_supers = n_supers;
229   if (!pnode)
230     {
231       node->supers[0] = type;
232       node->supers[1] = 0;
233
234       node->is_classed = (type_flags & G_TYPE_FLAG_CLASSED) != 0;
235       node->is_instantiatable = (type_flags & G_TYPE_FLAG_INSTANTIATABLE) != 0;
236       node->is_iface = G_TYPE_IS_INTERFACE (type);
237
238       node->n_ifaces = 0;
239       if (node->is_iface)
240         node->private.iface_conformants = NULL;
241       else
242         node->private.iface_entries = NULL;
243     }
244   else
245     {
246       node->supers[0] = type;
247       memcpy (node->supers + 1, pnode->supers, sizeof (GType) * (1 + pnode->n_supers + 1));
248
249       node->is_classed = pnode->is_classed;
250       node->is_instantiatable = pnode->is_instantiatable;
251       node->is_iface = pnode->is_iface;
252
253       if (node->is_iface)
254         {
255           node->n_ifaces = 0;
256           node->private.iface_conformants = NULL;
257         }
258       else
259         {
260           node->n_ifaces = pnode->n_ifaces;
261           node->private.iface_entries = g_memdup (pnode->private.iface_entries,
262                                                   sizeof (pnode->private.iface_entries[0]) * node->n_ifaces);
263         }
264       
265       i = pnode->n_children++;
266       pnode->children = g_renew (GType, pnode->children, pnode->n_children);
267       pnode->children[i] = type;
268     }
269
270   node->plugin = plugin;
271   node->n_children = 0;
272   node->children = NULL;
273   node->data = NULL;
274   node->qname = g_quark_from_string (name);
275   node->static_gdata = NULL;
276
277   g_hash_table_insert (g_type_nodes_ht,
278                        GUINT_TO_POINTER (node->qname),
279                        GUINT_TO_POINTER (type));
280
281   return node;
282 }
283
284 static inline GTypeFundamentalInfo*
285 type_node_fundamental_info (TypeNode *node)
286 {
287   GType ftype = G_TYPE_FUNDAMENTAL (NODE_TYPE (node));
288   
289   if (ftype != NODE_TYPE (node))
290     node = LOOKUP_TYPE_NODE (ftype);
291   
292   return node ? G_STRUCT_MEMBER_P (node, - sizeof (GTypeFundamentalInfo)) : NULL;
293 }
294
295 static TypeNode*
296 type_node_fundamental_new (GType                 ftype,
297                            const gchar          *name,
298                            GTypeFundamentalFlags type_flags)
299 {
300   GTypeFundamentalInfo *finfo;
301   TypeNode *node;
302   guint i, flast = last_fundamental_id;
303   
304   g_assert (ftype == G_TYPE_FUNDAMENTAL (ftype));
305   
306   type_flags &= TYPE_FUNDAMENTAL_FLAG_MASK;
307
308   last_fundamental_id = MAX (last_fundamental_id, ftype + 1);
309   if (last_fundamental_id > flast)
310     {
311       g_type_nodes = g_renew (TypeNode**, g_type_nodes, last_fundamental_id);
312       g_branch_seqnos = g_renew (GType, g_branch_seqnos, last_fundamental_id);
313       for (i = flast; i < last_fundamental_id; i++)
314         {
315           g_type_nodes[i] = NULL;
316           g_branch_seqnos[i] = 0;
317         }
318     }
319   g_assert (g_branch_seqnos[ftype] == 0);
320
321   node = type_node_any_new (NULL, ftype, name, NULL, type_flags);
322   finfo = type_node_fundamental_info (node);
323   finfo->type_flags = type_flags;
324
325   return node;
326 }
327
328 static TypeNode*
329 type_node_new (TypeNode    *pnode,
330                const gchar *name,
331                GTypePlugin *plugin)
332
333 {
334   g_assert (pnode);
335   g_assert (pnode->n_supers < MAX_N_SUPERS);
336   g_assert (pnode->n_children < MAX_N_CHILDREN);
337
338   return type_node_any_new (pnode, G_TYPE_FUNDAMENTAL (NODE_TYPE (pnode)), name, plugin, 0);
339 }
340
341 static inline IFaceEntry*
342 type_lookup_iface_entry (TypeNode *node,
343                          TypeNode *iface)
344 {
345   if (iface->is_iface && node->n_ifaces)
346     {
347       IFaceEntry *ifaces = node->private.iface_entries - 1;
348       guint n_ifaces = node->n_ifaces;
349       GType iface_type = NODE_TYPE (iface);
350
351       do                /* FIXME: should optimize iface lookups for <= 4 */
352         {
353           guint i;
354           IFaceEntry *check;
355
356           i = (n_ifaces + 1) / 2;
357           check = ifaces + i;
358           if (iface_type == check->iface_type)
359             return check;
360           else if (iface_type > check->iface_type)
361             {
362               n_ifaces -= i;
363               ifaces = check;
364             }
365           else /* if (iface_type < check->iface_type) */
366             n_ifaces = i - 1;
367         }
368       while (n_ifaces);
369     }
370
371   return NULL;
372 }
373
374 static inline gchar*
375 type_descriptive_name (GType type)
376 {
377   if (type)
378     {
379       gchar *name = g_type_name (type);
380
381       return name ? name : "<unknown>";
382     }
383   else
384     return "<invalid>";
385 }
386
387
388 /* --- type consistency checks --- */
389 static gboolean
390 check_plugin (GTypePlugin *plugin,
391               gboolean     need_complete_type_info,
392               gboolean     need_complete_interface_info,
393               const gchar *type_name)
394 {
395   if (!plugin)
396     {
397       g_warning ("plugin handle for type `%s' is NULL",
398                  type_name);
399       return FALSE;
400     }
401   if (!plugin->vtable)
402     {
403       g_warning ("plugin for type `%s' has no function table",
404                  type_name);
405       return FALSE;
406     }
407   if (!plugin->vtable->plugin_ref)
408     {
409       g_warning ("plugin for type `%s' has no plugin_ref() implementation",
410                  type_name);
411       return FALSE;
412     }
413   if (!plugin->vtable->plugin_unref)
414     {
415       g_warning ("plugin for type `%s' has no plugin_unref() implementation",
416                  type_name);
417       return FALSE;
418     }
419   if (need_complete_type_info && !plugin->vtable->complete_type_info)
420     {
421       g_warning ("plugin for type `%s' has no complete_type_info() implementation",
422                  type_name);
423       return FALSE;
424     }
425   if (need_complete_interface_info && !plugin->vtable->complete_interface_info)
426     {
427       g_warning ("plugin for type `%s' has no complete_interface_info() implementation",
428                  type_name);
429       return FALSE;
430     }
431   return TRUE;
432 }
433
434 static gboolean
435 check_type_name (const gchar *type_name)
436 {
437   static const gchar *extra_chars = "-_+";
438   const gchar *p = type_name;
439   gboolean name_valid;
440
441   if (!type_name[0] || !type_name[1] || !type_name[2])
442     {
443       g_warning ("type name `%s' is too short", type_name);
444       return FALSE;
445     }
446   /* check the first letter */
447   name_valid = (p[0] >= 'A' && p[0] <= 'Z') || (p[0] >= 'a' && p[0] <= 'z') || p[0] == '_';
448   for (p = type_name + 1; *p; p++)
449     name_valid &= ((p[0] >= 'A' && p[0] <= 'Z') ||
450                    (p[0] >= 'a' && p[0] <= 'z') ||
451                    (p[0] >= '0' && p[0] <= '9') ||
452                    strchr (extra_chars, p[0]));
453   if (!name_valid)
454     {
455       g_warning ("type name `%s' contains invalid characters", type_name);
456       return FALSE;
457     }
458   if (g_type_from_name (type_name))
459     {
460       g_warning ("cannot register existing type `%s'", type_name);
461       return FALSE;
462     }
463
464   return TRUE;
465 }
466
467 static gboolean
468 check_derivation (GType        parent_type,
469                   const gchar *type_name)
470 {
471   TypeNode *pnode = LOOKUP_TYPE_NODE (parent_type);
472   GTypeFundamentalInfo* finfo = type_node_fundamental_info (pnode);
473   
474   if (!pnode)
475     {
476       g_warning ("cannot derive type `%s' from invalid parent type `%s'",
477                  type_name,
478                  type_descriptive_name (parent_type));
479       return FALSE;
480     }
481   /* ensure flat derivability */
482   if (!(finfo->type_flags & G_TYPE_FLAG_DERIVABLE))
483     {
484       g_warning ("cannot derive `%s' from non-derivable parent type `%s'",
485                  type_name,
486                  NODE_NAME (pnode));
487       return FALSE;
488     }
489   /* ensure deep derivability */
490   if (parent_type != G_TYPE_FUNDAMENTAL (parent_type) &&
491       !(finfo->type_flags & G_TYPE_FLAG_DEEP_DERIVABLE))
492     {
493       g_warning ("cannot derive `%s' from non-fundamental parent type `%s'",
494                  type_name,
495                  NODE_NAME (pnode));
496       return FALSE;
497     }
498   
499   return TRUE;
500 }
501
502 static gboolean
503 check_value_table (const gchar           *type_name,
504                    const GTypeValueTable *value_table)
505 {
506   if (!value_table)
507     return FALSE;
508   else if (value_table->value_init == NULL)
509     {
510       if (value_table->value_free || value_table->value_copy ||
511           value_table->value_peek_pointer ||
512           value_table->collect_type || value_table->collect_value ||
513           value_table->lcopy_type || value_table->lcopy_value)
514         g_warning ("cannot handle uninitializable values of type `%s'",
515                    type_name);
516
517       return FALSE;
518     }
519   else /* value_table->value_init != NULL */
520     {
521       if (!value_table->value_free)
522         {
523           /* +++ optional +++
524            * g_warning ("missing `value_free()' for type `%s'", type_name);
525            * return FALSE;
526            */
527         }
528       if (!value_table->value_copy)
529         {
530           g_warning ("missing `value_copy()' for type `%s'", type_name);
531           return FALSE;
532         }
533       if ((value_table->collect_type || value_table->collect_value) &&
534           (!value_table->collect_type || !value_table->collect_value))
535         {
536           g_warning ("one of `collect_type' and `collect_value()' is unspecified for type `%s'",
537                      type_name);
538           return FALSE;
539         }
540       if ((value_table->lcopy_type || value_table->lcopy_value) &&
541           (!value_table->lcopy_type || !value_table->lcopy_value))
542         {
543           g_warning ("one of `lcopy_type' and `lcopy_value()' is unspecified for type `%s'",
544                      type_name);
545           return FALSE;
546         }
547     }
548
549   return TRUE;
550 }
551
552 static gboolean
553 check_type_info (TypeNode        *pnode,
554                  GType            ftype,
555                  const gchar     *type_name,
556                  const GTypeInfo *info)
557 {
558   GTypeFundamentalInfo *finfo = type_node_fundamental_info (LOOKUP_TYPE_NODE (ftype));
559   gboolean is_interface = G_TYPE_IS_INTERFACE (ftype);
560
561   /* check instance members */
562   if (!(finfo->type_flags & G_TYPE_FLAG_INSTANTIATABLE) &&
563       (info->instance_size || info->n_preallocs || info->instance_init))
564     {
565       if (pnode)
566         g_warning ("cannot instantiate `%s', derived from non-instantiatable parent type `%s'",
567                    type_name,
568                    NODE_NAME (pnode));
569       else
570         g_warning ("cannot instantiate `%s' as non-instantiatable fundamental",
571                    type_name);
572       return FALSE;
573     }
574   /* check class & interface members */
575   if (!(finfo->type_flags & G_TYPE_FLAG_CLASSED) &&
576       (info->class_init || info->class_finalize || info->class_data ||
577        (!is_interface && (info->class_size || info->base_init || info->base_finalize))))
578     {
579       if (pnode)
580         g_warning ("cannot create class for `%s', derived from non-classed parent type `%s'",
581                    type_name,
582                    NODE_NAME (pnode));
583       else
584         g_warning ("cannot create class for `%s' as non-classed fundamental",
585                    type_name);
586       return FALSE;
587     }
588   /* check interface size */
589   if (is_interface && info->class_size < sizeof (GTypeInterface))
590     {
591       g_warning ("specified interface size for type `%s' is smaller than `GTypeInterface' size",
592                  type_name);
593       return FALSE;
594     }
595   /* check class size */
596   if (finfo->type_flags & G_TYPE_FLAG_CLASSED)
597     {
598       if (info->class_size < sizeof (GTypeClass))
599         {
600           g_warning ("specified class size for type `%s' is smaller than `GTypeClass' size",
601                      type_name);
602           return FALSE;
603         }
604       if (pnode && info->class_size < pnode->data->class.class_size)
605         {
606           g_warning ("specified class size for type `%s' is smaller "
607                      "than the parent type's `%s' class size",
608                      type_name,
609                      NODE_NAME (pnode));
610           return FALSE;
611         }
612     }
613   /* check instance size */
614   if (finfo->type_flags & G_TYPE_FLAG_INSTANTIATABLE)
615     {
616       if (info->instance_size < sizeof (GTypeInstance))
617         {
618           g_warning ("specified instance size for type `%s' is smaller than `GTypeInstance' size",
619                      type_name);
620           return FALSE;
621         }
622       if (pnode && info->instance_size < pnode->data->instance.instance_size)
623         {
624           g_warning ("specified instance size for type `%s' is smaller "
625                      "than the parent type's `%s' instance size",
626                      type_name,
627                      NODE_NAME (pnode));
628           return FALSE;
629         }
630     }
631
632   return TRUE;
633 }
634
635 static TypeNode*
636 find_conforming_type (TypeNode *pnode,
637                       TypeNode *iface)
638 {
639   TypeNode *node = NULL;
640   guint i;
641
642   if (type_lookup_iface_entry (pnode, iface))
643     return pnode;
644
645   for (i = 0; i < pnode->n_children && !node; i++)
646     node = find_conforming_type (LOOKUP_TYPE_NODE (pnode->children[i]), iface);
647
648   return node;
649 }
650
651 static gboolean
652 check_add_interface (GType instance_type,
653                      GType iface_type)
654 {
655   TypeNode *node = LOOKUP_TYPE_NODE (instance_type);
656   TypeNode *iface = LOOKUP_TYPE_NODE (iface_type);
657   TypeNode *tnode;
658
659   if (!node || !node->is_instantiatable)
660     {
661       g_warning ("cannot add interfaces to invalid (non-instantiatable) type `%s'",
662                  type_descriptive_name (instance_type));
663       return FALSE;
664     }
665   if (!iface || !iface->is_iface)
666     {
667       g_warning ("cannot add invalid (non-interface) type `%s' to type `%s'",
668                  type_descriptive_name (iface_type),
669                  NODE_NAME (node));
670       return FALSE;
671     }
672   tnode = LOOKUP_TYPE_NODE (NODE_PARENT_TYPE (iface));
673   if (NODE_PARENT_TYPE (tnode) && !type_lookup_iface_entry (node, tnode))
674     {
675       g_warning ("cannot add sub-interface `%s' to type `%s' which does not conform to super-interface `%s'",
676                  NODE_NAME (iface),
677                  NODE_NAME (node),
678                  NODE_NAME (tnode));
679       return FALSE;
680     }
681   tnode = find_conforming_type (node, iface);
682   if (tnode)
683     {
684       g_warning ("cannot add interface type `%s' to type `%s', since type `%s' already conforms to interface",
685                  NODE_NAME (iface),
686                  NODE_NAME (node),
687                  NODE_NAME (tnode));
688       return FALSE;
689     }
690
691   return TRUE;
692 }
693
694 static gboolean
695 check_interface_info (TypeNode             *iface,
696                       GType                 instance_type,
697                       const GInterfaceInfo *info)
698 {
699   if ((info->interface_finalize || info->interface_data) && !info->interface_init)
700     {
701       g_warning ("interface type `%s' for type `%s' comes without initializer",
702                  NODE_NAME (iface),
703                  type_descriptive_name (instance_type));
704       return FALSE;
705     }
706
707   return TRUE;
708 }
709
710
711 /* --- type info (type node data) --- */
712 static void
713 type_add_flags (TypeNode  *node,
714                 GTypeFlags flags)
715 {
716   guint dflags;
717
718   g_return_if_fail ((flags & ~TYPE_FLAG_MASK) == 0);
719   g_return_if_fail (node != NULL);
720
721   if (!quark_type_flags)
722     quark_type_flags = g_quark_from_static_string ("GTypeFlags");
723   if ((flags & G_TYPE_FLAG_ABSTRACT) && node->is_classed &&
724       node->data && node->data->class.class)
725     g_warning ("tagging type `%s' as abstract after class initialization", NODE_NAME (node));
726   dflags = GPOINTER_TO_UINT (g_type_get_qdata (NODE_TYPE (node), quark_type_flags));
727   dflags |= flags;
728   g_type_set_qdata (NODE_TYPE (node), quark_type_flags, GUINT_TO_POINTER (dflags));
729 }
730
731 static void
732 type_data_make (TypeNode              *node,
733                 const GTypeInfo       *info,
734                 const GTypeValueTable *value_table)
735 {
736   TypeData *data;
737   GTypeValueTable *vtable = NULL;
738   guint vtable_size = 0;
739   
740   g_assert (node->data == NULL && info != NULL);
741   
742   if (!value_table)
743     {
744       TypeNode *pnode = LOOKUP_TYPE_NODE (NODE_PARENT_TYPE (node));
745       
746       if (pnode)
747         vtable = pnode->data->common.value_table;
748       else
749         {
750           static const GTypeValueTable zero_vtable = { NULL, };
751           
752           value_table = &zero_vtable;
753         }
754     }
755   if (value_table)
756     vtable_size = sizeof (GTypeValueTable);
757   
758   if (node->is_instantiatable) /* carefull, is_instantiatable is also is_classed */
759     {
760       data = g_malloc0 (sizeof (InstanceData) + vtable_size);
761       if (vtable_size)
762         vtable = G_STRUCT_MEMBER_P (data, sizeof (InstanceData));
763       data->instance.class_size = info->class_size;
764       data->instance.class_init_base = info->base_init;
765       data->instance.class_finalize_base = info->base_finalize;
766       data->instance.class_init = info->class_init;
767       data->instance.class_finalize = info->class_finalize;
768       data->instance.class_data = info->class_data;
769       data->instance.class = NULL;
770       data->instance.instance_size = info->instance_size;
771       data->instance.n_preallocs = MIN (info->n_preallocs, 1024);
772 #ifdef FIXME_DISABLE_PREALLOCATIONS
773       data->instance.n_preallocs = 0;
774 #endif
775       data->instance.instance_init = info->instance_init;
776       data->instance.mem_chunk = NULL;
777     }
778   else if (node->is_classed) /* only classed */
779     {
780       data = g_malloc0 (sizeof (ClassData) + vtable_size);
781       if (vtable_size)
782         vtable = G_STRUCT_MEMBER_P (data, sizeof (ClassData));
783       data->class.class_size = info->class_size;
784       data->class.class_init_base = info->base_init;
785       data->class.class_finalize_base = info->base_finalize;
786       data->class.class_init = info->class_init;
787       data->class.class_finalize = info->class_finalize;
788       data->class.class_data = info->class_data;
789       data->class.class = NULL;
790     }
791   else if (node->is_iface)
792     {
793       data = g_malloc0 (sizeof (IFaceData) + vtable_size);
794       if (vtable_size)
795         vtable = G_STRUCT_MEMBER_P (data, sizeof (IFaceData));
796       data->iface.vtable_size = info->class_size;
797       data->iface.vtable_init_base = info->base_init;
798       data->iface.vtable_finalize_base = info->base_finalize;
799     }
800   else
801     {
802       data = g_malloc0 (sizeof (CommonData) + vtable_size);
803       if (vtable_size)
804         vtable = G_STRUCT_MEMBER_P (data, sizeof (CommonData));
805     }
806   
807   node->data = data;
808   node->data->common.ref_count = 1;
809   
810   if (vtable_size)
811     *vtable = *value_table;
812   node->data->common.value_table = vtable;
813
814   g_assert (node->data->common.value_table != NULL); /* FIXME: paranoid */
815 }
816
817 static inline void
818 type_data_ref (TypeNode *node)
819 {
820   if (!node->data)
821     {
822       TypeNode *pnode = LOOKUP_TYPE_NODE (NODE_PARENT_TYPE (node));
823       GTypeInfo tmp_info;
824       GTypeValueTable tmp_value_table;
825       
826       g_assert (node->plugin != NULL);
827       
828       if (pnode)
829         type_data_ref (pnode);
830       
831       memset (&tmp_info, 0, sizeof (tmp_info));
832       memset (&tmp_value_table, 0, sizeof (tmp_value_table));
833       g_type_plugin_ref (node->plugin);
834       g_type_plugin_complete_type_info (node->plugin, NODE_TYPE (node), &tmp_info, &tmp_value_table);
835       check_type_info (pnode, G_TYPE_FUNDAMENTAL (NODE_TYPE (node)), NODE_NAME (node), &tmp_info);
836       type_data_make (node, &tmp_info,
837                       check_value_table (NODE_NAME (node), &tmp_value_table) ? &tmp_value_table : NULL);
838     }
839   else
840     {
841       g_assert (node->data->common.ref_count > 0);
842
843       node->data->common.ref_count += 1;
844     }
845 }
846
847 static inline void
848 type_data_unref (TypeNode *node,
849                  gboolean  uncached)
850 {
851   g_assert (node->data && node->data->common.ref_count);
852
853   if (node->data->common.ref_count > 1)
854     node->data->common.ref_count -= 1;
855   else
856     {
857       if (!node->plugin)
858         {
859           g_warning ("static type `%s' unreferenced too often",
860                      NODE_NAME (node));
861           return;
862         }
863
864       type_data_last_unref (NODE_TYPE (node), uncached);
865     }
866 }
867
868 static void
869 type_node_add_iface_entry (TypeNode *node,
870                            GType     iface_type)
871 {
872   IFaceEntry *entries;
873   guint i;
874
875   g_assert (node->is_instantiatable && node->n_ifaces < MAX_N_IFACES);
876
877   node->n_ifaces++;
878   node->private.iface_entries = g_renew (IFaceEntry, node->private.iface_entries, node->n_ifaces);
879   entries = node->private.iface_entries;
880   for (i = 0; i < node->n_ifaces - 1; i++)
881     if (entries[i].iface_type > iface_type)
882       break;
883   g_memmove (entries + i + 1, entries + i, sizeof (entries[0]) * (node->n_ifaces - i - 1));
884   entries[i].iface_type = iface_type;
885   entries[i].vtable = NULL;
886
887   for (i = 0; i < node->n_children; i++)
888     type_node_add_iface_entry (LOOKUP_TYPE_NODE (node->children[i]), iface_type);
889 }
890
891 static void
892 type_add_interface (TypeNode             *node,
893                     TypeNode             *iface,
894                     const GInterfaceInfo *info,
895                     GTypePlugin          *plugin)
896 {
897   IFaceHolder *iholder = g_new0 (IFaceHolder, 1);
898   
899   /* we must not call any functions of GInterfaceInfo from within here, since
900    * we got most probably called from _within_ a type registration function
901    */
902   g_assert (node->is_instantiatable && iface->is_iface && ((info && !plugin) || (!info && plugin)));
903   
904   iholder->next = iface->private.iface_conformants;
905   iface->private.iface_conformants = iholder;
906   iholder->instance_type = NODE_TYPE (node);
907   iholder->info = info ? g_memdup (info, sizeof (*info)) : NULL;
908   iholder->plugin = plugin;
909
910   type_node_add_iface_entry (node, NODE_TYPE (iface));
911 }
912
913 static IFaceHolder*
914 type_iface_retrive_holder_info (TypeNode *iface,
915                                 GType     instance_type)
916 {
917   IFaceHolder *iholder = iface->private.iface_conformants;
918
919   g_assert (iface->is_iface);
920
921   while (iholder->instance_type != instance_type)
922     iholder = iholder->next;
923
924   if (!iholder->info)
925     {
926       GInterfaceInfo tmp_info;
927       
928       g_assert (iholder->plugin != NULL);
929       
930       type_data_ref (iface);
931
932       memset (&tmp_info, 0, sizeof (tmp_info));
933       g_type_plugin_ref (iholder->plugin);
934       g_type_plugin_complete_interface_info (iholder->plugin, NODE_TYPE (iface), instance_type, &tmp_info);
935       check_interface_info (iface, instance_type, &tmp_info);
936       iholder->info = g_memdup (&tmp_info, sizeof (tmp_info));
937     }
938   
939   return iholder;
940 }
941
942 static void
943 type_iface_blow_holder_info (TypeNode *iface,
944                              GType     instance_type)
945 {
946   IFaceHolder *iholder = iface->private.iface_conformants;
947
948   g_assert (iface->is_iface);
949
950   while (iholder->instance_type != instance_type)
951     iholder = iholder->next;
952
953   if (iholder->info && iholder->plugin)
954     {
955       g_free (iholder->info);
956       iholder->info = NULL;
957       g_type_plugin_unref (iholder->plugin);
958
959       type_data_unref (iface, FALSE);
960     }
961 }
962
963
964 /* --- type structure creation/destruction --- */
965 GTypeInstance*
966 g_type_create_instance (GType type)
967 {
968   TypeNode *node = LOOKUP_TYPE_NODE (type);
969   GTypeInstance *instance;
970   GTypeClass *class;
971   guint i;
972   
973   if (!node || !node->is_instantiatable)
974     {
975       g_warning ("cannot create new instance of invalid (non-instantiatable) type `%s'",
976                  type_descriptive_name (type));
977       return NULL;
978     }
979   if (G_TYPE_IS_ABSTRACT (type))
980     {
981       g_warning ("cannot create instance of abstract (non-instantiatable) type `%s'",
982                  type_descriptive_name (type));
983       return NULL;
984     }
985   
986   class = g_type_class_ref (type);
987   
988   if (node->data->instance.n_preallocs)
989     {
990       if (!node->data->instance.mem_chunk)
991         node->data->instance.mem_chunk = g_mem_chunk_new (NODE_NAME (node),
992                                                           node->data->instance.instance_size,
993                                                           (node->data->instance.instance_size *
994                                                            node->data->instance.n_preallocs),
995                                                           G_ALLOC_AND_FREE);
996       instance = g_chunk_new0 (GTypeInstance, node->data->instance.mem_chunk);
997     }
998   else
999     instance = g_malloc0 (node->data->instance.instance_size);
1000   
1001   for (i = node->n_supers; i > 0; i--)
1002     {
1003       TypeNode *pnode = LOOKUP_TYPE_NODE (node->supers[i]);
1004       
1005       if (pnode->data->instance.instance_init)
1006         {
1007           instance->g_class = pnode->data->instance.class;
1008           pnode->data->instance.instance_init (instance, class);
1009         }
1010     }
1011   instance->g_class = class;
1012   if (node->data->instance.instance_init)
1013     node->data->instance.instance_init (instance, class);
1014
1015   return instance;
1016 }
1017
1018 void
1019 g_type_free_instance (GTypeInstance *instance)
1020 {
1021   TypeNode *node;
1022   GTypeClass *class;
1023
1024   g_return_if_fail (instance != NULL && instance->g_class != NULL);
1025
1026   class = instance->g_class;
1027   node = LOOKUP_TYPE_NODE (class->g_type);
1028   if (!node || !node->is_instantiatable || !node->data || node->data->class.class != (gpointer) class)
1029     {
1030       g_warning ("cannot free instance of invalid (non-instantiatable) type `%s'",
1031                  type_descriptive_name (class->g_type));
1032       return;
1033     }
1034   if (G_TYPE_IS_ABSTRACT (NODE_TYPE (node)))
1035     {
1036       g_warning ("cannot free instance of abstract (non-instantiatable) type `%s'",
1037                  NODE_NAME (node));
1038       return;
1039     }
1040
1041   instance->g_class = NULL;
1042   memset (instance, 0xaa, node->data->instance.instance_size);  // FIXME
1043   if (node->data->instance.n_preallocs)
1044     g_chunk_free (instance, node->data->instance.mem_chunk);
1045   else
1046     g_free (instance);
1047
1048   g_type_class_unref (class);
1049 }
1050
1051 static void
1052 type_propagate_iface_vtable (TypeNode       *pnode,
1053                              TypeNode       *iface,
1054                              GTypeInterface *vtable)
1055 {
1056   IFaceEntry *entry = type_lookup_iface_entry (pnode, iface);
1057   guint i;
1058
1059   entry->vtable = vtable;
1060   for (i = 0; i < pnode->n_children; i++)
1061     {
1062       TypeNode *node = LOOKUP_TYPE_NODE (pnode->children[i]);
1063
1064       type_propagate_iface_vtable (node, iface, vtable);
1065     }
1066 }
1067
1068 static void
1069 type_iface_vtable_init (TypeNode       *iface,
1070                         TypeNode       *node)
1071 {
1072   IFaceEntry *entry = type_lookup_iface_entry (node, iface);
1073   IFaceHolder *iholder = type_iface_retrive_holder_info (iface, NODE_TYPE (node));
1074   GTypeInterface *vtable;
1075   
1076   g_assert (iface->data && entry && entry->vtable == NULL && iholder && iholder->info);
1077
1078   vtable = g_malloc0 (iface->data->iface.vtable_size);
1079   type_propagate_iface_vtable (node, iface, vtable);
1080   vtable->g_type = NODE_TYPE (iface);
1081   vtable->g_instance_type = NODE_TYPE (node);
1082
1083   if (iface->data->iface.vtable_init_base)
1084     iface->data->iface.vtable_init_base (vtable);
1085   if (iholder->info->interface_init)
1086     iholder->info->interface_init (vtable, iholder->info->interface_data);
1087 }
1088
1089 static void
1090 type_iface_vtable_finalize (TypeNode       *iface,
1091                             TypeNode       *node,
1092                             GTypeInterface *vtable)
1093 {
1094   IFaceEntry *entry = type_lookup_iface_entry (node, iface);
1095   IFaceHolder *iholder = iface->private.iface_conformants;
1096
1097   g_assert (entry && entry->vtable == vtable);
1098
1099   while (iholder->instance_type != NODE_TYPE (node))
1100     iholder = iholder->next;
1101   g_assert (iholder && iholder->info);
1102
1103   type_propagate_iface_vtable (node, iface, NULL);
1104   if (iholder->info->interface_finalize)
1105     iholder->info->interface_finalize (vtable, iholder->info->interface_data);
1106   if (iface->data->iface.vtable_finalize_base)
1107     iface->data->iface.vtable_finalize_base (vtable);
1108   
1109   vtable->g_type = 0;
1110   vtable->g_instance_type = 0;
1111   g_free (vtable);
1112
1113   type_iface_blow_holder_info (iface, NODE_TYPE (node));
1114 }
1115
1116 static void
1117 type_class_init (TypeNode   *node,
1118                  GTypeClass *pclass)
1119 {
1120   GSList *slist, *init_slist = NULL;
1121   GTypeClass *class;
1122   IFaceEntry *entry;
1123   TypeNode *bnode;
1124   guint i;
1125   
1126   g_assert (node->is_classed && node->data &&
1127             node->data->class.class_size &&
1128             !node->data->class.class);
1129   
1130   class = g_malloc0 (node->data->class.class_size);
1131   node->data->class.class = class;
1132   
1133   if (pclass)
1134     {
1135       TypeNode *pnode = LOOKUP_TYPE_NODE (pclass->g_type);
1136       
1137       memcpy (class, pclass, pnode->data->class.class_size);
1138     }
1139   
1140   class->g_type = NODE_TYPE (node);
1141   
1142   /* stack all base class initialization functions, so we
1143    * call them in ascending order.
1144    */
1145   for (bnode = node; bnode; bnode = LOOKUP_TYPE_NODE (NODE_PARENT_TYPE (bnode)))
1146     if (bnode->data->class.class_init_base)
1147       init_slist = g_slist_prepend (init_slist, (gpointer) bnode->data->class.class_init_base);
1148   for (slist = init_slist; slist; slist = slist->next)
1149     {
1150       GBaseInitFunc class_init_base = (GBaseInitFunc) slist->data;
1151       
1152       class_init_base (class);
1153     }
1154   g_slist_free (init_slist);
1155   
1156   if (node->data->class.class_init)
1157     node->data->class.class_init (class, (gpointer) node->data->class.class_data);
1158
1159   /* ok, we got the class done, now initialize all interfaces */
1160   for (entry = NULL, i = 0; i < node->n_ifaces; i++)
1161     if (!node->private.iface_entries[i].vtable)
1162       entry = node->private.iface_entries + i;
1163   while (entry)
1164     {
1165       type_iface_vtable_init (LOOKUP_TYPE_NODE (entry->iface_type), node);
1166       
1167       for (entry = NULL, i = 0; i < node->n_ifaces; i++)
1168         if (!node->private.iface_entries[i].vtable)
1169           entry = node->private.iface_entries + i;
1170     }
1171 }
1172
1173 static void
1174 type_data_finalize_class_ifaces (TypeNode *node)
1175 {
1176   IFaceEntry *entry;
1177   guint i;
1178   
1179   g_assert (node->is_instantiatable && node->data && node->data->class.class && node->data->common.ref_count == 0);
1180   
1181   g_message ("finalizing interfaces for %sClass `%s'",
1182              type_descriptive_name (G_TYPE_FUNDAMENTAL (NODE_TYPE (node))),
1183              type_descriptive_name (NODE_TYPE (node)));
1184   
1185   for (entry = NULL, i = 0; i < node->n_ifaces; i++)
1186     if (node->private.iface_entries[i].vtable &&
1187         node->private.iface_entries[i].vtable->g_instance_type == NODE_TYPE (node))
1188       entry = node->private.iface_entries + i;
1189   while (entry)
1190     {
1191       type_iface_vtable_finalize (LOOKUP_TYPE_NODE (entry->iface_type), node, entry->vtable);
1192       
1193       for (entry = NULL, i = 0; i < node->n_ifaces; i++)
1194         if (node->private.iface_entries[i].vtable &&
1195             node->private.iface_entries[i].vtable->g_instance_type == NODE_TYPE (node))
1196           entry = node->private.iface_entries + i;
1197     }
1198 }
1199
1200 static void
1201 type_data_finalize_class (TypeNode  *node,
1202                           ClassData *cdata)
1203 {
1204   GTypeClass *class = cdata->class;
1205   TypeNode *bnode;
1206   
1207   g_assert (cdata->class && cdata->common.ref_count == 0);
1208   
1209   g_message ("finalizing %sClass `%s'",
1210              type_descriptive_name (G_TYPE_FUNDAMENTAL (NODE_TYPE (node))),
1211              type_descriptive_name (NODE_TYPE (node)));
1212
1213   if (cdata->class_finalize)
1214     cdata->class_finalize (class, (gpointer) cdata->class_data);
1215   
1216   /* call all base class destruction functions in descending order
1217    */
1218   if (cdata->class_finalize_base)
1219     cdata->class_finalize_base (class);
1220   for (bnode = LOOKUP_TYPE_NODE (NODE_PARENT_TYPE (node)); bnode; bnode = LOOKUP_TYPE_NODE (NODE_PARENT_TYPE (bnode)))
1221     if (bnode->data->class.class_finalize_base)
1222       bnode->data->class.class_finalize_base (class);
1223   
1224   class->g_type = 0;
1225   g_free (cdata->class);
1226 }
1227
1228 static void
1229 type_data_last_unref (GType    type,
1230                       gboolean uncached)
1231 {
1232   TypeNode *node = LOOKUP_TYPE_NODE (type);
1233
1234   g_return_if_fail (node != NULL && node->plugin != NULL);
1235   
1236   if (!node->data || node->data->common.ref_count == 0)
1237     {
1238       g_warning ("cannot drop last reference to unreferenced type `%s'",
1239                  type_descriptive_name (type));
1240       return;
1241     }
1242
1243   if (node->is_classed && node->data && node->data->class.class)
1244     {
1245       guint i;
1246
1247       for (i = 0; i < n_class_cache_funcs; i++)
1248         if (class_cache_funcs[i].cache_func (class_cache_funcs[i].cache_data, node->data->class.class))
1249           break;
1250     }
1251
1252   if (node->data->common.ref_count > 1) /* may have been re-referenced meanwhile */
1253     node->data->common.ref_count -= 1;
1254   else
1255     {
1256       GType ptype = NODE_PARENT_TYPE (node);
1257       TypeData *tdata;
1258       
1259       node->data->common.ref_count = 0;
1260       
1261       if (node->is_instantiatable && node->data->instance.mem_chunk)
1262         {
1263           g_mem_chunk_destroy (node->data->instance.mem_chunk);
1264           node->data->instance.mem_chunk = NULL;
1265         }
1266       
1267       tdata = node->data;
1268       if (node->is_classed && tdata->class.class)
1269         {
1270           if (node->n_ifaces)
1271             type_data_finalize_class_ifaces (node);
1272           node->data = NULL;
1273           type_data_finalize_class (node, &tdata->class);
1274         }
1275       else
1276         node->data = NULL;
1277
1278       g_free (tdata);
1279       
1280       if (ptype)
1281         type_data_unref (LOOKUP_TYPE_NODE (ptype), FALSE);
1282       g_type_plugin_unref (node->plugin);
1283     }
1284 }
1285
1286 void
1287 g_type_add_class_cache_func (gpointer            cache_data,
1288                              GTypeClassCacheFunc cache_func)
1289 {
1290   guint i;
1291
1292   g_return_if_fail (cache_func != NULL);
1293
1294   i = n_class_cache_funcs++;
1295   class_cache_funcs = g_renew (ClassCacheFunc, class_cache_funcs, n_class_cache_funcs);
1296   class_cache_funcs[i].cache_data = cache_data;
1297   class_cache_funcs[i].cache_func = cache_func;
1298 }
1299
1300 void
1301 g_type_remove_class_cache_func (gpointer            cache_data,
1302                                 GTypeClassCacheFunc cache_func)
1303 {
1304   guint i;
1305
1306   g_return_if_fail (cache_func != NULL);
1307
1308   for (i = 0; i < n_class_cache_funcs; i++)
1309     if (class_cache_funcs[i].cache_data == cache_data &&
1310         class_cache_funcs[i].cache_func == cache_func)
1311       {
1312         n_class_cache_funcs--;
1313         g_memmove (class_cache_funcs + i,
1314                    class_cache_funcs + i + 1,
1315                    sizeof (class_cache_funcs[0]) * (n_class_cache_funcs - i));
1316         class_cache_funcs = g_renew (ClassCacheFunc, class_cache_funcs, n_class_cache_funcs);
1317
1318         return;
1319       }
1320
1321   g_warning (G_STRLOC ": cannot remove unregistered class cache func %p with data %p",
1322              cache_func, cache_data);
1323 }
1324
1325
1326 /* --- type registration --- */
1327 GType
1328 g_type_register_fundamental (GType                       type_id,
1329                              const gchar                *type_name,
1330                              const GTypeInfo            *info,
1331                              const GTypeFundamentalInfo *finfo,
1332                              GTypeFlags                  flags)
1333 {
1334   GTypeFundamentalInfo *node_finfo;
1335   TypeNode *node;
1336
1337   g_return_val_if_fail (type_id > 0, 0);
1338   g_return_val_if_fail (type_name != NULL, 0);
1339   g_return_val_if_fail (info != NULL, 0);
1340   g_return_val_if_fail (finfo != NULL, 0);
1341
1342   if (!check_type_name (type_name))
1343     return 0;
1344   if (G_TYPE_FUNDAMENTAL (type_id) != type_id)
1345     {
1346       g_warning ("cannot register fundamental type `%s' with non-fundamental id (%u)",
1347                  type_name,
1348                  type_id);
1349       return 0;
1350     }
1351   if (LOOKUP_TYPE_NODE (type_id))
1352     {
1353       g_warning ("cannot register existing fundamental type `%s' (as `%s')",
1354                  type_descriptive_name (type_id),
1355                  type_name);
1356       return 0;
1357     }
1358   if ((finfo->type_flags & G_TYPE_FLAG_INSTANTIATABLE) &&
1359       !(finfo->type_flags & G_TYPE_FLAG_CLASSED))
1360     {
1361       g_warning ("cannot register instantiatable fundamental type `%s' as non-classed",
1362                  type_name);
1363       return 0;
1364     }
1365
1366   node = type_node_fundamental_new (type_id, type_name, finfo->type_flags);
1367   node_finfo = type_node_fundamental_info (node);
1368   type_add_flags (node, flags);
1369
1370   if (!check_type_info (NULL, G_TYPE_FUNDAMENTAL (NODE_TYPE (node)), type_name, info))
1371     return NODE_TYPE (node);
1372   type_data_make (node, info,
1373                   check_value_table (type_name, info->value_table) ? info->value_table : NULL);
1374
1375   return NODE_TYPE (node);
1376 }
1377
1378 GType
1379 g_type_register_static (GType            parent_type,
1380                         const gchar     *type_name,
1381                         const GTypeInfo *info,
1382                         GTypeFlags       flags)
1383 {
1384   TypeNode *pnode, *node;
1385   GType type;
1386   
1387   g_return_val_if_fail (parent_type > 0, 0);
1388   g_return_val_if_fail (type_name != NULL, 0);
1389   g_return_val_if_fail (info != NULL, 0);
1390   
1391   if (!check_type_name (type_name))
1392     return 0;
1393   if (!check_derivation (parent_type, type_name))
1394     return 0;
1395
1396   pnode = LOOKUP_TYPE_NODE (parent_type);
1397   type_data_ref (pnode);
1398
1399   if (!check_type_info (pnode, G_TYPE_FUNDAMENTAL (parent_type), type_name, info))
1400     return 0;
1401   if (info->class_finalize)
1402     {
1403       g_warning ("class finalizer specified for static type `%s'",
1404                  type_name);
1405       return 0;
1406     }
1407
1408   node = type_node_new (pnode, type_name, NULL);
1409   type_add_flags (node, flags);
1410   type = NODE_TYPE (node);
1411   type_data_make (node, info,
1412                   check_value_table (type_name, info->value_table) ? info->value_table : NULL);
1413
1414   return type;
1415 }
1416
1417 GType
1418 g_type_register_dynamic (GType        parent_type,
1419                          const gchar *type_name,
1420                          GTypePlugin *plugin,
1421                          GTypeFlags   flags)
1422 {
1423   TypeNode *pnode, *node;
1424   GType type;
1425
1426   g_return_val_if_fail (parent_type > 0, 0);
1427   g_return_val_if_fail (type_name != NULL, 0);
1428   g_return_val_if_fail (plugin != NULL, 0);
1429
1430   if (!check_type_name (type_name))
1431     return 0;
1432   if (!check_derivation (parent_type, type_name))
1433     return 0;
1434   if (!check_plugin (plugin, TRUE, FALSE, type_name))
1435     return 0;
1436   pnode = LOOKUP_TYPE_NODE (parent_type);
1437
1438   node = type_node_new (pnode, type_name, plugin);
1439   type_add_flags (node, flags);
1440   type = NODE_TYPE (node);
1441
1442   return type;
1443 }
1444
1445 void
1446 g_type_add_interface_static (GType                 instance_type,
1447                              GType                 interface_type,
1448                              const GInterfaceInfo *info)
1449 {
1450   TypeNode *node;
1451   TypeNode *iface;
1452   
1453   g_return_if_fail (G_TYPE_IS_INSTANTIATABLE (instance_type));
1454   g_return_if_fail (g_type_parent (interface_type) == G_TYPE_INTERFACE);
1455
1456   if (!check_add_interface (instance_type, interface_type))
1457     return;
1458   node = LOOKUP_TYPE_NODE (instance_type);
1459   iface = LOOKUP_TYPE_NODE (interface_type);
1460   if (!check_interface_info (iface, NODE_TYPE (node), info))
1461     return;
1462   type_add_interface (node, iface, info, NULL);
1463 }
1464
1465 void
1466 g_type_add_interface_dynamic (GType        instance_type,
1467                               GType        interface_type,
1468                               GTypePlugin *plugin)
1469 {
1470   TypeNode *node;
1471   TypeNode *iface;
1472   
1473   g_return_if_fail (G_TYPE_IS_INSTANTIATABLE (instance_type));
1474   g_return_if_fail (g_type_parent (interface_type) == G_TYPE_INTERFACE);
1475
1476   if (!check_add_interface (instance_type, interface_type))
1477     return;
1478   node = LOOKUP_TYPE_NODE (instance_type);
1479   iface = LOOKUP_TYPE_NODE (interface_type);
1480   if (!check_plugin (plugin, FALSE, TRUE, NODE_NAME (node)))
1481     return;
1482   type_add_interface (node, iface, NULL, plugin);
1483 }
1484
1485
1486 /* --- public API functions --- */
1487 gpointer
1488 g_type_class_ref (GType type)
1489 {
1490   TypeNode *node = LOOKUP_TYPE_NODE (type);
1491
1492   /* optimize for common code path
1493    */
1494   if (node && node->is_classed && node->data &&
1495       node->data->class.class && node->data->common.ref_count > 0)
1496     {
1497       type_data_ref (node);
1498
1499       return node->data->class.class;
1500     }
1501
1502   if (!node || !node->is_classed ||
1503       (node->data && node->data->common.ref_count < 1))
1504     {
1505       g_warning ("cannot retrive class for invalid (unclassed) type `%s'",
1506                  type_descriptive_name (type));
1507       return NULL;
1508     }
1509
1510   type_data_ref (node);
1511
1512   if (!node->data->class.class)
1513     {
1514       GType ptype = NODE_PARENT_TYPE (node);
1515       GTypeClass *pclass = ptype ? g_type_class_ref (ptype) : NULL;
1516
1517       type_class_init (node, pclass);
1518     }
1519
1520   return node->data->class.class;
1521 }
1522
1523 void
1524 g_type_class_unref (gpointer g_class)
1525 {
1526   TypeNode *node;
1527   GTypeClass *class = g_class;
1528
1529   g_return_if_fail (g_class != NULL);
1530
1531   node = LOOKUP_TYPE_NODE (class->g_type);
1532   if (node && node->is_classed && node->data &&
1533       node->data->class.class == class && node->data->common.ref_count > 0)
1534     type_data_unref (node, FALSE);
1535   else
1536     g_warning ("cannot unreference class of invalid (unclassed) type `%s'",
1537                type_descriptive_name (class->g_type));
1538 }
1539
1540 void
1541 g_type_class_unref_uncached (gpointer g_class)
1542 {
1543   TypeNode *node;
1544   GTypeClass *class = g_class;
1545
1546   g_return_if_fail (g_class != NULL);
1547
1548   node = LOOKUP_TYPE_NODE (class->g_type);
1549   if (node && node->is_classed && node->data &&
1550       node->data->class.class == class && node->data->common.ref_count > 0)
1551     type_data_unref (node, TRUE);
1552   else
1553     g_warning ("cannot unreference class of invalid (unclassed) type `%s'",
1554                type_descriptive_name (class->g_type));
1555 }
1556
1557 gpointer
1558 g_type_class_peek (GType type)
1559 {
1560   TypeNode *node = LOOKUP_TYPE_NODE (type);
1561
1562   if (node && node->is_classed && node->data && node->data->class.class) /* common.ref_count _may_ be 0 */
1563     return node->data->class.class;
1564   else
1565     return NULL;
1566 }
1567
1568 gpointer
1569 g_type_class_peek_parent (gpointer g_class)
1570 {
1571   TypeNode *node;
1572
1573   g_return_val_if_fail (g_class != NULL, NULL);
1574
1575   node = LOOKUP_TYPE_NODE (G_TYPE_FROM_CLASS (g_class));
1576   if (node && node->is_classed && node->data && NODE_PARENT_TYPE (node))
1577     {
1578       node = LOOKUP_TYPE_NODE (NODE_PARENT_TYPE (node));
1579
1580       return node->data->class.class;
1581     }
1582
1583   return NULL;
1584 }
1585
1586 gpointer
1587 g_type_interface_peek (gpointer instance_class,
1588                        GType    iface_type)
1589 {
1590   TypeNode *node;
1591   TypeNode *iface;
1592   GTypeClass *class = instance_class;
1593
1594   g_return_val_if_fail (instance_class != NULL, NULL);
1595
1596   node = LOOKUP_TYPE_NODE (class->g_type);
1597   iface = LOOKUP_TYPE_NODE (iface_type);
1598   if (node && node->is_instantiatable && iface)
1599     {
1600       IFaceEntry *entry = type_lookup_iface_entry (node, iface);
1601
1602       if (entry && entry->vtable)
1603         return entry->vtable;
1604     }
1605
1606   return NULL;
1607 }
1608
1609 GTypeValueTable*
1610 g_type_value_table_peek (GType type)
1611 {
1612   TypeNode *node = LOOKUP_TYPE_NODE (type);
1613
1614   if (node && node->data && node->data->common.ref_count > 0)
1615     return node->data->common.value_table->value_init ? node->data->common.value_table : NULL;
1616   else
1617     return NULL;
1618 }
1619
1620 gchar*
1621 g_type_name (GType type)
1622 {
1623   TypeNode *node = LOOKUP_TYPE_NODE (type);
1624   
1625   return node ? NODE_NAME (node) : NULL;
1626 }
1627
1628 GQuark
1629 g_type_qname (GType type)
1630 {
1631   TypeNode *node = LOOKUP_TYPE_NODE (type);
1632
1633   return node ? node->qname : 0;
1634 }
1635
1636 GType
1637 g_type_from_name (const gchar *name)
1638 {
1639   GQuark quark;
1640   
1641   g_return_val_if_fail (name != NULL, 0);
1642   
1643   quark = g_quark_try_string (name);
1644   if (quark)
1645     {
1646       GType type = GPOINTER_TO_UINT (g_hash_table_lookup (g_type_nodes_ht, GUINT_TO_POINTER (quark)));
1647       
1648       if (type)
1649         return type;
1650     }
1651   
1652   return 0;
1653 }
1654
1655 GType
1656 g_type_parent (GType type)
1657 {
1658   TypeNode *node = LOOKUP_TYPE_NODE (type);
1659
1660   return node ? NODE_PARENT_TYPE (node) : 0;
1661 }
1662
1663 GType
1664 g_type_next_base (GType type,
1665                   GType base_type)
1666 {
1667   TypeNode *node = LOOKUP_TYPE_NODE (type);
1668   
1669   if (node)
1670     {
1671       TypeNode *base_node = LOOKUP_TYPE_NODE (base_type);
1672       
1673       if (base_node && base_node->n_supers < node->n_supers)
1674         {
1675           guint n = node->n_supers - base_node->n_supers;
1676           
1677           if (node->supers[n] == base_type)
1678             return node->supers[n - 1];
1679         }
1680     }
1681   
1682   return 0;
1683 }
1684
1685 gboolean
1686 g_type_is_a (GType type,
1687              GType is_a_type)
1688 {
1689   if (type != is_a_type)
1690     {
1691       TypeNode *node = LOOKUP_TYPE_NODE (type);
1692
1693       if (node)
1694         {
1695           TypeNode *a_node = LOOKUP_TYPE_NODE (is_a_type);
1696
1697           if (a_node && a_node->n_supers <= node->n_supers)
1698             return node->supers[node->n_supers - a_node->n_supers] == is_a_type;
1699         }
1700     }
1701   else
1702     return LOOKUP_TYPE_NODE (type) != NULL;
1703
1704   return FALSE;
1705 }
1706
1707 gboolean
1708 g_type_conforms_to (GType type,
1709                     GType iface_type)
1710 {
1711   if (type != iface_type)
1712     {
1713       TypeNode *node = LOOKUP_TYPE_NODE (type);
1714
1715       if (node)
1716         {
1717           TypeNode *iface_node = LOOKUP_TYPE_NODE (iface_type);
1718
1719           if (iface_node)
1720             {
1721               if (iface_node->is_iface && node->is_instantiatable)
1722                 return type_lookup_iface_entry (node, iface_node) != NULL;
1723               else if (iface_node->n_supers <= node->n_supers)
1724                 return node->supers[node->n_supers - iface_node->n_supers] == iface_type;
1725             }
1726         }
1727     }
1728   else
1729     return LOOKUP_TYPE_NODE (type) != NULL;
1730
1731   return FALSE;
1732 }
1733
1734 guint
1735 g_type_fundamental_branch_last (GType type)
1736 {
1737   GType ftype = G_TYPE_FUNDAMENTAL (type);
1738
1739   return ftype < last_fundamental_id ? g_branch_seqnos[ftype] : 0;
1740 }
1741
1742 GType* /* free result */
1743 g_type_children (GType  type,
1744                  guint *n_children)
1745 {
1746   TypeNode *node = LOOKUP_TYPE_NODE (type);
1747   
1748   if (node)
1749     {
1750       GType *children = g_new (GType, node->n_children + 1);
1751       
1752       memcpy (children, node->children, sizeof (GType) * node->n_children);
1753       children[node->n_children] = 0;
1754       
1755       if (n_children)
1756         *n_children = node->n_children;
1757       
1758       return children;
1759     }
1760   else
1761     {
1762       if (n_children)
1763         *n_children = 0;
1764       
1765       return NULL;
1766     }
1767 }
1768
1769 GType* /* free result */
1770 g_type_interfaces (GType  type,
1771                    guint *n_interfaces)
1772 {
1773   TypeNode *node = LOOKUP_TYPE_NODE (type);
1774
1775   if (node && node->is_instantiatable)
1776     {
1777       GType *ifaces = g_new (GType, node->n_ifaces + 1);
1778       guint i;
1779
1780       for (i = 0; i < node->n_ifaces; i++)
1781         ifaces[i] = node->private.iface_entries[i].iface_type;
1782       ifaces[i] = 0;
1783
1784       if (n_interfaces)
1785         *n_interfaces = node->n_ifaces;
1786
1787       return ifaces;
1788     }
1789   else
1790     {
1791       if (n_interfaces)
1792         *n_interfaces = 0;
1793
1794       return NULL;
1795     }
1796 }
1797
1798 typedef struct _QData QData;
1799 struct _GData
1800 {
1801   guint  n_qdatas;
1802   QData *qdatas;
1803 };
1804 struct _QData
1805 {
1806   GQuark   quark;
1807   gpointer data;
1808 };
1809
1810 gpointer
1811 g_type_get_qdata (GType  type,
1812                   GQuark quark)
1813 {
1814   TypeNode *node = LOOKUP_TYPE_NODE (type);
1815   GData *gdata;
1816   
1817   g_return_val_if_fail (node != NULL, NULL);
1818
1819   gdata = node->static_gdata;
1820   if (quark && gdata && gdata->n_qdatas)
1821     {
1822       QData *qdatas = gdata->qdatas - 1;
1823       guint n_qdatas = gdata->n_qdatas;
1824
1825       do                /* FIXME: should optimize qdata lookups for <= 4 */
1826         {
1827           guint i;
1828           QData *check;
1829
1830           i = (n_qdatas + 1) / 2;
1831           check = qdatas + i;
1832           if (quark == check->quark)
1833             return check->data;
1834           else if (quark > check->quark)
1835             {
1836               n_qdatas -= i;
1837               qdatas = check;
1838             }
1839           else /* if (quark < check->quark) */
1840             n_qdatas = i - 1;
1841         }
1842       while (n_qdatas);
1843     }
1844
1845   return NULL;
1846 }
1847
1848 void
1849 g_type_set_qdata (GType    type,
1850                   GQuark   quark,
1851                   gpointer data)
1852 {
1853   TypeNode *node = LOOKUP_TYPE_NODE (type);
1854   GData *gdata;
1855   QData *qdata;
1856   guint i;
1857
1858   g_return_if_fail (node != NULL);
1859   g_return_if_fail (quark != 0);
1860
1861   /* setup qdata list if necessary */
1862   if (!node->static_gdata)
1863     node->static_gdata = g_new0 (GData, 1);
1864   gdata = node->static_gdata;
1865
1866   /* try resetting old data */
1867   qdata = gdata->qdatas;
1868   for (i = 0; i < gdata->n_qdatas; i++)
1869     if (qdata[i].quark == quark)
1870       {
1871         qdata[i].data = data;
1872         return;
1873       }
1874
1875   /* add new entry */
1876   gdata->n_qdatas++;
1877   gdata->qdatas = g_renew (QData, gdata->qdatas, gdata->n_qdatas);
1878   qdata = gdata->qdatas;
1879   for (i = 0; i < gdata->n_qdatas - 1; i++)
1880     if (qdata[i].quark > quark)
1881       break;
1882   g_memmove (qdata + i + 1, qdata + i, sizeof (qdata[0]) * (gdata->n_qdatas - i - 1));
1883   qdata[i].quark = quark;
1884   qdata[i].data = data;
1885 }
1886
1887
1888 /* --- implementation details --- */
1889 gboolean
1890 g_type_check_flags (GType type,
1891                     guint flags)
1892 {
1893   TypeNode *node = LOOKUP_TYPE_NODE (type);
1894   gboolean result = FALSE;
1895
1896   if (node)
1897     {
1898       guint fflags = flags & TYPE_FUNDAMENTAL_FLAG_MASK;
1899       guint tflags = flags & TYPE_FLAG_MASK;
1900
1901       if (fflags)
1902         {
1903           GTypeFundamentalInfo *finfo = type_node_fundamental_info (node);
1904           
1905           fflags = (finfo->type_flags & fflags) == fflags;
1906         }
1907       else
1908         fflags = TRUE;
1909       
1910       if (tflags)
1911         tflags = (tflags & GPOINTER_TO_UINT (g_type_get_qdata (type, quark_type_flags))) == tflags;
1912       else
1913         tflags = TRUE;
1914       
1915       result = tflags && fflags;
1916     }
1917   return result;
1918 }
1919
1920 GTypePlugin*
1921 g_type_get_plugin (GType type)
1922 {
1923   TypeNode *node = LOOKUP_TYPE_NODE (type);
1924
1925   return node ? node->plugin : NULL;
1926 }
1927
1928 GType
1929 g_type_fundamental_last (void)
1930 {
1931   return last_fundamental_id;
1932 }
1933
1934 gboolean
1935 g_type_instance_conforms_to (GTypeInstance *type_instance,
1936                              GType          iface_type)
1937 {
1938   return (type_instance && type_instance->g_class &&
1939           G_TYPE_IS_INSTANTIATABLE (type_instance->g_class->g_type) &&
1940           g_type_conforms_to (type_instance->g_class->g_type, iface_type));
1941 }
1942
1943 gboolean
1944 g_type_class_is_a (GTypeClass *type_class,
1945                    GType       is_a_type)
1946 {
1947   return (type_class && G_TYPE_IS_CLASSED (type_class->g_type) &&
1948           g_type_is_a (type_class->g_type, is_a_type));
1949 }
1950
1951 gboolean
1952 g_type_value_conforms_to (GValue *value,
1953                           GType   type)
1954 {
1955   TypeNode *node;
1956   
1957   if (!value)
1958     return FALSE;
1959   node = LOOKUP_TYPE_NODE (value->g_type);
1960 #if 0
1961   if (!G_TYPE_IS_FUNDAMENTAL (value->g_type) && !node || !node->data)
1962     node = LOOKUP_TYPE_NODE (G_TYPE_FUNDAMENTAL (value->g_type));
1963 #endif
1964   if (!node || !node->data || node->data->common.ref_count < 1 ||
1965       !node->data->common.value_table->value_init ||
1966       !g_type_conforms_to (value->g_type, type))
1967     return FALSE;
1968   
1969   return TRUE;
1970 }
1971
1972 gboolean
1973 g_type_check_value (GValue *value)
1974 {
1975   return value && g_type_value_conforms_to (value, value->g_type);
1976 }
1977
1978 GTypeInstance*
1979 g_type_check_instance_cast (GTypeInstance *type_instance,
1980                             GType          iface_type)
1981 {
1982   if (!type_instance)
1983     {
1984       g_warning ("invalid cast from (NULL) pointer to `%s'",
1985                  type_descriptive_name (iface_type));
1986       return type_instance;
1987     }
1988   if (!type_instance->g_class)
1989     {
1990       g_warning ("invalid unclassed pointer in cast to `%s'",
1991                  type_descriptive_name (iface_type));
1992       return type_instance;
1993     }
1994   if (!G_TYPE_IS_INSTANTIATABLE (type_instance->g_class->g_type))
1995     {
1996       g_warning ("invalid uninstantiatable type `%s' in cast to `%s'",
1997                  type_descriptive_name (type_instance->g_class->g_type),
1998                  type_descriptive_name (iface_type));
1999       return type_instance;
2000     }
2001   if (!g_type_conforms_to (type_instance->g_class->g_type, iface_type))
2002     {
2003       g_warning ("invalid cast from `%s' to `%s'",
2004                  type_descriptive_name (type_instance->g_class->g_type),
2005                  type_descriptive_name (iface_type));
2006       return type_instance;
2007     }
2008
2009   return type_instance;
2010 }
2011
2012 GTypeClass*
2013 g_type_check_class_cast (GTypeClass *type_class,
2014                          GType       is_a_type)
2015 {
2016   if (!type_class)
2017     {
2018       g_warning ("invalid class cast from (NULL) pointer to `%s'",
2019                  type_descriptive_name (is_a_type));
2020       return type_class;
2021     }
2022   if (!G_TYPE_IS_CLASSED (type_class->g_type))
2023     {
2024       g_warning ("invalid unclassed type `%s' in class cast to `%s'",
2025                  type_descriptive_name (type_class->g_type),
2026                  type_descriptive_name (is_a_type));
2027       return type_class;
2028     }
2029   if (!g_type_is_a (type_class->g_type, is_a_type))
2030     {
2031       g_warning ("invalid class cast from `%s' to `%s'",
2032                  type_descriptive_name (type_class->g_type),
2033                  type_descriptive_name (is_a_type));
2034       return type_class;
2035     }
2036
2037   return type_class;
2038 }
2039
2040 gboolean
2041 g_type_check_instance (GTypeInstance *type_instance)
2042 {
2043   /* this function is just here to make the signal system
2044    * conveniently elaborated on instance checks
2045    */
2046   if (!type_instance)
2047     {
2048       g_warning ("instance is invalid (NULL) pointer");
2049       return FALSE;
2050     }
2051   if (!type_instance->g_class)
2052     {
2053       g_warning ("instance with invalid (NULL) class pointer");
2054       return FALSE;
2055     }
2056   if (!G_TYPE_IS_CLASSED (type_instance->g_class->g_type))
2057     {
2058       g_warning ("instance of invalid unclassed type `%s'",
2059                  type_descriptive_name (type_instance->g_class->g_type));
2060       return FALSE;
2061     }
2062   if (!G_TYPE_IS_INSTANTIATABLE (type_instance->g_class->g_type))
2063     {
2064       g_warning ("instance of invalid non-instantiatable type `%s'",
2065                  type_descriptive_name (type_instance->g_class->g_type));
2066       return FALSE;
2067     }
2068
2069   return TRUE;
2070 }
2071
2072
2073 /* --- foreign prototypes --- */
2074 extern void     g_value_types_init      (void); /* sync with gvaluetypes.c */
2075 extern void     g_enum_types_init       (void); /* sync with genums.c */
2076 extern void     g_param_type_init       (void); /* sync with gparam.c */
2077 extern void     g_boxed_type_init       (void); /* sync with gboxed.c */
2078 extern void     g_object_type_init      (void); /* sync with gobject.c */
2079 extern void     g_param_spec_types_init (void); /* sync with gparamspecs.c */
2080 extern void     g_signal_init           (void); /* sync with gsignal.c */
2081
2082
2083 /* --- initialization --- */
2084 void
2085 g_type_init (void)
2086 {
2087   static TypeNode *type0_node = NULL;
2088   GTypeInfo info;
2089   TypeNode *node;
2090   GType type;
2091
2092   if (last_fundamental_id)
2093     return;
2094
2095   /* type qname hash table */
2096   g_type_nodes_ht = g_hash_table_new (g_direct_hash, g_direct_equal);
2097
2098   /* invalid type G_TYPE_INVALID (0)
2099    */
2100   last_fundamental_id = 1;
2101   g_type_nodes = g_renew (TypeNode**, g_type_nodes, last_fundamental_id);
2102   g_type_nodes[0] = &type0_node;
2103   g_branch_seqnos = g_renew (GType, g_branch_seqnos, last_fundamental_id);
2104   g_branch_seqnos[0] = 1;
2105
2106   /* void type G_TYPE_NONE
2107    */
2108   node = type_node_fundamental_new (G_TYPE_NONE, "void", 0);
2109   type = NODE_TYPE (node);
2110   g_assert (type == G_TYPE_NONE);
2111
2112   /* interface fundamental type G_TYPE_INTERFACE (!classed)
2113    */
2114   memset (&info, 0, sizeof (info));
2115   node = type_node_fundamental_new (G_TYPE_INTERFACE, "GInterface", G_TYPE_FLAG_DERIVABLE);
2116   type = NODE_TYPE (node);
2117   type_data_make (node, &info, NULL); /* FIXME */
2118   g_assert (type == G_TYPE_INTERFACE);
2119
2120   /* G_TYPE_* value types
2121    */
2122   g_value_types_init ();
2123   
2124   /* G_TYPE_ENUM & G_TYPE_FLAGS
2125    */
2126   g_enum_types_init ();
2127   
2128   /* G_TYPE_PARAM
2129    */
2130   g_param_type_init ();
2131
2132   /* G_TYPE_PARAM
2133    */
2134   g_boxed_type_init ();
2135
2136   /* G_TYPE_OBJECT
2137    */
2138   g_object_type_init ();
2139
2140   /* G_TYPE_PARAM_* pspec types
2141    */
2142   g_param_spec_types_init ();
2143
2144   /* Signal system
2145    */
2146   g_signal_init ();
2147 }