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