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