[perl-Glib-Object-Introspection/ppc64-fixes: 3/6] Handle arg and type infos in the common invocation code
- From: Torsten Schönfeld <tsch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [perl-Glib-Object-Introspection/ppc64-fixes: 3/6] Handle arg and type infos in the common invocation code
- Date: Mon, 8 Sep 2014 20:29:53 +0000 (UTC)
commit 5caa700fb67f8c201d085ba97388d88b54354195
Author: Torsten Schönfeld <kaffeetisch gmx de>
Date: Sun Sep 7 18:40:06 2014 +0200
Handle arg and type infos in the common invocation code
Also, rename a struct field to avoid confusion.
GObjectIntrospection.xs | 7 ++++-
gperl-i11n-invoke-c.c | 56 ++++++++++++++--------------------------------
gperl-i11n-invoke-perl.c | 27 +++++-----------------
gperl-i11n-invoke.c | 22 +++++++++++++++++-
4 files changed, 49 insertions(+), 63 deletions(-)
---
diff --git a/GObjectIntrospection.xs b/GObjectIntrospection.xs
index 21327c7..2f72c2b 100644
--- a/GObjectIntrospection.xs
+++ b/GObjectIntrospection.xs
@@ -100,6 +100,10 @@ typedef struct {
* args. */
guint current_pos;
+ /* Information about the args from the typelib. */
+ GIArgInfo ** arg_infos;
+ GITypeInfo ** arg_types;
+
/* An array of places for storing out out/in-out or automatic args. */
GIArgument * aux_args;
@@ -137,10 +141,9 @@ typedef struct {
guint n_given_args;
gpointer * args;
- ffi_type ** arg_types;
+ ffi_type ** arg_types_ffi;
GIArgument * in_args;
GIArgument * out_args;
- GITypeInfo ** out_arg_infos;
gboolean * is_automatic_arg;
guint method_offset;
diff --git a/gperl-i11n-invoke-c.c b/gperl-i11n-invoke-c.c
index 075fe95..b15df84 100644
--- a/gperl-i11n-invoke-c.c
+++ b/gperl-i11n-invoke-c.c
@@ -45,7 +45,7 @@ invoke_c_code (GICallableInfo *info,
if (iinfo.is_method) {
instance = instance_sv_to_pointer (info, ST (0 + iinfo.stack_offset));
- iinfo.arg_types[0] = &ffi_type_pointer;
+ iinfo.arg_types_ffi[0] = &ffi_type_pointer;
iinfo.args[0] = &instance;
}
@@ -61,10 +61,8 @@ invoke_c_code (GICallableInfo *info,
gint perl_stack_pos, ffi_stack_pos;
SV *current_sv;
- arg_info = g_callable_info_get_arg ((GICallableInfo *) info, i);
- /* In case of out and in-out args, arg_type is unref'ed after
- * the function has been invoked */
- arg_type = g_arg_info_get_type (arg_info);
+ arg_info = iinfo.base.arg_infos[i];
+ arg_type = iinfo.base.arg_types[i];
transfer = g_arg_info_get_ownership_transfer (arg_info);
may_be_null = g_arg_info_may_be_null (arg_info);
#if GI_CHECK_VERSION (1, 29, 0)
@@ -106,10 +104,9 @@ invoke_c_code (GICallableInfo *info,
&iinfo.in_args[i], arg_info, arg_type,
transfer, may_be_null, &iinfo.base);
}
- iinfo.arg_types[ffi_stack_pos] =
+ iinfo.arg_types_ffi[ffi_stack_pos] =
g_type_info_get_ffi_type (arg_type);
iinfo.args[ffi_stack_pos] = &iinfo.in_args[i];
- g_base_info_unref ((GIBaseInfo *) arg_type);
break;
case GI_DIRECTION_OUT:
@@ -122,8 +119,7 @@ invoke_c_code (GICallableInfo *info,
iinfo.out_args[i].v_pointer = &iinfo.base.aux_args[i];
iinfo.args[ffi_stack_pos] = &iinfo.out_args[i];
}
- iinfo.out_arg_infos[i] = arg_type;
- iinfo.arg_types[ffi_stack_pos] = &ffi_type_pointer;
+ iinfo.arg_types_ffi[ffi_stack_pos] = &ffi_type_pointer;
/* Adjust the dynamic stack offset so that this out
* argument doesn't inadvertedly eat up an in argument. */
iinfo.dynamic_stack_offset--;
@@ -145,13 +141,10 @@ invoke_c_code (GICallableInfo *info,
iinfo.in_args[i].v_pointer, arg_info, arg_type,
transfer, may_be_null, &iinfo.base);
}
- iinfo.out_arg_infos[i] = arg_type;
- iinfo.arg_types[ffi_stack_pos] = &ffi_type_pointer;
+ iinfo.arg_types_ffi[ffi_stack_pos] = &ffi_type_pointer;
iinfo.args[ffi_stack_pos] = &iinfo.in_args[i];
break;
}
-
- g_base_info_unref ((GIBaseInfo *) arg_info);
}
/* do another pass to handle automatic args */
@@ -159,7 +152,7 @@ invoke_c_code (GICallableInfo *info,
GIArgInfo * arg_info;
if (!iinfo.is_automatic_arg[i])
continue;
- arg_info = g_callable_info_get_arg ((GICallableInfo *) info, i);
+ arg_info = iinfo.base.arg_infos[i];
switch (g_arg_info_get_direction (arg_info)) {
case GI_DIRECTION_IN:
_handle_automatic_arg (i, &iinfo.in_args[i], &iinfo);
@@ -171,12 +164,11 @@ invoke_c_code (GICallableInfo *info,
/* handled later */
break;
}
- g_base_info_unref ((GIBaseInfo *) arg_info);
}
if (iinfo.throws) {
iinfo.args[iinfo.n_invoke_args - 1] = &local_error_address;
- iinfo.arg_types[iinfo.n_invoke_args - 1] = &ffi_type_pointer;
+ iinfo.arg_types_ffi[iinfo.n_invoke_args - 1] = &ffi_type_pointer;
}
/*
@@ -185,7 +177,7 @@ invoke_c_code (GICallableInfo *info,
/* prepare and call the function */
if (FFI_OK != ffi_prep_cif (&cif, FFI_DEFAULT_ABI, iinfo.n_invoke_args,
- iinfo.base.return_type_ffi, iinfo.arg_types))
+ iinfo.base.return_type_ffi, iinfo.arg_types_ffi))
{
_clear_c_invocation_info (&iinfo);
ccroak ("Could not prepare a call interface");
@@ -248,10 +240,9 @@ invoke_c_code (GICallableInfo *info,
GIArgInfo * arg_info;
if (iinfo.is_automatic_arg[i])
continue;
- arg_info = g_callable_info_get_arg ((GICallableInfo *) info, i);
+ arg_info = iinfo.base.arg_infos[i];
#if GI_CHECK_VERSION (1, 29, 0)
if (g_arg_info_is_skip (arg_info)) {
- g_base_info_unref ((GIBaseInfo *) arg_info);
continue;
}
#endif
@@ -266,21 +257,19 @@ invoke_c_code (GICallableInfo *info,
? GI_TRANSFER_CONTAINER
: g_arg_info_get_ownership_transfer (arg_info);
sv = SAVED_STACK_SV (arg_to_sv (iinfo.out_args[i].v_pointer,
- iinfo.out_arg_infos[i],
+ iinfo.base.arg_types[i],
transfer,
&iinfo.base));
if (sv) {
XPUSHs (sv_2mortal (sv));
n_return_values++;
}
- g_base_info_unref ((GIBaseInfo*) iinfo.out_arg_infos[i]);
break;
}
default:
break;
}
- g_base_info_unref ((GIBaseInfo *) arg_info);
}
_clear_c_invocation_info (&iinfo);
@@ -371,8 +360,7 @@ _prepare_c_invocation_info (GPerlI11nCInvocationInfo *iinfo,
gint n = iinfo->n_invoke_args;
iinfo->in_args = gperl_alloc_temp (sizeof (GIArgument) * n);
iinfo->out_args = gperl_alloc_temp (sizeof (GIArgument) * n);
- iinfo->out_arg_infos = gperl_alloc_temp (sizeof (GITypeInfo*) * n);
- iinfo->arg_types = gperl_alloc_temp (sizeof (ffi_type *) * n);
+ iinfo->arg_types_ffi = gperl_alloc_temp (sizeof (ffi_type *) * n);
iinfo->args = gperl_alloc_temp (sizeof (gpointer) * n);
iinfo->is_automatic_arg = gperl_alloc_temp (sizeof (gboolean) * n);
}
@@ -383,9 +371,8 @@ _prepare_c_invocation_info (GPerlI11nCInvocationInfo *iinfo,
/* Make a first pass to mark args that are filled in automatically, and
* thus have no counterpart on the Perl side. */
for (i = 0 ; i < iinfo->base.n_args ; i++) {
- GIArgInfo * arg_info =
- g_callable_info_get_arg ((GICallableInfo *) info, i);
- GITypeInfo * arg_type = g_arg_info_get_type (arg_info);
+ GIArgInfo * arg_info = iinfo->base.arg_infos[i];
+ GITypeInfo * arg_type = iinfo->base.arg_types[i];
GITypeTag arg_tag = g_type_info_get_tag (arg_type);
if (arg_tag == GI_TYPE_TAG_ARRAY) {
@@ -408,18 +395,14 @@ _prepare_c_invocation_info (GPerlI11nCInvocationInfo *iinfo,
}
g_base_info_unref ((GIBaseInfo *) interface);
}
-
- g_base_info_unref ((GIBaseInfo *) arg_type);
- g_base_info_unref ((GIBaseInfo *) arg_info);
}
/* Make another pass to count the expected args. */
iinfo->n_expected_args = iinfo->method_offset;
iinfo->n_nullable_args = 0;
for (i = 0 ; i < iinfo->base.n_args ; i++) {
- GIArgInfo * arg_info =
- g_callable_info_get_arg ((GICallableInfo *) info, i);
- GITypeInfo * arg_type = g_arg_info_get_type (arg_info);
+ GIArgInfo * arg_info = iinfo->base.arg_infos[i];
+ GITypeInfo * arg_type = iinfo->base.arg_types[i];
GITypeTag arg_tag = g_type_info_get_tag (arg_type);
gboolean is_out = GI_DIRECTION_OUT == g_arg_info_get_direction (arg_info);
gboolean is_automatic = iinfo->is_automatic_arg[i];
@@ -433,9 +416,6 @@ _prepare_c_invocation_info (GPerlI11nCInvocationInfo *iinfo,
/* Callback user data may always be NULL. */
if (g_arg_info_may_be_null (arg_info) || arg_tag == GI_TYPE_TAG_VOID)
iinfo->n_nullable_args++;
-
- g_base_info_unref ((GIBaseInfo *) arg_type);
- g_base_info_unref ((GIBaseInfo *) arg_info);
}
/* If the return value is an array which comes with an outbound length
@@ -443,13 +423,11 @@ _prepare_c_invocation_info (GPerlI11nCInvocationInfo *iinfo,
if (g_type_info_get_tag (iinfo->base.return_type_info) == GI_TYPE_TAG_ARRAY) {
gint pos = g_type_info_get_array_length (iinfo->base.return_type_info);
if (pos >= 0) {
- GIArgInfo * arg_info =
- g_callable_info_get_arg ((GICallableInfo *) info, pos);
+ GIArgInfo * arg_info = iinfo->base.arg_infos[pos];
if (GI_DIRECTION_OUT == g_arg_info_get_direction (arg_info)) {
dwarn (" pos %d is automatic (array length)\n", pos);
iinfo->is_automatic_arg[pos] = TRUE;
}
- g_base_info_unref (arg_info);
}
}
diff --git a/gperl-i11n-invoke-perl.c b/gperl-i11n-invoke-perl.c
index 2e74372..49c855f 100644
--- a/gperl-i11n-invoke-perl.c
+++ b/gperl-i11n-invoke-perl.c
@@ -73,8 +73,8 @@ invoke_perl_code (ffi_cif* cif, gpointer resp, gpointer* args, gpointer userdata
* stack */
in_inout = 0;
for (i = 0; i < iinfo.base.n_args; i++) {
- GIArgInfo *arg_info = g_callable_info_get_arg (cb_interface, i);
- GITypeInfo *arg_type = g_arg_info_get_type (arg_info);
+ GIArgInfo *arg_info = iinfo.base.arg_infos[i];
+ GITypeInfo *arg_type = iinfo.base.arg_types[i];
GITransfer transfer = g_arg_info_get_ownership_transfer (arg_info);
GIDirection direction = g_arg_info_get_direction (arg_info);
@@ -126,9 +126,6 @@ invoke_perl_code (ffi_cif* cif, gpointer resp, gpointer* args, gpointer userdata
{
in_inout++;
}
-
- g_base_info_unref ((GIBaseInfo *) arg_info);
- g_base_info_unref ((GIBaseInfo *) arg_type);
}
/* push the last SV onto the stack; this might be the user data or the
@@ -195,15 +192,13 @@ invoke_perl_code (ffi_cif* cif, gpointer resp, gpointer* args, gpointer userdata
out_index = 0;
for (i = 0; i < iinfo.base.n_args; i++) {
- GIArgInfo *arg_info = g_callable_info_get_arg (cb_interface, i);
- GITypeInfo *arg_type = g_arg_info_get_type (arg_info);
+ GIArgInfo *arg_info = iinfo.base.arg_infos[i];
+ GITypeInfo *arg_type = iinfo.base.arg_types[i];
GIDirection direction = g_arg_info_get_direction (arg_info);
gpointer out_pointer = * (gpointer *) args[i+args_offset];
if (!out_pointer) {
dwarn ("skipping out arg %d\n", i);
- g_base_info_unref (arg_info);
- g_base_info_unref (arg_type);
continue;
}
@@ -232,9 +227,6 @@ invoke_perl_code (ffi_cif* cif, gpointer resp, gpointer* args, gpointer userdata
}
out_index++;
}
-
- g_base_info_unref (arg_info);
- g_base_info_unref (arg_type);
}
g_free (returned_values);
@@ -361,25 +353,18 @@ _prepare_perl_invocation_info (GPerlI11nPerlInvocationInfo *iinfo,
/* Find array length arguments and store their value in aux_args so
* that array_to_sv can later fetch them. */
for (i = 0 ; i < iinfo->base.n_args ; i++) {
- GIArgInfo *arg_info = g_callable_info_get_arg (info, i);
- GITypeInfo *arg_type = g_arg_info_get_type (arg_info);
+ GITypeInfo *arg_type = iinfo->base.arg_types[i];
GITypeTag arg_tag = g_type_info_get_tag (arg_type);
if (arg_tag == GI_TYPE_TAG_ARRAY) {
gint pos = g_type_info_get_array_length (arg_type);
if (pos >= 0) {
- GIArgInfo *length_arg_info = g_callable_info_get_arg (info, i);
- GITypeInfo *length_arg_type = g_arg_info_get_type (arg_info);
+ GITypeInfo *length_arg_type = iinfo->base.arg_types[i];
raw_to_arg (args[pos], &iinfo->base.aux_args[pos], length_arg_type);
dwarn (" pos %d is array length => %"G_GSIZE_FORMAT"\n",
pos, iinfo->aux_args[pos].v_size);
- g_base_info_unref (length_arg_type);
- g_base_info_unref (length_arg_info);
}
}
-
- g_base_info_unref (arg_type);
- g_base_info_unref (arg_info);
}
}
diff --git a/gperl-i11n-invoke.c b/gperl-i11n-invoke.c
index e52b6fe..2eb8ea3 100644
--- a/gperl-i11n-invoke.c
+++ b/gperl-i11n-invoke.c
@@ -4,6 +4,8 @@ static void
prepare_invocation_info (GPerlI11nInvocationInfo *iinfo,
GICallableInfo *info)
{
+ guint i;
+
dwarn ("invoke: %s\n"
" n_args: %d\n",
g_base_info_get_name (info),
@@ -20,9 +22,19 @@ prepare_invocation_info (GPerlI11nInvocationInfo *iinfo,
iinfo->n_args = g_callable_info_get_n_args (info);
- iinfo->aux_args = NULL;
if (iinfo->n_args) {
+ iinfo->arg_infos = gperl_alloc_temp (sizeof (GITypeInfo*) * iinfo->n_args);
+ iinfo->arg_types = gperl_alloc_temp (sizeof (GITypeInfo*) * iinfo->n_args);
iinfo->aux_args = gperl_alloc_temp (sizeof (GIArgument) * iinfo->n_args);
+ } else {
+ iinfo->arg_infos = NULL;
+ iinfo->arg_types = NULL;
+ iinfo->aux_args = NULL;
+ }
+
+ for (i = 0 ; i < iinfo->n_args ; i++) {
+ iinfo->arg_infos[i] = g_callable_info_get_arg (info, i);
+ iinfo->arg_types[i] = g_arg_info_get_type (iinfo->arg_infos[i]);
}
iinfo->return_type_info = g_callable_info_get_return_type (info);
@@ -33,12 +45,20 @@ prepare_invocation_info (GPerlI11nInvocationInfo *iinfo,
iinfo->callback_infos = NULL;
iinfo->array_infos = NULL;
+
iinfo->free_after_call = NULL;
}
static void
clear_invocation_info (GPerlI11nInvocationInfo *iinfo)
{
+ guint i;
+
+ for (i = 0 ; i < iinfo->n_args ; i++) {
+ g_base_info_unref ((GIBaseInfo *) iinfo->arg_types[i]);
+ g_base_info_unref ((GIBaseInfo *) iinfo->arg_infos[i]);
+ }
+
g_slist_free (iinfo->free_after_call);
iinfo->free_after_call = NULL;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]