Bug 557383 - Virtual method support

Broadly speaking, this change adds the concept of <vfunc> to the .gir.
The typelib already had most of the infrastructure for virtual functions,
though there is one API addition.

The scanner assumes that any class callback slot that doesn't match
a signal name is a virtual.  In the .gir, we write out *both* the <method>
wrapper and a <vfunc>.  If we can determine an association between
them (based on the names matching, or a new Virtual: annotation),
then we notate that in the .gir.

The typelib gains an association from the vfunc to the function, if
it exists.  This will be useful for bindings since they already know
how to consume FunctionInfo.
This commit is contained in:
Colin Walters
2009-02-27 19:02:48 -05:00
parent cd845500a5
commit 7299c89fc9
6 changed files with 170 additions and 4 deletions

View File

@@ -265,6 +265,7 @@ g_ir_node_free (GIrNode *node)
GIrNodeVFunc *vfunc = (GIrNodeVFunc *)node;
g_free (node->name);
g_free (vfunc->invoker);
for (l = vfunc->parameters; l; l = l->next)
g_ir_node_free ((GIrNode *)l->data);
g_list_free (vfunc->parameters);
@@ -1186,6 +1187,30 @@ g_ir_find_node (GIrModule *module,
return node != NULL;
}
static int
get_index_of_member_type (GIrNodeInterface *node,
GIrNodeTypeId type,
const char *name)
{
guint index = -1;
GList *l;
for (l = node->members; l; l = l->next)
{
GIrNode *node = l->data;
if (node->type != type)
continue;
index++;
if (strcmp (node->name, name) == 0)
break;
}
return index;
}
static void
serialize_type (GIrModule *module,
GList *modules,
@@ -1759,6 +1784,18 @@ g_ir_node_build_typelib (GIrNode *node,
blob->class_closure = 0; /* FIXME */
blob->reserved = 0;
if (vfunc->invoker)
{
int index = get_index_of_member_type ((GIrNodeInterface*)parent, G_IR_NODE_FUNCTION, vfunc->invoker);
if (index == -1)
{
g_error ("Unknown member function %s for vfunc %s", vfunc->invoker, node->name);
}
blob->invoker = (guint) index;
}
else
blob->invoker = 0x3ff; /* max of 10 bits */
blob->struct_offset = vfunc->offset;
blob->reserved2 = 0;
blob->signature = signature;