mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-12 15:36:17 +01:00
g-ir-compiler: Add support for callback fields on GObjects
Use ParseState enum instead of a boolean for the ParseContexts embedded_type flag. This allows specific tracking of the embedded type currently being parsed which can now either be STATE_STRUCT_FIELD or STATE_CLASS_FIELD (or allow for future expansion). Add ParseState::STATE_NONE as the default for this field. Fix GObject FieldBlob validation to take into account the sizeof CallbackBlobs (copied from the struct validator). Add static g_object_info_get_field_offset which parallels g_struct_info_get_field_offset which is needed since callback fields may vary in size. https://bugzilla.gnome.org/show_bug.cgi?id=725198
This commit is contained in:
parent
90a99b4fcc
commit
cf4fb6a0fe
@ -47,6 +47,40 @@
|
||||
* </refsect1>
|
||||
*/
|
||||
|
||||
/**
|
||||
* g_object_info_get_field_offset:
|
||||
* @info: a #GIObjectInfo
|
||||
* @n: index of queried field
|
||||
*
|
||||
* Obtain the offset of the specified field.
|
||||
*
|
||||
* Returns: field offset in bytes
|
||||
*/
|
||||
static gint32
|
||||
g_object_info_get_field_offset (GIObjectInfo *info,
|
||||
gint n)
|
||||
{
|
||||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||||
Header *header = (Header *)rinfo->typelib->data;
|
||||
ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||||
guint32 offset;
|
||||
gint i;
|
||||
FieldBlob *field_blob;
|
||||
|
||||
offset = rinfo->offset + header->object_blob_size
|
||||
+ (blob->n_interfaces + blob->n_interfaces % 2) * 2;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
field_blob = (FieldBlob *)&rinfo->typelib->data[offset];
|
||||
offset += header->field_blob_size;
|
||||
if (field_blob->has_embedded_type)
|
||||
offset += header->callback_blob_size;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_object_info_get_parent:
|
||||
* @info: a #GIObjectInfo
|
||||
@ -251,18 +285,11 @@ g_object_info_get_field (GIObjectInfo *info,
|
||||
{
|
||||
gint offset;
|
||||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||||
Header *header;
|
||||
ObjectBlob *blob;
|
||||
|
||||
g_return_val_if_fail (info != NULL, NULL);
|
||||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
|
||||
|
||||
header = (Header *)rinfo->typelib->data;
|
||||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||||
|
||||
offset = rinfo->offset + header->object_blob_size
|
||||
+ (blob->n_interfaces + blob->n_interfaces % 2) * 2
|
||||
+ n * header->field_blob_size;
|
||||
offset = g_object_info_get_field_offset(info, n);
|
||||
|
||||
return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib, offset);
|
||||
}
|
||||
@ -313,9 +340,7 @@ g_object_info_get_property (GIObjectInfo *info,
|
||||
header = (Header *)rinfo->typelib->data;
|
||||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||||
|
||||
offset = rinfo->offset + header->object_blob_size
|
||||
+ (blob->n_interfaces + blob->n_interfaces % 2) * 2
|
||||
+ blob->n_fields * header->field_blob_size
|
||||
offset = g_object_info_get_field_offset(info, blob->n_fields)
|
||||
+ n * header->property_blob_size;
|
||||
|
||||
return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, (GIBaseInfo*)info,
|
||||
@ -370,9 +395,7 @@ g_object_info_get_method (GIObjectInfo *info,
|
||||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||||
|
||||
|
||||
offset = rinfo->offset + header->object_blob_size
|
||||
+ (blob->n_interfaces + blob->n_interfaces % 2) * 2
|
||||
+ blob->n_fields * header->field_blob_size
|
||||
offset = g_object_info_get_field_offset(info, blob->n_fields)
|
||||
+ blob->n_properties * header->property_blob_size
|
||||
+ n * header->function_blob_size;
|
||||
|
||||
@ -406,9 +429,7 @@ g_object_info_find_method (GIObjectInfo *info,
|
||||
header = (Header *)rinfo->typelib->data;
|
||||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||||
|
||||
offset = rinfo->offset + header->object_blob_size
|
||||
+ (blob->n_interfaces + blob->n_interfaces % 2) * 2
|
||||
+ blob->n_fields * header->field_blob_size +
|
||||
offset = g_object_info_get_field_offset(info, blob->n_fields)
|
||||
+ blob->n_properties * header->property_blob_size;
|
||||
|
||||
return _g_base_info_find_method ((GIBaseInfo*)info, offset, blob->n_methods, name);
|
||||
@ -518,9 +539,7 @@ g_object_info_get_signal (GIObjectInfo *info,
|
||||
header = (Header *)rinfo->typelib->data;
|
||||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||||
|
||||
offset = rinfo->offset + header->object_blob_size
|
||||
+ (blob->n_interfaces + blob->n_interfaces % 2) * 2
|
||||
+ blob->n_fields * header->field_blob_size
|
||||
offset = g_object_info_get_field_offset(info, blob->n_fields)
|
||||
+ blob->n_properties * header->property_blob_size
|
||||
+ blob->n_methods * header->function_blob_size
|
||||
+ n * header->signal_blob_size;
|
||||
@ -609,9 +628,7 @@ g_object_info_get_vfunc (GIObjectInfo *info,
|
||||
header = (Header *)rinfo->typelib->data;
|
||||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||||
|
||||
offset = rinfo->offset + header->object_blob_size
|
||||
+ (blob->n_interfaces + blob->n_interfaces % 2) * 2
|
||||
+ blob->n_fields * header->field_blob_size
|
||||
offset = g_object_info_get_field_offset(info, blob->n_fields)
|
||||
+ blob->n_properties * header->property_blob_size
|
||||
+ blob->n_methods * header->function_blob_size
|
||||
+ blob->n_signals * header->signal_blob_size
|
||||
@ -652,9 +669,7 @@ g_object_info_find_vfunc (GIObjectInfo *info,
|
||||
header = (Header *)rinfo->typelib->data;
|
||||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||||
|
||||
offset = rinfo->offset + header->object_blob_size
|
||||
+ (blob->n_interfaces + blob->n_interfaces % 2) * 2
|
||||
+ blob->n_fields * header->field_blob_size
|
||||
offset = g_object_info_get_field_offset(info, blob->n_fields)
|
||||
+ blob->n_properties * header->property_blob_size
|
||||
+ blob->n_methods * header->function_blob_size
|
||||
+ blob->n_signals * header->signal_blob_size;
|
||||
@ -769,9 +784,7 @@ g_object_info_get_constant (GIObjectInfo *info,
|
||||
header = (Header *)rinfo->typelib->data;
|
||||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||||
|
||||
offset = rinfo->offset + header->object_blob_size
|
||||
+ (blob->n_interfaces + blob->n_interfaces % 2) * 2
|
||||
+ blob->n_fields * header->field_blob_size
|
||||
offset = g_object_info_get_field_offset(info, blob->n_fields)
|
||||
+ blob->n_properties * header->property_blob_size
|
||||
+ blob->n_methods * header->function_blob_size
|
||||
+ blob->n_signals * header->signal_blob_size
|
||||
|
41
girparser.c
41
girparser.c
@ -62,37 +62,38 @@ struct _GIrParser
|
||||
|
||||
typedef enum
|
||||
{
|
||||
STATE_NONE = 0,
|
||||
STATE_START,
|
||||
STATE_END,
|
||||
STATE_REPOSITORY,
|
||||
STATE_INCLUDE,
|
||||
STATE_C_INCLUDE,
|
||||
STATE_PACKAGE, /* 5 */
|
||||
STATE_C_INCLUDE, /* 5 */
|
||||
STATE_PACKAGE,
|
||||
STATE_NAMESPACE,
|
||||
STATE_ENUM,
|
||||
STATE_BITFIELD,
|
||||
STATE_FUNCTION,
|
||||
STATE_FUNCTION_RETURN, /* 10 */
|
||||
STATE_FUNCTION, /* 10 */
|
||||
STATE_FUNCTION_RETURN,
|
||||
STATE_FUNCTION_PARAMETERS,
|
||||
STATE_FUNCTION_PARAMETER,
|
||||
STATE_CLASS,
|
||||
STATE_CLASS_FIELD,
|
||||
STATE_CLASS_PROPERTY, /* 15 */
|
||||
STATE_CLASS_FIELD, /* 15 */
|
||||
STATE_CLASS_PROPERTY,
|
||||
STATE_INTERFACE,
|
||||
STATE_INTERFACE_PROPERTY,
|
||||
STATE_INTERFACE_FIELD,
|
||||
STATE_IMPLEMENTS,
|
||||
STATE_PREREQUISITE, /* 20 */
|
||||
STATE_IMPLEMENTS, /* 20 */
|
||||
STATE_PREREQUISITE,
|
||||
STATE_BOXED,
|
||||
STATE_BOXED_FIELD,
|
||||
STATE_STRUCT,
|
||||
STATE_STRUCT_FIELD,
|
||||
STATE_UNION, /* 25 */
|
||||
STATE_STRUCT_FIELD, /* 25 */
|
||||
STATE_UNION,
|
||||
STATE_UNION_FIELD,
|
||||
STATE_NAMESPACE_CONSTANT,
|
||||
STATE_CLASS_CONSTANT,
|
||||
STATE_INTERFACE_CONSTANT,
|
||||
STATE_ALIAS, /* 30 */
|
||||
STATE_INTERFACE_CONSTANT, /* 30 */
|
||||
STATE_ALIAS,
|
||||
STATE_TYPE,
|
||||
STATE_ATTRIBUTE,
|
||||
STATE_PASSTHROUGH
|
||||
@ -123,7 +124,7 @@ struct _ParseContext
|
||||
GList *type_stack;
|
||||
GList *type_parameters;
|
||||
int type_depth;
|
||||
gboolean in_embedded_type;
|
||||
ParseState in_embedded_state;
|
||||
};
|
||||
#define CURRENT_NODE(ctx) ((GIrNode *)((ctx)->node_stack->data))
|
||||
|
||||
@ -807,7 +808,7 @@ start_function (GMarkupParseContext *context,
|
||||
const gchar *throws;
|
||||
GIrNodeFunction *function;
|
||||
gboolean found = FALSE;
|
||||
gboolean in_embedded_type;
|
||||
ParseState in_embedded_state = STATE_NONE;
|
||||
|
||||
switch (ctx->state)
|
||||
{
|
||||
@ -830,8 +831,10 @@ start_function (GMarkupParseContext *context,
|
||||
case STATE_ENUM:
|
||||
found = strcmp (element_name, "function") == 0;
|
||||
break;
|
||||
case STATE_CLASS_FIELD:
|
||||
case STATE_STRUCT_FIELD:
|
||||
found = (found || strcmp (element_name, "callback") == 0);
|
||||
in_embedded_state = ctx->state;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -840,12 +843,10 @@ start_function (GMarkupParseContext *context,
|
||||
if (!found)
|
||||
return FALSE;
|
||||
|
||||
in_embedded_type = ctx->state == STATE_STRUCT_FIELD;
|
||||
|
||||
if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_FUNCTION))
|
||||
return TRUE;
|
||||
|
||||
ctx->in_embedded_type = in_embedded_type;
|
||||
ctx->in_embedded_state = in_embedded_state;
|
||||
|
||||
name = find_attribute ("name", attribute_names, attribute_values);
|
||||
shadows = find_attribute ("shadows", attribute_names, attribute_values);
|
||||
@ -3210,10 +3211,10 @@ end_element_handler (GMarkupParseContext *context,
|
||||
else
|
||||
{
|
||||
g_debug("case STATE_FUNCTION %d", CURRENT_NODE (ctx)->type);
|
||||
if (ctx->in_embedded_type)
|
||||
if (ctx->in_embedded_state != STATE_NONE)
|
||||
{
|
||||
ctx->in_embedded_type = FALSE;
|
||||
state_switch (ctx, STATE_STRUCT_FIELD);
|
||||
state_switch (ctx, ctx->in_embedded_state);
|
||||
ctx->in_embedded_state = STATE_NONE;
|
||||
}
|
||||
else if (CURRENT_NODE (ctx)->type == G_IR_NODE_INTERFACE)
|
||||
state_switch (ctx, STATE_INTERFACE);
|
||||
|
@ -1773,10 +1773,17 @@ validate_object_blob (ValidateContext *ctx,
|
||||
|
||||
push_context (ctx, get_string_nofail (typelib, blob->name));
|
||||
|
||||
for (i = 0; i < blob->n_fields; i++, offset2 += sizeof (FieldBlob))
|
||||
for (i = 0; i < blob->n_fields; i++)
|
||||
{
|
||||
FieldBlob *blob = (FieldBlob*) &typelib->data[offset2];
|
||||
|
||||
if (!validate_field_blob (ctx, offset2, error))
|
||||
return FALSE;
|
||||
|
||||
offset2 += sizeof (FieldBlob);
|
||||
/* Special case fields which are callbacks. */
|
||||
if (blob->has_embedded_type)
|
||||
offset2 += sizeof (CallbackBlob);
|
||||
}
|
||||
|
||||
for (i = 0; i < blob->n_properties; i++, offset2 += sizeof (PropertyBlob))
|
||||
|
Loading…
Reference in New Issue
Block a user