1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
2 * GObject introspection: Typelib creation
4 * Copyright (C) 2005 Matthias Clasen
5 * Copyright (C) 2008,2009 Red Hat, Inc.
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.
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.
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.
27 #include "girmodule.h"
29 #include "gitypelib-internal.h"
31 static gulong string_count = 0;
32 static gulong unique_string_count = 0;
33 static gulong string_size = 0;
34 static gulong unique_string_size = 0;
35 static gulong types_count = 0;
36 static gulong unique_types_count = 0;
39 _g_irnode_init_stats (void)
42 unique_string_count = 0;
44 unique_string_size = 0;
46 unique_types_count = 0;
50 _g_irnode_dump_stats (void)
52 g_message ("%lu strings (%lu before sharing), %lu bytes (%lu before sharing)",
53 unique_string_count, string_count, unique_string_size, string_size);
54 g_message ("%lu types (%lu before sharing)", unique_types_count, types_count);
57 #define DO_ALIGNED_COPY(dest_addr, value, type) \
61 memcpy(dest_addr, &tmp_var, sizeof(type)); \
64 #define ALIGN_VALUE(this, boundary) \
65 (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
69 _g_ir_node_type_to_string (GIrNodeTypeId type)
73 case G_IR_NODE_FUNCTION:
75 case G_IR_NODE_CALLBACK:
81 case G_IR_NODE_OBJECT:
83 case G_IR_NODE_INTERFACE:
85 case G_IR_NODE_SIGNAL:
87 case G_IR_NODE_PROPERTY:
99 case G_IR_NODE_STRUCT:
101 case G_IR_NODE_VALUE:
103 case G_IR_NODE_CONSTANT:
107 case G_IR_NODE_UNION:
115 _g_ir_node_new (GIrNodeTypeId type,
118 GIrNode *node = NULL;
122 case G_IR_NODE_FUNCTION:
123 case G_IR_NODE_CALLBACK:
124 node = g_malloc0 (sizeof (GIrNodeFunction));
127 case G_IR_NODE_PARAM:
128 node = g_malloc0 (sizeof (GIrNodeParam));
132 node = g_malloc0 (sizeof (GIrNodeType));
135 case G_IR_NODE_OBJECT:
136 case G_IR_NODE_INTERFACE:
137 node = g_malloc0 (sizeof (GIrNodeInterface));
140 case G_IR_NODE_SIGNAL:
141 node = g_malloc0 (sizeof (GIrNodeSignal));
144 case G_IR_NODE_PROPERTY:
145 node = g_malloc0 (sizeof (GIrNodeProperty));
148 case G_IR_NODE_VFUNC:
149 node = g_malloc0 (sizeof (GIrNodeFunction));
152 case G_IR_NODE_FIELD:
153 node = g_malloc0 (sizeof (GIrNodeField));
157 case G_IR_NODE_FLAGS:
158 node = g_malloc0 (sizeof (GIrNodeEnum));
161 case G_IR_NODE_BOXED:
162 node = g_malloc0 (sizeof (GIrNodeBoxed));
165 case G_IR_NODE_STRUCT:
166 node = g_malloc0 (sizeof (GIrNodeStruct));
169 case G_IR_NODE_VALUE:
170 node = g_malloc0 (sizeof (GIrNodeValue));
173 case G_IR_NODE_CONSTANT:
174 node = g_malloc0 (sizeof (GIrNodeConstant));
178 node = g_malloc0 (sizeof (GIrNodeXRef));
181 case G_IR_NODE_UNION:
182 node = g_malloc0 (sizeof (GIrNodeUnion));
186 g_error ("Unhandled node type %d\n", type);
191 node->module = module;
193 node->attributes = g_hash_table_new_full (g_str_hash, g_str_equal,
200 _g_ir_node_free (GIrNode *node)
209 case G_IR_NODE_FUNCTION:
210 case G_IR_NODE_CALLBACK:
212 GIrNodeFunction *function = (GIrNodeFunction *)node;
215 g_free (function->symbol);
216 _g_ir_node_free ((GIrNode *)function->result);
217 for (l = function->parameters; l; l = l->next)
218 _g_ir_node_free ((GIrNode *)l->data);
219 g_list_free (function->parameters);
225 GIrNodeType *type = (GIrNodeType *)node;
228 _g_ir_node_free ((GIrNode *)type->parameter_type1);
229 _g_ir_node_free ((GIrNode *)type->parameter_type2);
231 g_free (type->interface);
232 g_strfreev (type->errors);
237 case G_IR_NODE_PARAM:
239 GIrNodeParam *param = (GIrNodeParam *)node;
242 _g_ir_node_free ((GIrNode *)param->type);
246 case G_IR_NODE_PROPERTY:
248 GIrNodeProperty *property = (GIrNodeProperty *)node;
251 _g_ir_node_free ((GIrNode *)property->type);
255 case G_IR_NODE_SIGNAL:
257 GIrNodeSignal *signal = (GIrNodeSignal *)node;
260 for (l = signal->parameters; l; l = l->next)
261 _g_ir_node_free ((GIrNode *)l->data);
262 g_list_free (signal->parameters);
263 _g_ir_node_free ((GIrNode *)signal->result);
267 case G_IR_NODE_VFUNC:
269 GIrNodeVFunc *vfunc = (GIrNodeVFunc *)node;
272 g_free (vfunc->invoker);
273 for (l = vfunc->parameters; l; l = l->next)
274 _g_ir_node_free ((GIrNode *)l->data);
275 g_list_free (vfunc->parameters);
276 _g_ir_node_free ((GIrNode *)vfunc->result);
280 case G_IR_NODE_FIELD:
282 GIrNodeField *field = (GIrNodeField *)node;
285 _g_ir_node_free ((GIrNode *)field->type);
286 _g_ir_node_free ((GIrNode *)field->callback);
290 case G_IR_NODE_OBJECT:
291 case G_IR_NODE_INTERFACE:
293 GIrNodeInterface *iface = (GIrNodeInterface *)node;
296 g_free (iface->gtype_name);
297 g_free (iface->gtype_init);
298 g_free (iface->ref_func);
299 g_free (iface->unref_func);
300 g_free (iface->set_value_func);
301 g_free (iface->get_value_func);
304 g_free (iface->glib_type_struct);
305 g_free (iface->parent);
307 for (l = iface->interfaces; l; l = l->next)
308 g_free ((GIrNode *)l->data);
309 g_list_free (iface->interfaces);
311 for (l = iface->members; l; l = l->next)
312 _g_ir_node_free ((GIrNode *)l->data);
313 g_list_free (iface->members);
318 case G_IR_NODE_VALUE:
325 case G_IR_NODE_FLAGS:
327 GIrNodeEnum *enum_ = (GIrNodeEnum *)node;
330 g_free (enum_->gtype_name);
331 g_free (enum_->gtype_init);
332 g_free (enum_->error_domain);
334 for (l = enum_->values; l; l = l->next)
335 _g_ir_node_free ((GIrNode *)l->data);
336 g_list_free (enum_->values);
338 for (l = enum_->methods; l; l = l->next)
339 _g_ir_node_free ((GIrNode *)l->data);
340 g_list_free (enum_->methods);
344 case G_IR_NODE_BOXED:
346 GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
349 g_free (boxed->gtype_name);
350 g_free (boxed->gtype_init);
352 for (l = boxed->members; l; l = l->next)
353 _g_ir_node_free ((GIrNode *)l->data);
354 g_list_free (boxed->members);
358 case G_IR_NODE_STRUCT:
360 GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
363 g_free (struct_->gtype_name);
364 g_free (struct_->gtype_init);
366 for (l = struct_->members; l; l = l->next)
367 _g_ir_node_free ((GIrNode *)l->data);
368 g_list_free (struct_->members);
372 case G_IR_NODE_CONSTANT:
374 GIrNodeConstant *constant = (GIrNodeConstant *)node;
377 g_free (constant->value);
378 _g_ir_node_free ((GIrNode *)constant->type);
384 GIrNodeXRef *xref = (GIrNodeXRef *)node;
387 g_free (xref->namespace);
391 case G_IR_NODE_UNION:
393 GIrNodeUnion *union_ = (GIrNodeUnion *)node;
396 g_free (union_->gtype_name);
397 g_free (union_->gtype_init);
399 _g_ir_node_free ((GIrNode *)union_->discriminator_type);
400 for (l = union_->members; l; l = l->next)
401 _g_ir_node_free ((GIrNode *)l->data);
402 for (l = union_->discriminators; l; l = l->next)
403 _g_ir_node_free ((GIrNode *)l->data);
408 g_error ("Unhandled node type %d\n", node->type);
412 g_hash_table_destroy (node->attributes);
417 /* returns the fixed size of the blob */
419 _g_ir_node_get_size (GIrNode *node)
426 case G_IR_NODE_CALLBACK:
427 size = sizeof (CallbackBlob);
430 case G_IR_NODE_FUNCTION:
431 size = sizeof (FunctionBlob);
434 case G_IR_NODE_PARAM:
435 /* See the comment in the G_IR_NODE_PARAM/ArgBlob writing below */
436 size = sizeof (ArgBlob) - sizeof (SimpleTypeBlob);
440 size = sizeof (SimpleTypeBlob);
443 case G_IR_NODE_OBJECT:
445 GIrNodeInterface *iface = (GIrNodeInterface *)node;
447 n = g_list_length (iface->interfaces);
448 size = sizeof (ObjectBlob) + 2 * (n + (n % 2));
450 for (l = iface->members; l; l = l->next)
451 size += _g_ir_node_get_size ((GIrNode *)l->data);
455 case G_IR_NODE_INTERFACE:
457 GIrNodeInterface *iface = (GIrNodeInterface *)node;
459 n = g_list_length (iface->prerequisites);
460 size = sizeof (InterfaceBlob) + 2 * (n + (n % 2));
462 for (l = iface->members; l; l = l->next)
463 size += _g_ir_node_get_size ((GIrNode *)l->data);
468 case G_IR_NODE_FLAGS:
470 GIrNodeEnum *enum_ = (GIrNodeEnum *)node;
472 size = sizeof (EnumBlob);
473 for (l = enum_->values; l; l = l->next)
474 size += _g_ir_node_get_size ((GIrNode *)l->data);
475 for (l = enum_->methods; l; l = l->next)
476 size += _g_ir_node_get_size ((GIrNode *)l->data);
480 case G_IR_NODE_VALUE:
481 size = sizeof (ValueBlob);
484 case G_IR_NODE_STRUCT:
486 GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
488 size = sizeof (StructBlob);
489 for (l = struct_->members; l; l = l->next)
490 size += _g_ir_node_get_size ((GIrNode *)l->data);
494 case G_IR_NODE_BOXED:
496 GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
498 size = sizeof (StructBlob);
499 for (l = boxed->members; l; l = l->next)
500 size += _g_ir_node_get_size ((GIrNode *)l->data);
504 case G_IR_NODE_PROPERTY:
505 size = sizeof (PropertyBlob);
508 case G_IR_NODE_SIGNAL:
509 size = sizeof (SignalBlob);
512 case G_IR_NODE_VFUNC:
513 size = sizeof (VFuncBlob);
516 case G_IR_NODE_FIELD:
518 GIrNodeField *field = (GIrNodeField *)node;
520 size = sizeof (FieldBlob);
522 size += _g_ir_node_get_size ((GIrNode *)field->callback);
526 case G_IR_NODE_CONSTANT:
527 size = sizeof (ConstantBlob);
534 case G_IR_NODE_UNION:
536 GIrNodeUnion *union_ = (GIrNodeUnion *)node;
538 size = sizeof (UnionBlob);
539 for (l = union_->members; l; l = l->next)
540 size += _g_ir_node_get_size ((GIrNode *)l->data);
541 for (l = union_->discriminators; l; l = l->next)
542 size += _g_ir_node_get_size ((GIrNode *)l->data);
547 g_error ("Unhandled node type '%s'\n",
548 _g_ir_node_type_to_string (node->type));
552 g_debug ("node %p type '%s' size %d", node,
553 _g_ir_node_type_to_string (node->type), size);
559 add_attribute_size (gpointer key, gpointer value, gpointer data)
561 const gchar *key_str = key;
562 const gchar *value_str = value;
565 *size_p += sizeof (AttributeBlob);
566 *size_p += ALIGN_VALUE (strlen (key_str) + 1, 4);
567 *size_p += ALIGN_VALUE (strlen (value_str) + 1, 4);
570 /* returns the full size of the blob including variable-size parts (including attributes) */
572 _g_ir_node_get_full_size_internal (GIrNode *parent,
578 if (node == NULL && parent != NULL)
579 g_error ("Caught NULL node, parent=%s", parent->name);
581 g_debug ("node %p type '%s'", node,
582 _g_ir_node_type_to_string (node->type));
586 case G_IR_NODE_CALLBACK:
588 GIrNodeFunction *function = (GIrNodeFunction *)node;
589 size = sizeof (CallbackBlob);
590 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
591 for (l = function->parameters; l; l = l->next)
593 size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
595 size += _g_ir_node_get_full_size_internal (node, (GIrNode *)function->result);
599 case G_IR_NODE_FUNCTION:
601 GIrNodeFunction *function = (GIrNodeFunction *)node;
602 size = sizeof (FunctionBlob);
603 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
604 size += ALIGN_VALUE (strlen (function->symbol) + 1, 4);
605 for (l = function->parameters; l; l = l->next)
606 size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
607 size += _g_ir_node_get_full_size_internal (node, (GIrNode *)function->result);
611 case G_IR_NODE_PARAM:
613 GIrNodeParam *param = (GIrNodeParam *)node;
615 /* See the comment in the G_IR_NODE_PARAM/ArgBlob writing below */
616 size = sizeof (ArgBlob) - sizeof (SimpleTypeBlob);
618 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
619 size += _g_ir_node_get_full_size_internal (node, (GIrNode *)param->type);
625 GIrNodeType *type = (GIrNodeType *)node;
626 size = sizeof (SimpleTypeBlob);
627 if (!G_TYPE_TAG_IS_BASIC(type->tag))
629 g_debug ("node %p type tag '%s'", node,
630 g_type_tag_to_string (type->tag));
634 case GI_TYPE_TAG_ARRAY:
635 size = sizeof (ArrayTypeBlob);
636 if (type->parameter_type1)
637 size += _g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1);
639 case GI_TYPE_TAG_INTERFACE:
640 size += sizeof (InterfaceTypeBlob);
642 case GI_TYPE_TAG_GLIST:
643 case GI_TYPE_TAG_GSLIST:
644 size += sizeof (ParamTypeBlob);
645 if (type->parameter_type1)
646 size += _g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1);
648 case GI_TYPE_TAG_GHASH:
649 size += sizeof (ParamTypeBlob) * 2;
650 if (type->parameter_type1)
651 size += _g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1);
652 if (type->parameter_type2)
653 size += _g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type2);
655 case GI_TYPE_TAG_ERROR:
656 size += sizeof (ErrorTypeBlob);
659 g_error ("Unknown type tag %d\n", type->tag);
666 case G_IR_NODE_OBJECT:
668 GIrNodeInterface *iface = (GIrNodeInterface *)node;
670 n = g_list_length (iface->interfaces);
671 size = sizeof(ObjectBlob);
673 size += ALIGN_VALUE (strlen (iface->parent) + 1, 4);
674 if (iface->glib_type_struct)
675 size += ALIGN_VALUE (strlen (iface->glib_type_struct) + 1, 4);
676 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
677 size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4);
678 if (iface->gtype_init)
679 size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4);
681 size += ALIGN_VALUE (strlen (iface->ref_func) + 1, 4);
682 if (iface->unref_func)
683 size += ALIGN_VALUE (strlen (iface->unref_func) + 1, 4);
684 if (iface->set_value_func)
685 size += ALIGN_VALUE (strlen (iface->set_value_func) + 1, 4);
686 if (iface->get_value_func)
687 size += ALIGN_VALUE (strlen (iface->get_value_func) + 1, 4);
688 size += 2 * (n + (n % 2));
690 for (l = iface->members; l; l = l->next)
691 size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
695 case G_IR_NODE_INTERFACE:
697 GIrNodeInterface *iface = (GIrNodeInterface *)node;
699 n = g_list_length (iface->prerequisites);
700 size = sizeof (InterfaceBlob);
701 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
702 size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4);
703 size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4);
704 size += 2 * (n + (n % 2));
706 for (l = iface->members; l; l = l->next)
707 size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
712 case G_IR_NODE_FLAGS:
714 GIrNodeEnum *enum_ = (GIrNodeEnum *)node;
716 size = sizeof (EnumBlob);
717 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
718 if (enum_->gtype_name)
720 size += ALIGN_VALUE (strlen (enum_->gtype_name) + 1, 4);
721 size += ALIGN_VALUE (strlen (enum_->gtype_init) + 1, 4);
723 if (enum_->error_domain)
724 size += ALIGN_VALUE (strlen (enum_->error_domain) + 1, 4);
726 for (l = enum_->values; l; l = l->next)
727 size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
728 for (l = enum_->methods; l; l = l->next)
729 size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
733 case G_IR_NODE_VALUE:
735 size = sizeof (ValueBlob);
736 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
740 case G_IR_NODE_STRUCT:
742 GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
744 size = sizeof (StructBlob);
745 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
746 if (struct_->gtype_name)
747 size += ALIGN_VALUE (strlen (struct_->gtype_name) + 1, 4);
748 if (struct_->gtype_init)
749 size += ALIGN_VALUE (strlen (struct_->gtype_init) + 1, 4);
750 for (l = struct_->members; l; l = l->next)
751 size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
755 case G_IR_NODE_BOXED:
757 GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
759 size = sizeof (StructBlob);
760 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
761 if (boxed->gtype_name)
763 size += ALIGN_VALUE (strlen (boxed->gtype_name) + 1, 4);
764 size += ALIGN_VALUE (strlen (boxed->gtype_init) + 1, 4);
766 for (l = boxed->members; l; l = l->next)
767 size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
771 case G_IR_NODE_PROPERTY:
773 GIrNodeProperty *prop = (GIrNodeProperty *)node;
775 size = sizeof (PropertyBlob);
776 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
777 size += _g_ir_node_get_full_size_internal (node, (GIrNode *)prop->type);
781 case G_IR_NODE_SIGNAL:
783 GIrNodeSignal *signal = (GIrNodeSignal *)node;
785 size = sizeof (SignalBlob);
786 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
787 for (l = signal->parameters; l; l = l->next)
788 size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
789 size += _g_ir_node_get_full_size_internal (node, (GIrNode *)signal->result);
793 case G_IR_NODE_VFUNC:
795 GIrNodeVFunc *vfunc = (GIrNodeVFunc *)node;
797 size = sizeof (VFuncBlob);
798 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
799 for (l = vfunc->parameters; l; l = l->next)
800 size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
801 size += _g_ir_node_get_full_size_internal (node, (GIrNode *)vfunc->result);
805 case G_IR_NODE_FIELD:
807 GIrNodeField *field = (GIrNodeField *)node;
809 size = sizeof (FieldBlob);
810 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
812 size += _g_ir_node_get_full_size_internal (node, (GIrNode *)field->callback);
814 size += _g_ir_node_get_full_size_internal (node, (GIrNode *)field->type);
818 case G_IR_NODE_CONSTANT:
820 GIrNodeConstant *constant = (GIrNodeConstant *)node;
822 size = sizeof (ConstantBlob);
823 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
824 /* FIXME non-string values */
825 size += ALIGN_VALUE (strlen (constant->value) + 1, 4);
826 size += _g_ir_node_get_full_size_internal (node, (GIrNode *)constant->type);
832 GIrNodeXRef *xref = (GIrNodeXRef *)node;
835 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
836 size += ALIGN_VALUE (strlen (xref->namespace) + 1, 4);
840 case G_IR_NODE_UNION:
842 GIrNodeUnion *union_ = (GIrNodeUnion *)node;
844 size = sizeof (UnionBlob);
845 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
846 if (union_->gtype_name)
847 size += ALIGN_VALUE (strlen (union_->gtype_name) + 1, 4);
848 if (union_->gtype_init)
849 size += ALIGN_VALUE (strlen (union_->gtype_init) + 1, 4);
850 for (l = union_->members; l; l = l->next)
851 size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
852 for (l = union_->discriminators; l; l = l->next)
853 size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
858 g_error ("Unknown type tag %d\n", node->type);
862 g_debug ("node %s%s%s%p type '%s' full size %d",
863 node->name ? "'" : "",
864 node->name ? node->name : "",
865 node->name ? "' " : "",
866 node, _g_ir_node_type_to_string (node->type), size);
868 g_hash_table_foreach (node->attributes, add_attribute_size, &size);
874 _g_ir_node_get_full_size (GIrNode *node)
876 return _g_ir_node_get_full_size_internal (NULL, node);
880 _g_ir_node_cmp (GIrNode *node,
883 if (node->type < other->type)
885 else if (node->type > other->type)
888 return strcmp (node->name, other->name);
892 _g_ir_node_can_have_member (GIrNode *node)
896 case G_IR_NODE_OBJECT:
897 case G_IR_NODE_INTERFACE:
898 case G_IR_NODE_BOXED:
899 case G_IR_NODE_STRUCT:
900 case G_IR_NODE_UNION:
902 /* list others individually rather than with default: so that compiler
903 * warns if new node types are added without adding them to the switch
905 case G_IR_NODE_INVALID:
906 case G_IR_NODE_FUNCTION:
907 case G_IR_NODE_CALLBACK:
909 case G_IR_NODE_FLAGS:
910 case G_IR_NODE_CONSTANT:
911 case G_IR_NODE_INVALID_0:
912 case G_IR_NODE_PARAM:
914 case G_IR_NODE_PROPERTY:
915 case G_IR_NODE_SIGNAL:
916 case G_IR_NODE_VALUE:
917 case G_IR_NODE_VFUNC:
918 case G_IR_NODE_FIELD:
926 _g_ir_node_add_member (GIrNode *node,
927 GIrNodeFunction *member)
929 g_return_if_fail (node != NULL);
930 g_return_if_fail (member != NULL);
934 case G_IR_NODE_OBJECT:
935 case G_IR_NODE_INTERFACE:
937 GIrNodeInterface *iface = (GIrNodeInterface *)node;
939 g_list_insert_sorted (iface->members, member,
940 (GCompareFunc) _g_ir_node_cmp);
943 case G_IR_NODE_BOXED:
945 GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
947 g_list_insert_sorted (boxed->members, member,
948 (GCompareFunc) _g_ir_node_cmp);
951 case G_IR_NODE_STRUCT:
953 GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
955 g_list_insert_sorted (struct_->members, member,
956 (GCompareFunc) _g_ir_node_cmp);
959 case G_IR_NODE_UNION:
961 GIrNodeUnion *union_ = (GIrNodeUnion *)node;
963 g_list_insert_sorted (union_->members, member,
964 (GCompareFunc) _g_ir_node_cmp);
968 g_error ("Cannot add a member to unknown type tag type %d\n",
975 _g_ir_node_param_direction_string (GIrNodeParam * node)
988 parse_int_value (const gchar *str)
990 return strtoll (str, NULL, 0);
994 parse_uint_value (const gchar *str)
996 return strtoull (str, NULL, 0);
1000 parse_float_value (const gchar *str)
1002 return strtod (str, NULL);
1006 parse_boolean_value (const gchar *str)
1008 if (strcmp (str, "TRUE") == 0)
1011 if (strcmp (str, "FALSE") == 0)
1014 return parse_int_value (str) ? TRUE : FALSE;
1018 find_entry_node (GIrTypelibBuild *build,
1023 GIrModule *module = build->module;
1028 GIrNode *result = NULL;
1030 g_assert (name != NULL);
1031 g_assert (strlen (name) > 0);
1033 names = g_strsplit (name, ".", 0);
1034 n_names = g_strv_length (names);
1036 g_error ("Too many name parts");
1038 for (l = module->entries, i = 1; l; l = l->next, i++)
1040 GIrNode *node = (GIrNode *)l->data;
1044 if (node->type != G_IR_NODE_XREF)
1047 if (((GIrNodeXRef *)node)->namespace == NULL ||
1048 strcmp (((GIrNodeXRef *)node)->namespace, names[0]) != 0)
1052 if (strcmp (node->name, names[n_names - 1]) == 0)
1064 GIrNode *node = _g_ir_node_new (G_IR_NODE_XREF, module);
1066 ((GIrNodeXRef *)node)->namespace = g_strdup (names[0]);
1067 node->name = g_strdup (names[1]);
1069 module->entries = g_list_append (module->entries, node);
1072 *idx = g_list_length (module->entries);
1076 g_debug ("Creating XREF: %s %s", names[0], names[1]);
1082 _g_ir_module_fatal (build, -1, "type reference '%s' not found",
1092 find_entry (GIrTypelibBuild *build,
1097 find_entry_node (build, name, &idx);
1103 find_namespace (GIrModule *module,
1109 if (strcmp (module->name, name) == 0)
1112 for (l = module->include_modules; l; l = l->next)
1114 GIrModule *submodule = l->data;
1116 if (strcmp (submodule->name, name) == 0)
1119 target = find_namespace (submodule, name);
1127 _g_ir_find_node (GIrTypelibBuild *build,
1128 GIrModule *src_module,
1132 GIrNode *return_node = NULL;
1133 char **names = g_strsplit (name, ".", 0);
1134 gint n_names = g_strv_length (names);
1135 const char *target_name;
1136 GIrModule *target_module;
1140 target_module = src_module;
1145 target_module = find_namespace (build->module, names[0]);
1146 target_name = names[1];
1149 for (l = target_module->entries; l; l = l->next)
1151 GIrNode *node = (GIrNode *)l->data;
1153 if (strcmp (node->name, target_name) == 0)
1166 get_index_of_member_type (GIrNodeInterface *node,
1173 for (l = node->members; l; l = l->next)
1175 GIrNode *node = l->data;
1177 if (node->type != type)
1182 if (strcmp (node->name, name) == 0)
1190 serialize_type (GIrTypelibBuild *build,
1196 if (G_TYPE_TAG_IS_BASIC(node->tag))
1198 g_string_append_printf (str, "%s%s", g_type_tag_to_string (node->tag),
1199 node->is_pointer ? "*" : "");
1201 else if (node->tag == GI_TYPE_TAG_ARRAY)
1203 if (node->array_type == GI_ARRAY_TYPE_C)
1205 serialize_type (build, node->parameter_type1, str);
1206 g_string_append (str, "[");
1208 if (node->has_length)
1209 g_string_append_printf (str, "length=%d", node->length);
1210 else if (node->has_size)
1211 g_string_append_printf (str, "fixed-size=%d", node->size);
1213 if (node->zero_terminated)
1214 g_string_append_printf (str, "%szero-terminated=1",
1215 node->has_length ? "," : "");
1217 g_string_append (str, "]");
1218 if (node->is_pointer)
1219 g_string_append (str, "*");
1221 else if (node->array_type == GI_ARRAY_TYPE_BYTE_ARRAY)
1223 /* We on purpose skip serializing parameter_type1, which should
1226 g_string_append (str, "GByteArray");
1230 if (node->array_type == GI_ARRAY_TYPE_ARRAY)
1231 g_string_append (str, "GArray");
1233 g_string_append (str, "GPtrArray");
1234 if (node->parameter_type1)
1236 g_string_append (str, "<");
1237 serialize_type (build, node->parameter_type1, str);
1238 g_string_append (str, ">");
1242 else if (node->tag == GI_TYPE_TAG_INTERFACE)
1247 iface = find_entry_node (build, node->interface, NULL);
1250 if (iface->type == G_IR_NODE_XREF)
1251 g_string_append_printf (str, "%s.", ((GIrNodeXRef *)iface)->namespace);
1256 g_warning ("Interface for type reference %s not found", node->interface);
1257 name = node->interface;
1260 g_string_append_printf (str, "%s%s", name,
1261 node->is_pointer ? "*" : "");
1263 else if (node->tag == GI_TYPE_TAG_GLIST)
1265 g_string_append (str, "GList");
1266 if (node->parameter_type1)
1268 g_string_append (str, "<");
1269 serialize_type (build, node->parameter_type1, str);
1270 g_string_append (str, ">");
1273 else if (node->tag == GI_TYPE_TAG_GSLIST)
1275 g_string_append (str, "GSList");
1276 if (node->parameter_type1)
1278 g_string_append (str, "<");
1279 serialize_type (build, node->parameter_type1, str);
1280 g_string_append (str, ">");
1283 else if (node->tag == GI_TYPE_TAG_GHASH)
1285 g_string_append (str, "GHashTable");
1286 if (node->parameter_type1)
1288 g_string_append (str, "<");
1289 serialize_type (build, node->parameter_type1, str);
1290 g_string_append (str, ",");
1291 serialize_type (build, node->parameter_type2, str);
1292 g_string_append (str, ">");
1295 else if (node->tag == GI_TYPE_TAG_ERROR)
1297 g_string_append (str, "GError");
1300 g_string_append (str, "<");
1301 for (i = 0; node->errors[i]; i++)
1304 g_string_append (str, ",");
1305 g_string_append (str, node->errors[i]);
1307 g_string_append (str, ">");
1313 _g_ir_node_build_members (GList **members,
1317 GIrTypelibBuild *build,
1321 GList *l = *members;
1325 GIrNode *member = (GIrNode *)l->data;
1326 GList *next = l->next;
1328 if (member->type == type)
1331 _g_ir_node_build_typelib (member, parent, build, offset, offset2);
1332 *members = g_list_delete_link (*members, l);
1339 _g_ir_node_check_unhandled_members (GList **members,
1340 GIrNodeTypeId container_type)
1347 for (l = *members; l; l = l->next)
1349 GIrNode *member = (GIrNode *)l->data;
1350 g_printerr ("Unhandled '%s' member '%s' type '%s'\n",
1351 _g_ir_node_type_to_string (container_type),
1353 _g_ir_node_type_to_string (member->type));
1356 g_list_free (*members);
1359 g_error ("Unhandled members. Aborting.");
1362 g_list_free (*members);
1368 _g_ir_node_build_typelib (GIrNode *node,
1370 GIrTypelibBuild *build,
1374 gboolean appended_stack;
1375 GHashTable *strings = build->strings;
1376 GHashTable *types = build->types;
1377 guchar *data = build->data;
1379 guint32 old_offset = *offset;
1380 guint32 old_offset2 = *offset2;
1382 g_assert (node != NULL);
1384 g_debug ("build_typelib: %s%s(%s)",
1385 node->name ? node->name : "",
1386 node->name ? " " : "",
1387 _g_ir_node_type_to_string (node->type));
1390 appended_stack = node != (GIrNode*)build->stack->data;
1392 appended_stack = TRUE;
1394 build->stack = g_list_prepend (build->stack, node);
1396 _g_ir_node_compute_offsets (build, node);
1398 /* We should only be building each node once. If we do a typelib expansion, we also
1399 * reset the offset in girmodule.c.
1401 g_assert (node->offset == 0);
1402 node->offset = *offset;
1403 build->nodes_with_attributes = g_list_prepend (build->nodes_with_attributes, node);
1405 build->n_attributes += g_hash_table_size (node->attributes);
1409 case G_IR_NODE_TYPE:
1411 GIrNodeType *type = (GIrNodeType *)node;
1412 SimpleTypeBlob *blob = (SimpleTypeBlob *)&data[*offset];
1414 *offset += sizeof (SimpleTypeBlob);
1416 if (G_TYPE_TAG_IS_BASIC (type->tag))
1418 blob->flags.reserved = 0;
1419 blob->flags.reserved2 = 0;
1420 blob->flags.pointer = type->is_pointer;
1421 blob->flags.reserved3 = 0;
1422 blob->flags.tag = type->tag;
1430 str = g_string_new (0);
1431 serialize_type (build, type, str);
1432 s = g_string_free (str, FALSE);
1435 value = g_hash_table_lookup (types, s);
1438 blob->offset = GPOINTER_TO_UINT (value);
1443 unique_types_count += 1;
1444 g_hash_table_insert (types, s, GUINT_TO_POINTER(*offset2));
1446 blob->offset = *offset2;
1449 case GI_TYPE_TAG_ARRAY:
1451 ArrayTypeBlob *array = (ArrayTypeBlob *)&data[*offset2];
1454 array->pointer = type->is_pointer;
1455 array->reserved = 0;
1456 array->tag = type->tag;
1457 array->zero_terminated = type->zero_terminated;
1458 array->has_length = type->has_length;
1459 array->has_size = type->has_size;
1460 array->array_type = type->array_type;
1461 array->reserved2 = 0;
1462 if (array->has_length)
1463 array->dimensions.length = type->length;
1464 else if (array->has_size)
1465 array->dimensions.size = type->size;
1467 array->dimensions.length = -1;
1469 pos = *offset2 + G_STRUCT_OFFSET (ArrayTypeBlob, type);
1470 *offset2 += sizeof (ArrayTypeBlob);
1472 _g_ir_node_build_typelib ((GIrNode *)type->parameter_type1,
1473 node, build, &pos, offset2);
1477 case GI_TYPE_TAG_INTERFACE:
1479 InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&data[*offset2];
1480 *offset2 += sizeof (InterfaceTypeBlob);
1482 iface->pointer = type->is_pointer;
1483 iface->reserved = 0;
1484 iface->tag = type->tag;
1485 iface->reserved2 = 0;
1486 iface->interface = find_entry (build, type->interface);
1491 case GI_TYPE_TAG_GLIST:
1492 case GI_TYPE_TAG_GSLIST:
1494 ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2];
1498 param->reserved = 0;
1499 param->tag = type->tag;
1500 param->reserved2 = 0;
1503 pos = *offset2 + G_STRUCT_OFFSET (ParamTypeBlob, type);
1504 *offset2 += sizeof (ParamTypeBlob) + sizeof (SimpleTypeBlob);
1506 _g_ir_node_build_typelib ((GIrNode *)type->parameter_type1,
1507 node, build, &pos, offset2);
1511 case GI_TYPE_TAG_GHASH:
1513 ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2];
1517 param->reserved = 0;
1518 param->tag = type->tag;
1519 param->reserved2 = 0;
1522 pos = *offset2 + G_STRUCT_OFFSET (ParamTypeBlob, type);
1523 *offset2 += sizeof (ParamTypeBlob) + sizeof (SimpleTypeBlob)*2;
1525 _g_ir_node_build_typelib ((GIrNode *)type->parameter_type1,
1526 node, build, &pos, offset2);
1527 _g_ir_node_build_typelib ((GIrNode *)type->parameter_type2,
1528 node, build, &pos, offset2);
1532 case GI_TYPE_TAG_ERROR:
1534 ErrorTypeBlob *blob = (ErrorTypeBlob *)&data[*offset2];
1538 blob->tag = type->tag;
1539 blob->reserved2 = 0;
1540 blob->n_domains = 0;
1542 *offset2 += sizeof (ErrorTypeBlob);
1547 g_error ("Unknown type tag %d\n", type->tag);
1555 case G_IR_NODE_FIELD:
1557 GIrNodeField *field = (GIrNodeField *)node;
1560 blob = (FieldBlob *)&data[*offset];
1562 blob->name = _g_ir_write_string (node->name, strings, data, offset2);
1563 blob->readable = field->readable;
1564 blob->writable = field->writable;
1567 if (field->offset >= 0)
1568 blob->struct_offset = field->offset;
1570 blob->struct_offset = 0xFFFF; /* mark as unknown */
1572 if (field->callback)
1574 blob->has_embedded_type = TRUE;
1575 blob->type.offset = GI_INFO_TYPE_CALLBACK;
1576 *offset += sizeof (FieldBlob);
1577 _g_ir_node_build_typelib ((GIrNode *)field->callback,
1578 node, build, offset, offset2);
1582 blob->has_embedded_type = FALSE;
1583 /* We handle the size member specially below, so subtract it */
1584 *offset += sizeof (FieldBlob) - sizeof (SimpleTypeBlob);
1585 _g_ir_node_build_typelib ((GIrNode *)field->type,
1586 node, build, offset, offset2);
1591 case G_IR_NODE_PROPERTY:
1593 GIrNodeProperty *prop = (GIrNodeProperty *)node;
1594 PropertyBlob *blob = (PropertyBlob *)&data[*offset];
1595 /* We handle the size member specially below, so subtract it */
1596 *offset += sizeof (PropertyBlob) - sizeof (SimpleTypeBlob);
1598 blob->name = _g_ir_write_string (node->name, strings, data, offset2);
1599 blob->deprecated = prop->deprecated;
1600 blob->readable = prop->readable;
1601 blob->writable = prop->writable;
1602 blob->construct = prop->construct;
1603 blob->construct_only = prop->construct_only;
1604 blob->transfer_ownership = prop->transfer;
1605 blob->transfer_container_ownership = prop->shallow_transfer;
1608 _g_ir_node_build_typelib ((GIrNode *)prop->type,
1609 node, build, offset, offset2);
1613 case G_IR_NODE_FUNCTION:
1615 FunctionBlob *blob = (FunctionBlob *)&data[*offset];
1616 SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1617 GIrNodeFunction *function = (GIrNodeFunction *)node;
1621 signature = *offset2;
1622 n = g_list_length (function->parameters);
1624 *offset += sizeof (FunctionBlob);
1625 *offset2 += sizeof (SignatureBlob) + n * sizeof (ArgBlob);
1627 blob->blob_type = BLOB_TYPE_FUNCTION;
1628 blob->deprecated = function->deprecated;
1629 blob->is_static = !function->is_method;
1630 blob->setter = function->is_setter;
1631 blob->getter = function->is_getter;
1632 blob->constructor = function->is_constructor;
1633 blob->wraps_vfunc = function->wraps_vfunc;
1634 blob->throws = function->throws;
1636 blob->name = _g_ir_write_string (node->name, strings, data, offset2);
1637 blob->symbol = _g_ir_write_string (function->symbol, strings, data, offset2);
1638 blob->signature = signature;
1640 /* function->result is special since it doesn't appear in the serialized format but
1641 * we do want the attributes for it to appear
1643 build->nodes_with_attributes = g_list_prepend (build->nodes_with_attributes, function->result);
1644 build->n_attributes += g_hash_table_size (((GIrNode *) function->result)->attributes);
1645 g_assert (((GIrNode *) function->result)->offset == 0);
1646 ((GIrNode *) function->result)->offset = signature;
1648 g_debug ("building function '%s'", function->symbol);
1650 _g_ir_node_build_typelib ((GIrNode *)function->result->type,
1651 node, build, &signature, offset2);
1653 blob2->may_return_null = function->result->allow_none;
1654 blob2->caller_owns_return_value = function->result->transfer;
1655 blob2->caller_owns_return_container = function->result->shallow_transfer;
1656 blob2->skip_return = function->result->skip;
1657 blob2->reserved = 0;
1658 blob2->n_arguments = n;
1662 for (l = function->parameters; l; l = l->next)
1664 GIrNode *param = (GIrNode *)l->data;
1666 _g_ir_node_build_typelib (param, node, build, &signature, offset2);
1672 case G_IR_NODE_CALLBACK:
1674 CallbackBlob *blob = (CallbackBlob *)&data[*offset];
1675 SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1676 GIrNodeFunction *function = (GIrNodeFunction *)node;
1680 signature = *offset2;
1681 n = g_list_length (function->parameters);
1683 *offset += sizeof (CallbackBlob);
1684 *offset2 += sizeof (SignatureBlob) + n * sizeof (ArgBlob);
1686 blob->blob_type = BLOB_TYPE_CALLBACK;
1687 blob->deprecated = function->deprecated;
1689 blob->name = _g_ir_write_string (node->name, strings, data, offset2);
1690 blob->signature = signature;
1692 _g_ir_node_build_typelib ((GIrNode *)function->result->type,
1693 node, build, &signature, offset2);
1695 blob2->may_return_null = function->result->allow_none;
1696 blob2->caller_owns_return_value = function->result->transfer;
1697 blob2->caller_owns_return_container = function->result->shallow_transfer;
1698 blob2->reserved = 0;
1699 blob2->n_arguments = n;
1703 for (l = function->parameters; l; l = l->next)
1705 GIrNode *param = (GIrNode *)l->data;
1707 _g_ir_node_build_typelib (param, node, build, &signature, offset2);
1712 case G_IR_NODE_SIGNAL:
1714 SignalBlob *blob = (SignalBlob *)&data[*offset];
1715 SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1716 GIrNodeSignal *signal = (GIrNodeSignal *)node;
1720 signature = *offset2;
1721 n = g_list_length (signal->parameters);
1723 *offset += sizeof (SignalBlob);
1724 *offset2 += sizeof (SignatureBlob) + n * sizeof (ArgBlob);
1726 blob->deprecated = signal->deprecated;
1727 blob->run_first = signal->run_first;
1728 blob->run_last = signal->run_last;
1729 blob->run_cleanup = signal->run_cleanup;
1730 blob->no_recurse = signal->no_recurse;
1731 blob->detailed = signal->detailed;
1732 blob->action = signal->action;
1733 blob->no_hooks = signal->no_hooks;
1734 blob->has_class_closure = 0; /* FIXME */
1735 blob->true_stops_emit = 0; /* FIXME */
1737 blob->class_closure = 0; /* FIXME */
1738 blob->name = _g_ir_write_string (node->name, strings, data, offset2);
1739 blob->signature = signature;
1741 /* signal->result is special since it doesn't appear in the serialized format but
1742 * we do want the attributes for it to appear
1744 build->nodes_with_attributes = g_list_prepend (build->nodes_with_attributes, signal->result);
1745 build->n_attributes += g_hash_table_size (((GIrNode *) signal->result)->attributes);
1746 g_assert (((GIrNode *) signal->result)->offset == 0);
1747 ((GIrNode *) signal->result)->offset = signature;
1749 _g_ir_node_build_typelib ((GIrNode *)signal->result->type,
1750 node, build, &signature, offset2);
1752 blob2->may_return_null = signal->result->allow_none;
1753 blob2->caller_owns_return_value = signal->result->transfer;
1754 blob2->caller_owns_return_container = signal->result->shallow_transfer;
1755 blob2->reserved = 0;
1756 blob2->n_arguments = n;
1760 for (l = signal->parameters; l; l = l->next)
1762 GIrNode *param = (GIrNode *)l->data;
1764 _g_ir_node_build_typelib (param, node, build, &signature, offset2);
1769 case G_IR_NODE_VFUNC:
1771 VFuncBlob *blob = (VFuncBlob *)&data[*offset];
1772 SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1773 GIrNodeVFunc *vfunc = (GIrNodeVFunc *)node;
1777 signature = *offset2;
1778 n = g_list_length (vfunc->parameters);
1780 *offset += sizeof (VFuncBlob);
1781 *offset2 += sizeof (SignatureBlob) + n * sizeof (ArgBlob);
1783 blob->name = _g_ir_write_string (node->name, strings, data, offset2);
1784 blob->must_chain_up = 0; /* FIXME */
1785 blob->must_be_implemented = 0; /* FIXME */
1786 blob->must_not_be_implemented = 0; /* FIXME */
1787 blob->class_closure = 0; /* FIXME */
1788 blob->throws = vfunc->throws;
1793 int index = get_index_of_member_type ((GIrNodeInterface*)parent, G_IR_NODE_FUNCTION, vfunc->invoker);
1796 g_error ("Unknown member function %s for vfunc %s", vfunc->invoker, node->name);
1798 blob->invoker = (guint) index;
1801 blob->invoker = 0x3ff; /* max of 10 bits */
1803 blob->struct_offset = vfunc->offset;
1804 blob->reserved2 = 0;
1805 blob->signature = signature;
1807 _g_ir_node_build_typelib ((GIrNode *)vfunc->result->type,
1808 node, build, &signature, offset2);
1810 blob2->may_return_null = vfunc->result->allow_none;
1811 blob2->caller_owns_return_value = vfunc->result->transfer;
1812 blob2->caller_owns_return_container = vfunc->result->shallow_transfer;
1813 blob2->reserved = 0;
1814 blob2->n_arguments = n;
1818 for (l = vfunc->parameters; l; l = l->next)
1820 GIrNode *param = (GIrNode *)l->data;
1822 _g_ir_node_build_typelib (param, node, build, &signature, offset2);
1827 case G_IR_NODE_PARAM:
1829 ArgBlob *blob = (ArgBlob *)&data[*offset];
1830 GIrNodeParam *param = (GIrNodeParam *)node;
1832 /* The offset for this one is smaller than the struct because
1833 * we recursively build the simple type inline here below.
1835 *offset += sizeof (ArgBlob) - sizeof (SimpleTypeBlob);
1837 blob->name = _g_ir_write_string (node->name, strings, data, offset2);
1838 blob->in = param->in;
1839 blob->out = param->out;
1840 blob->caller_allocates = param->caller_allocates;
1841 blob->allow_none = param->allow_none;
1842 blob->skip = param->skip;
1843 blob->optional = param->optional;
1844 blob->transfer_ownership = param->transfer;
1845 blob->transfer_container_ownership = param->shallow_transfer;
1846 blob->return_value = param->retval;
1847 blob->scope = param->scope;
1849 blob->closure = param->closure;
1850 blob->destroy = param->destroy;
1852 _g_ir_node_build_typelib ((GIrNode *)param->type, node, build, offset, offset2);
1856 case G_IR_NODE_STRUCT:
1858 StructBlob *blob = (StructBlob *)&data[*offset];
1859 GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
1862 blob->blob_type = BLOB_TYPE_STRUCT;
1863 blob->foreign = struct_->foreign;
1864 blob->deprecated = struct_->deprecated;
1865 blob->is_gtype_struct = struct_->is_gtype_struct;
1867 blob->name = _g_ir_write_string (node->name, strings, data, offset2);
1868 blob->alignment = struct_->alignment;
1869 blob->size = struct_->size;
1871 if (struct_->gtype_name)
1873 blob->unregistered = FALSE;
1874 blob->gtype_name = _g_ir_write_string (struct_->gtype_name, strings, data, offset2);
1875 blob->gtype_init = _g_ir_write_string (struct_->gtype_init, strings, data, offset2);
1879 blob->unregistered = TRUE;
1880 blob->gtype_name = 0;
1881 blob->gtype_init = 0;
1885 blob->n_methods = 0;
1887 *offset += sizeof (StructBlob);
1889 members = g_list_copy (struct_->members);
1891 _g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields,
1892 node, build, offset, offset2);
1894 _g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods,
1895 node, build, offset, offset2);
1897 _g_ir_node_check_unhandled_members (&members, node->type);
1899 g_assert (members == NULL);
1903 case G_IR_NODE_BOXED:
1905 StructBlob *blob = (StructBlob *)&data[*offset];
1906 GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
1909 blob->blob_type = BLOB_TYPE_BOXED;
1910 blob->deprecated = boxed->deprecated;
1911 blob->unregistered = FALSE;
1913 blob->name = _g_ir_write_string (node->name, strings, data, offset2);
1914 blob->gtype_name = _g_ir_write_string (boxed->gtype_name, strings, data, offset2);
1915 blob->gtype_init = _g_ir_write_string (boxed->gtype_init, strings, data, offset2);
1916 blob->alignment = boxed->alignment;
1917 blob->size = boxed->size;
1920 blob->n_methods = 0;
1922 *offset += sizeof (StructBlob);
1924 members = g_list_copy (boxed->members);
1926 _g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields,
1927 node, build, offset, offset2);
1929 _g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods,
1930 node, build, offset, offset2);
1932 _g_ir_node_check_unhandled_members (&members, node->type);
1934 g_assert (members == NULL);
1938 case G_IR_NODE_UNION:
1940 UnionBlob *blob = (UnionBlob *)&data[*offset];
1941 GIrNodeUnion *union_ = (GIrNodeUnion *)node;
1944 blob->blob_type = BLOB_TYPE_UNION;
1945 blob->deprecated = union_->deprecated;
1947 blob->name = _g_ir_write_string (node->name, strings, data, offset2);
1948 blob->alignment = union_->alignment;
1949 blob->size = union_->size;
1950 if (union_->gtype_name)
1952 blob->unregistered = FALSE;
1953 blob->gtype_name = _g_ir_write_string (union_->gtype_name, strings, data, offset2);
1954 blob->gtype_init = _g_ir_write_string (union_->gtype_init, strings, data, offset2);
1958 blob->unregistered = TRUE;
1959 blob->gtype_name = 0;
1960 blob->gtype_init = 0;
1964 blob->n_functions = 0;
1966 blob->discriminator_offset = union_->discriminator_offset;
1968 /* We don't support Union discriminators right now. */
1970 if (union_->discriminator_type)
1973 blob->discriminated = TRUE;
1974 _g_ir_node_build_typelib ((GIrNode *)union_->discriminator_type,
1975 build, offset, offset2);
1980 *offset += sizeof (UnionBlob);
1981 blob->discriminated = FALSE;
1982 blob->discriminator_type.offset = 0;
1984 members = g_list_copy (union_->members);
1986 _g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields,
1987 node, build, offset, offset2);
1989 _g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_functions,
1990 node, build, offset, offset2);
1992 _g_ir_node_check_unhandled_members (&members, node->type);
1994 g_assert (members == NULL);
1996 if (union_->discriminator_type)
1998 for (l = union_->discriminators; l; l = l->next)
2000 GIrNode *member = (GIrNode *)l->data;
2002 _g_ir_node_build_typelib (member, node, build, offset, offset2);
2008 case G_IR_NODE_ENUM:
2009 case G_IR_NODE_FLAGS:
2011 EnumBlob *blob = (EnumBlob *)&data[*offset];
2012 GIrNodeEnum *enum_ = (GIrNodeEnum *)node;
2014 *offset += sizeof (EnumBlob);
2016 if (node->type == G_IR_NODE_ENUM)
2017 blob->blob_type = BLOB_TYPE_ENUM;
2019 blob->blob_type = BLOB_TYPE_FLAGS;
2021 blob->deprecated = enum_->deprecated;
2023 blob->storage_type = enum_->storage_type;
2024 blob->name = _g_ir_write_string (node->name, strings, data, offset2);
2025 if (enum_->gtype_name)
2027 blob->unregistered = FALSE;
2028 blob->gtype_name = _g_ir_write_string (enum_->gtype_name, strings, data, offset2);
2029 blob->gtype_init = _g_ir_write_string (enum_->gtype_init, strings, data, offset2);
2033 blob->unregistered = TRUE;
2034 blob->gtype_name = 0;
2035 blob->gtype_init = 0;
2037 if (enum_->error_domain)
2038 blob->error_domain = _g_ir_write_string (enum_->error_domain, strings, data, offset2);
2040 blob->error_domain = 0;
2043 blob->n_methods = 0;
2045 for (l = enum_->values; l; l = l->next)
2047 GIrNode *value = (GIrNode *)l->data;
2050 _g_ir_node_build_typelib (value, node, build, offset, offset2);
2053 for (l = enum_->methods; l; l = l->next)
2055 GIrNode *method = (GIrNode *)l->data;
2058 _g_ir_node_build_typelib (method, node, build, offset, offset2);
2063 case G_IR_NODE_OBJECT:
2065 ObjectBlob *blob = (ObjectBlob *)&data[*offset];
2066 GIrNodeInterface *object = (GIrNodeInterface *)node;
2069 blob->blob_type = BLOB_TYPE_OBJECT;
2070 blob->abstract = object->abstract;
2071 blob->fundamental = object->fundamental;
2072 blob->deprecated = object->deprecated;
2074 blob->name = _g_ir_write_string (node->name, strings, data, offset2);
2075 blob->gtype_name = _g_ir_write_string (object->gtype_name, strings, data, offset2);
2076 blob->gtype_init = _g_ir_write_string (object->gtype_init, strings, data, offset2);
2077 if (object->ref_func)
2078 blob->ref_func = _g_ir_write_string (object->ref_func, strings, data, offset2);
2079 if (object->unref_func)
2080 blob->unref_func = _g_ir_write_string (object->unref_func, strings, data, offset2);
2081 if (object->set_value_func)
2082 blob->set_value_func = _g_ir_write_string (object->set_value_func, strings, data, offset2);
2083 if (object->get_value_func)
2084 blob->get_value_func = _g_ir_write_string (object->get_value_func, strings, data, offset2);
2086 blob->parent = find_entry (build, object->parent);
2089 if (object->glib_type_struct)
2090 blob->gtype_struct = find_entry (build, object->glib_type_struct);
2092 blob->gtype_struct = 0;
2094 blob->n_interfaces = 0;
2096 blob->n_properties = 0;
2097 blob->n_methods = 0;
2098 blob->n_signals = 0;
2100 blob->n_constants = 0;
2102 *offset += sizeof(ObjectBlob);
2103 for (l = object->interfaces; l; l = l->next)
2105 blob->n_interfaces++;
2106 *(guint16*)&data[*offset] = find_entry (build, (gchar *)l->data);
2110 members = g_list_copy (object->members);
2112 *offset = ALIGN_VALUE (*offset, 4);
2113 _g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields,
2114 node, build, offset, offset2);
2116 *offset = ALIGN_VALUE (*offset, 4);
2117 _g_ir_node_build_members (&members, G_IR_NODE_PROPERTY, &blob->n_properties,
2118 node, build, offset, offset2);
2120 *offset = ALIGN_VALUE (*offset, 4);
2121 _g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods,
2122 node, build, offset, offset2);
2124 *offset = ALIGN_VALUE (*offset, 4);
2125 _g_ir_node_build_members (&members, G_IR_NODE_SIGNAL, &blob->n_signals,
2126 node, build, offset, offset2);
2128 *offset = ALIGN_VALUE (*offset, 4);
2129 _g_ir_node_build_members (&members, G_IR_NODE_VFUNC, &blob->n_vfuncs,
2130 node, build, offset, offset2);
2132 *offset = ALIGN_VALUE (*offset, 4);
2133 _g_ir_node_build_members (&members, G_IR_NODE_CONSTANT, &blob->n_constants,
2134 node, build, offset, offset2);
2136 _g_ir_node_check_unhandled_members (&members, node->type);
2138 g_assert (members == NULL);
2142 case G_IR_NODE_INTERFACE:
2144 InterfaceBlob *blob = (InterfaceBlob *)&data[*offset];
2145 GIrNodeInterface *iface = (GIrNodeInterface *)node;
2148 blob->blob_type = BLOB_TYPE_INTERFACE;
2149 blob->deprecated = iface->deprecated;
2151 blob->name = _g_ir_write_string (node->name, strings, data, offset2);
2152 blob->gtype_name = _g_ir_write_string (iface->gtype_name, strings, data, offset2);
2153 blob->gtype_init = _g_ir_write_string (iface->gtype_init, strings, data, offset2);
2154 if (iface->glib_type_struct)
2155 blob->gtype_struct = find_entry (build, iface->glib_type_struct);
2157 blob->gtype_struct = 0;
2158 blob->n_prerequisites = 0;
2159 blob->n_properties = 0;
2160 blob->n_methods = 0;
2161 blob->n_signals = 0;
2163 blob->n_constants = 0;
2165 *offset += sizeof (InterfaceBlob);
2166 for (l = iface->prerequisites; l; l = l->next)
2168 blob->n_prerequisites++;
2169 *(guint16*)&data[*offset] = find_entry (build, (gchar *)l->data);
2173 members = g_list_copy (iface->members);
2175 *offset = ALIGN_VALUE (*offset, 4);
2176 _g_ir_node_build_members (&members, G_IR_NODE_PROPERTY, &blob->n_properties,
2177 node, build, offset, offset2);
2179 *offset = ALIGN_VALUE (*offset, 4);
2180 _g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods,
2181 node, build, offset, offset2);
2183 *offset = ALIGN_VALUE (*offset, 4);
2184 _g_ir_node_build_members (&members, G_IR_NODE_SIGNAL, &blob->n_signals,
2185 node, build, offset, offset2);
2187 *offset = ALIGN_VALUE (*offset, 4);
2188 _g_ir_node_build_members (&members, G_IR_NODE_VFUNC, &blob->n_vfuncs,
2189 node, build, offset, offset2);
2191 *offset = ALIGN_VALUE (*offset, 4);
2192 _g_ir_node_build_members (&members, G_IR_NODE_CONSTANT, &blob->n_constants,
2193 node, build, offset, offset2);
2195 _g_ir_node_check_unhandled_members (&members, node->type);
2197 g_assert (members == NULL);
2202 case G_IR_NODE_VALUE:
2204 GIrNodeValue *value = (GIrNodeValue *)node;
2205 ValueBlob *blob = (ValueBlob *)&data[*offset];
2206 *offset += sizeof (ValueBlob);
2208 blob->deprecated = value->deprecated;
2210 blob->unsigned_value = value->value >= 0 ? 1 : 0;
2211 blob->name = _g_ir_write_string (node->name, strings, data, offset2);
2212 blob->value = (gint32)value->value;
2216 case G_IR_NODE_CONSTANT:
2218 GIrNodeConstant *constant = (GIrNodeConstant *)node;
2219 ConstantBlob *blob = (ConstantBlob *)&data[*offset];
2222 pos = *offset + G_STRUCT_OFFSET (ConstantBlob, type);
2223 *offset += sizeof (ConstantBlob);
2225 blob->blob_type = BLOB_TYPE_CONSTANT;
2226 blob->deprecated = constant->deprecated;
2228 blob->name = _g_ir_write_string (node->name, strings, data, offset2);
2230 blob->offset = *offset2;
2231 switch (constant->type->tag)
2233 case GI_TYPE_TAG_BOOLEAN:
2235 *(gboolean*)&data[blob->offset] = parse_boolean_value (constant->value);
2237 case GI_TYPE_TAG_INT8:
2239 *(gint8*)&data[blob->offset] = (gint8) parse_int_value (constant->value);
2241 case GI_TYPE_TAG_UINT8:
2243 *(guint8*)&data[blob->offset] = (guint8) parse_uint_value (constant->value);
2245 case GI_TYPE_TAG_INT16:
2247 *(gint16*)&data[blob->offset] = (gint16) parse_int_value (constant->value);
2249 case GI_TYPE_TAG_UINT16:
2251 *(guint16*)&data[blob->offset] = (guint16) parse_uint_value (constant->value);
2253 case GI_TYPE_TAG_INT32:
2255 *(gint32*)&data[blob->offset] = (gint32) parse_int_value (constant->value);
2257 case GI_TYPE_TAG_UINT32:
2259 *(guint32*)&data[blob->offset] = (guint32) parse_uint_value (constant->value);
2261 case GI_TYPE_TAG_INT64:
2263 DO_ALIGNED_COPY(&data[blob->offset], parse_int_value (constant->value), gint64);
2265 case GI_TYPE_TAG_UINT64:
2267 DO_ALIGNED_COPY(&data[blob->offset], parse_uint_value (constant->value), guint64);
2269 case GI_TYPE_TAG_FLOAT:
2270 blob->size = sizeof (gfloat);
2271 DO_ALIGNED_COPY(&data[blob->offset], parse_float_value (constant->value), gfloat);
2273 case GI_TYPE_TAG_DOUBLE:
2274 blob->size = sizeof (gdouble);
2275 DO_ALIGNED_COPY(&data[blob->offset], parse_float_value (constant->value), gdouble);
2277 case GI_TYPE_TAG_UTF8:
2278 case GI_TYPE_TAG_FILENAME:
2279 blob->size = strlen (constant->value) + 1;
2280 memcpy (&data[blob->offset], constant->value, blob->size);
2283 *offset2 += ALIGN_VALUE (blob->size, 4);
2285 _g_ir_node_build_typelib ((GIrNode *)constant->type, node, build, &pos, offset2);
2289 g_assert_not_reached ();
2292 g_debug ("node %s%s%s%p type '%s', offset %d -> %d, offset2 %d -> %d",
2293 node->name ? "'" : "",
2294 node->name ? node->name : "",
2295 node->name ? "' " : "",
2296 node, _g_ir_node_type_to_string (node->type),
2297 old_offset, *offset, old_offset2, *offset2);
2299 if (*offset2 - old_offset2 + *offset - old_offset > _g_ir_node_get_full_size (node))
2300 g_error ("exceeding space reservation; offset: %d (prev %d) offset2: %d (prev %d) nodesize: %d",
2301 *offset, old_offset, *offset2, old_offset2, _g_ir_node_get_full_size (node));
2304 build->stack = g_list_delete_link (build->stack, build->stack);
2307 /* if str is already in the pool, return previous location, otherwise write str
2308 * to the typelib at offset, put it in the pool and update offset. If the
2309 * typelib is not large enough to hold the string, reallocate it.
2312 _g_ir_write_string (const gchar *str,
2313 GHashTable *strings,
2321 string_size += strlen (str);
2323 value = g_hash_table_lookup (strings, str);
2326 return GPOINTER_TO_UINT (value);
2328 unique_string_count += 1;
2329 unique_string_size += strlen (str);
2331 g_hash_table_insert (strings, (gpointer)str, GUINT_TO_POINTER (*offset));
2334 *offset = ALIGN_VALUE (start + strlen (str) + 1, 4);
2336 strcpy ((gchar*)&data[start], str);