Bug 560825 – Add size and alignment to typelib
authorOwen Taylor <otaylor@src.gnome.org>
Sun, 16 Nov 2008 21:15:54 +0000 (21:15 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Sun, 16 Nov 2008 21:15:54 +0000 (21:15 +0000)
Include the size and alignment of structures and unions in the typelib,
and add getter methods to retrieve them from GIStructInfo/GIUnionInfo.

* docs/typelib-format.txt girepository/gtypelib.h girepository/girnode.c
girepository/girmodule.c girepository/gtypelib.c: Add size and alignment
to StructBlob and UnionBlob.

* girepository/ginfo.c girepository/girepository.h:
Add g_[struct|union]_get[size|alignment]().

* test/offsets/gen-gitestoffsets: Test overall structure size and alignment.

svn path=/trunk/; revision=930

ChangeLog
docs/typelib-format.txt
girepository/ginfo.c
girepository/girepository.h
girepository/girmodule.c
girepository/girnode.c
girepository/gtypelib.c
girepository/gtypelib.h
tests/offsets/gen-gitestoffsets

index ff663e8..7bb958f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2008-11-16  Owen Taylor  <otaylor@redhat.com>
+
+       Bug 560825 – Add size and alignment to typelib
+
+       Include the size and alignment of structures and unions in the typelib,
+       and add getter methods to retrieve them from GIStructInfo/GIUnionInfo.
+
+       * docs/typelib-format.txt girepository/gtypelib.h girepository/girnode.c
+       girepository/girmodule.c girepository/gtypelib.c: Add size and alignment
+       to StructBlob and UnionBlob.
+
+       * girepository/ginfo.c girepository/girepository.h:
+       Add g_[struct|union]_get[size|alignment]().
+
+       * test/offsets/gen-gitestoffsets: Test overall structure size and alignment.
+
 2008-11-16  Owen Taylor  <otaylor@redhat.com>
 
        Bug 552371 – implement struct field get/set
index 80b29c9..fa76393 100644 (file)
@@ -812,11 +812,14 @@ struct StructBlob
   guint16      blob_type; /* 3: struct, 4: boxed */
   guint        deprecated   : 1;
   guint        unregistered : 1;
-  guint        reserved     :14;
+  guint        alignment    : 6;
+  guint        reserved     : 8;
   guint32      name;
 
   GTypeBlob    gtype;
 
+  guint32      size;
+
   guint16      n_fields;
   guint16      n_functions;
 
@@ -827,6 +830,11 @@ struct StructBlob
 unregistered: 
           If this is set, the type is not registered with GType.
 
+alignment:
+         The byte boundary that the struct is aligned to in memory
+
+size:    The size of the struct in bytes.
+
 gtype:    For types which are registered with GType, contains the 
           information about the GType. Otherwise unused.
 
@@ -1045,11 +1053,14 @@ struct UnionBlob
   guint        deprecated    : 1;
   guint        unregistered  : 1;
   guint        discriminated : 1;
-  guint        reserved      :13;
+  guint        alignment     : 6;
+  guint        reserved      : 7;
   guint32      name;
 
   GTypeBlob    gtype;
 
+  guint32      size;
+
   guint16      n_fields;
   guint16      n_functions;
 
@@ -1067,6 +1078,11 @@ unregistered:
 discriminated: 
           Is set if the union is discriminated
 
+alignment:
+         The byte boundary that the union is aligned to in memory
+
+size:    The size of the union in bytes.
+
 gtype:    For types which are registered with GType, contains the 
           information about the GType. Otherwise unused.
 
index 3de0cf5..a3813d6 100644 (file)
@@ -1112,6 +1112,24 @@ g_struct_info_find_method (GIStructInfo *info,
   return find_method (base, offset, blob->n_methods, name);
 }
 
+gsize
+g_struct_info_get_size (GIStructInfo *info)
+{
+  GIBaseInfo *base = (GIBaseInfo *)info;
+  StructBlob *blob = (StructBlob *)&base->typelib->data[base->offset];
+
+  return blob->size;
+}
+
+gsize
+g_struct_info_get_alignment (GIStructInfo *info)
+{
+  GIBaseInfo *base = (GIBaseInfo *)info;
+  StructBlob *blob = (StructBlob *)&base->typelib->data[base->offset];
+
+  return blob->alignment;
+}
+
 gint
 g_enum_info_get_n_values (GIEnumInfo *info)
 {
@@ -1887,3 +1905,20 @@ g_union_info_find_method (GIUnionInfo *info,
   return find_method (base, offset, blob->n_functions, name);
 }
 
+gsize
+g_union_info_get_size (GIUnionInfo *info)
+{
+  GIBaseInfo *base = (GIBaseInfo *)info;
+  UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset];
+
+  return blob->size;
+}
+
+gsize
+g_union_info_get_alignment (GIUnionInfo *info)
+{
+  GIBaseInfo *base = (GIBaseInfo *)info;
+  UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset];
+
+  return blob->alignment;
+}
index fc5768c..a671cb5 100644 (file)
@@ -377,6 +377,8 @@ GIConstantInfo *       g_union_info_get_discriminator      (GIUnionInfo *info,
                                                            gint         n);
 GIFunctionInfo *       g_union_info_find_method    (GIUnionInfo *info,
                                                     const gchar *name);
+gsize                  g_union_info_get_size       (GIUnionInfo *info);
+gsize                  g_union_info_get_alignment  (GIUnionInfo *info);
 
 
 /* GIStructInfo */
@@ -388,6 +390,8 @@ GIFunctionInfo *       g_struct_info_get_method    (GIStructInfo *info,
                                                    gint         n);
 GIFunctionInfo *       g_struct_info_find_method   (GIStructInfo *info,
                                                    const gchar *name);
+gsize                  g_struct_info_get_size      (GIStructInfo *info);
+gsize                  g_struct_info_get_alignment (GIStructInfo *info);
 
 /* GIRegisteredTypeInfo */
 
index 1b7c304..1b26f3d 100644 (file)
@@ -222,10 +222,10 @@ g_ir_module_build_typelib (GIrModule  *module,
   header->annotation_blob_size = 12;
   header->signature_blob_size = 8;
   header->enum_blob_size = 20;
-  header->struct_blob_size = 20;
+  header->struct_blob_size = 24;
   header->object_blob_size = 32;
   header->interface_blob_size = 28;
-  header->union_blob_size = 28;
+  header->union_blob_size = 32;
 
   /* fill in directory and content */
   entry = (DirEntry *)&data[header->directory];
index 8851df0..9f809d4 100644 (file)
@@ -469,7 +469,7 @@ g_ir_node_get_size (GIrNode *node)
       {
        GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
 
-       size = 20;
+       size = 24;
        for (l = struct_->members; l; l = l->next)
          size += g_ir_node_get_size ((GIrNode *)l->data);
       }
@@ -479,7 +479,7 @@ g_ir_node_get_size (GIrNode *node)
       {
        GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
 
-       size = 20;
+       size = 24;
        for (l = boxed->members; l; l = l->next)
          size += g_ir_node_get_size ((GIrNode *)l->data);
       }
@@ -517,7 +517,7 @@ g_ir_node_get_size (GIrNode *node)
       {
        GIrNodeUnion *union_ = (GIrNodeUnion *)node;
 
-       size = 28;
+       size = 32;
        for (l = union_->members; l; l = l->next)
          size += g_ir_node_get_size ((GIrNode *)l->data);
        for (l = union_->discriminators; l; l = l->next)
@@ -707,7 +707,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent,
       {
        GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
 
-       size = 20;
+       size = 24;
        size += ALIGN_VALUE (strlen (node->name) + 1, 4);
        if (struct_->gtype_name)
          size += ALIGN_VALUE (strlen (struct_->gtype_name) + 1, 4);
@@ -722,7 +722,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent,
       {
        GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
 
-       size = 20;
+       size = 24;
        size += ALIGN_VALUE (strlen (node->name) + 1, 4);
        if (boxed->gtype_name)
          {
@@ -814,7 +814,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent,
       {
        GIrNodeUnion *union_ = (GIrNodeUnion *)node;
 
-       size = 28;
+       size = 32;
        size += ALIGN_VALUE (strlen (node->name) + 1, 4);
        if (union_->gtype_name)
          size += ALIGN_VALUE (strlen (union_->gtype_name) + 1, 4);
@@ -1789,6 +1789,9 @@ g_ir_node_build_typelib (GIrNode    *node,
        blob->deprecated = struct_->deprecated;
        blob->reserved = 0;
        blob->name = write_string (node->name, strings, data, offset2);
+       blob->alignment = struct_->alignment;
+       blob->size = struct_->size;
+
        if (struct_->gtype_name)
          {
            blob->unregistered = FALSE;
@@ -1805,7 +1808,7 @@ g_ir_node_build_typelib (GIrNode    *node,
        blob->n_fields = 0;
        blob->n_methods = 0;
 
-       *offset += 20
+       *offset += 24
 
        members = g_list_copy (struct_->members);
 
@@ -1836,11 +1839,13 @@ g_ir_node_build_typelib (GIrNode    *node,
        blob->name = write_string (node->name, strings, data, offset2);
        blob->gtype_name = write_string (boxed->gtype_name, strings, data, offset2);
        blob->gtype_init = write_string (boxed->gtype_init, strings, data, offset2);
+       blob->alignment = boxed->alignment;
+       blob->size = boxed->size;
 
        blob->n_fields = 0;
        blob->n_methods = 0;
 
-       *offset += 20
+       *offset += 24
 
        members = g_list_copy (boxed->members);
 
@@ -1868,6 +1873,8 @@ g_ir_node_build_typelib (GIrNode    *node,
        blob->deprecated = union_->deprecated;
        blob->reserved = 0;
        blob->name = write_string (node->name, strings, data, offset2);
+       blob->alignment = union_->alignment;
+       blob->size = union_->size;
        if (union_->gtype_name)
          {
            blob->unregistered = FALSE;
@@ -1888,7 +1895,7 @@ g_ir_node_build_typelib (GIrNode    *node,
 
        if (union_->discriminator_type)
          {
-           *offset += 24;
+           *offset += 28;
            blob->discriminated = TRUE;
            g_ir_node_build_typelib ((GIrNode *)union_->discriminator_type, 
                                     module, modules, strings, types,
@@ -1896,7 +1903,7 @@ g_ir_node_build_typelib (GIrNode    *node,
          }
        else 
          {
-           *offset += 28;
+           *offset += 32;
            blob->discriminated = FALSE;
            blob->discriminator_type.offset = 0;
          }
index be470a4..8472195 100644 (file)
@@ -168,7 +168,7 @@ g_typelib_check_sanity (void)
   CHECK_SIZE (ValueBlob, 12);
   CHECK_SIZE (FieldBlob, 12);
   CHECK_SIZE (RegisteredTypeBlob, 16);
-  CHECK_SIZE (StructBlob, 20);
+  CHECK_SIZE (StructBlob, 24);
   CHECK_SIZE (EnumBlob, 20);
   CHECK_SIZE (PropertyBlob, 12);
   CHECK_SIZE (SignalBlob, 12);
@@ -177,7 +177,7 @@ g_typelib_check_sanity (void)
   CHECK_SIZE (InterfaceBlob, 28);
   CHECK_SIZE (ConstantBlob, 20);
   CHECK_SIZE (AnnotationBlob, 12);
-  CHECK_SIZE (UnionBlob, 28);
+  CHECK_SIZE (UnionBlob, 32);
 #undef CHECK_SIZE
 
   g_assert (size_check_ok);
@@ -320,10 +320,10 @@ validate_header (ValidateContext  *ctx,
       header->annotation_blob_size != 12 ||
       header->signature_blob_size != 8 ||
       header->enum_blob_size != 20 ||
-      header->struct_blob_size != 20 ||
+      header->struct_blob_size != 24 ||
       header->object_blob_size != 32 ||
       header->interface_blob_size != 28 ||
-      header->union_blob_size != 28)
+      header->union_blob_size != 32)
     {
       g_set_error (error,
                   G_TYPELIB_ERROR,
index 458d429..1b2b893 100644 (file)
@@ -295,13 +295,16 @@ typedef struct
 
   guint16   deprecated   : 1;
   guint16   unregistered : 1;
-  guint16   reserved     :14;
+  guint16   alignment    : 6;
+  guint16   reserved     : 8;
 
   guint32   name;
 
   guint32   gtype_name;
   guint32   gtype_init;
 
+  guint32   size;
+
   guint16   n_fields;
   guint16   n_methods;
 
@@ -318,12 +321,15 @@ typedef struct
   guint16      deprecated    : 1;
   guint16      unregistered  : 1;
   guint16      discriminated : 1;
-  guint16      reserved      :13;
+  guint16      alignment     : 6;
+  guint16      reserved      : 7;
   guint32      name;
 
   guint32      gtype_name;
   guint32      gtype_init;
 
+  guint32      size;
+
   guint16      n_fields;
   guint16      n_functions;
 
index 27fff23..ce4a977 100755 (executable)
@@ -141,10 +141,17 @@ for symbol in symbols:
     fields = symbol_fields[symbol]
 
     output({'symbol' : symbol}, r'''
+|typedef struct {
+|   char dummy;
+|   %(symbol)s struct_;
+|} Align%(symbol)s;
+|
 |static void
 |compiled_%(symbol)s (FILE *outfile)
 |{
-|  fprintf (outfile, "%(symbol)s:\n");
+|  fprintf (outfile, "%(symbol)s: size=%%" G_GSIZE_FORMAT ", alignment=%%ld\n",
+|           sizeof(%(symbol)s),
+|           G_STRUCT_OFFSET(Align%(symbol)s, struct_));
 |
            ''')
 
@@ -174,7 +181,9 @@ for symbol in symbols:
 |  if (!struct_info)
 |     g_error ("Can't find GIStructInfo for '%(symbol)s'");
 |
-|  fprintf (outfile, "%(symbol)s:\n");
+|  fprintf (outfile, "%(symbol)s: size=%%" G_GSIZE_FORMAT ", alignment=%%" G_GSIZE_FORMAT "\n",
+|           g_struct_info_get_size (struct_info),
+|           g_struct_info_get_alignment (struct_info));
 |
            ''')
     for field in fields: