mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-02 17:26:17 +01:00
giroffsets: Uniformly handle alignments as size_t
Do this by tracking the state of the size/alignment calculations separately, rather than bunging it into the `alignment` field using magic values. Signed-off-by: Philip Withnall <pwithnall@gnome.org> Helps: #3155
This commit is contained in:
parent
9fcec66115
commit
515b3fc1dc
@ -70,6 +70,27 @@ typedef enum
|
|||||||
GI_IR_NODE_XREF = 19
|
GI_IR_NODE_XREF = 19
|
||||||
} GIIrNodeTypeId;
|
} GIIrNodeTypeId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GIIrOffsetsState:
|
||||||
|
* @GI_IR_OFFSETS_UNKNOWN: offsets have not been calculated yet
|
||||||
|
* @GI_IR_OFFSETS_COMPUTED: offsets have been successfully calculated
|
||||||
|
* @GI_IR_OFFSETS_FAILED: calculating the offsets failed
|
||||||
|
* @GI_IR_OFFSETS_IN_PROGRESS: offsets are currently being calculated (used to
|
||||||
|
* detect type recursion)
|
||||||
|
*
|
||||||
|
* State tracking for calculating size and alignment of
|
||||||
|
* [type@GIRepository.IrNode]s.
|
||||||
|
*
|
||||||
|
* Since: 2.80
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GI_IR_OFFSETS_UNKNOWN,
|
||||||
|
GI_IR_OFFSETS_COMPUTED,
|
||||||
|
GI_IR_OFFSETS_FAILED,
|
||||||
|
GI_IR_OFFSETS_IN_PROGRESS,
|
||||||
|
} GIIrOffsetsState;
|
||||||
|
|
||||||
struct _GIIrNode
|
struct _GIIrNode
|
||||||
{
|
{
|
||||||
GIIrNodeTypeId type;
|
GIIrNodeTypeId type;
|
||||||
@ -261,8 +282,9 @@ struct _GIIrNodeInterface
|
|||||||
GList *interfaces;
|
GList *interfaces;
|
||||||
GList *prerequisites;
|
GList *prerequisites;
|
||||||
|
|
||||||
gssize alignment;
|
size_t alignment;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
GIIrOffsetsState offsets_state;
|
||||||
|
|
||||||
GList *members;
|
GList *members;
|
||||||
};
|
};
|
||||||
@ -311,8 +333,9 @@ struct _GIIrNodeBoxed
|
|||||||
char *gtype_name;
|
char *gtype_name;
|
||||||
char *gtype_init;
|
char *gtype_init;
|
||||||
|
|
||||||
gssize alignment;
|
size_t alignment;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
GIIrOffsetsState offsets_state;
|
||||||
|
|
||||||
GList *members;
|
GList *members;
|
||||||
};
|
};
|
||||||
@ -334,8 +357,9 @@ struct _GIIrNodeStruct
|
|||||||
char *copy_func;
|
char *copy_func;
|
||||||
char *free_func;
|
char *free_func;
|
||||||
|
|
||||||
gssize alignment;
|
size_t alignment;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
GIIrOffsetsState offsets_state;
|
||||||
|
|
||||||
GList *members;
|
GList *members;
|
||||||
};
|
};
|
||||||
@ -355,8 +379,9 @@ struct _GIIrNodeUnion
|
|||||||
char *copy_func;
|
char *copy_func;
|
||||||
char *free_func;
|
char *free_func;
|
||||||
|
|
||||||
gssize alignment;
|
size_t alignment;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
GIIrOffsetsState offsets_state;
|
||||||
|
|
||||||
int discriminator_offset;
|
int discriminator_offset;
|
||||||
GIIrNodeType *discriminator_type;
|
GIIrNodeType *discriminator_type;
|
||||||
|
@ -150,7 +150,7 @@ compute_enum_storage_type (GIIrNodeEnum *enum_node)
|
|||||||
static gboolean
|
static gboolean
|
||||||
get_enum_size_alignment (GIIrNodeEnum *enum_node,
|
get_enum_size_alignment (GIIrNodeEnum *enum_node,
|
||||||
size_t *size,
|
size_t *size,
|
||||||
gssize *alignment)
|
size_t *alignment)
|
||||||
{
|
{
|
||||||
ffi_type *type_ffi;
|
ffi_type *type_ffi;
|
||||||
|
|
||||||
@ -189,7 +189,7 @@ static gboolean
|
|||||||
get_interface_size_alignment (GIIrTypelibBuild *build,
|
get_interface_size_alignment (GIIrTypelibBuild *build,
|
||||||
GIIrNodeType *type,
|
GIIrNodeType *type,
|
||||||
size_t *size,
|
size_t *size,
|
||||||
gssize *alignment,
|
size_t *alignment,
|
||||||
const char *who)
|
const char *who)
|
||||||
{
|
{
|
||||||
GIIrNode *iface;
|
GIIrNode *iface;
|
||||||
@ -198,8 +198,8 @@ get_interface_size_alignment (GIIrTypelibBuild *build,
|
|||||||
if (!iface)
|
if (!iface)
|
||||||
{
|
{
|
||||||
gi_ir_module_fatal (build, 0, "Can't resolve type '%s' for %s", type->giinterface, who);
|
gi_ir_module_fatal (build, 0, "Can't resolve type '%s' for %s", type->giinterface, who);
|
||||||
*size = -1;
|
*size = 0;
|
||||||
*alignment = -1;
|
*alignment = 0;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,9 +253,9 @@ get_interface_size_alignment (GIIrTypelibBuild *build,
|
|||||||
g_warning ("%s has is not a pointer and is of type %s",
|
g_warning ("%s has is not a pointer and is of type %s",
|
||||||
who,
|
who,
|
||||||
gi_ir_node_type_to_string (iface->type));
|
gi_ir_node_type_to_string (iface->type));
|
||||||
*size = -1;
|
*size = 0;
|
||||||
*alignment = -1;
|
*alignment = 0;
|
||||||
break;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,7 +266,7 @@ static gboolean
|
|||||||
get_type_size_alignment (GIIrTypelibBuild *build,
|
get_type_size_alignment (GIIrTypelibBuild *build,
|
||||||
GIIrNodeType *type,
|
GIIrNodeType *type,
|
||||||
size_t *size,
|
size_t *size,
|
||||||
gssize *alignment,
|
size_t *alignment,
|
||||||
const char *who)
|
const char *who)
|
||||||
{
|
{
|
||||||
ffi_type *type_ffi;
|
ffi_type *type_ffi;
|
||||||
@ -278,14 +278,14 @@ get_type_size_alignment (GIIrTypelibBuild *build,
|
|||||||
else if (type->tag == GI_TYPE_TAG_ARRAY)
|
else if (type->tag == GI_TYPE_TAG_ARRAY)
|
||||||
{
|
{
|
||||||
size_t elt_size;
|
size_t elt_size;
|
||||||
gssize elt_alignment;
|
size_t elt_alignment;
|
||||||
|
|
||||||
if (!type->has_size
|
if (!type->has_size
|
||||||
|| !get_type_size_alignment(build, type->parameter_type1,
|
|| !get_type_size_alignment(build, type->parameter_type1,
|
||||||
&elt_size, &elt_alignment, who))
|
&elt_size, &elt_alignment, who))
|
||||||
{
|
{
|
||||||
*size = -1;
|
*size = 0;
|
||||||
*alignment = -1;
|
*alignment = 0;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,8 +307,8 @@ get_type_size_alignment (GIIrTypelibBuild *build,
|
|||||||
if (type_ffi == &ffi_type_void)
|
if (type_ffi == &ffi_type_void)
|
||||||
{
|
{
|
||||||
g_warning ("%s has void type", who);
|
g_warning ("%s has void type", who);
|
||||||
*size = -1;
|
*size = 0;
|
||||||
*alignment = -1;
|
*alignment = 0;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
else if (type_ffi == &ffi_type_pointer)
|
else if (type_ffi == &ffi_type_pointer)
|
||||||
@ -316,8 +316,8 @@ get_type_size_alignment (GIIrTypelibBuild *build,
|
|||||||
g_warning ("%s has is not a pointer and is of type %s",
|
g_warning ("%s has is not a pointer and is of type %s",
|
||||||
who,
|
who,
|
||||||
gi_type_tag_to_string (type->tag));
|
gi_type_tag_to_string (type->tag));
|
||||||
*size = -1;
|
*size = 0;
|
||||||
*alignment = -1;
|
*alignment = 0;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -335,7 +335,7 @@ get_field_size_alignment (GIIrTypelibBuild *build,
|
|||||||
GIIrNodeField *field,
|
GIIrNodeField *field,
|
||||||
GIIrNode *parent_node,
|
GIIrNode *parent_node,
|
||||||
size_t *size,
|
size_t *size,
|
||||||
gssize *alignment)
|
size_t *alignment)
|
||||||
{
|
{
|
||||||
GIIrModule *module = build->module;
|
GIIrModule *module = build->module;
|
||||||
char *who;
|
char *who;
|
||||||
@ -363,14 +363,15 @@ compute_struct_field_offsets (GIIrTypelibBuild *build,
|
|||||||
GIIrNode *node,
|
GIIrNode *node,
|
||||||
GList *members,
|
GList *members,
|
||||||
size_t *size_out,
|
size_t *size_out,
|
||||||
gssize *alignment_out)
|
size_t *alignment_out,
|
||||||
|
GIIrOffsetsState *offsets_state_out)
|
||||||
{
|
{
|
||||||
int size = 0;
|
size_t size = 0;
|
||||||
int alignment = 1;
|
size_t alignment = 1;
|
||||||
GList *l;
|
GList *l;
|
||||||
gboolean have_error = FALSE;
|
gboolean have_error = FALSE;
|
||||||
|
|
||||||
*alignment_out = -2; /* mark to detect recursion */
|
*offsets_state_out = GI_IR_OFFSETS_IN_PROGRESS; /* mark to detect recursion */
|
||||||
|
|
||||||
for (l = members; l; l = l->next)
|
for (l = members; l; l = l->next)
|
||||||
{
|
{
|
||||||
@ -383,7 +384,7 @@ compute_struct_field_offsets (GIIrTypelibBuild *build,
|
|||||||
if (!have_error)
|
if (!have_error)
|
||||||
{
|
{
|
||||||
size_t member_size;
|
size_t member_size;
|
||||||
gssize member_alignment;
|
size_t member_alignment;
|
||||||
|
|
||||||
if (get_field_size_alignment (build, field, node,
|
if (get_field_size_alignment (build, field, node,
|
||||||
&member_size, &member_alignment))
|
&member_size, &member_alignment))
|
||||||
@ -415,11 +416,13 @@ compute_struct_field_offsets (GIIrTypelibBuild *build,
|
|||||||
{
|
{
|
||||||
*size_out = size;
|
*size_out = size;
|
||||||
*alignment_out = alignment;
|
*alignment_out = alignment;
|
||||||
|
*offsets_state_out = GI_IR_OFFSETS_COMPUTED;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*size_out = -1;
|
*size_out = 0;
|
||||||
*alignment_out = -1;
|
*alignment_out = 0;
|
||||||
|
*offsets_state_out = GI_IR_OFFSETS_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return !have_error;
|
return !have_error;
|
||||||
@ -430,14 +433,15 @@ compute_union_field_offsets (GIIrTypelibBuild *build,
|
|||||||
GIIrNode *node,
|
GIIrNode *node,
|
||||||
GList *members,
|
GList *members,
|
||||||
size_t *size_out,
|
size_t *size_out,
|
||||||
gssize *alignment_out)
|
size_t *alignment_out,
|
||||||
|
GIIrOffsetsState *offsets_state_out)
|
||||||
{
|
{
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
int alignment = 1;
|
size_t alignment = 1;
|
||||||
GList *l;
|
GList *l;
|
||||||
gboolean have_error = FALSE;
|
gboolean have_error = FALSE;
|
||||||
|
|
||||||
*alignment_out = -2; /* mark to detect recursion */
|
*offsets_state_out = GI_IR_OFFSETS_IN_PROGRESS; /* mark to detect recursion */
|
||||||
|
|
||||||
for (l = members; l; l = l->next)
|
for (l = members; l; l = l->next)
|
||||||
{
|
{
|
||||||
@ -450,7 +454,7 @@ compute_union_field_offsets (GIIrTypelibBuild *build,
|
|||||||
if (!have_error)
|
if (!have_error)
|
||||||
{
|
{
|
||||||
size_t member_size;
|
size_t member_size;
|
||||||
gssize member_alignment;
|
size_t member_alignment;
|
||||||
|
|
||||||
if (get_field_size_alignment (build,field, node,
|
if (get_field_size_alignment (build,field, node,
|
||||||
&member_size, &member_alignment))
|
&member_size, &member_alignment))
|
||||||
@ -471,11 +475,13 @@ compute_union_field_offsets (GIIrTypelibBuild *build,
|
|||||||
{
|
{
|
||||||
*size_out = size;
|
*size_out = size;
|
||||||
*alignment_out = alignment;
|
*alignment_out = alignment;
|
||||||
|
*offsets_state_out = GI_IR_OFFSETS_COMPUTED;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*size_out = -1;
|
*size_out = 0;
|
||||||
*alignment_out = -1;
|
*alignment_out = 0;
|
||||||
|
*offsets_state_out = GI_IR_OFFSETS_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return !have_error;
|
return !have_error;
|
||||||
@ -484,22 +490,17 @@ compute_union_field_offsets (GIIrTypelibBuild *build,
|
|||||||
static gboolean
|
static gboolean
|
||||||
check_needs_computation (GIIrTypelibBuild *build,
|
check_needs_computation (GIIrTypelibBuild *build,
|
||||||
GIIrNode *node,
|
GIIrNode *node,
|
||||||
int alignment)
|
GIIrOffsetsState offsets_state)
|
||||||
{
|
{
|
||||||
GIIrModule *module = build->module;
|
GIIrModule *module = build->module;
|
||||||
/*
|
|
||||||
* 0: Not yet computed
|
if (offsets_state == GI_IR_OFFSETS_IN_PROGRESS)
|
||||||
* >0: Previously succeeded
|
|
||||||
* -1: Previously failed
|
|
||||||
* -2: In progress
|
|
||||||
*/
|
|
||||||
if (alignment == -2)
|
|
||||||
{
|
{
|
||||||
g_warning ("Recursion encountered when computing the size of %s.%s",
|
g_warning ("Recursion encountered when computing the size of %s.%s",
|
||||||
module->name, node->name);
|
module->name, node->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return alignment == 0;
|
return offsets_state == GI_IR_OFFSETS_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -532,22 +533,22 @@ gi_ir_node_compute_offsets (GIIrTypelibBuild *build,
|
|||||||
{
|
{
|
||||||
GIIrNodeBoxed *boxed = (GIIrNodeBoxed *)node;
|
GIIrNodeBoxed *boxed = (GIIrNodeBoxed *)node;
|
||||||
|
|
||||||
if (!check_needs_computation (build, node, boxed->alignment))
|
if (!check_needs_computation (build, node, boxed->offsets_state))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
compute_struct_field_offsets (build, node, boxed->members,
|
compute_struct_field_offsets (build, node, boxed->members,
|
||||||
&boxed->size, &boxed->alignment);
|
&boxed->size, &boxed->alignment, &boxed->offsets_state);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GI_IR_NODE_STRUCT:
|
case GI_IR_NODE_STRUCT:
|
||||||
{
|
{
|
||||||
GIIrNodeStruct *struct_ = (GIIrNodeStruct *)node;
|
GIIrNodeStruct *struct_ = (GIIrNodeStruct *)node;
|
||||||
|
|
||||||
if (!check_needs_computation (build, node, struct_->alignment))
|
if (!check_needs_computation (build, node, struct_->offsets_state))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
compute_struct_field_offsets (build, node, struct_->members,
|
compute_struct_field_offsets (build, node, struct_->members,
|
||||||
&struct_->size, &struct_->alignment);
|
&struct_->size, &struct_->alignment, &struct_->offsets_state);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GI_IR_NODE_OBJECT:
|
case GI_IR_NODE_OBJECT:
|
||||||
@ -555,22 +556,22 @@ gi_ir_node_compute_offsets (GIIrTypelibBuild *build,
|
|||||||
{
|
{
|
||||||
GIIrNodeInterface *iface = (GIIrNodeInterface *)node;
|
GIIrNodeInterface *iface = (GIIrNodeInterface *)node;
|
||||||
|
|
||||||
if (!check_needs_computation (build, node, iface->alignment))
|
if (!check_needs_computation (build, node, iface->offsets_state))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
compute_struct_field_offsets (build, node, iface->members,
|
compute_struct_field_offsets (build, node, iface->members,
|
||||||
&iface->size, &iface->alignment);
|
&iface->size, &iface->alignment, &iface->offsets_state);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GI_IR_NODE_UNION:
|
case GI_IR_NODE_UNION:
|
||||||
{
|
{
|
||||||
GIIrNodeUnion *union_ = (GIIrNodeUnion *)node;
|
GIIrNodeUnion *union_ = (GIIrNodeUnion *)node;
|
||||||
|
|
||||||
if (!check_needs_computation (build, node, union_->alignment))
|
if (!check_needs_computation (build, node, union_->offsets_state))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
compute_union_field_offsets (build, (GIIrNode*)union_, union_->members,
|
compute_union_field_offsets (build, (GIIrNode*)union_, union_->members,
|
||||||
&union_->size, &union_->alignment);
|
&union_->size, &union_->alignment, &union_->offsets_state);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GI_IR_NODE_ENUM:
|
case GI_IR_NODE_ENUM:
|
||||||
|
Loading…
Reference in New Issue
Block a user