diff options
author | Owen Taylor <otaylor@src.gnome.org> | 2008-11-16 21:15:54 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 2008-11-16 21:15:54 +0000 |
commit | c68cef1ba60d2a7563cf8d191aa8c10453467ed7 (patch) | |
tree | ce1a0be4a4ff0044870989ebe03d430bf59998a7 | |
parent | a5d45df66370320ec2ae493383ba1388157182da (diff) | |
download | gobject-introspection-c68cef1ba60d2a7563cf8d191aa8c10453467ed7.tar.gz |
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.
svn path=/trunk/; revision=930
-rw-r--r-- | ChangeLog | 16 | ||||
-rw-r--r-- | docs/typelib-format.txt | 20 | ||||
-rw-r--r-- | girepository/ginfo.c | 35 | ||||
-rw-r--r-- | girepository/girepository.h | 4 | ||||
-rw-r--r-- | girepository/girmodule.c | 4 | ||||
-rw-r--r-- | girepository/girnode.c | 27 | ||||
-rw-r--r-- | girepository/gtypelib.c | 8 | ||||
-rw-r--r-- | girepository/gtypelib.h | 10 | ||||
-rwxr-xr-x | tests/offsets/gen-gitestoffsets | 13 |
9 files changed, 115 insertions, 22 deletions
@@ -1,5 +1,21 @@ 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 * girepository/gfield.c girepository/girepository.h: Add diff --git a/docs/typelib-format.txt b/docs/typelib-format.txt index 80b29c9b..fa76393e 100644 --- a/docs/typelib-format.txt +++ b/docs/typelib-format.txt @@ -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. diff --git a/girepository/ginfo.c b/girepository/ginfo.c index 3de0cf59..a3813d64 100644 --- a/girepository/ginfo.c +++ b/girepository/ginfo.c @@ -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; +} diff --git a/girepository/girepository.h b/girepository/girepository.h index fc5768c5..a671cb5c 100644 --- a/girepository/girepository.h +++ b/girepository/girepository.h @@ -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 */ diff --git a/girepository/girmodule.c b/girepository/girmodule.c index 1b7c3048..1b26f3de 100644 --- a/girepository/girmodule.c +++ b/girepository/girmodule.c @@ -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]; diff --git a/girepository/girnode.c b/girepository/girnode.c index 8851df06..9f809d4b 100644 --- a/girepository/girnode.c +++ b/girepository/girnode.c @@ -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; } diff --git a/girepository/gtypelib.c b/girepository/gtypelib.c index be470a4b..8472195f 100644 --- a/girepository/gtypelib.c +++ b/girepository/gtypelib.c @@ -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, diff --git a/girepository/gtypelib.h b/girepository/gtypelib.h index 458d429d..1b2b8934 100644 --- a/girepository/gtypelib.h +++ b/girepository/gtypelib.h @@ -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; diff --git a/tests/offsets/gen-gitestoffsets b/tests/offsets/gen-gitestoffsets index 27fff23b..ce4a977c 100755 --- a/tests/offsets/gen-gitestoffsets +++ b/tests/offsets/gen-gitestoffsets @@ -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: |