mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-04-16 04:28:05 +02: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>
|
* </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:
|
* g_object_info_get_parent:
|
||||||
* @info: a #GIObjectInfo
|
* @info: a #GIObjectInfo
|
||||||
@ -251,18 +285,11 @@ g_object_info_get_field (GIObjectInfo *info,
|
|||||||
{
|
{
|
||||||
gint offset;
|
gint offset;
|
||||||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||||||
Header *header;
|
|
||||||
ObjectBlob *blob;
|
|
||||||
|
|
||||||
g_return_val_if_fail (info != NULL, NULL);
|
g_return_val_if_fail (info != NULL, NULL);
|
||||||
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
|
g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
|
||||||
|
|
||||||
header = (Header *)rinfo->typelib->data;
|
offset = g_object_info_get_field_offset(info, n);
|
||||||
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;
|
|
||||||
|
|
||||||
return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib, offset);
|
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;
|
header = (Header *)rinfo->typelib->data;
|
||||||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||||||
|
|
||||||
offset = rinfo->offset + header->object_blob_size
|
offset = g_object_info_get_field_offset(info, blob->n_fields)
|
||||||
+ (blob->n_interfaces + blob->n_interfaces % 2) * 2
|
|
||||||
+ blob->n_fields * header->field_blob_size
|
|
||||||
+ n * header->property_blob_size;
|
+ n * header->property_blob_size;
|
||||||
|
|
||||||
return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, (GIBaseInfo*)info,
|
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];
|
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||||||
|
|
||||||
|
|
||||||
offset = rinfo->offset + header->object_blob_size
|
offset = g_object_info_get_field_offset(info, blob->n_fields)
|
||||||
+ (blob->n_interfaces + blob->n_interfaces % 2) * 2
|
|
||||||
+ blob->n_fields * header->field_blob_size
|
|
||||||
+ blob->n_properties * header->property_blob_size
|
+ blob->n_properties * header->property_blob_size
|
||||||
+ n * header->function_blob_size;
|
+ n * header->function_blob_size;
|
||||||
|
|
||||||
@ -406,9 +429,7 @@ g_object_info_find_method (GIObjectInfo *info,
|
|||||||
header = (Header *)rinfo->typelib->data;
|
header = (Header *)rinfo->typelib->data;
|
||||||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||||||
|
|
||||||
offset = rinfo->offset + header->object_blob_size
|
offset = g_object_info_get_field_offset(info, blob->n_fields)
|
||||||
+ (blob->n_interfaces + blob->n_interfaces % 2) * 2
|
|
||||||
+ blob->n_fields * header->field_blob_size +
|
|
||||||
+ blob->n_properties * header->property_blob_size;
|
+ blob->n_properties * header->property_blob_size;
|
||||||
|
|
||||||
return _g_base_info_find_method ((GIBaseInfo*)info, offset, blob->n_methods, name);
|
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;
|
header = (Header *)rinfo->typelib->data;
|
||||||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||||||
|
|
||||||
offset = rinfo->offset + header->object_blob_size
|
offset = g_object_info_get_field_offset(info, blob->n_fields)
|
||||||
+ (blob->n_interfaces + blob->n_interfaces % 2) * 2
|
|
||||||
+ blob->n_fields * header->field_blob_size
|
|
||||||
+ blob->n_properties * header->property_blob_size
|
+ blob->n_properties * header->property_blob_size
|
||||||
+ blob->n_methods * header->function_blob_size
|
+ blob->n_methods * header->function_blob_size
|
||||||
+ n * header->signal_blob_size;
|
+ n * header->signal_blob_size;
|
||||||
@ -609,9 +628,7 @@ g_object_info_get_vfunc (GIObjectInfo *info,
|
|||||||
header = (Header *)rinfo->typelib->data;
|
header = (Header *)rinfo->typelib->data;
|
||||||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||||||
|
|
||||||
offset = rinfo->offset + header->object_blob_size
|
offset = g_object_info_get_field_offset(info, blob->n_fields)
|
||||||
+ (blob->n_interfaces + blob->n_interfaces % 2) * 2
|
|
||||||
+ blob->n_fields * header->field_blob_size
|
|
||||||
+ blob->n_properties * header->property_blob_size
|
+ blob->n_properties * header->property_blob_size
|
||||||
+ blob->n_methods * header->function_blob_size
|
+ blob->n_methods * header->function_blob_size
|
||||||
+ blob->n_signals * header->signal_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;
|
header = (Header *)rinfo->typelib->data;
|
||||||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||||||
|
|
||||||
offset = rinfo->offset + header->object_blob_size
|
offset = g_object_info_get_field_offset(info, blob->n_fields)
|
||||||
+ (blob->n_interfaces + blob->n_interfaces % 2) * 2
|
|
||||||
+ blob->n_fields * header->field_blob_size
|
|
||||||
+ blob->n_properties * header->property_blob_size
|
+ blob->n_properties * header->property_blob_size
|
||||||
+ blob->n_methods * header->function_blob_size
|
+ blob->n_methods * header->function_blob_size
|
||||||
+ blob->n_signals * header->signal_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;
|
header = (Header *)rinfo->typelib->data;
|
||||||
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
|
||||||
|
|
||||||
offset = rinfo->offset + header->object_blob_size
|
offset = g_object_info_get_field_offset(info, blob->n_fields)
|
||||||
+ (blob->n_interfaces + blob->n_interfaces % 2) * 2
|
|
||||||
+ blob->n_fields * header->field_blob_size
|
|
||||||
+ blob->n_properties * header->property_blob_size
|
+ blob->n_properties * header->property_blob_size
|
||||||
+ blob->n_methods * header->function_blob_size
|
+ blob->n_methods * header->function_blob_size
|
||||||
+ blob->n_signals * header->signal_blob_size
|
+ blob->n_signals * header->signal_blob_size
|
||||||
|
41
girparser.c
41
girparser.c
@ -62,37 +62,38 @@ struct _GIrParser
|
|||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
STATE_NONE = 0,
|
||||||
STATE_START,
|
STATE_START,
|
||||||
STATE_END,
|
STATE_END,
|
||||||
STATE_REPOSITORY,
|
STATE_REPOSITORY,
|
||||||
STATE_INCLUDE,
|
STATE_INCLUDE,
|
||||||
STATE_C_INCLUDE,
|
STATE_C_INCLUDE, /* 5 */
|
||||||
STATE_PACKAGE, /* 5 */
|
STATE_PACKAGE,
|
||||||
STATE_NAMESPACE,
|
STATE_NAMESPACE,
|
||||||
STATE_ENUM,
|
STATE_ENUM,
|
||||||
STATE_BITFIELD,
|
STATE_BITFIELD,
|
||||||
STATE_FUNCTION,
|
STATE_FUNCTION, /* 10 */
|
||||||
STATE_FUNCTION_RETURN, /* 10 */
|
STATE_FUNCTION_RETURN,
|
||||||
STATE_FUNCTION_PARAMETERS,
|
STATE_FUNCTION_PARAMETERS,
|
||||||
STATE_FUNCTION_PARAMETER,
|
STATE_FUNCTION_PARAMETER,
|
||||||
STATE_CLASS,
|
STATE_CLASS,
|
||||||
STATE_CLASS_FIELD,
|
STATE_CLASS_FIELD, /* 15 */
|
||||||
STATE_CLASS_PROPERTY, /* 15 */
|
STATE_CLASS_PROPERTY,
|
||||||
STATE_INTERFACE,
|
STATE_INTERFACE,
|
||||||
STATE_INTERFACE_PROPERTY,
|
STATE_INTERFACE_PROPERTY,
|
||||||
STATE_INTERFACE_FIELD,
|
STATE_INTERFACE_FIELD,
|
||||||
STATE_IMPLEMENTS,
|
STATE_IMPLEMENTS, /* 20 */
|
||||||
STATE_PREREQUISITE, /* 20 */
|
STATE_PREREQUISITE,
|
||||||
STATE_BOXED,
|
STATE_BOXED,
|
||||||
STATE_BOXED_FIELD,
|
STATE_BOXED_FIELD,
|
||||||
STATE_STRUCT,
|
STATE_STRUCT,
|
||||||
STATE_STRUCT_FIELD,
|
STATE_STRUCT_FIELD, /* 25 */
|
||||||
STATE_UNION, /* 25 */
|
STATE_UNION,
|
||||||
STATE_UNION_FIELD,
|
STATE_UNION_FIELD,
|
||||||
STATE_NAMESPACE_CONSTANT,
|
STATE_NAMESPACE_CONSTANT,
|
||||||
STATE_CLASS_CONSTANT,
|
STATE_CLASS_CONSTANT,
|
||||||
STATE_INTERFACE_CONSTANT,
|
STATE_INTERFACE_CONSTANT, /* 30 */
|
||||||
STATE_ALIAS, /* 30 */
|
STATE_ALIAS,
|
||||||
STATE_TYPE,
|
STATE_TYPE,
|
||||||
STATE_ATTRIBUTE,
|
STATE_ATTRIBUTE,
|
||||||
STATE_PASSTHROUGH
|
STATE_PASSTHROUGH
|
||||||
@ -123,7 +124,7 @@ struct _ParseContext
|
|||||||
GList *type_stack;
|
GList *type_stack;
|
||||||
GList *type_parameters;
|
GList *type_parameters;
|
||||||
int type_depth;
|
int type_depth;
|
||||||
gboolean in_embedded_type;
|
ParseState in_embedded_state;
|
||||||
};
|
};
|
||||||
#define CURRENT_NODE(ctx) ((GIrNode *)((ctx)->node_stack->data))
|
#define CURRENT_NODE(ctx) ((GIrNode *)((ctx)->node_stack->data))
|
||||||
|
|
||||||
@ -807,7 +808,7 @@ start_function (GMarkupParseContext *context,
|
|||||||
const gchar *throws;
|
const gchar *throws;
|
||||||
GIrNodeFunction *function;
|
GIrNodeFunction *function;
|
||||||
gboolean found = FALSE;
|
gboolean found = FALSE;
|
||||||
gboolean in_embedded_type;
|
ParseState in_embedded_state = STATE_NONE;
|
||||||
|
|
||||||
switch (ctx->state)
|
switch (ctx->state)
|
||||||
{
|
{
|
||||||
@ -830,8 +831,10 @@ start_function (GMarkupParseContext *context,
|
|||||||
case STATE_ENUM:
|
case STATE_ENUM:
|
||||||
found = strcmp (element_name, "function") == 0;
|
found = strcmp (element_name, "function") == 0;
|
||||||
break;
|
break;
|
||||||
|
case STATE_CLASS_FIELD:
|
||||||
case STATE_STRUCT_FIELD:
|
case STATE_STRUCT_FIELD:
|
||||||
found = (found || strcmp (element_name, "callback") == 0);
|
found = (found || strcmp (element_name, "callback") == 0);
|
||||||
|
in_embedded_state = ctx->state;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -840,12 +843,10 @@ start_function (GMarkupParseContext *context,
|
|||||||
if (!found)
|
if (!found)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
in_embedded_type = ctx->state == STATE_STRUCT_FIELD;
|
|
||||||
|
|
||||||
if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_FUNCTION))
|
if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_FUNCTION))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
ctx->in_embedded_type = in_embedded_type;
|
ctx->in_embedded_state = in_embedded_state;
|
||||||
|
|
||||||
name = find_attribute ("name", attribute_names, attribute_values);
|
name = find_attribute ("name", attribute_names, attribute_values);
|
||||||
shadows = find_attribute ("shadows", attribute_names, attribute_values);
|
shadows = find_attribute ("shadows", attribute_names, attribute_values);
|
||||||
@ -3210,10 +3211,10 @@ end_element_handler (GMarkupParseContext *context,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_debug("case STATE_FUNCTION %d", CURRENT_NODE (ctx)->type);
|
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, ctx->in_embedded_state);
|
||||||
state_switch (ctx, STATE_STRUCT_FIELD);
|
ctx->in_embedded_state = STATE_NONE;
|
||||||
}
|
}
|
||||||
else if (CURRENT_NODE (ctx)->type == G_IR_NODE_INTERFACE)
|
else if (CURRENT_NODE (ctx)->type == G_IR_NODE_INTERFACE)
|
||||||
state_switch (ctx, STATE_INTERFACE);
|
state_switch (ctx, STATE_INTERFACE);
|
||||||
|
@ -1773,10 +1773,17 @@ validate_object_blob (ValidateContext *ctx,
|
|||||||
|
|
||||||
push_context (ctx, get_string_nofail (typelib, blob->name));
|
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))
|
if (!validate_field_blob (ctx, offset2, error))
|
||||||
return FALSE;
|
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))
|
for (i = 0; i < blob->n_properties; i++, offset2 += sizeof (PropertyBlob))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user