summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@src.gnome.org>2008-11-16 21:15:54 +0000
committerOwen Taylor <otaylor@src.gnome.org>2008-11-16 21:15:54 +0000
commitc68cef1ba60d2a7563cf8d191aa8c10453467ed7 (patch)
treece1a0be4a4ff0044870989ebe03d430bf59998a7
parenta5d45df66370320ec2ae493383ba1388157182da (diff)
downloadgobject-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--ChangeLog16
-rw-r--r--docs/typelib-format.txt20
-rw-r--r--girepository/ginfo.c35
-rw-r--r--girepository/girepository.h4
-rw-r--r--girepository/girmodule.c4
-rw-r--r--girepository/girnode.c27
-rw-r--r--girepository/gtypelib.c8
-rw-r--r--girepository/gtypelib.h10
-rwxr-xr-xtests/offsets/gen-gitestoffsets13
9 files changed, 115 insertions, 22 deletions
diff --git a/ChangeLog b/ChangeLog
index ff663e8f..7bb958f6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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: