From b95d92aca0d78f7b35649e5ce51f55863a6d2422 Mon Sep 17 00:00:00 2001 From: Andreas Rottmann Date: Sat, 3 Jan 2009 13:44:42 +0000 Subject: [PATCH] =?UTF-8?q?Bug=20556489=20=E2=80=93=20callback=20annotatio?= =?UTF-8?q?ns?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2008-01-03 Andreas Rottmann Bug 556489 – callback annotations * giscanner/transformer.py * tools/generate.c (write_callable_info): Write out the new scope, closure and destroy attributes. * giscanner/transformer.py (Transformer._type_is_callback): New method, checking if a given type is a callback. (Transformer._augment_callback_params): New method; adds information (closure, destroy) to callback parameters. (Transformer._handle_closure, Transformer._handle_destroy): New methods, auxiliary to _augment_callback_params. (Transformer._create_function): Call _augment_callback_params(). (Transformer._create_parameter): Handle scope option. (Transformer._create_typedef_callback): New method, creates a callback, and registers it in the typedef namespace (Transformer._create_typedef): Use _create_typedef_callback() instead of the plain _create_callback(). * giscanner/ast.py (Parameter): Added callback-related fields. * giscanner/girwriter.py: Write out new Parameter fields. * girepository/girnode.h (GIrNodeParam): Added fields scope, closure and destroy. * girepository/gtypelib.h (ArgBlob): Ditto. * girepository/girparser.c (start_parameter): Handle new fields. * girepository/girmodule.c (g_ir_module_build_typelib): Adjust arg_blob_size, bump major version due to this change. * girepository/girnode.c (g_ir_node_get_full_size_internal) (g_ir_node_build_typelib) * girepository/gtypelib.c (g_typelib_check_sanity): ArgBlob size adjustments. (g_ir_node_build_typelib): Fill in new ArgBlob flags from param. * girepository/girepository.h (GIScope): New enumeration, listing the different possible scopes for callbacks. * girepository/ginfo.c (g_arg_info_get_scope) (g_arg_info_get_closure, g_arg_info_get_destroy): Accessors for callback-related argument indices (callback scope, closure for a callback, destroy notification for a callback). * tests/scanner/: Added testcases for new features. svn path=/trunk/; revision=998 --- ginfo.c | 29 ++++++++++++++++++++++++++++- girepository.h | 11 +++++++++++ girmodule.c | 4 ++-- girnode.c | 9 ++++++--- girnode.h | 4 ++++ girparser.c | 22 +++++++++++++++++++++- gtypelib.c | 6 +++--- gtypelib.h | 6 +++++- 8 files changed, 80 insertions(+), 11 deletions(-) diff --git a/ginfo.c b/ginfo.c index 5df1e3f83..8324c05b0 100644 --- a/ginfo.c +++ b/ginfo.c @@ -741,12 +741,39 @@ g_arg_info_get_ownership_transfer (GIArgInfo *info) return GI_TRANSFER_NOTHING; } +GIScopeType +g_arg_info_get_scope (GIArgInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset]; + + return blob->scope; +} + +gint +g_arg_info_get_closure (GIArgInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset]; + + return blob->closure; +} + +gint +g_arg_info_get_destroy (GIArgInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset]; + + return blob->destroy; +} + GITypeInfo * g_arg_info_get_type (GIArgInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - return g_type_info_new (base, base->typelib, base->offset + 8); + return g_type_info_new (base, base->typelib, base->offset + 12); } /* GITypeInfo functions */ diff --git a/girepository.h b/girepository.h index abeb85700..38697c69f 100644 --- a/girepository.h +++ b/girepository.h @@ -269,12 +269,23 @@ typedef enum { GI_DIRECTION_INOUT } GIDirection; +typedef enum { + GI_SCOPE_TYPE_INVALID, + GI_SCOPE_TYPE_CALL, + GI_SCOPE_TYPE_OBJECT, + GI_SCOPE_TYPE_ASYNC, + GI_SCOPE_TYPE_NOTIFIED +} GIScopeType; + GIDirection g_arg_info_get_direction (GIArgInfo *info); gboolean g_arg_info_is_dipper (GIArgInfo *info); gboolean g_arg_info_is_return_value (GIArgInfo *info); gboolean g_arg_info_is_optional (GIArgInfo *info); gboolean g_arg_info_may_be_null (GIArgInfo *info); GITransfer g_arg_info_get_ownership_transfer (GIArgInfo *info); +GIScopeType g_arg_info_get_scope (GIArgInfo *info); +gint g_arg_info_get_closure (GIArgInfo *info); +gint g_arg_info_get_destroy (GIArgInfo *info); GITypeInfo * g_arg_info_get_type (GIArgInfo *info); diff --git a/girmodule.c b/girmodule.c index be41a1ed3..85103bff1 100644 --- a/girmodule.c +++ b/girmodule.c @@ -190,7 +190,7 @@ g_ir_module_build_typelib (GIrModule *module, /* fill in header */ header = (Header *)data; memcpy (header, G_IR_MAGIC, 16); - header->major_version = 1; + header->major_version = 2; header->minor_version = 0; header->reserved = 0; header->n_entries = n_entries; @@ -213,7 +213,7 @@ g_ir_module_build_typelib (GIrModule *module, header->callback_blob_size = 12; header->signal_blob_size = 12; header->vfunc_blob_size = 16; - header->arg_blob_size = 12; + header->arg_blob_size = 16; header->property_blob_size = 12; header->field_blob_size = 12; header->value_blob_size = 12; diff --git a/girnode.c b/girnode.c index 61e4f0b6c..c4045ef7e 100644 --- a/girnode.c +++ b/girnode.c @@ -582,7 +582,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, { GIrNodeParam *param = (GIrNodeParam *)node; - size = 12; + size = 16; if (node->name) size += ALIGN_VALUE (strlen (node->name) + 1, 4); size += g_ir_node_get_full_size_internal (node, (GIrNode *)param->type); @@ -1764,7 +1764,7 @@ g_ir_node_build_typelib (GIrNode *node, ArgBlob *blob = (ArgBlob *)&data[*offset]; GIrNodeParam *param = (GIrNodeParam *)node; - *offset += 8; + *offset += 12; blob->name = write_string (node->name, strings, data, offset2); blob->in = param->in; @@ -1775,8 +1775,11 @@ g_ir_node_build_typelib (GIrNode *node, blob->transfer_ownership = param->transfer; blob->transfer_container_ownership = param->shallow_transfer; blob->return_value = param->retval; + blob->scope = param->scope; blob->reserved = 0; - + blob->closure = param->closure; + blob->destroy = param->destroy; + g_ir_node_build_typelib ((GIrNode *)param->type, module, modules, strings, types, data, offset, offset2); } diff --git a/girnode.h b/girnode.h index 674594d8a..a1b8f0dc0 100644 --- a/girnode.h +++ b/girnode.h @@ -143,6 +143,10 @@ struct _GIrNodeParam gboolean allow_none; gboolean transfer; gboolean shallow_transfer; + GIScopeType scope; + + gint8 closure; + gint8 destroy; GIrNodeType *type; }; diff --git a/girparser.c b/girparser.c index e6d59b4c3..1072ecc5a 100644 --- a/girparser.c +++ b/girparser.c @@ -837,6 +837,9 @@ start_parameter (GMarkupParseContext *context, const gchar *optional; const gchar *allow_none; const gchar *transfer; + const gchar *scope; + const gchar *closure; + const gchar *destroy; GIrNodeParam *param; if (!(strcmp (element_name, "parameter") == 0 && @@ -850,7 +853,10 @@ start_parameter (GMarkupParseContext *context, optional = find_attribute ("optional", attribute_names, attribute_values); allow_none = find_attribute ("allow-none", attribute_names, attribute_values); transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values); - + scope = find_attribute ("scope", attribute_names, attribute_values); + closure = find_attribute ("closure", attribute_names, attribute_values); + destroy = find_attribute ("destroy", attribute_names, attribute_values); + if (name == NULL) name = "unknown"; @@ -899,6 +905,20 @@ start_parameter (GMarkupParseContext *context, parse_param_transfer (param, transfer); + if (scope && strcmp (scope, "call") == 0) + param->scope = GI_SCOPE_TYPE_CALL; + else if (scope && strcmp (scope, "object") == 0) + param->scope = GI_SCOPE_TYPE_OBJECT; + else if (scope && strcmp (scope, "async") == 0) + param->scope = GI_SCOPE_TYPE_ASYNC; + else if (scope && strcmp (scope, "notified") == 0) + param->scope = GI_SCOPE_TYPE_NOTIFIED; + else + param->scope = GI_SCOPE_TYPE_INVALID; + + param->closure = closure ? atoi (closure) : -1; + param->destroy = destroy ? atoi (destroy) : -1; + ((GIrNode *)param)->name = g_strdup (name); switch (ctx->current_node->type) diff --git a/gtypelib.c b/gtypelib.c index 51cbafcd2..d7b09f214 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -164,7 +164,7 @@ g_typelib_check_sanity (void) CHECK_SIZE (Header, 108); CHECK_SIZE (DirEntry, 12); CHECK_SIZE (SimpleTypeBlob, 4); - CHECK_SIZE (ArgBlob, 12); + CHECK_SIZE (ArgBlob, 16); CHECK_SIZE (SignatureBlob, 8); CHECK_SIZE (CommonBlob, 8); CHECK_SIZE (FunctionBlob, 20); @@ -286,7 +286,7 @@ validate_header (ValidateContext *ctx, } - if (header->major_version != 1 || header->minor_version != 0) + if (header->major_version != 2 || header->minor_version != 0) { g_set_error (error, G_TYPELIB_ERROR, @@ -319,7 +319,7 @@ validate_header (ValidateContext *ctx, header->callback_blob_size != 12 || header->signal_blob_size != 12 || header->vfunc_blob_size != 16 || - header->arg_blob_size != 12 || + header->arg_blob_size != 16 || header->property_blob_size != 12 || header->field_blob_size != 12 || header->value_blob_size != 12 || diff --git a/gtypelib.h b/gtypelib.h index 343f9e1bb..a68d00800 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -132,7 +132,11 @@ typedef struct guint transfer_ownership : 1; guint transfer_container_ownership : 1; guint return_value : 1; - guint reserved :24; + guint scope : 3; + guint reserved :21; + + gint8 closure; + gint8 destroy; SimpleTypeBlob arg_type; } ArgBlob;