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