Remove usage of (GAPI-oriented) TypeTag in favor of GITypeTag from
[gnome.gobject-introspection] / girepository / girnode.c
1 /* GObject introspection: Typelib creation
2  *
3  * Copyright (C) 2005 Matthias Clasen
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24
25 #include "girmodule.h"
26 #include "girnode.h"
27 #include "gtypelib.h"
28
29 static gulong string_count = 0;
30 static gulong unique_string_count = 0;
31 static gulong string_size = 0;
32 static gulong unique_string_size = 0;
33 static gulong types_count = 0;
34 static gulong unique_types_count = 0;
35
36 void
37 init_stats (void)
38 {
39   string_count = 0;
40   unique_string_count = 0;
41   string_size = 0;
42   unique_string_size = 0;
43   types_count = 0;
44   unique_types_count = 0;
45 }
46
47 void
48 dump_stats (void)
49 {
50   g_message ("%lu strings (%lu before sharing), %lu bytes (%lu before sharing)",
51              unique_string_count, string_count, unique_string_size, string_size);
52   g_message ("%lu types (%lu before sharing)", unique_types_count, types_count);
53 }
54
55 #define ALIGN_VALUE(this, boundary) \
56   (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
57
58
59 static const gchar *
60 g_ir_node_type_to_string (GIrNodeTypeId type)
61 {
62   switch (type)
63     {
64     case G_IR_NODE_FUNCTION:
65       return "function";
66     case G_IR_NODE_CALLBACK:
67       return "callback";
68     case G_IR_NODE_PARAM:
69       return "param";
70     case G_IR_NODE_TYPE:
71       return "type";
72     case G_IR_NODE_OBJECT:
73       return "object";
74     case G_IR_NODE_INTERFACE:
75       return "interface";
76     case G_IR_NODE_SIGNAL:
77       return "signal";
78     case G_IR_NODE_PROPERTY:
79       return "property";
80     case G_IR_NODE_VFUNC:
81       return "vfunc";
82     case G_IR_NODE_FIELD:
83       return "field";
84     case G_IR_NODE_ENUM:
85       return "enum";
86     case G_IR_NODE_FLAGS:
87       return "flags";
88     case G_IR_NODE_BOXED:
89       return "boxed";
90     case G_IR_NODE_STRUCT:
91       return "struct";
92     case G_IR_NODE_VALUE:
93       return "value";
94     case G_IR_NODE_CONSTANT:
95       return "constant";
96     case G_IR_NODE_ERROR_DOMAIN:
97       return "error-domain";
98     case G_IR_NODE_XREF:
99       return "xref";
100     case G_IR_NODE_UNION:
101       return "union";
102     default:
103       return "unknown";
104     }
105 }
106
107 static const gchar*
108 gi_type_tag_to_string (GITypeTag type)
109 {
110   switch (type)
111     {
112     case GI_TYPE_TAG_VOID:
113       return "void";
114     case GI_TYPE_TAG_BOOLEAN:
115       return "boolean";
116     case GI_TYPE_TAG_INT8:
117       return "int8";
118     case GI_TYPE_TAG_UINT8:
119       return "uint8";
120     case GI_TYPE_TAG_INT16:
121       return "int16";
122     case GI_TYPE_TAG_UINT16:
123       return "uint16";
124     case GI_TYPE_TAG_INT32:
125       return "int32";
126     case GI_TYPE_TAG_UINT32:
127       return "uint32";
128     case GI_TYPE_TAG_INT64:
129       return "int64";
130     case GI_TYPE_TAG_UINT64:
131       return "uint64";
132     case GI_TYPE_TAG_INT:
133       return "int";
134     case GI_TYPE_TAG_UINT:
135       return "uint";
136     case GI_TYPE_TAG_LONG:
137       return "long";
138     case GI_TYPE_TAG_ULONG:
139       return "ulong";
140     case GI_TYPE_TAG_SSIZE:
141       return "ssize";
142     case GI_TYPE_TAG_SIZE:
143       return "size";
144     case GI_TYPE_TAG_FLOAT:
145       return "float";
146     case GI_TYPE_TAG_DOUBLE:
147       return "double";
148     case GI_TYPE_TAG_UTF8:
149       return "utf8";
150     case GI_TYPE_TAG_FILENAME:
151       return "filename";
152     case GI_TYPE_TAG_ARRAY:
153       return "array";
154     case GI_TYPE_TAG_INTERFACE:
155       return "interface";
156     case GI_TYPE_TAG_GLIST:
157       return "glist";
158     case GI_TYPE_TAG_GSLIST:
159       return "gslist";
160     case GI_TYPE_TAG_GHASH:
161       return "ghash";
162     case GI_TYPE_TAG_ERROR:
163       return "error";
164     default:
165       return "unknown";
166     }
167 }
168
169 GIrNode *
170 g_ir_node_new (GIrNodeTypeId type)
171 {
172   GIrNode *node = NULL;
173
174   switch (type)
175     {
176    case G_IR_NODE_FUNCTION:
177    case G_IR_NODE_CALLBACK:
178       node = g_malloc0 (sizeof (GIrNodeFunction));
179       break;
180
181    case G_IR_NODE_PARAM:
182       node = g_malloc0 (sizeof (GIrNodeParam));
183       break;
184
185    case G_IR_NODE_TYPE:
186       node = g_malloc0 (sizeof (GIrNodeType));
187       break;
188
189     case G_IR_NODE_OBJECT:
190     case G_IR_NODE_INTERFACE:
191       node = g_malloc0 (sizeof (GIrNodeInterface));
192       break;
193
194     case G_IR_NODE_SIGNAL:
195       node = g_malloc0 (sizeof (GIrNodeSignal));
196       break;
197
198     case G_IR_NODE_PROPERTY:
199       node = g_malloc0 (sizeof (GIrNodeProperty));
200       break;
201
202     case G_IR_NODE_VFUNC:
203       node = g_malloc0 (sizeof (GIrNodeFunction));
204       break;
205
206     case G_IR_NODE_FIELD:
207       node = g_malloc0 (sizeof (GIrNodeField));
208       break;
209
210     case G_IR_NODE_ENUM:
211     case G_IR_NODE_FLAGS:
212       node = g_malloc0 (sizeof (GIrNodeEnum));
213       break;
214
215     case G_IR_NODE_BOXED:
216       node = g_malloc0 (sizeof (GIrNodeBoxed));
217       break;
218
219     case G_IR_NODE_STRUCT:
220       node = g_malloc0 (sizeof (GIrNodeStruct));
221       break;
222
223     case G_IR_NODE_VALUE:
224       node = g_malloc0 (sizeof (GIrNodeValue));
225       break;
226
227     case G_IR_NODE_CONSTANT:
228       node = g_malloc0 (sizeof (GIrNodeConstant));
229       break;
230
231     case G_IR_NODE_ERROR_DOMAIN:
232       node = g_malloc0 (sizeof (GIrNodeErrorDomain));
233       break;
234
235     case G_IR_NODE_XREF:
236       node = g_malloc0 (sizeof (GIrNodeXRef));
237       break;
238
239     case G_IR_NODE_UNION:
240       node = g_malloc0 (sizeof (GIrNodeUnion));
241       break;
242
243     default:
244       g_error ("Unhandled node type %d\n", type);
245       break;
246     }
247
248   node->type = type;
249
250   return node;
251 }
252
253 void
254 g_ir_node_free (GIrNode *node)
255 {
256   GList *l;
257
258   if (node == NULL)
259     return;
260
261   switch (node->type)
262     {
263     case G_IR_NODE_FUNCTION:
264     case G_IR_NODE_CALLBACK:
265       {
266         GIrNodeFunction *function = (GIrNodeFunction *)node;
267         
268         g_free (node->name);
269         g_free (function->symbol);
270         g_ir_node_free ((GIrNode *)function->result);
271         for (l = function->parameters; l; l = l->next)
272           g_ir_node_free ((GIrNode *)l->data);
273         g_list_free (function->parameters);
274       }
275       break;
276
277     case G_IR_NODE_TYPE:
278       {
279         GIrNodeType *type = (GIrNodeType *)node;
280         
281         g_free (node->name);
282         g_ir_node_free ((GIrNode *)type->parameter_type1);
283         g_ir_node_free ((GIrNode *)type->parameter_type2);
284
285         g_free (type->interface);
286         g_strfreev (type->errors);
287
288       }
289       break;
290
291     case G_IR_NODE_PARAM:
292       {
293         GIrNodeParam *param = (GIrNodeParam *)node;
294         
295         g_free (node->name);
296         g_ir_node_free ((GIrNode *)param->type);
297       }
298       break;
299
300     case G_IR_NODE_PROPERTY:
301       {
302         GIrNodeProperty *property = (GIrNodeProperty *)node;
303         
304         g_free (node->name);
305         g_ir_node_free ((GIrNode *)property->type);
306       }
307       break;
308
309     case G_IR_NODE_SIGNAL:
310       {
311         GIrNodeSignal *signal = (GIrNodeSignal *)node;
312         
313         g_free (node->name);
314         for (l = signal->parameters; l; l = l->next)
315           g_ir_node_free ((GIrNode *)l->data);
316         g_list_free (signal->parameters);
317         g_ir_node_free ((GIrNode *)signal->result);
318       }
319       break;
320
321     case G_IR_NODE_VFUNC:
322       {
323         GIrNodeVFunc *vfunc = (GIrNodeVFunc *)node;
324         
325         g_free (node->name);
326         for (l = vfunc->parameters; l; l = l->next)
327           g_ir_node_free ((GIrNode *)l->data);
328         g_list_free (vfunc->parameters);
329         g_ir_node_free ((GIrNode *)vfunc->result);
330       }
331       break;
332
333     case G_IR_NODE_FIELD:
334       {
335         GIrNodeField *field = (GIrNodeField *)node;
336         
337         g_free (node->name);
338         g_ir_node_free ((GIrNode *)field->type);
339       }
340       break;
341
342     case G_IR_NODE_OBJECT:
343     case G_IR_NODE_INTERFACE:
344       {
345         GIrNodeInterface *iface = (GIrNodeInterface *)node;
346         
347         g_free (node->name);
348         g_free (iface->gtype_name);
349         g_free (iface->gtype_init);
350         
351         g_free (iface->parent);
352
353         for (l = iface->interfaces; l; l = l->next)
354           g_free ((GIrNode *)l->data);
355         g_list_free (iface->interfaces);
356
357         for (l = iface->members; l; l = l->next)
358           g_ir_node_free ((GIrNode *)l->data);
359         g_list_free (iface->members);
360
361       }
362       break;
363  
364     case G_IR_NODE_VALUE:
365       {
366         g_free (node->name);
367       }
368       break;
369
370     case G_IR_NODE_ENUM:
371     case G_IR_NODE_FLAGS:
372       {
373         GIrNodeEnum *enum_ = (GIrNodeEnum *)node;
374         
375         g_free (node->name);
376         g_free (enum_->gtype_name);
377         g_free (enum_->gtype_init);
378
379         for (l = enum_->values; l; l = l->next)
380           g_ir_node_free ((GIrNode *)l->data);
381         g_list_free (enum_->values);
382       }
383       break;
384
385     case G_IR_NODE_BOXED:
386       {
387         GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
388         
389         g_free (node->name);
390         g_free (boxed->gtype_name);
391         g_free (boxed->gtype_init);
392
393         for (l = boxed->members; l; l = l->next)
394           g_ir_node_free ((GIrNode *)l->data);
395         g_list_free (boxed->members);
396       }
397       break;
398
399     case G_IR_NODE_STRUCT:
400       {
401         GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
402
403         g_free (node->name);
404         for (l = struct_->members; l; l = l->next)
405           g_ir_node_free ((GIrNode *)l->data);
406         g_list_free (struct_->members);
407       }
408       break;
409
410     case G_IR_NODE_CONSTANT:
411       {
412         GIrNodeConstant *constant = (GIrNodeConstant *)node;
413         
414         g_free (node->name);
415         g_free (constant->value);
416         g_ir_node_free ((GIrNode *)constant->type);
417       }
418       break;
419
420     case G_IR_NODE_ERROR_DOMAIN:
421       {
422         GIrNodeErrorDomain *domain = (GIrNodeErrorDomain *)node;
423         
424         g_free (node->name);
425         g_free (domain->getquark);
426         g_free (domain->codes);
427       }
428       break;
429
430     case G_IR_NODE_XREF:
431       {
432         GIrNodeXRef *xref = (GIrNodeXRef *)node;
433         
434         g_free (node->name);
435         g_free (xref->namespace);
436       }
437       break;
438
439     case G_IR_NODE_UNION:
440       {
441         GIrNodeUnion *union_ = (GIrNodeUnion *)node;
442         
443         g_free (node->name);
444         g_free (union_->gtype_name);
445         g_free (union_->gtype_init);
446
447         g_ir_node_free ((GIrNode *)union_->discriminator_type);
448         for (l = union_->members; l; l = l->next)
449           g_ir_node_free ((GIrNode *)l->data);
450         for (l = union_->discriminators; l; l = l->next)
451           g_ir_node_free ((GIrNode *)l->data);
452       }
453       break;
454
455     default:
456       g_error ("Unhandled node type %d\n", node->type);
457       break;
458     } 
459
460   g_free (node);
461 }
462
463 /* returns the fixed size of the blob */
464 guint32
465 g_ir_node_get_size (GIrNode *node)
466 {
467   GList *l;
468   gint size, n;
469
470   switch (node->type)
471     {
472     case G_IR_NODE_CALLBACK:
473       size = 12; 
474       break;
475
476     case G_IR_NODE_FUNCTION:
477       size = 16; 
478       break;
479
480     case G_IR_NODE_PARAM:
481       size = 12;
482       break;
483
484     case G_IR_NODE_TYPE:
485       size = 4;
486       break;
487
488     case G_IR_NODE_OBJECT:
489       {
490         GIrNodeInterface *iface = (GIrNodeInterface *)node;
491
492         n = g_list_length (iface->interfaces);
493         size = 32 + 2 * (n + (n % 2));
494
495         for (l = iface->members; l; l = l->next)
496           size += g_ir_node_get_size ((GIrNode *)l->data);
497       }
498       break;
499
500     case G_IR_NODE_INTERFACE:
501       {
502         GIrNodeInterface *iface = (GIrNodeInterface *)node;
503
504         n = g_list_length (iface->prerequisites);
505         size = 28 + 2 * (n + (n % 2));
506
507         for (l = iface->members; l; l = l->next)
508           size += g_ir_node_get_size ((GIrNode *)l->data);
509       }
510       break;
511
512     case G_IR_NODE_ENUM:
513     case G_IR_NODE_FLAGS:
514       {
515         GIrNodeEnum *enum_ = (GIrNodeEnum *)node;
516         
517         size = 20;
518         for (l = enum_->values; l; l = l->next)
519           size += g_ir_node_get_size ((GIrNode *)l->data);
520       }
521       break;
522
523     case G_IR_NODE_VALUE:
524       size = 12;
525       break;
526
527     case G_IR_NODE_STRUCT:
528       {
529         GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
530
531         size = 20;
532         for (l = struct_->members; l; l = l->next)
533           size += g_ir_node_get_size ((GIrNode *)l->data);
534       }
535       break;
536
537     case G_IR_NODE_BOXED:
538       {
539         GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
540
541         size = 20;
542         for (l = boxed->members; l; l = l->next)
543           size += g_ir_node_get_size ((GIrNode *)l->data);
544       }
545       break;
546
547     case G_IR_NODE_PROPERTY:
548       size = 12;
549       break;
550
551     case G_IR_NODE_SIGNAL:
552       size = 12;
553       break;
554
555     case G_IR_NODE_VFUNC:
556       size = 16;
557       break;
558
559     case G_IR_NODE_FIELD:
560       size = 12;
561       break;
562
563     case G_IR_NODE_CONSTANT:
564       size = 20;
565       break;
566
567     case G_IR_NODE_ERROR_DOMAIN:
568       size = 16;
569       break;
570
571     case G_IR_NODE_XREF:
572       size = 0;
573       break;
574
575     case G_IR_NODE_UNION:
576       {
577         GIrNodeUnion *union_ = (GIrNodeUnion *)node;
578
579         size = 28;
580         for (l = union_->members; l; l = l->next)
581           size += g_ir_node_get_size ((GIrNode *)l->data);
582         for (l = union_->discriminators; l; l = l->next)
583           size += g_ir_node_get_size ((GIrNode *)l->data);
584       }
585       break;
586
587     default: 
588       g_error ("Unhandled node type '%s'\n",
589                g_ir_node_type_to_string (node->type));
590       size = 0;
591     }
592
593   g_debug ("node %p type '%s' size %d", node,
594            g_ir_node_type_to_string (node->type), size);
595
596   return size;
597 }
598
599 /* returns the full size of the blob including variable-size parts */
600 static guint32
601 g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node)
602 {
603   GList *l;
604   gint size, n;
605
606   if (node == NULL && parent != NULL)
607     g_error ("Caught NULL node, parent=%s", parent->name);
608
609   g_debug ("node %p type '%s'", node,
610            g_ir_node_type_to_string (node->type));
611
612   switch (node->type)
613     {
614     case G_IR_NODE_CALLBACK:
615       {
616         GIrNodeFunction *function = (GIrNodeFunction *)node;
617         size = 12; 
618         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
619         for (l = function->parameters; l; l = l->next)
620           {
621             size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
622           }
623         size += g_ir_node_get_full_size_internal (node, (GIrNode *)function->result);
624       }
625       break;
626
627     case G_IR_NODE_FUNCTION:
628       {
629         GIrNodeFunction *function = (GIrNodeFunction *)node;
630         size = 24;
631         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
632         size += ALIGN_VALUE (strlen (function->symbol) + 1, 4);
633         for (l = function->parameters; l; l = l->next)
634           size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
635         size += g_ir_node_get_full_size_internal (node, (GIrNode *)function->result);
636       }
637       break;
638
639     case G_IR_NODE_PARAM:
640       {
641         GIrNodeParam *param = (GIrNodeParam *)node;
642         
643         size = 12;
644         if (node->name)
645           size += ALIGN_VALUE (strlen (node->name) + 1, 4);
646         size += g_ir_node_get_full_size_internal (node, (GIrNode *)param->type);        
647       }
648       break;
649
650     case G_IR_NODE_TYPE:
651       {
652         GIrNodeType *type = (GIrNodeType *)node;
653         if (type->tag < GI_TYPE_TAG_ARRAY) 
654           size = 4;
655         else
656           {
657             g_debug ("node %p type tag '%s'", node,
658                      gi_type_tag_to_string (type->tag));
659
660             switch (type->tag)
661               {
662               case GI_TYPE_TAG_ARRAY:
663                 size = 4 + 4;
664                 if (type->parameter_type1)
665                   size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1);
666                 break;
667               case GI_TYPE_TAG_INTERFACE:
668                 size = 4 + 4;
669                 break;
670               case GI_TYPE_TAG_GLIST:
671               case GI_TYPE_TAG_GSLIST:
672                 size = 4 + 4;
673                 if (type->parameter_type1)
674                   size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1);
675                 break;
676               case GI_TYPE_TAG_GHASH:
677                 size = 4 + 4 + 4;
678                 if (type->parameter_type1)
679                   size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1);
680                 if (type->parameter_type2)
681                   size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type2);
682                 break;
683               case GI_TYPE_TAG_ERROR:
684                 {
685                   gint n;
686                   
687                   if (type->errors)
688                     n = g_strv_length (type->errors);
689                   else
690                     n = 0;
691
692                   size = 4 + 4 + 2 * (n + n % 2);
693                 }
694                 break;
695               default:
696                 g_error ("Unknown type tag %d\n", type->tag);
697                 break;
698               }
699           }
700       }
701       break;
702
703     case G_IR_NODE_OBJECT:
704       {
705         GIrNodeInterface *iface = (GIrNodeInterface *)node;
706
707         n = g_list_length (iface->interfaces);
708         size = 32;
709         if (iface->parent)
710           size += ALIGN_VALUE (strlen (iface->parent) + 1, 4);
711         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
712         size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4);
713         size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4);
714         size += 2 * (n + (n % 2));
715
716         for (l = iface->members; l; l = l->next)
717           size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
718       }
719       break;
720
721     case G_IR_NODE_INTERFACE:
722       {
723         GIrNodeInterface *iface = (GIrNodeInterface *)node;
724
725         n = g_list_length (iface->prerequisites);
726         size = 28;
727         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
728         size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4);
729         size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4);
730         size += 2 * (n + (n % 2));
731
732         for (l = iface->members; l; l = l->next)
733           size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
734       }
735       break;
736
737     case G_IR_NODE_ENUM:
738     case G_IR_NODE_FLAGS:
739       {
740         GIrNodeEnum *enum_ = (GIrNodeEnum *)node;
741         
742         size = 20;
743         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
744         if (enum_->gtype_name)
745           {
746             size += ALIGN_VALUE (strlen (enum_->gtype_name) + 1, 4);
747             size += ALIGN_VALUE (strlen (enum_->gtype_init) + 1, 4);
748           }
749
750         for (l = enum_->values; l; l = l->next)
751           size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);  
752       }
753       break;
754
755     case G_IR_NODE_VALUE:
756       {
757         size = 12;
758         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
759       }
760       break;
761
762     case G_IR_NODE_STRUCT:
763       {
764         GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
765
766         size = 20;
767         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
768         for (l = struct_->members; l; l = l->next)
769           size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
770       }
771       break;
772
773     case G_IR_NODE_BOXED:
774       {
775         GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
776
777         size = 20;
778         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
779         if (boxed->gtype_name)
780           {
781             size += ALIGN_VALUE (strlen (boxed->gtype_name) + 1, 4);
782             size += ALIGN_VALUE (strlen (boxed->gtype_init) + 1, 4);
783           }
784         for (l = boxed->members; l; l = l->next)
785           size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
786       }
787       break;
788
789     case G_IR_NODE_PROPERTY:
790       {
791         GIrNodeProperty *prop = (GIrNodeProperty *)node;
792         
793         size = 12;
794         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
795         size += g_ir_node_get_full_size_internal (node, (GIrNode *)prop->type); 
796       }
797       break;
798
799     case G_IR_NODE_SIGNAL:
800       {
801         GIrNodeSignal *signal = (GIrNodeSignal *)node;
802
803         size = 12;
804         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
805         for (l = signal->parameters; l; l = l->next)
806           size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
807         size += g_ir_node_get_full_size_internal (node, (GIrNode *)signal->result);
808       }
809       break;
810
811     case G_IR_NODE_VFUNC:
812       {
813         GIrNodeVFunc *vfunc = (GIrNodeVFunc *)node;
814
815         size = 16;
816         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
817         for (l = vfunc->parameters; l; l = l->next)
818           size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
819         size += g_ir_node_get_full_size_internal (node, (GIrNode *)vfunc->result);
820       }
821       break;
822
823     case G_IR_NODE_FIELD:
824       {
825         GIrNodeField *field = (GIrNodeField *)node;
826
827         size = 12;
828         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
829         size += g_ir_node_get_full_size_internal (node, (GIrNode *)field->type);        
830       }
831       break;
832
833     case G_IR_NODE_CONSTANT:
834       {
835         GIrNodeConstant *constant = (GIrNodeConstant *)node;
836
837         size = 20;
838         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
839         /* FIXME non-string values */
840         size += ALIGN_VALUE (strlen (constant->value) + 1, 4);
841         size += g_ir_node_get_full_size_internal (node, (GIrNode *)constant->type);     
842       }
843       break;
844
845     case G_IR_NODE_ERROR_DOMAIN:
846       {
847         GIrNodeErrorDomain *domain = (GIrNodeErrorDomain *)node;
848
849         size = 16;
850         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
851         size += ALIGN_VALUE (strlen (domain->getquark) + 1, 4);
852       }
853       break;
854
855     case G_IR_NODE_XREF:
856       {
857         GIrNodeXRef *xref = (GIrNodeXRef *)node;
858         
859         size = 0;
860         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
861         size += ALIGN_VALUE (strlen (xref->namespace) + 1, 4);
862       }
863       break;
864
865     case G_IR_NODE_UNION:
866       {
867         GIrNodeUnion *union_ = (GIrNodeUnion *)node;
868
869         size = 28;
870         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
871         for (l = union_->members; l; l = l->next)
872           size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
873         for (l = union_->discriminators; l; l = l->next)
874           size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
875       }
876       break;
877
878     default: 
879       g_error ("Unknown type tag %d\n", node->type);
880       size = 0;
881     }
882
883   g_debug ("node %p type '%s' full size %d", node,
884            g_ir_node_type_to_string (node->type), size);
885
886   return size;
887 }
888
889 guint32
890 g_ir_node_get_full_size (GIrNode *node)
891 {
892   return g_ir_node_get_full_size_internal (NULL, node);
893 }
894
895 int
896 g_ir_node_cmp (GIrNode *node,
897                 GIrNode *other)
898 {
899   if (node->type < other->type)
900     return -1;
901   else if (node->type > other->type)
902     return 1;
903   else
904     return strcmp (node->name, other->name);
905 }
906
907 gboolean
908 g_ir_node_can_have_member (GIrNode    *node)
909 {
910   switch (node->type)
911     {
912     case G_IR_NODE_OBJECT:
913     case G_IR_NODE_INTERFACE:
914     case G_IR_NODE_BOXED:
915     case G_IR_NODE_STRUCT:
916     case G_IR_NODE_UNION:
917       return TRUE;
918     };
919   return FALSE;
920 }
921
922 void
923 g_ir_node_add_member (GIrNode         *node,
924                        GIrNodeFunction *member)
925 {
926   g_return_if_fail (node != NULL);
927   g_return_if_fail (member != NULL);
928                     
929   switch (node->type)
930     {
931     case G_IR_NODE_OBJECT:
932     case G_IR_NODE_INTERFACE:
933       {
934         GIrNodeInterface *iface = (GIrNodeInterface *)node;
935         iface->members =
936           g_list_insert_sorted (iface->members, member,
937                                 (GCompareFunc) g_ir_node_cmp);
938         break;
939       }
940     case G_IR_NODE_BOXED:
941       {
942         GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
943         boxed->members =
944           g_list_insert_sorted (boxed->members, member,
945                                 (GCompareFunc) g_ir_node_cmp);
946         break;
947       }
948     case G_IR_NODE_STRUCT:
949       {
950         GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
951         struct_->members =
952           g_list_insert_sorted (struct_->members, member,
953                                 (GCompareFunc) g_ir_node_cmp);
954         break;
955       }
956     case G_IR_NODE_UNION:
957       {
958         GIrNodeUnion *union_ = (GIrNodeUnion *)node;
959         union_->members =
960           g_list_insert_sorted (union_->members, member,
961                                 (GCompareFunc) g_ir_node_cmp);
962         break;
963       }
964     default:
965       g_error ("Cannot add a member to unknown type tag type %d\n",
966                node->type);
967       break;
968     }
969 }
970
971 const gchar *
972 g_ir_node_param_direction_string (GIrNodeParam * node)
973 {
974   if (node->out)
975     {
976       if (node->in)
977         return "in-out";
978       else
979         return "out";
980     }
981   return "in";
982 }
983
984 static gint64
985 parse_int_value (const gchar *str)
986 {
987   return strtoll (str, NULL, 0);
988 }
989
990 static guint64
991 parse_uint_value (const gchar *str)
992 {
993   return strtoull (str, NULL, 0);
994 }
995
996 static gdouble
997 parse_float_value (const gchar *str)
998 {
999   return strtod (str, NULL);
1000 }
1001
1002 static gboolean
1003 parse_boolean_value (const gchar *str)
1004 {
1005   if (strcmp (str, "TRUE") == 0)
1006     return TRUE;
1007   
1008   if (strcmp (str, "FALSE") == 0)
1009     return FALSE;
1010
1011   return parse_int_value (str) ? TRUE : FALSE;
1012 }
1013
1014 static GIrNode *
1015 find_entry_node (GIrModule  *module,
1016                  GList       *modules,
1017                  const gchar *name,
1018                  guint16     *idx)
1019
1020 {
1021   GList *l;
1022   gint i;
1023   gchar **names;
1024   gint n_names;
1025   GIrNode *result = NULL;
1026
1027   names = g_strsplit (name, ".", 0);
1028   n_names = g_strv_length (names);
1029   if (n_names > 2)
1030     g_error ("Too many name parts");
1031   
1032   for (l = module->entries, i = 1; l; l = l->next, i++)
1033     {
1034       GIrNode *node = (GIrNode *)l->data;
1035       
1036       if (n_names > 1)
1037         {
1038           if (node->type != G_IR_NODE_XREF)
1039             continue;
1040           
1041           if (((GIrNodeXRef *)node)->namespace == NULL ||
1042               strcmp (((GIrNodeXRef *)node)->namespace, names[0]) != 0)
1043             continue;
1044         }
1045          
1046       if (strcmp (node->name, names[n_names - 1]) == 0)
1047         {
1048           if (idx)
1049             *idx = i;
1050           
1051           result = node;
1052           goto out;
1053         }
1054     }
1055
1056   if (n_names > 1)
1057     {
1058       GIrNode *node = g_ir_node_new (G_IR_NODE_XREF);
1059
1060       ((GIrNodeXRef *)node)->namespace = g_strdup (names[0]);
1061       node->name = g_strdup (names[1]);
1062   
1063       module->entries = g_list_append (module->entries, node);
1064   
1065       if (idx)
1066         *idx = g_list_length (module->entries);
1067
1068       result = node;
1069
1070       goto out;
1071     }
1072
1073   g_warning ("Entry '%s' not found", name);
1074
1075  out:
1076
1077   g_strfreev (names);
1078
1079   return result;
1080 }
1081
1082 static guint16
1083 find_entry (GIrModule  *module,
1084             GList       *modules,
1085             const gchar *name)
1086 {
1087   guint16 idx = 0;
1088
1089   find_entry_node (module, modules, name, &idx);
1090
1091   return idx;
1092 }
1093
1094 static void
1095 serialize_type (GIrModule   *module, 
1096                 GList        *modules,
1097                 GIrNodeType *node, 
1098                 GString      *str)
1099 {
1100   gint i;
1101   const gchar* basic[] = {
1102     "void", 
1103     "boolean", 
1104     "int8", 
1105     "uint8", 
1106     "int16", 
1107     "uint16", 
1108     "int32", 
1109     "uint32", 
1110     "int64", 
1111     "uint64", 
1112     "int",
1113     "uint",
1114     "long",
1115     "ulong",
1116     "ssize",
1117     "size",
1118     "float", 
1119     "double",
1120     "utf8", 
1121     "filename",
1122     "string",
1123     "sequence",
1124     "any"
1125   };
1126   
1127   if (node->tag < 20)
1128     {
1129       g_string_append_printf (str, "%s%s", 
1130                               basic[node->tag], node->is_pointer ? "*" : "");
1131     }
1132   else if (node->tag == 20)
1133     {
1134       serialize_type (module, modules, node->parameter_type1, str);
1135       g_string_append (str, "[");
1136
1137       if (node->has_length)
1138         g_string_append_printf (str, "length=%d", node->length);
1139       
1140       if (node->zero_terminated)
1141         g_string_append_printf (str, "%szero-terminated=1", 
1142                                 node->has_length ? "," : "");
1143       
1144       g_string_append (str, "]");
1145     }
1146   else if (node->tag == 21)
1147     {
1148       GIrNode *iface;
1149       gchar *name;
1150
1151       iface = find_entry_node (module, modules, node->interface, NULL);
1152       if (iface)
1153         name = iface->name;
1154       else
1155         {
1156           g_warning ("Interface for type reference %s not found", node->interface);
1157           name = node->interface;
1158         }
1159
1160       g_string_append_printf (str, "%s%s", name, node->is_pointer ? "*" : "");
1161     }
1162   else if (node->tag == 22)
1163     {
1164       g_string_append (str, "GList");
1165       if (node->parameter_type1)
1166         {
1167           g_string_append (str, "<"); 
1168           serialize_type (module, modules, node->parameter_type1, str);
1169           g_string_append (str, ">"); 
1170         }
1171     }
1172   else if (node->tag == 23)
1173     {
1174       g_string_append (str, "GSList");
1175       if (node->parameter_type1)
1176         {
1177           g_string_append (str, "<"); 
1178           serialize_type (module, modules, node->parameter_type1, str);
1179           g_string_append (str, ">"); 
1180         }
1181     }
1182   else if (node->tag == 24)
1183     {
1184       g_string_append (str, "GHashTable<");
1185       if (node->parameter_type1)
1186         {
1187           g_string_append (str, "<"); 
1188           serialize_type (module, modules, node->parameter_type1, str);
1189           g_string_append (str, ","); 
1190           serialize_type (module, modules, node->parameter_type2, str);
1191           g_string_append (str, ">"); 
1192         }
1193     }
1194   else if (node->tag == 25) 
1195     {
1196       g_string_append (str, "GError");
1197       if (node->errors)
1198         {
1199           g_string_append (str, "<"); 
1200           for (i = 0; node->errors[i]; i++)
1201             {
1202               if (i > 0)
1203                 g_string_append (str, ",");
1204               g_string_append (str, node->errors[i]);
1205             }
1206           g_string_append (str, ">"); 
1207         }
1208     }
1209 }
1210
1211 void
1212 g_ir_node_build_typelib (GIrNode   *node,
1213                          GIrModule *module,
1214                          GList      *modules,
1215                          GHashTable *strings,
1216                          GHashTable *types,
1217                          guchar     *data,
1218                          guint32    *offset,
1219                          guint32    *offset2)
1220 {
1221   GList *l;
1222   guint32 old_offset = *offset;
1223   guint32 old_offset2 = *offset2;
1224
1225   g_assert (node != NULL);
1226
1227   g_debug ("build_typelib: %s (%s)",
1228            node->name,
1229            g_ir_node_type_to_string (node->type));
1230
1231   switch (node->type)
1232     {
1233     case G_IR_NODE_TYPE:
1234       {
1235         GIrNodeType *type = (GIrNodeType *)node;
1236         SimpleTypeBlob *blob = (SimpleTypeBlob *)&data[*offset];
1237
1238         *offset += 4;
1239         
1240         if (type->tag < GI_TYPE_TAG_ARRAY ||
1241             type->tag == GI_TYPE_TAG_UTF8)
1242           { 
1243             blob->reserved = 0;
1244             blob->reserved2 = 0;
1245             blob->pointer = type->is_pointer;
1246             blob->reserved3 = 0;
1247             blob->tag = type->tag;
1248           }
1249         else 
1250           {
1251             GString *str;
1252             gchar *s;
1253             gpointer value;
1254             
1255             str = g_string_new (0);
1256             serialize_type (module, modules, type, str);
1257             s = g_string_free (str, FALSE);
1258             
1259             types_count += 1;
1260             value = g_hash_table_lookup (types, s);
1261             if (value)
1262               {
1263                 blob->offset = GPOINTER_TO_INT (value);
1264                 g_free (s);
1265               }
1266             else
1267               {
1268                 unique_types_count += 1;
1269                 g_hash_table_insert (types, s, GINT_TO_POINTER(*offset2));
1270                                      
1271                 blob->offset = *offset2;
1272                 switch (type->tag)
1273                   {
1274                   case GI_TYPE_TAG_ARRAY:
1275                     {
1276                       ArrayTypeBlob *array = (ArrayTypeBlob *)&data[*offset2];
1277                       guint32 pos;
1278                       
1279                       array->pointer = 1;
1280                       array->reserved = 0;
1281                       array->tag = type->tag;
1282                       array->zero_terminated = type->zero_terminated;
1283                       array->has_length = type->has_length;
1284                       array->reserved2 = 0;
1285                       array->length = type->length;
1286                       
1287                       pos = *offset2 + 4;
1288                       *offset2 += 8;
1289                       
1290                       g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, 
1291                                                module, modules, strings, types, 
1292                                                data, &pos, offset2);
1293                     }
1294                     break;
1295                     
1296                   case GI_TYPE_TAG_INTERFACE:
1297                     {
1298                       InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&data[*offset2];
1299                       *offset2 += 4;
1300
1301                       iface->pointer = type->is_pointer;
1302                       iface->reserved = 0;
1303                       iface->tag = type->tag;
1304                       iface->reserved2 = 0;
1305                       iface->interface = find_entry (module, modules, type->interface);
1306
1307                     }
1308                     break;
1309                     
1310                   case GI_TYPE_TAG_GLIST:
1311                   case GI_TYPE_TAG_GSLIST:
1312                     {
1313                       ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2];
1314                       guint32 pos;
1315                       
1316                       param->pointer = 1;
1317                       param->reserved = 0;
1318                       param->tag = type->tag;
1319                       param->reserved2 = 0;
1320                       param->n_types = 1;
1321                       
1322                       pos = *offset2 + 4;
1323                       *offset2 += 8;
1324                       
1325                       g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, 
1326                                                module, modules, strings, types,
1327                                                data, &pos, offset2);
1328                     }
1329                     break;
1330                     
1331                   case GI_TYPE_TAG_GHASH:
1332                     {
1333                       ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2];
1334                       guint32 pos;
1335                       
1336                       param->pointer = 1;
1337                       param->reserved = 0;
1338                       param->tag = type->tag;
1339                       param->reserved2 = 0;
1340                       param->n_types = 2;
1341                       
1342                       pos = *offset2 + 4;
1343                       *offset2 += 12;
1344                       
1345                       g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, 
1346                                                module, modules, strings, types, 
1347                                                data, &pos, offset2);
1348                       g_ir_node_build_typelib ((GIrNode *)type->parameter_type2, 
1349                                                module, modules, strings, types, 
1350                                                data, &pos, offset2);
1351                     }
1352                     break;
1353                     
1354                   case GI_TYPE_TAG_ERROR:
1355                     {
1356                       ErrorTypeBlob *blob = (ErrorTypeBlob *)&data[*offset2];
1357                       gint i;
1358                       
1359                       blob->pointer = 1;
1360                       blob->reserved = 0;
1361                       blob->tag = type->tag;
1362                       blob->reserved2 = 0;
1363                       if (type->errors) 
1364                         blob->n_domains = g_strv_length (type->errors);
1365                       else
1366                         blob->n_domains = 0;
1367                       
1368                       *offset2 = ALIGN_VALUE (*offset2 + 4 + 2 * blob->n_domains, 4);
1369                       for (i = 0; i < blob->n_domains; i++)
1370                         blob->domains[i] = find_entry (module, modules, type->errors[i]);
1371                     }
1372                     break;
1373                     
1374                   default:
1375                     g_error ("Unknown type tag %d\n", type->tag);
1376                     break;
1377                   }
1378               }
1379           }
1380       }
1381       break;
1382
1383     case G_IR_NODE_FIELD:
1384       {
1385         GIrNodeField *field = (GIrNodeField *)node;
1386         FieldBlob *blob;
1387
1388         blob = (FieldBlob *)&data[*offset];
1389         *offset += 8;
1390
1391         blob->name = write_string (node->name, strings, data, offset2);
1392         blob->readable = field->readable;
1393         blob->writable = field->writable;
1394         blob->reserved = 0;
1395         blob->bits = 0;
1396         blob->struct_offset = field->offset;
1397
1398         g_ir_node_build_typelib ((GIrNode *)field->type, 
1399                                  module, modules, strings, types,
1400                                  data, offset, offset2);
1401       }
1402       break;
1403
1404     case G_IR_NODE_PROPERTY:
1405       {
1406         GIrNodeProperty *prop = (GIrNodeProperty *)node;
1407         PropertyBlob *blob = (PropertyBlob *)&data[*offset];
1408         *offset += 8;
1409
1410         blob->name = write_string (node->name, strings, data, offset2);
1411         blob->deprecated = prop->deprecated;
1412         blob->readable = prop->readable;
1413         blob->writable = prop->writable;
1414         blob->construct = prop->construct;
1415         blob->construct_only = prop->construct_only;
1416         blob->reserved = 0;
1417
1418         g_ir_node_build_typelib ((GIrNode *)prop->type, 
1419                                  module, modules, strings, types,
1420                                  data, offset, offset2);
1421       }
1422       break;
1423
1424     case G_IR_NODE_FUNCTION:
1425       {
1426         FunctionBlob *blob = (FunctionBlob *)&data[*offset];
1427         SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1428         GIrNodeFunction *function = (GIrNodeFunction *)node;
1429         guint32 signature;
1430         gint n;
1431
1432         signature = *offset2;
1433         n = g_list_length (function->parameters);
1434
1435         *offset += 16;
1436         *offset2 += 8 + n * 12;
1437
1438         blob->blob_type = BLOB_TYPE_FUNCTION;
1439         blob->deprecated = function->deprecated;
1440         blob->setter = function->is_setter;
1441         blob->getter = function->is_getter;
1442         blob->constructor = function->is_constructor;
1443         blob->wraps_vfunc = function->wraps_vfunc;
1444         blob->reserved = 0;
1445         blob->index = 0;
1446         blob->name = write_string (node->name, strings, data, offset2);
1447         blob->symbol = write_string (function->symbol, strings, data, offset2);
1448         blob->signature = signature;
1449         
1450         g_ir_node_build_typelib ((GIrNode *)function->result->type, 
1451                                  module, modules, strings, types,
1452                                  data, &signature, offset2);
1453
1454         blob2->may_return_null = function->result->null_ok;
1455         blob2->caller_owns_return_value = function->result->transfer;
1456         blob2->caller_owns_return_container = function->result->shallow_transfer;
1457         blob2->reserved = 0;
1458         blob2->n_arguments = n;
1459
1460         signature += 4;
1461         
1462         for (l = function->parameters; l; l = l->next)
1463           {
1464             GIrNode *param = (GIrNode *)l->data;
1465
1466             g_ir_node_build_typelib (param, 
1467                                      module, modules, strings, types,
1468                                      data, &signature, offset2);
1469           }
1470       }
1471       break;
1472
1473     case G_IR_NODE_CALLBACK:
1474       {
1475         CallbackBlob *blob = (CallbackBlob *)&data[*offset];
1476         SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1477         GIrNodeFunction *function = (GIrNodeFunction *)node;
1478         guint32 signature;
1479         gint n;
1480
1481         signature = *offset2;
1482         n = g_list_length (function->parameters);
1483
1484         *offset += 12;
1485         *offset2 += 8 + n * 12;
1486
1487         blob->blob_type = BLOB_TYPE_CALLBACK;
1488         blob->deprecated = function->deprecated;
1489         blob->reserved = 0;
1490         blob->name = write_string (node->name, strings, data, offset2);
1491         blob->signature = signature;
1492         
1493         g_ir_node_build_typelib ((GIrNode *)function->result->type, 
1494                                  module, modules, strings, types,
1495                                  data, &signature, offset2);
1496
1497         blob2->may_return_null = function->result->null_ok;
1498         blob2->caller_owns_return_value = function->result->transfer;
1499         blob2->caller_owns_return_container = function->result->shallow_transfer;
1500         blob2->reserved = 0;
1501         blob2->n_arguments = n;
1502
1503         signature += 4;
1504         
1505         for (l = function->parameters; l; l = l->next)
1506           {
1507             GIrNode *param = (GIrNode *)l->data;
1508
1509             g_ir_node_build_typelib (param, 
1510                                      module, modules, strings, types,
1511                                      data, &signature, offset2);
1512           }
1513       }
1514       break;
1515
1516     case G_IR_NODE_SIGNAL:
1517       {
1518         SignalBlob *blob = (SignalBlob *)&data[*offset];
1519         SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1520         GIrNodeSignal *signal = (GIrNodeSignal *)node;
1521         guint32 signature;
1522         gint n;
1523
1524         signature = *offset2;
1525         n = g_list_length (signal->parameters);
1526
1527         *offset += 12;
1528         *offset2 += 8 + n * 12;
1529
1530         blob->deprecated = signal->deprecated;
1531         blob->run_first = signal->run_first;
1532         blob->run_last = signal->run_last;
1533         blob->run_cleanup = signal->run_cleanup;
1534         blob->no_recurse = signal->no_recurse;
1535         blob->detailed = signal->detailed;
1536         blob->action = signal->action;
1537         blob->no_hooks = signal->no_hooks;
1538         blob->has_class_closure = 0; /* FIXME */
1539         blob->true_stops_emit = 0; /* FIXME */
1540         blob->reserved = 0;
1541         blob->class_closure = 0; /* FIXME */
1542         blob->name = write_string (node->name, strings, data, offset2);
1543         blob->signature = signature;
1544         
1545         g_ir_node_build_typelib ((GIrNode *)signal->result->type, 
1546                                  module, modules, strings, types,
1547                                  data, &signature, offset2);
1548
1549         blob2->may_return_null = signal->result->null_ok;
1550         blob2->caller_owns_return_value = signal->result->transfer;
1551         blob2->caller_owns_return_container = signal->result->shallow_transfer;
1552         blob2->reserved = 0;
1553         blob2->n_arguments = n;
1554
1555         signature += 4;
1556         
1557         for (l = signal->parameters; l; l = l->next)
1558           {
1559             GIrNode *param = (GIrNode *)l->data;
1560
1561             g_ir_node_build_typelib (param, module, modules, strings, types,
1562                                      data, &signature, offset2);
1563           }
1564       }
1565       break;
1566
1567     case G_IR_NODE_VFUNC:
1568       {
1569         VFuncBlob *blob = (VFuncBlob *)&data[*offset];
1570         SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1571         GIrNodeVFunc *vfunc = (GIrNodeVFunc *)node;
1572         guint32 signature;
1573         gint n;
1574
1575         signature = *offset2;
1576         n = g_list_length (vfunc->parameters);
1577
1578         *offset += 16;
1579         *offset2 += 8 + n * 12;
1580
1581         blob->name = write_string (node->name, strings, data, offset2);
1582         blob->must_chain_up = 0; /* FIXME */
1583         blob->must_be_implemented = 0; /* FIXME */
1584         blob->must_not_be_implemented = 0; /* FIXME */
1585         blob->class_closure = 0; /* FIXME */
1586         blob->reserved = 0;
1587
1588         blob->struct_offset = vfunc->offset;
1589         blob->reserved2 = 0;
1590         blob->signature = signature;
1591         
1592         g_ir_node_build_typelib ((GIrNode *)vfunc->result->type, 
1593                                  module, modules, strings, types,
1594                                  data, &signature, offset2);
1595
1596         blob2->may_return_null = vfunc->result->null_ok;
1597         blob2->caller_owns_return_value = vfunc->result->transfer;
1598         blob2->caller_owns_return_container = vfunc->result->shallow_transfer;
1599         blob2->reserved = 0;
1600         blob2->n_arguments = n;
1601
1602         signature += 4;
1603         
1604         for (l = vfunc->parameters; l; l = l->next)
1605           {
1606             GIrNode *param = (GIrNode *)l->data;
1607
1608             g_ir_node_build_typelib (param, module, modules, strings, 
1609                                      types, data, &signature, offset2);
1610           }
1611       }
1612       break;
1613
1614     case G_IR_NODE_PARAM:
1615       {
1616         ArgBlob *blob = (ArgBlob *)&data[*offset];
1617         GIrNodeParam *param = (GIrNodeParam *)node;
1618         
1619         *offset += 8;
1620
1621         blob->name = write_string (node->name, strings, data, offset2);
1622         blob->in = param->in;
1623         blob->out = param->out;
1624         blob->dipper = param->dipper;
1625         blob->null_ok = param->null_ok;
1626         blob->optional = param->optional;
1627         blob->transfer_ownership = param->transfer;
1628         blob->transfer_container_ownership = param->shallow_transfer;
1629         blob->return_value = param->retval;
1630         blob->reserved = 0;
1631
1632         g_ir_node_build_typelib ((GIrNode *)param->type, module, modules, 
1633                                  strings, types, data, offset, offset2);
1634       }
1635       break;
1636
1637     case G_IR_NODE_STRUCT:
1638       {
1639         StructBlob *blob = (StructBlob *)&data[*offset];
1640         GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
1641         
1642         blob->blob_type = BLOB_TYPE_STRUCT;
1643         blob->deprecated = struct_->deprecated;
1644         blob->unregistered = TRUE;
1645         blob->reserved = 0;
1646         blob->name = write_string (node->name, strings, data, offset2);
1647         blob->gtype_name = 0;
1648         blob->gtype_init = 0;
1649
1650         blob->n_fields = 0;
1651         blob->n_methods = 0;
1652
1653         *offset += 20; 
1654         for (l = struct_->members; l; l = l->next)
1655           {
1656             GIrNode *member = (GIrNode *)l->data;
1657
1658             if (member->type == G_IR_NODE_FIELD)
1659               {
1660                 blob->n_fields++;
1661                 g_ir_node_build_typelib (member, module, modules, strings, 
1662                                          types, data, offset, offset2);
1663               }
1664           }
1665
1666         for (l = struct_->members; l; l = l->next)
1667           {
1668             GIrNode *member = (GIrNode *)l->data;
1669             
1670             if (member->type == G_IR_NODE_FUNCTION)
1671               {
1672                 blob->n_methods++;
1673                 g_ir_node_build_typelib (member, module, modules, strings, 
1674                                          types, data, offset, offset2);
1675               }
1676           }
1677       }
1678       break;
1679
1680     case G_IR_NODE_BOXED:
1681       {
1682         StructBlob *blob = (StructBlob *)&data[*offset];
1683         GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
1684
1685         blob->blob_type = BLOB_TYPE_BOXED;
1686         blob->deprecated = boxed->deprecated;
1687         blob->unregistered = FALSE;
1688         blob->reserved = 0;
1689         blob->name = write_string (node->name, strings, data, offset2);
1690         blob->gtype_name = write_string (boxed->gtype_name, strings, data, offset2);
1691         blob->gtype_init = write_string (boxed->gtype_init, strings, data, offset2);
1692
1693         blob->n_fields = 0;
1694         blob->n_methods = 0;
1695
1696         *offset += 20; 
1697         for (l = boxed->members; l; l = l->next)
1698           {
1699             GIrNode *member = (GIrNode *)l->data;
1700
1701             if (member->type == G_IR_NODE_FIELD)
1702               {
1703                 blob->n_fields++;
1704                 g_ir_node_build_typelib (member, module, modules, strings, 
1705                                          types, data, offset, offset2);
1706               }
1707           }
1708
1709         for (l = boxed->members; l; l = l->next)
1710           {
1711             GIrNode *member = (GIrNode *)l->data;
1712
1713             if (member->type == G_IR_NODE_FUNCTION)
1714               {
1715                 blob->n_methods++;
1716                 g_ir_node_build_typelib (member, module, modules, strings, 
1717                                          types, data, offset, offset2);
1718               }
1719           }
1720       }
1721       break;
1722
1723     case G_IR_NODE_UNION:
1724       {
1725         UnionBlob *blob = (UnionBlob *)&data[*offset];
1726         GIrNodeUnion *union_ = (GIrNodeUnion *)node;
1727
1728         blob->blob_type = BLOB_TYPE_UNION;
1729         blob->deprecated = union_->deprecated;
1730         blob->reserved = 0;
1731         blob->name = write_string (node->name, strings, data, offset2);
1732         if (union_->gtype_name)
1733           {
1734             blob->unregistered = FALSE;
1735             blob->gtype_name = write_string (union_->gtype_name, strings, data, offset2);
1736             blob->gtype_init = write_string (union_->gtype_init, strings, data, offset2);
1737           }
1738         else
1739           {
1740             blob->unregistered = TRUE;
1741             blob->gtype_name = 0;
1742             blob->gtype_init = 0;
1743           }
1744
1745         blob->n_fields = 0;
1746         blob->n_functions = 0;
1747
1748         blob->discriminator_offset = union_->discriminator_offset;
1749
1750         if (union_->discriminator_type)
1751           {
1752             *offset += 24;
1753             blob->discriminated = TRUE;
1754             g_ir_node_build_typelib ((GIrNode *)union_->discriminator_type, 
1755                                      module, modules, strings, types,
1756                                      data, offset, offset2);
1757           }
1758         else 
1759           {
1760             *offset += 28;
1761             blob->discriminated = FALSE;
1762             blob->discriminator_type.offset = 0;
1763           }
1764         
1765         
1766         for (l = union_->members; l; l = l->next)
1767           {
1768             GIrNode *member = (GIrNode *)l->data;
1769
1770             if (member->type == G_IR_NODE_FIELD)
1771               {
1772                 blob->n_fields++;
1773                 g_ir_node_build_typelib (member, module, modules, strings, 
1774                                          types, data, offset, offset2);
1775               }
1776           }
1777
1778         for (l = union_->members; l; l = l->next)
1779           {
1780             GIrNode *member = (GIrNode *)l->data;
1781
1782             if (member->type == G_IR_NODE_FUNCTION)
1783               {
1784                 blob->n_functions++;
1785                 g_ir_node_build_typelib (member, module, modules, strings, 
1786                                          types, data, offset, offset2);
1787               }
1788           }
1789
1790         if (union_->discriminator_type)
1791           {
1792             for (l = union_->discriminators; l; l = l->next)
1793               {
1794                 GIrNode *member = (GIrNode *)l->data;
1795                 
1796                 g_ir_node_build_typelib (member, module, modules, strings, 
1797                                          types, data, offset, offset2);
1798               }
1799           }
1800       }
1801       break;
1802
1803     case G_IR_NODE_ENUM:
1804     case G_IR_NODE_FLAGS:
1805       {
1806         EnumBlob *blob = (EnumBlob *)&data[*offset];
1807         GIrNodeEnum *enum_ = (GIrNodeEnum *)node;
1808
1809         *offset += 20; 
1810         
1811         if (node->type == G_IR_NODE_ENUM)
1812           blob->blob_type = BLOB_TYPE_ENUM;
1813         else
1814           blob->blob_type = BLOB_TYPE_FLAGS;
1815           
1816         blob->deprecated = enum_->deprecated;
1817         blob->reserved = 0;
1818         blob->name = write_string (node->name, strings, data, offset2);
1819         if (enum_->gtype_name)
1820           {
1821             blob->unregistered = FALSE;
1822             blob->gtype_name = write_string (enum_->gtype_name, strings, data, offset2);
1823             blob->gtype_init = write_string (enum_->gtype_init, strings, data, offset2);
1824           }
1825         else
1826           {
1827             blob->unregistered = TRUE;
1828             blob->gtype_name = 0;
1829             blob->gtype_init = 0;
1830           }
1831
1832         blob->n_values = 0;
1833         blob->reserved2 = 0;
1834
1835         for (l = enum_->values; l; l = l->next)
1836           {
1837             GIrNode *value = (GIrNode *)l->data;
1838
1839             blob->n_values++;
1840             g_ir_node_build_typelib (value, module, modules, strings, types,
1841                                      data, offset, offset2);
1842           }
1843       }
1844       break;
1845       
1846     case G_IR_NODE_OBJECT:
1847       {
1848         ObjectBlob *blob = (ObjectBlob *)&data[*offset];
1849         GIrNodeInterface *object = (GIrNodeInterface *)node;
1850
1851         blob->blob_type = BLOB_TYPE_OBJECT;
1852         blob->deprecated = object->deprecated;
1853         blob->reserved = 0;
1854         blob->name = write_string (node->name, strings, data, offset2);
1855         blob->gtype_name = write_string (object->gtype_name, strings, data, offset2);
1856         blob->gtype_init = write_string (object->gtype_init, strings, data, offset2);
1857         if (object->parent)
1858           blob->parent = find_entry (module, modules, object->parent);
1859         else
1860           blob->parent = 0;
1861
1862         blob->n_interfaces = 0;
1863         blob->n_fields = 0;
1864         blob->n_properties = 0;
1865         blob->n_methods = 0;
1866         blob->n_signals = 0;
1867         blob->n_vfuncs = 0;
1868         blob->n_constants = 0;
1869         
1870         *offset += 32;
1871         for (l = object->interfaces; l; l = l->next)
1872           {
1873             blob->n_interfaces++;
1874             *(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data);
1875             *offset += 2;
1876           }
1877         
1878         *offset = ALIGN_VALUE (*offset, 4);
1879         for (l = object->members; l; l = l->next)
1880           {
1881             GIrNode *member = (GIrNode *)l->data;
1882
1883             if (member->type == G_IR_NODE_FIELD)
1884               {
1885                 blob->n_fields++;
1886                 g_ir_node_build_typelib (member, module, modules, strings, 
1887                                          types, data, offset, offset2);
1888               }
1889           }
1890
1891         *offset = ALIGN_VALUE (*offset, 4);
1892         for (l = object->members; l; l = l->next)
1893           {
1894             GIrNode *member = (GIrNode *)l->data;
1895
1896             if (member->type == G_IR_NODE_PROPERTY)
1897               {
1898                 blob->n_properties++;
1899                 g_ir_node_build_typelib (member, module, modules, strings, 
1900                                          types, data, offset, offset2);
1901               }
1902           }
1903
1904         *offset = ALIGN_VALUE (*offset, 4);
1905         for (l = object->members; l; l = l->next)
1906           {
1907             GIrNode *member = (GIrNode *)l->data;
1908
1909             if (member->type == G_IR_NODE_FUNCTION)
1910               {
1911                 blob->n_methods++;
1912                 g_ir_node_build_typelib (member, module, modules, strings, 
1913                                          types, data, offset, offset2);
1914               }
1915           }
1916
1917         *offset = ALIGN_VALUE (*offset, 4);
1918         for (l = object->members; l; l = l->next)
1919           {
1920             GIrNode *member = (GIrNode *)l->data;
1921
1922             if (member->type == G_IR_NODE_SIGNAL)
1923               {
1924                 blob->n_signals++;
1925                 g_ir_node_build_typelib (member, module, modules, strings, 
1926                                          types, data, offset, offset2);
1927               }
1928           }
1929
1930         *offset = ALIGN_VALUE (*offset, 4);
1931         for (l = object->members; l; l = l->next)
1932           {
1933             GIrNode *member = (GIrNode *)l->data;
1934
1935             if (member->type == G_IR_NODE_VFUNC)
1936               {
1937                 blob->n_vfuncs++;
1938                 g_ir_node_build_typelib (member, module, modules, strings, 
1939                                          types, data, offset, offset2);
1940               }
1941           }
1942
1943         *offset = ALIGN_VALUE (*offset, 4);
1944         for (l = object->members; l; l = l->next)
1945           {
1946             GIrNode *member = (GIrNode *)l->data;
1947
1948             if (member->type == G_IR_NODE_CONSTANT)
1949               {
1950                 blob->n_constants++;
1951                 g_ir_node_build_typelib (member, module, modules, strings, 
1952                                          types, data, offset, offset2);
1953               }
1954           }
1955       }
1956       break;
1957
1958     case G_IR_NODE_INTERFACE:
1959       {
1960         InterfaceBlob *blob = (InterfaceBlob *)&data[*offset];
1961         GIrNodeInterface *iface = (GIrNodeInterface *)node;
1962
1963         blob->blob_type = BLOB_TYPE_INTERFACE;
1964         blob->deprecated = iface->deprecated;
1965         blob->reserved = 0;
1966         blob->name = write_string (node->name, strings, data, offset2);
1967         blob->gtype_name = write_string (iface->gtype_name, strings, data, offset2);
1968         blob->gtype_init = write_string (iface->gtype_init, strings, data, offset2);
1969         blob->n_prerequisites = 0;
1970         blob->n_properties = 0;
1971         blob->n_methods = 0;
1972         blob->n_signals = 0;
1973         blob->n_vfuncs = 0;
1974         blob->n_constants = 0;
1975         
1976         *offset += 28;
1977         for (l = iface->prerequisites; l; l = l->next)
1978           {
1979             blob->n_prerequisites++;
1980             *(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data);
1981             *offset += 2;
1982           }
1983         
1984         *offset = ALIGN_VALUE (*offset, 4);
1985         for (l = iface->members; l; l = l->next)
1986           {
1987             GIrNode *member = (GIrNode *)l->data;
1988
1989             if (member->type == G_IR_NODE_PROPERTY)
1990               {
1991                 blob->n_properties++;
1992                 g_ir_node_build_typelib (member, module, modules, strings, 
1993                                          types, data, offset, offset2);
1994               }
1995           }
1996
1997         *offset = ALIGN_VALUE (*offset, 4);
1998         for (l = iface->members; l; l = l->next)
1999           {
2000             GIrNode *member = (GIrNode *)l->data;
2001
2002             if (member->type == G_IR_NODE_FUNCTION)
2003               {
2004                 blob->n_methods++;
2005                 g_ir_node_build_typelib (member, module, modules, strings, 
2006                                          types, data, offset, offset2);
2007               }
2008           }
2009
2010         *offset = ALIGN_VALUE (*offset, 4);
2011         for (l = iface->members; l; l = l->next)
2012           {
2013             GIrNode *member = (GIrNode *)l->data;
2014
2015             if (member->type == G_IR_NODE_SIGNAL)
2016               {
2017                 blob->n_signals++;
2018                 g_ir_node_build_typelib (member, module, modules, strings, 
2019                                          types, data, offset, offset2);
2020               }
2021           }
2022
2023         *offset = ALIGN_VALUE (*offset, 4);
2024         for (l = iface->members; l; l = l->next)
2025           {
2026             GIrNode *member = (GIrNode *)l->data;
2027
2028             if (member->type == G_IR_NODE_VFUNC)
2029               {
2030                 blob->n_vfuncs++;
2031                 g_ir_node_build_typelib (member, module, modules, strings, 
2032                                          types, data, offset, offset2);
2033               }
2034           }
2035
2036         *offset = ALIGN_VALUE (*offset, 4);
2037         for (l = iface->members; l; l = l->next)
2038           {
2039             GIrNode *member = (GIrNode *)l->data;
2040
2041             if (member->type == G_IR_NODE_CONSTANT)
2042               {
2043                 blob->n_constants++;
2044                 g_ir_node_build_typelib (member, module, modules, strings, 
2045                                          types, data, offset, offset2);
2046               }
2047           }
2048       }
2049       break;
2050
2051
2052     case G_IR_NODE_VALUE:
2053       {
2054         GIrNodeValue *value = (GIrNodeValue *)node;
2055         ValueBlob *blob = (ValueBlob *)&data[*offset];
2056         *offset += 12;
2057
2058         blob->deprecated = value->deprecated;
2059         blob->reserved = 0;
2060         blob->name = write_string (node->name, strings, data, offset2);
2061         blob->value = value->value;
2062       }
2063       break;
2064
2065     case G_IR_NODE_ERROR_DOMAIN:
2066       {
2067         GIrNodeErrorDomain *domain = (GIrNodeErrorDomain *)node;
2068         ErrorDomainBlob *blob = (ErrorDomainBlob *)&data[*offset];
2069         *offset += 16;
2070
2071         blob->blob_type = BLOB_TYPE_ERROR_DOMAIN;
2072         blob->deprecated = domain->deprecated;
2073         blob->reserved = 0;
2074         blob->name = write_string (node->name, strings, data, offset2);
2075         blob->get_quark = write_string (domain->getquark, strings, data, offset2);
2076         blob->error_codes = find_entry (module, modules, domain->codes);
2077         blob->reserved2 = 0;
2078       }
2079       break;
2080
2081     case G_IR_NODE_CONSTANT:
2082       {
2083         GIrNodeConstant *constant = (GIrNodeConstant *)node;
2084         ConstantBlob *blob = (ConstantBlob *)&data[*offset];
2085         guint32 pos;
2086
2087         pos = *offset + 8;
2088         *offset += 20;
2089
2090         blob->blob_type = BLOB_TYPE_CONSTANT;
2091         blob->deprecated = constant->deprecated;
2092         blob->reserved = 0;
2093         blob->name = write_string (node->name, strings, data, offset2);
2094
2095         blob->offset = *offset2;
2096         switch (constant->type->tag)
2097           {
2098           case GI_TYPE_TAG_BOOLEAN:
2099             blob->size = 4;
2100             *(gboolean*)&data[blob->offset] = parse_boolean_value (constant->value);
2101             break;
2102             case GI_TYPE_TAG_INT8:
2103             blob->size = 1;
2104               *(gint8*)&data[blob->offset] = (gint8) parse_int_value (constant->value);
2105             break;
2106           case GI_TYPE_TAG_UINT8:
2107             blob->size = 1;
2108             *(guint8*)&data[blob->offset] = (guint8) parse_uint_value (constant->value);
2109             break;
2110           case GI_TYPE_TAG_INT16:
2111             blob->size = 2;
2112             *(gint16*)&data[blob->offset] = (gint16) parse_int_value (constant->value);
2113             break;
2114           case GI_TYPE_TAG_UINT16:
2115             blob->size = 2;
2116             *(guint16*)&data[blob->offset] = (guint16) parse_uint_value (constant->value);
2117             break;
2118           case GI_TYPE_TAG_INT32:
2119             blob->size = 4;
2120             *(gint32*)&data[blob->offset] = (gint32) parse_int_value (constant->value);
2121             break;
2122           case GI_TYPE_TAG_UINT32:
2123             blob->size = 4;
2124             *(guint32*)&data[blob->offset] = (guint32) parse_uint_value (constant->value);
2125             break;
2126           case GI_TYPE_TAG_INT64:
2127             blob->size = 8;
2128             *(gint64*)&data[blob->offset] = (gint64) parse_int_value (constant->value);
2129             break;
2130           case GI_TYPE_TAG_UINT64:
2131             blob->size = 8;
2132             *(guint64*)&data[blob->offset] = (guint64) parse_uint_value (constant->value);
2133             break;
2134           case GI_TYPE_TAG_INT:
2135             blob->size = sizeof (gint);
2136             *(gint*)&data[blob->offset] = (gint) parse_int_value (constant->value);
2137             break;
2138           case GI_TYPE_TAG_UINT:
2139             blob->size = sizeof (guint);
2140             *(gint*)&data[blob->offset] = (guint) parse_uint_value (constant->value);
2141             break;
2142           case GI_TYPE_TAG_SSIZE: /* FIXME */
2143           case GI_TYPE_TAG_LONG:
2144             blob->size = sizeof (glong);
2145             *(glong*)&data[blob->offset] = (glong) parse_int_value (constant->value);
2146             break;
2147           case GI_TYPE_TAG_SIZE: /* FIXME */
2148           case GI_TYPE_TAG_ULONG:
2149             blob->size = sizeof (gulong);
2150             *(gulong*)&data[blob->offset] = (gulong) parse_uint_value (constant->value);
2151             break;
2152           case GI_TYPE_TAG_FLOAT:
2153             blob->size = sizeof (gfloat);
2154             *(gfloat*)&data[blob->offset] = (gfloat) parse_float_value (constant->value);
2155             break;
2156           case GI_TYPE_TAG_DOUBLE:
2157             blob->size = sizeof (gdouble);
2158             *(gdouble*)&data[blob->offset] = (gdouble) parse_float_value (constant->value);
2159             break;
2160           case GI_TYPE_TAG_UTF8:
2161           case GI_TYPE_TAG_FILENAME:
2162             blob->size = strlen (constant->value) + 1;
2163             memcpy (&data[blob->offset], constant->value, blob->size);
2164             break;
2165           }
2166         *offset2 += ALIGN_VALUE (blob->size, 4);
2167         
2168         g_ir_node_build_typelib ((GIrNode *)constant->type, module, modules, 
2169                                  strings, types, data, &pos, offset2);
2170       }
2171       break;
2172     default:
2173       g_assert_not_reached ();
2174     }
2175   
2176   g_debug ("node %p type '%s', offset %d -> %d, offset2 %d -> %d",
2177            node, g_ir_node_type_to_string (node->type),
2178            old_offset, *offset, old_offset2, *offset2);
2179
2180   if (*offset2 - old_offset2 + *offset - old_offset > g_ir_node_get_full_size (node))
2181     g_error ("exceeding space reservation !!");
2182 }
2183
2184 /* if str is already in the pool, return previous location, otherwise write str
2185  * to the typelib at offset, put it in the pool and update offset. If the 
2186  * typelib is not large enough to hold the string, reallocate it.
2187  */
2188 guint32 
2189 write_string (const gchar *str,
2190               GHashTable  *strings, 
2191               guchar      *data,
2192               guint32     *offset)
2193 {
2194   gpointer value;
2195   guint32 start;
2196
2197   string_count += 1;
2198   string_size += strlen (str);
2199
2200   value = g_hash_table_lookup (strings, str);
2201   
2202   if (value)
2203     return GPOINTER_TO_INT (value);
2204
2205   unique_string_count += 1;
2206   unique_string_size += strlen (str);
2207
2208   g_hash_table_insert (strings, (gpointer)str, GINT_TO_POINTER (*offset));
2209
2210   start = *offset;
2211   *offset = ALIGN_VALUE (start + strlen (str) + 1, 4);
2212
2213   strcpy ((gchar*)&data[start], str);
2214   
2215   return start;
2216 }
2217