+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
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;
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.
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;
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.
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)
{
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;
+}
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 */
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 */
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];
{
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);
}
{
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);
}
{
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)
{
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);
{
GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
- size = 20;
+ size = 24;
size += ALIGN_VALUE (strlen (node->name) + 1, 4);
if (boxed->gtype_name)
{
{
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);
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;
blob->n_fields = 0;
blob->n_methods = 0;
- *offset += 20;
+ *offset += 24;
members = g_list_copy (struct_->members);
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);
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;
if (union_->discriminator_type)
{
- *offset += 24;
+ *offset += 28;
blob->discriminated = TRUE;
g_ir_node_build_typelib ((GIrNode *)union_->discriminator_type,
module, modules, strings, types,
}
else
{
- *offset += 28;
+ *offset += 32;
blob->discriminated = FALSE;
blob->discriminator_type.offset = 0;
}
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);
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);
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,
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;
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;
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_));
|
''')
| 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: