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