1 /* -*- Mode: C; c-basic-offset: 4 -*-
2 * vim: tabstop=4 shiftwidth=4 expandtab
4 * Copyright (C) 2005-2009 Johan Dahlin <johan@gnome.org>
6 * pygi-invoke.c: main invocation function
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
25 #include "pygi-invoke.h"
27 struct invocation_state
30 gboolean is_constructor;
39 gsize n_return_values;
41 guint8 callback_index;
42 guint8 user_data_index;
43 guint8 destroy_notify_index;
44 PyGICClosure *closure;
48 GIArgInfo **arg_infos;
49 GITypeInfo **arg_type_infos;
50 GITypeInfo *return_type_info;
51 GITypeTag return_type_tag;
54 gboolean *args_is_auxiliary;
58 GIArgument *out_values;
59 GIArgument *backup_args;
60 GIArgument return_arg;
62 PyObject *return_value;
64 GType implementor_gtype;
66 /* hack to avoid treating C arrays as GArrays during free
67 * due to overly complicated array handling
68 * this will be removed when the new invoke branch is merged
70 gboolean c_arrays_are_wrapped;
74 _initialize_invocation_state (struct invocation_state *state,
79 if (g_base_info_get_type (info) == GI_INFO_TYPE_FUNCTION) {
80 GIFunctionInfoFlags flags = g_function_info_get_flags (info);
82 state->is_method = (flags & GI_FUNCTION_IS_METHOD) != 0;
83 state->is_constructor = (flags & GI_FUNCTION_IS_CONSTRUCTOR) != 0;
84 state->implementor_gtype = 0;
88 state->is_method = TRUE;
89 state->is_constructor = FALSE;
91 obj = PyDict_GetItemString (kwargs, "gtype");
93 PyErr_SetString (PyExc_TypeError,
94 "need the GType of the implementor class");
98 state->implementor_gtype = pyg_type_from_object (obj);
99 if (state->implementor_gtype == 0)
103 /* Count arguments. */
104 state->n_args = g_callable_info_get_n_args ( (GICallableInfo *) info);
105 state->n_in_args = 0;
106 state->n_out_args = 0;
107 state->n_backup_args = 0;
108 state->n_aux_in_args = 0;
109 state->n_aux_out_args = 0;
111 /* Check the argument count. */
112 state->n_py_args = PyTuple_Size (py_args);
113 g_assert (state->n_py_args >= 0);
115 state->error_arg_pos = -1;
117 state->arg_infos = g_slice_alloc0 (sizeof (gpointer) * state->n_args);
118 state->arg_type_infos = g_slice_alloc0 (sizeof (gpointer) * state->n_args);
119 state->args_is_auxiliary = g_slice_alloc0 (sizeof (gboolean) * state->n_args);
121 state->return_value = NULL;
122 state->closure = NULL;
123 state->return_type_info = NULL;
125 state->in_args = NULL;
126 state->out_args = NULL;
127 state->out_values = NULL;
128 state->backup_args = NULL;
130 /* HACK: this gets marked FALSE whenever a C array in the args is
131 * not wrapped by a GArray
133 state->c_arrays_are_wrapped = TRUE;
139 _prepare_invocation_state (struct invocation_state *state,
140 GIFunctionInfo *function_info, PyObject *py_args)
144 if (!_pygi_scan_for_callbacks (function_info,
146 &state->callback_index, &state->user_data_index,
147 &state->destroy_notify_index))
150 if (state->callback_index != G_MAXUINT8) {
152 if (!_pygi_create_callback (function_info,
154 state->is_constructor,
155 state->n_args, state->n_py_args,
156 py_args, state->callback_index,
157 state->user_data_index,
158 state->destroy_notify_index, &state->closure))
161 state->args_is_auxiliary[state->callback_index] = FALSE;
162 if (state->destroy_notify_index != G_MAXUINT8) {
163 state->args_is_auxiliary[state->destroy_notify_index] = TRUE;
164 state->n_aux_in_args += 1;
168 if (state->is_method) {
169 /* The first argument is the instance. */
170 state->n_in_args += 1;
173 /* We do a first (well, second) pass here over the function to scan for special cases.
174 * This is currently array+length combinations, GError and GValue.
176 for (i = 0; i < state->n_args; i++) {
177 GIDirection direction;
179 GITypeTag arg_type_tag;
181 state->arg_infos[i] = g_callable_info_get_arg ( (GICallableInfo *) function_info,
184 state->arg_type_infos[i] = g_arg_info_get_type (state->arg_infos[i]);
186 direction = g_arg_info_get_direction (state->arg_infos[i]);
187 transfer = g_arg_info_get_ownership_transfer (state->arg_infos[i]);
188 arg_type_tag = g_type_info_get_tag (state->arg_type_infos[i]);
190 if (direction == GI_DIRECTION_IN || direction == GI_DIRECTION_INOUT) {
191 state->n_in_args += 1;
193 if (direction == GI_DIRECTION_INOUT) {
194 state->n_backup_args += 1;
196 if (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT) {
197 state->n_out_args += 1;
200 switch (arg_type_tag) {
201 case GI_TYPE_TAG_ARRAY:
205 length_arg_pos = g_type_info_get_array_length (state->arg_type_infos[i]);
207 if (length_arg_pos < 0) {
211 /* For array lengths, we're going to delete the length argument;
212 * so remove the extra backup we just added above */
213 if (direction == GI_DIRECTION_INOUT) {
214 state->n_backup_args -= 1;
217 g_assert (length_arg_pos < state->n_args);
218 state->args_is_auxiliary[length_arg_pos] = TRUE;
220 if (direction == GI_DIRECTION_IN || direction == GI_DIRECTION_INOUT) {
221 state->n_aux_in_args += 1;
223 if (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT) {
224 state->n_aux_out_args += 1;
229 case GI_TYPE_TAG_ERROR:
230 g_warn_if_fail (state->error_arg_pos < 0);
231 state->error_arg_pos = i;
238 state->return_type_info = g_callable_info_get_return_type ( (GICallableInfo *) function_info);
239 state->return_type_tag = g_type_info_get_tag (state->return_type_info);
241 if (state->return_type_tag == GI_TYPE_TAG_ARRAY) {
243 length_arg_pos = g_type_info_get_array_length (state->return_type_info);
245 if (length_arg_pos >= 0) {
246 g_assert (length_arg_pos < state->n_args);
247 state->args_is_auxiliary[length_arg_pos] = TRUE;
248 state->n_aux_out_args += 1;
252 state->n_return_values = state->n_out_args - state->n_aux_out_args;
253 if (state->return_type_tag != GI_TYPE_TAG_VOID) {
254 state->n_return_values += 1;
258 gsize n_py_args_expected;
259 Py_ssize_t py_args_pos;
261 n_py_args_expected = state->n_in_args
262 + (state->is_constructor ? 1 : 0)
263 - state->n_aux_in_args
264 - (state->error_arg_pos >= 0 ? 1 : 0);
266 if (state->n_py_args != n_py_args_expected) {
267 PyErr_Format (PyExc_TypeError,
268 "%s() takes exactly %zd argument(s) (%zd given)",
269 g_base_info_get_name ( (GIBaseInfo *) function_info),
270 n_py_args_expected, state->n_py_args);
274 /* Check argument typestate-> */
276 if (state->is_constructor || state->is_method) {
280 for (i = 0; i < state->n_args; i++) {
281 GIDirection direction;
287 direction = g_arg_info_get_direction (state->arg_infos[i]);
288 type_tag = g_type_info_get_tag (state->arg_type_infos[i]);
290 if (direction == GI_DIRECTION_OUT
291 || state->args_is_auxiliary[i]
292 || type_tag == GI_TYPE_TAG_ERROR) {
296 g_assert (py_args_pos < state->n_py_args);
297 py_arg = PyTuple_GET_ITEM (py_args, py_args_pos);
299 allow_none = g_arg_info_may_be_null (state->arg_infos[i]);
301 retval = _pygi_g_type_info_check_object (state->arg_type_infos[i],
307 } else if (!retval) {
308 _PyGI_ERROR_PREFIX ("argument %zd: ", py_args_pos);
315 g_assert (py_args_pos == state->n_py_args);
318 state->args = g_slice_alloc0 (sizeof (gpointer) * state->n_args);
319 state->in_args = g_slice_alloc0 (sizeof (GIArgument) * state->n_in_args);
320 state->out_args = g_slice_alloc0 (sizeof (GIArgument) * state->n_out_args);
321 state->out_values = g_slice_alloc0 (sizeof (GIArgument) * state->n_out_args);
322 state->backup_args = g_slice_alloc0 (sizeof (GIArgument) * state->n_backup_args);
324 /* Bind args so we can use an unique index. */
329 in_args_pos = state->is_method ? 1 : 0;
332 for (i = 0; i < state->n_args; i++) {
333 GIDirection direction;
335 gboolean is_caller_allocates;
337 direction = g_arg_info_get_direction (state->arg_infos[i]);
338 is_caller_allocates = g_arg_info_is_caller_allocates (state->arg_infos[i]);
341 case GI_DIRECTION_IN:
342 g_assert (in_args_pos < state->n_in_args);
343 state->args[i] = &state->in_args[in_args_pos];
346 case GI_DIRECTION_INOUT:
347 g_assert (in_args_pos < state->n_in_args);
348 g_assert (out_args_pos < state->n_out_args);
350 state->in_args[in_args_pos].v_pointer = &state->out_values[out_args_pos];
352 case GI_DIRECTION_OUT:
353 g_assert (out_args_pos < state->n_out_args);
355 /* caller allocates only applies to structures but GI has
356 * no way to denote that yet, so we only use caller allocates
357 * if we see a structure
359 if (is_caller_allocates) {
362 is_caller_allocates = FALSE;
363 type_tag = g_type_info_get_tag (state->arg_type_infos[i]);
365 if (type_tag == GI_TYPE_TAG_INTERFACE) {
366 GIInfoType info_type;
368 info = g_type_info_get_interface (state->arg_type_infos[i]);
369 g_assert (info != NULL);
370 info_type = g_base_info_get_type (info);
372 if (info_type == GI_INFO_TYPE_STRUCT)
373 is_caller_allocates = TRUE;
377 if (is_caller_allocates) {
378 /* if caller allocates only use one level of indirection */
379 state->out_args[out_args_pos].v_pointer = NULL;
380 state->args[i] = &state->out_args[out_args_pos];
381 if (g_struct_info_is_foreign((GIStructInfo *) info) ) {
382 PyObject *foreign_struct =
383 pygi_struct_foreign_convert_from_g_argument(info, NULL);
385 pygi_struct_foreign_convert_to_g_argument(
388 GI_TRANSFER_EVERYTHING,
391 Py_DECREF(foreign_struct);
392 } else if (g_type_is_a (g_registered_type_info_get_g_type (info), G_TYPE_BOXED)) {
393 state->args[i]->v_pointer = _pygi_boxed_alloc (info, NULL);
395 gssize size = g_struct_info_get_size ( (GIStructInfo *) info);
396 state->args[i]->v_pointer = g_malloc0 (size);
399 state->out_args[out_args_pos].v_pointer = &state->out_values[out_args_pos];
400 state->out_values[out_args_pos].v_pointer = NULL;
401 state->args[i] = &state->out_values[out_args_pos];
408 g_assert (in_args_pos == state->n_in_args);
409 g_assert (out_args_pos == state->n_out_args);
412 /* Convert the input arguments. */
414 Py_ssize_t py_args_pos;
415 gsize backup_args_pos;
420 if (state->is_constructor) {
421 /* Skip the first argument. */
423 } else if (state->is_method) {
424 /* Get the instance. */
425 GIBaseInfo *container_info;
426 GIInfoType container_info_type;
430 container_info = g_base_info_get_container (function_info);
431 container_info_type = g_base_info_get_type (container_info);
433 g_assert (py_args_pos < state->n_py_args);
434 py_arg = PyTuple_GET_ITEM (py_args, py_args_pos);
436 /* In python 2 python takes care of checking the type
437 * of the self instance. In python 3 it does not
438 * so we have to check it here
440 check_val = _pygi_g_type_interface_check_object(container_info,
444 } else if (!check_val) {
445 _PyGI_ERROR_PREFIX ("instance: ");
449 switch (container_info_type) {
450 case GI_INFO_TYPE_UNION:
451 case GI_INFO_TYPE_STRUCT:
455 type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *) container_info);
457 if (g_type_is_a (type, G_TYPE_BOXED)) {
458 g_assert (state->n_in_args > 0);
459 state->in_args[0].v_pointer = pyg_boxed_get (py_arg, void);
460 } else if (g_struct_info_is_foreign (container_info)) {
462 result = pygi_struct_foreign_convert_to_g_argument (
463 py_arg, container_info,
466 } else if (g_type_is_a (type, G_TYPE_POINTER) || type == G_TYPE_NONE) {
467 g_assert (state->n_in_args > 0);
468 state->in_args[0].v_pointer = pyg_pointer_get (py_arg, void);
470 PyErr_Format (PyExc_TypeError, "unable to convert an instance of '%s'", g_type_name (type));
476 case GI_INFO_TYPE_OBJECT:
477 case GI_INFO_TYPE_INTERFACE:
478 g_assert (state->n_in_args > 0);
479 state->in_args[0].v_pointer = pygobject_get (py_arg);
482 /* Other types don't have methods. */
483 g_assert_not_reached();
489 for (i = 0; i < state->n_args; i++) {
490 GIDirection direction;
492 if (i == state->callback_index) {
494 state->args[i]->v_pointer = state->closure->closure;
496 /* Some callbacks params accept NULL */
497 state->args[i]->v_pointer = NULL;
500 } else if (i == state->user_data_index) {
501 state->args[i]->v_pointer = state->closure;
504 } else if (i == state->destroy_notify_index) {
505 if (state->closure) {
506 /* No need to clean up if the callback is NULL */
507 PyGICClosure *destroy_notify = _pygi_destroy_notify_create();
508 state->args[i]->v_pointer = destroy_notify->closure;
513 if (state->args_is_auxiliary[i]) {
517 direction = g_arg_info_get_direction (state->arg_infos[i]);
519 if (direction == GI_DIRECTION_IN || direction == GI_DIRECTION_INOUT) {
521 GITypeTag arg_type_tag;
524 arg_type_tag = g_type_info_get_tag (state->arg_type_infos[i]);
526 if (arg_type_tag == GI_TYPE_TAG_ERROR) {
529 error = g_slice_new (GError *);
532 state->args[i]->v_pointer = error;
536 transfer = g_arg_info_get_ownership_transfer (state->arg_infos[i]);
538 g_assert (py_args_pos < state->n_py_args);
539 py_arg = PyTuple_GET_ITEM (py_args, py_args_pos);
541 *state->args[i] = _pygi_argument_from_object (py_arg, state->arg_type_infos[i], transfer);
543 if (PyErr_Occurred()) {
544 /* TODO: release previous input arguments. */
548 if (direction == GI_DIRECTION_INOUT) {
549 /* We need to keep a copy of the argument to be able to release it later. */
550 g_assert (backup_args_pos < state->n_backup_args);
551 state->backup_args[backup_args_pos] = *state->args[i];
552 backup_args_pos += 1;
555 if (arg_type_tag == GI_TYPE_TAG_ARRAY) {
557 gssize length_arg_pos;
559 array = state->args[i]->v_pointer;
561 length_arg_pos = g_type_info_get_array_length (state->arg_type_infos[i]);
562 if (length_arg_pos >= 0) {
564 /* Set the auxiliary argument holding the length. */
568 state->args[length_arg_pos]->v_size = len;
571 /* Get rid of the GArray. */
572 if ( (array != NULL) &&
573 (g_type_info_get_array_type (state->arg_type_infos[i]) == GI_ARRAY_TYPE_C)) {
574 state->args[i]->v_pointer = array->data;
576 /* HACK: We have unwrapped a C array so
577 * set the state to reflect this.
578 * If there is an error between now
579 * and when we rewrap the array
580 * we will leak C arrays due to
581 * being in an inconsitant state.
582 * e.g. for interfaces with more
583 * than one C array argument, an
584 * error may occure when not all
585 * C arrays have been rewrapped.
586 * This will be removed once the invoke
587 * rewrite branch is merged.
589 state->c_arrays_are_wrapped = FALSE;
590 if (direction != GI_DIRECTION_INOUT || transfer != GI_TRANSFER_NOTHING) {
591 /* The array hasn't been referenced anywhere, so free it to avoid losing memory. */
592 g_array_free (array, FALSE);
601 g_assert (py_args_pos == state->n_py_args);
602 g_assert (backup_args_pos == state->n_backup_args);
609 _invoke_function (struct invocation_state *state,
610 GICallableInfo *callable_info, PyObject *py_args)
617 pyg_begin_allow_threads;
618 if (g_base_info_get_type (callable_info) == GI_INFO_TYPE_FUNCTION) {
619 retval = g_function_info_invoke ( (GIFunctionInfo *) callable_info,
627 retval = g_vfunc_info_invoke ( (GIVFuncInfo *) callable_info,
628 state->implementor_gtype,
636 pyg_end_allow_threads;
639 pyglib_error_check(&error);
641 /* TODO: release input arguments. */
646 if (state->error_arg_pos >= 0) {
649 error = state->args[state->error_arg_pos]->v_pointer;
651 if (pyglib_error_check(error)) {
652 /* TODO: release input arguments. */
662 _process_invocation_state (struct invocation_state *state,
663 GIFunctionInfo *function_info, PyObject *py_args)
667 /* Convert the return value. */
668 if (state->is_constructor) {
669 PyTypeObject *py_type;
671 GIInfoType info_type;
674 if (state->return_arg.v_pointer == NULL) {
675 PyErr_SetString (PyExc_TypeError, "constructor returned NULL");
679 g_assert (state->n_py_args > 0);
680 py_type = (PyTypeObject *) PyTuple_GET_ITEM (py_args, 0);
682 info = g_type_info_get_interface (state->return_type_info);
683 g_assert (info != NULL);
685 info_type = g_base_info_get_type (info);
687 transfer = g_callable_info_get_caller_owns ( (GICallableInfo *) function_info);
690 case GI_INFO_TYPE_UNION:
691 case GI_INFO_TYPE_STRUCT:
695 type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *) info);
697 if (g_struct_info_is_foreign (info)) {
698 state->return_value =
699 pygi_struct_foreign_convert_from_g_argument (
700 info, state->return_arg.v_pointer);
701 } else if (g_type_is_a (type, G_TYPE_BOXED)) {
702 g_warn_if_fail (transfer == GI_TRANSFER_EVERYTHING);
703 state->return_value = _pygi_boxed_new (py_type, state->return_arg.v_pointer, transfer == GI_TRANSFER_EVERYTHING);
704 } else if (g_type_is_a (type, G_TYPE_POINTER) || type == G_TYPE_NONE) {
705 if (transfer != GI_TRANSFER_NOTHING)
706 g_warning ("Return argument in %s returns a struct "
707 "with a transfer mode of \"full\" "
708 "Transfer mode should be set to None for "
709 "struct types as there is no way to free "
710 "them safely. Ignoring transfer mode "
711 "to prevent a potential invalid free. "
712 "This may cause a leak in your application.",
713 g_base_info_get_name ( (GIBaseInfo *) function_info) );
715 state->return_value = _pygi_struct_new (py_type, state->return_arg.v_pointer, FALSE);
717 PyErr_Format (PyExc_TypeError, "cannot create '%s' instances", py_type->tp_name);
718 g_base_info_unref (info);
724 case GI_INFO_TYPE_OBJECT:
725 if (state->return_arg.v_pointer == NULL) {
726 PyErr_SetString (PyExc_TypeError, "constructor returned NULL");
729 state->return_value = pygobject_new (state->return_arg.v_pointer);
730 if (transfer == GI_TRANSFER_EVERYTHING) {
731 /* The new wrapper increased the reference count, so decrease it. */
732 g_object_unref (state->return_arg.v_pointer);
734 if (state->is_constructor && G_IS_INITIALLY_UNOWNED (state->return_arg.v_pointer)) {
735 /* GInitiallyUnowned constructors always end up with one extra reference, so decrease it. */
736 g_object_unref (state->return_arg.v_pointer);
740 /* Other types don't have neither methods nor constructors. */
741 g_assert_not_reached();
744 g_base_info_unref (info);
746 if (state->return_value == NULL) {
747 /* TODO: release arguments. */
753 if ( (state->return_type_tag == GI_TYPE_TAG_ARRAY) &&
754 (g_type_info_get_array_type (state->return_type_info) == GI_ARRAY_TYPE_C)) {
755 /* Create a #GArray. */
756 state->return_arg.v_pointer = _pygi_argument_to_array (&state->return_arg, state->args, state->return_type_info, state->is_method);
759 transfer = g_callable_info_get_caller_owns ( (GICallableInfo *) function_info);
761 state->return_value = _pygi_argument_to_object (&state->return_arg, state->return_type_info, transfer);
762 if (state->return_value == NULL) {
763 /* TODO: release argument. */
767 _pygi_argument_release (&state->return_arg, state->return_type_info, transfer, GI_DIRECTION_OUT);
769 if (state->return_type_tag == GI_TYPE_TAG_ARRAY
770 && transfer == GI_TRANSFER_NOTHING) {
771 /* We created a #GArray, so free it. */
772 state->return_arg.v_pointer = g_array_free (state->return_arg.v_pointer, FALSE);
776 /* Convert output arguments and release arguments. */
778 gsize return_values_pos;
780 return_values_pos = 0;
782 if (state->n_return_values > 1) {
783 /* Return a tuple. */
784 PyObject *return_values;
786 return_values = PyTuple_New (state->n_return_values);
787 if (return_values == NULL) {
788 /* TODO: release arguments. */
792 if (state->return_type_tag == GI_TYPE_TAG_VOID) {
793 /* The current return value is None. */
794 Py_DECREF (state->return_value);
796 /* Put the return value first. */
797 g_assert (state->return_value != NULL);
798 PyTuple_SET_ITEM (return_values, return_values_pos, state->return_value);
799 return_values_pos += 1;
802 state->return_value = return_values;
805 for (i = 0; i < state->n_args; i++) {
806 GIDirection direction;
810 if (state->args_is_auxiliary[i]) {
811 /* Auxiliary arguments are handled at the same time as their relatives. */
815 direction = g_arg_info_get_direction (state->arg_infos[i]);
816 transfer = g_arg_info_get_ownership_transfer (state->arg_infos[i]);
818 type_tag = g_type_info_get_tag (state->arg_type_infos[i]);
820 if ( (type_tag == GI_TYPE_TAG_ARRAY) &&
821 (g_type_info_get_array_type (state->arg_type_infos[i]) == GI_ARRAY_TYPE_C) &&
822 (direction != GI_DIRECTION_IN || transfer == GI_TRANSFER_NOTHING)) {
823 /* Create a #GArray. */
824 state->args[i]->v_pointer = _pygi_argument_to_array (state->args[i], state->args, state->arg_type_infos[i], state->is_method);
827 if (direction == GI_DIRECTION_INOUT || direction == GI_DIRECTION_OUT) {
828 /* Convert the argument. */
831 /* If we created it, deallocate when it goes out of scope
832 * otherwise it is unsafe to deallocate random structures
835 if (type_tag == GI_TYPE_TAG_INTERFACE) {
837 GIInfoType info_type;
840 info = g_type_info_get_interface (state->arg_type_infos[i]);
841 g_assert (info != NULL);
842 info_type = g_base_info_get_type (info);
843 type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *) info);
845 if ( (info_type == GI_INFO_TYPE_STRUCT) &&
846 !g_struct_info_is_foreign((GIStructInfo *) info) &&
847 !g_type_is_a (type, G_TYPE_BOXED)) {
848 if (g_arg_info_is_caller_allocates (state->arg_infos[i])) {
849 transfer = GI_TRANSFER_EVERYTHING;
850 } else if (transfer == GI_TRANSFER_EVERYTHING) {
851 transfer = GI_TRANSFER_NOTHING;
852 g_warning ("Out argument %ld in %s returns a struct "
853 "with a transfer mode of \"full\". "
854 "Transfer mode should be set to \"none\" for "
855 "struct type returns as there is no way to free "
856 "them safely. Ignoring transfer mode "
857 "to prevent a potential invalid free. "
858 "This may cause a leak in your application.",
859 i, g_base_info_get_name ( (GIBaseInfo *) function_info) );
864 obj = _pygi_argument_to_object (state->args[i], state->arg_type_infos[i], transfer);
866 /* TODO: release arguments. */
870 g_assert (return_values_pos < state->n_return_values);
872 if (state->n_return_values > 1) {
873 PyTuple_SET_ITEM (state->return_value, return_values_pos, obj);
875 /* The current return value is None. */
876 Py_DECREF (state->return_value);
877 state->return_value = obj;
880 return_values_pos += 1;
885 /* HACK: We rewrapped any C arrays above in a GArray so they are ok to
886 * free as GArrays. We will always leak C arrays if there is
887 * an error before we reach this state as there is no easy way
888 * to know which arrays were wrapped if there are more than one.
889 * This will be removed with better array handling once merge
890 * the invoke rewrite branch.
892 state->c_arrays_are_wrapped = TRUE;
893 g_assert (state->n_return_values <= 1 || return_values_pos == state->n_return_values);
900 _free_invocation_state (struct invocation_state *state)
903 gsize backup_args_pos;
905 if (state->return_type_info != NULL) {
906 g_base_info_unref ( (GIBaseInfo *) state->return_type_info);
909 if (state->closure != NULL) {
910 if (state->closure->scope == GI_SCOPE_TYPE_CALL)
911 _pygi_invoke_closure_free (state->closure);
914 /* release all arguments. */
916 for (i = 0; i < state->n_args; i++) {
918 if (state->args_is_auxiliary[i]) {
919 /* Auxiliary arguments are not released. */
923 if (state->arg_infos[i] != NULL
924 && state->arg_type_infos[i] != NULL) {
925 GIDirection direction;
929 direction = g_arg_info_get_direction (state->arg_infos[i]);
930 transfer = g_arg_info_get_ownership_transfer (state->arg_infos[i]);
932 /* Release the argument. */
933 if (direction == GI_DIRECTION_INOUT) {
934 if (state->args != NULL) {
935 _pygi_argument_release (&state->backup_args[backup_args_pos],
936 state->arg_type_infos[i],
937 transfer, GI_DIRECTION_IN);
939 backup_args_pos += 1;
941 if (state->args != NULL && state->args[i] != NULL) {
942 type_tag = g_type_info_get_tag (state->arg_type_infos[i]);
944 if (type_tag == GI_TYPE_TAG_ARRAY &&
945 (direction == GI_DIRECTION_IN || direction == GI_DIRECTION_INOUT) &&
946 (g_type_info_get_array_type (state->arg_type_infos[i]) == GI_ARRAY_TYPE_C) &&
947 !state->c_arrays_are_wrapped) {
948 /* HACK: Noop - we are in an inconsitant state due to
949 * complex array handler so leak any C arrays
950 * as we don't know if we can free them safely.
951 * This will be removed when we merge the
952 * invoke rewrite branch.
955 _pygi_argument_release (state->args[i], state->arg_type_infos[i],
956 transfer, direction);
959 if (type_tag == GI_TYPE_TAG_ARRAY
960 && (direction != GI_DIRECTION_IN && transfer == GI_TRANSFER_NOTHING)) {
961 /* We created an *out* #GArray and it has not been released above, so free it. */
962 state->args[i]->v_pointer = g_array_free (state->args[i]->v_pointer, FALSE);
968 if (state->arg_type_infos[i] != NULL)
969 g_base_info_unref ( (GIBaseInfo *) state->arg_type_infos[i]);
970 if (state->arg_infos[i] != NULL)
971 g_base_info_unref ( (GIBaseInfo *) state->arg_infos[i]);
973 g_assert (backup_args_pos == state->n_backup_args);
975 g_slice_free1 (sizeof (gpointer) * state->n_args, state->arg_infos);
976 g_slice_free1 (sizeof (gpointer) * state->n_args, state->arg_type_infos);
977 g_slice_free1 (sizeof (gboolean) * state->n_args, state->args_is_auxiliary);
979 if (state->args != NULL) {
980 g_slice_free1 (sizeof (gpointer) * state->n_args, state->args);
983 if (state->in_args != NULL) {
984 g_slice_free1 (sizeof (GIArgument) * state->n_in_args, state->in_args);
987 if (state->out_args != NULL) {
988 g_slice_free1 (sizeof (GIArgument) * state->n_out_args, state->out_args);
991 if (state->out_values != NULL) {
992 g_slice_free1 (sizeof (GIArgument) * state->n_out_args, state->out_values);
995 if (state->backup_args != NULL) {
996 g_slice_free1 (sizeof (GIArgument) * state->n_backup_args, state->backup_args);
999 if (PyErr_Occurred()) {
1000 Py_CLEAR (state->return_value);
1006 _wrap_g_callable_info_invoke (PyGIBaseInfo *self, PyObject *py_args,
1009 struct invocation_state state = { 0, };
1011 if (!_initialize_invocation_state (&state, self->info, py_args, kwargs)) {
1012 _free_invocation_state (&state);
1016 if (!_prepare_invocation_state (&state, self->info, py_args)) {
1017 _free_invocation_state (&state);
1021 if (!_invoke_function (&state, self->info, py_args)) {
1022 _free_invocation_state (&state);
1026 if (!_process_invocation_state (&state, self->info, py_args)) {
1027 _free_invocation_state (&state);
1031 _free_invocation_state (&state);
1032 return state.return_value;