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