Add support for foreign structs
[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->foreign = struct_->foreign;
1889         blob->deprecated = struct_->deprecated;
1890         blob->is_gtype_struct = struct_->is_gtype_struct;
1891         blob->reserved = 0;
1892         blob->name = write_string (node->name, strings, data, offset2);
1893         blob->alignment = struct_->alignment;
1894         blob->size = struct_->size;
1895
1896         if (struct_->gtype_name)
1897           {
1898             blob->unregistered = FALSE;
1899             blob->gtype_name = write_string (struct_->gtype_name, strings, data, offset2);
1900             blob->gtype_init = write_string (struct_->gtype_init, strings, data, offset2);
1901           }
1902         else
1903           {
1904             blob->unregistered = TRUE;
1905             blob->gtype_name = 0;
1906             blob->gtype_init = 0;
1907           }
1908
1909         blob->n_fields = 0;
1910         blob->n_methods = 0;
1911
1912         *offset += sizeof (StructBlob);
1913
1914         members = g_list_copy (struct_->members);
1915
1916         g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields,
1917                                  node, build, offset, offset2);
1918
1919         g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods,
1920                                  node, build, offset, offset2);
1921
1922         g_ir_node_check_unhandled_members (&members, node->type);
1923
1924         g_assert (members == NULL);
1925       }
1926       break;
1927
1928     case G_IR_NODE_BOXED:
1929       {
1930         StructBlob *blob = (StructBlob *)&data[*offset];
1931         GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
1932         GList *members;
1933
1934         blob->blob_type = BLOB_TYPE_BOXED;
1935         blob->deprecated = boxed->deprecated;
1936         blob->unregistered = FALSE;
1937         blob->reserved = 0;
1938         blob->name = write_string (node->name, strings, data, offset2);
1939         blob->gtype_name = write_string (boxed->gtype_name, strings, data, offset2);
1940         blob->gtype_init = write_string (boxed->gtype_init, strings, data, offset2);
1941         blob->alignment = boxed->alignment;
1942         blob->size = boxed->size;
1943
1944         blob->n_fields = 0;
1945         blob->n_methods = 0;
1946
1947         *offset += sizeof (StructBlob);
1948
1949         members = g_list_copy (boxed->members);
1950
1951         g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields,
1952                                  node, build, offset, offset2);
1953
1954         g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods,
1955                                  node, build, offset, offset2);
1956
1957         g_ir_node_check_unhandled_members (&members, node->type);
1958
1959         g_assert (members == NULL);
1960       }
1961       break;
1962
1963     case G_IR_NODE_UNION:
1964       {
1965         UnionBlob *blob = (UnionBlob *)&data[*offset];
1966         GIrNodeUnion *union_ = (GIrNodeUnion *)node;
1967         GList *members;
1968
1969         blob->blob_type = BLOB_TYPE_UNION;
1970         blob->deprecated = union_->deprecated;
1971         blob->reserved = 0;
1972         blob->name = write_string (node->name, strings, data, offset2);
1973         blob->alignment = union_->alignment;
1974         blob->size = union_->size;
1975         if (union_->gtype_name)
1976           {
1977             blob->unregistered = FALSE;
1978             blob->gtype_name = write_string (union_->gtype_name, strings, data, offset2);
1979             blob->gtype_init = write_string (union_->gtype_init, strings, data, offset2);
1980           }
1981         else
1982           {
1983             blob->unregistered = TRUE;
1984             blob->gtype_name = 0;
1985             blob->gtype_init = 0;
1986           }
1987
1988         blob->n_fields = 0;
1989         blob->n_functions = 0;
1990
1991         blob->discriminator_offset = union_->discriminator_offset;
1992
1993         /* We don't support Union discriminators right now. */
1994         /*
1995         if (union_->discriminator_type)
1996           {
1997             *offset += 28;
1998             blob->discriminated = TRUE;
1999             g_ir_node_build_typelib ((GIrNode *)union_->discriminator_type,
2000                                      build, offset, offset2);
2001           }
2002         else
2003           {
2004         */
2005         *offset += sizeof (UnionBlob);
2006         blob->discriminated = FALSE;
2007         blob->discriminator_type.offset = 0;
2008
2009         members = g_list_copy (union_->members);
2010
2011         g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields,
2012                                  node, build, offset, offset2);
2013
2014         g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_functions,
2015                                  node, build, offset, offset2);
2016
2017         g_ir_node_check_unhandled_members (&members, node->type);
2018
2019         g_assert (members == NULL);
2020
2021         if (union_->discriminator_type)
2022           {
2023             for (l = union_->discriminators; l; l = l->next)
2024               {
2025                 GIrNode *member = (GIrNode *)l->data;
2026
2027                 g_ir_node_build_typelib (member, node, build, offset, offset2);
2028               }
2029           }
2030       }
2031       break;
2032
2033     case G_IR_NODE_ENUM:
2034     case G_IR_NODE_FLAGS:
2035       {
2036         EnumBlob *blob = (EnumBlob *)&data[*offset];
2037         GIrNodeEnum *enum_ = (GIrNodeEnum *)node;
2038
2039         *offset += sizeof (EnumBlob);
2040
2041         if (node->type == G_IR_NODE_ENUM)
2042           blob->blob_type = BLOB_TYPE_ENUM;
2043         else
2044           blob->blob_type = BLOB_TYPE_FLAGS;
2045
2046         blob->deprecated = enum_->deprecated;
2047         blob->reserved = 0;
2048         blob->storage_type = enum_->storage_type;
2049         blob->name = write_string (node->name, strings, data, offset2);
2050         if (enum_->gtype_name)
2051           {
2052             blob->unregistered = FALSE;
2053             blob->gtype_name = write_string (enum_->gtype_name, strings, data, offset2);
2054             blob->gtype_init = write_string (enum_->gtype_init, strings, data, offset2);
2055           }
2056         else
2057           {
2058             blob->unregistered = TRUE;
2059             blob->gtype_name = 0;
2060             blob->gtype_init = 0;
2061           }
2062
2063         blob->n_values = 0;
2064         blob->reserved2 = 0;
2065
2066         for (l = enum_->values; l; l = l->next)
2067           {
2068             GIrNode *value = (GIrNode *)l->data;
2069
2070             blob->n_values++;
2071             g_ir_node_build_typelib (value, node, build, offset, offset2);
2072           }
2073       }
2074       break;
2075
2076     case G_IR_NODE_OBJECT:
2077       {
2078         ObjectBlob *blob = (ObjectBlob *)&data[*offset];
2079         GIrNodeInterface *object = (GIrNodeInterface *)node;
2080         GList *members;
2081
2082         blob->blob_type = BLOB_TYPE_OBJECT;
2083         blob->abstract = object->abstract;
2084         blob->deprecated = object->deprecated;
2085         blob->reserved = 0;
2086         blob->name = write_string (node->name, strings, data, offset2);
2087         blob->gtype_name = write_string (object->gtype_name, strings, data, offset2);
2088         blob->gtype_init = write_string (object->gtype_init, strings, data, offset2);
2089         if (object->parent)
2090           blob->parent = find_entry (module, modules, object->parent);
2091         else
2092           blob->parent = 0;
2093         if (object->glib_type_struct)
2094           blob->gtype_struct = find_entry (module, modules, object->glib_type_struct);
2095         else
2096           blob->gtype_struct = 0;
2097
2098         blob->n_interfaces = 0;
2099         blob->n_fields = 0;
2100         blob->n_properties = 0;
2101         blob->n_methods = 0;
2102         blob->n_signals = 0;
2103         blob->n_vfuncs = 0;
2104         blob->n_constants = 0;
2105
2106         *offset += sizeof(ObjectBlob);
2107         for (l = object->interfaces; l; l = l->next)
2108           {
2109             blob->n_interfaces++;
2110             *(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data);
2111             *offset += 2;
2112           }
2113
2114         members = g_list_copy (object->members);
2115
2116         *offset = ALIGN_VALUE (*offset, 4);
2117         g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields,
2118                                  node, build, offset, offset2);
2119
2120         *offset = ALIGN_VALUE (*offset, 4);
2121         g_ir_node_build_members (&members, G_IR_NODE_PROPERTY, &blob->n_properties,
2122                                  node, build, offset, offset2);
2123
2124         *offset = ALIGN_VALUE (*offset, 4);
2125         g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods,
2126                                  node, build, offset, offset2);
2127
2128         *offset = ALIGN_VALUE (*offset, 4);
2129         g_ir_node_build_members (&members, G_IR_NODE_SIGNAL, &blob->n_signals,
2130                                  node, build, offset, offset2);
2131
2132         *offset = ALIGN_VALUE (*offset, 4);
2133         g_ir_node_build_members (&members, G_IR_NODE_VFUNC, &blob->n_vfuncs,
2134                                  node, build, offset, offset2);
2135
2136         *offset = ALIGN_VALUE (*offset, 4);
2137         g_ir_node_build_members (&members, G_IR_NODE_CONSTANT, &blob->n_constants,
2138                                  node, build, offset, offset2);
2139
2140         g_ir_node_check_unhandled_members (&members, node->type);
2141
2142         g_assert (members == NULL);
2143       }
2144       break;
2145
2146     case G_IR_NODE_INTERFACE:
2147       {
2148         InterfaceBlob *blob = (InterfaceBlob *)&data[*offset];
2149         GIrNodeInterface *iface = (GIrNodeInterface *)node;
2150         GList *members;
2151
2152         blob->blob_type = BLOB_TYPE_INTERFACE;
2153         blob->deprecated = iface->deprecated;
2154         blob->reserved = 0;
2155         blob->name = write_string (node->name, strings, data, offset2);
2156         blob->gtype_name = write_string (iface->gtype_name, strings, data, offset2);
2157         blob->gtype_init = write_string (iface->gtype_init, strings, data, offset2);
2158         if (iface->glib_type_struct)
2159           blob->gtype_struct = find_entry (module, modules, iface->glib_type_struct);
2160         else
2161           blob->gtype_struct = 0;
2162         blob->n_prerequisites = 0;
2163         blob->n_properties = 0;
2164         blob->n_methods = 0;
2165         blob->n_signals = 0;
2166         blob->n_vfuncs = 0;
2167         blob->n_constants = 0;
2168
2169         *offset += sizeof (InterfaceBlob);
2170         for (l = iface->prerequisites; l; l = l->next)
2171           {
2172             blob->n_prerequisites++;
2173             *(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data);
2174             *offset += 2;
2175           }
2176
2177         members = g_list_copy (iface->members);
2178
2179         *offset = ALIGN_VALUE (*offset, 4);
2180         g_ir_node_build_members (&members, G_IR_NODE_PROPERTY, &blob->n_properties,
2181                                  node, build, offset, offset2);
2182
2183         *offset = ALIGN_VALUE (*offset, 4);
2184         g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods,
2185                                  node, build, offset, offset2);
2186
2187         *offset = ALIGN_VALUE (*offset, 4);
2188         g_ir_node_build_members (&members, G_IR_NODE_SIGNAL, &blob->n_signals,
2189                                  node, build, offset, offset2);
2190
2191         *offset = ALIGN_VALUE (*offset, 4);
2192         g_ir_node_build_members (&members, G_IR_NODE_VFUNC, &blob->n_vfuncs,
2193                                  node, build, offset, offset2);
2194
2195         *offset = ALIGN_VALUE (*offset, 4);
2196         g_ir_node_build_members (&members, G_IR_NODE_CONSTANT, &blob->n_constants,
2197                                  node, build, offset, offset2);
2198
2199         g_ir_node_check_unhandled_members (&members, node->type);
2200
2201         g_assert (members == NULL);
2202       }
2203       break;
2204
2205
2206     case G_IR_NODE_VALUE:
2207       {
2208         GIrNodeValue *value = (GIrNodeValue *)node;
2209         ValueBlob *blob = (ValueBlob *)&data[*offset];
2210         *offset += sizeof (ValueBlob);
2211
2212         blob->deprecated = value->deprecated;
2213         blob->reserved = 0;
2214         blob->name = write_string (node->name, strings, data, offset2);
2215         blob->value = value->value;
2216       }
2217       break;
2218
2219     case G_IR_NODE_ERROR_DOMAIN:
2220       {
2221         GIrNodeErrorDomain *domain = (GIrNodeErrorDomain *)node;
2222         ErrorDomainBlob *blob = (ErrorDomainBlob *)&data[*offset];
2223         *offset += sizeof (ErrorDomainBlob);
2224
2225         blob->blob_type = BLOB_TYPE_ERROR_DOMAIN;
2226         blob->deprecated = domain->deprecated;
2227         blob->reserved = 0;
2228         blob->name = write_string (node->name, strings, data, offset2);
2229         blob->get_quark = write_string (domain->getquark, strings, data, offset2);
2230         blob->error_codes = find_entry (module, modules, domain->codes);
2231         blob->reserved2 = 0;
2232       }
2233       break;
2234
2235     case G_IR_NODE_CONSTANT:
2236       {
2237         GIrNodeConstant *constant = (GIrNodeConstant *)node;
2238         ConstantBlob *blob = (ConstantBlob *)&data[*offset];
2239         guint32 pos;
2240
2241         pos = *offset + G_STRUCT_OFFSET (ConstantBlob, type);
2242         *offset += sizeof (ConstantBlob);
2243
2244         blob->blob_type = BLOB_TYPE_CONSTANT;
2245         blob->deprecated = constant->deprecated;
2246         blob->reserved = 0;
2247         blob->name = write_string (node->name, strings, data, offset2);
2248
2249         blob->offset = *offset2;
2250         switch (constant->type->tag)
2251           {
2252           case GI_TYPE_TAG_BOOLEAN:
2253             blob->size = 4;
2254             *(gboolean*)&data[blob->offset] = parse_boolean_value (constant->value);
2255             break;
2256             case GI_TYPE_TAG_INT8:
2257             blob->size = 1;
2258               *(gint8*)&data[blob->offset] = (gint8) parse_int_value (constant->value);
2259             break;
2260           case GI_TYPE_TAG_UINT8:
2261             blob->size = 1;
2262             *(guint8*)&data[blob->offset] = (guint8) parse_uint_value (constant->value);
2263             break;
2264           case GI_TYPE_TAG_INT16:
2265             blob->size = 2;
2266             *(gint16*)&data[blob->offset] = (gint16) parse_int_value (constant->value);
2267             break;
2268           case GI_TYPE_TAG_UINT16:
2269             blob->size = 2;
2270             *(guint16*)&data[blob->offset] = (guint16) parse_uint_value (constant->value);
2271             break;
2272           case GI_TYPE_TAG_INT32:
2273             blob->size = 4;
2274             *(gint32*)&data[blob->offset] = (gint32) parse_int_value (constant->value);
2275             break;
2276           case GI_TYPE_TAG_UINT32:
2277             blob->size = 4;
2278             *(guint32*)&data[blob->offset] = (guint32) parse_uint_value (constant->value);
2279             break;
2280           case GI_TYPE_TAG_INT64:
2281             blob->size = 8;
2282             DO_ALIGNED_COPY(&data[blob->offset], parse_int_value (constant->value), gint64);
2283             break;
2284           case GI_TYPE_TAG_UINT64:
2285             blob->size = 8;
2286             DO_ALIGNED_COPY(&data[blob->offset], parse_uint_value (constant->value), guint64);
2287             break;
2288           case GI_TYPE_TAG_SHORT:
2289             blob->size = sizeof (gshort);
2290             *(gshort*)&data[blob->offset] = (gshort) parse_int_value (constant->value);
2291             break;
2292           case GI_TYPE_TAG_USHORT:
2293             blob->size = sizeof (gushort);
2294             *(gushort*)&data[blob->offset] = (gushort) parse_uint_value (constant->value);
2295             break;
2296           case GI_TYPE_TAG_INT:
2297             blob->size = sizeof (gint);
2298             *(gint*)&data[blob->offset] = (gint) parse_int_value (constant->value);
2299             break;
2300           case GI_TYPE_TAG_UINT:
2301             blob->size = sizeof (guint);
2302             *(gint*)&data[blob->offset] = (guint) parse_uint_value (constant->value);
2303             break;
2304           case GI_TYPE_TAG_SSIZE: /* FIXME */
2305           case GI_TYPE_TAG_LONG:
2306             blob->size = sizeof (glong);
2307             DO_ALIGNED_COPY(&data[blob->offset], parse_int_value (constant->value), glong);
2308             break;
2309           case GI_TYPE_TAG_SIZE: /* FIXME */
2310           case GI_TYPE_TAG_TIME_T:
2311           case GI_TYPE_TAG_ULONG:
2312             blob->size = sizeof (gulong);
2313             DO_ALIGNED_COPY(&data[blob->offset], parse_uint_value (constant->value), gulong);
2314             break;
2315           case GI_TYPE_TAG_FLOAT:
2316             blob->size = sizeof (gfloat);
2317             DO_ALIGNED_COPY(&data[blob->offset], parse_float_value (constant->value), gfloat);
2318             break;
2319           case GI_TYPE_TAG_DOUBLE:
2320             blob->size = sizeof (gdouble);
2321             DO_ALIGNED_COPY(&data[blob->offset], parse_float_value (constant->value), gdouble);
2322             break;
2323           case GI_TYPE_TAG_UTF8:
2324           case GI_TYPE_TAG_FILENAME:
2325             blob->size = strlen (constant->value) + 1;
2326             memcpy (&data[blob->offset], constant->value, blob->size);
2327             break;
2328           }
2329         *offset2 += ALIGN_VALUE (blob->size, 4);
2330
2331         g_ir_node_build_typelib ((GIrNode *)constant->type, node, build, &pos, offset2);
2332       }
2333       break;
2334     default:
2335       g_assert_not_reached ();
2336     }
2337
2338   g_debug ("node %s%s%s%p type '%s', offset %d -> %d, offset2 %d -> %d",
2339            node->name ? "'" : "",
2340            node->name ? node->name : "",
2341            node->name ? "' " : "",
2342            node, g_ir_node_type_to_string (node->type),
2343            old_offset, *offset, old_offset2, *offset2);
2344
2345   if (*offset2 - old_offset2 + *offset - old_offset > g_ir_node_get_full_size (node))
2346     g_error ("exceeding space reservation; offset: %d (prev %d) offset2: %d (prev %d) nodesize: %d",
2347              *offset, old_offset, *offset2, old_offset2, g_ir_node_get_full_size (node));
2348 }
2349
2350 /* if str is already in the pool, return previous location, otherwise write str
2351  * to the typelib at offset, put it in the pool and update offset. If the
2352  * typelib is not large enough to hold the string, reallocate it.
2353  */
2354 guint32
2355 write_string (const gchar *str,
2356               GHashTable  *strings,
2357               guchar      *data,
2358               guint32     *offset)
2359 {
2360   gpointer value;
2361   guint32 start;
2362
2363   string_count += 1;
2364   string_size += strlen (str);
2365
2366   value = g_hash_table_lookup (strings, str);
2367
2368   if (value)
2369     return GPOINTER_TO_UINT (value);
2370
2371   unique_string_count += 1;
2372   unique_string_size += strlen (str);
2373
2374   g_hash_table_insert (strings, (gpointer)str, GUINT_TO_POINTER (*offset));
2375
2376   start = *offset;
2377   *offset = ALIGN_VALUE (start + strlen (str) + 1, 4);
2378
2379   strcpy ((gchar*)&data[start], str);
2380
2381   return start;
2382 }
2383