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