1 /* -*- Mode: C; c-basic-offset: 4 -*-
2 * vim: tabstop=4 shiftwidth=4 expandtab
3 *
4 * Copyright (C) 2005-2009 Johan Dahlin <johan@gnome.org>
5 *
6 * pygi-invoke.c: main invocation function
7 *
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.
12 *
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.
17 *
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
21 * USA
22 */
23
24 #include <pyglib.h>
25 #include "pygi-invoke.h"
26
27 struct invocation_state
28 {
29 gboolean is_method;
30 gboolean is_constructor;
31
32 gsize n_args;
33 gsize n_in_args;
34 gsize n_out_args;
35 gsize n_backup_args;
36 Py_ssize_t n_py_args;
37 gsize n_aux_in_args;
38 gsize n_aux_out_args;
39 gsize n_return_values;
40
41 guint8 callback_index;
42 guint8 user_data_index;
43 guint8 destroy_notify_index;
44 PyGICClosure *closure;
45
46 glong error_arg_pos;
47
48 GIArgInfo **arg_infos;
49 GITypeInfo **arg_type_infos;
50 GITypeInfo *return_type_info;
51 GITypeTag return_type_tag;
52
53 GIArgument **args;
54 gboolean *args_is_auxiliary;
55
56 GIArgument *in_args;
57 GIArgument *out_args;
58 GIArgument *out_values;
59 GIArgument *backup_args;
60 GIArgument return_arg;
61
62 PyObject *return_value;
63
64 GType implementor_gtype;
65
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
69 */
70 gboolean c_arrays_are_wrapped;
71 };
72
73 static gboolean
_initialize_invocation_state(struct invocation_state * state,GIFunctionInfo * info,PyObject * py_args,PyObject * kwargs)74 _initialize_invocation_state (struct invocation_state *state,
75 GIFunctionInfo *info,
76 PyObject *py_args,
77 PyObject *kwargs)
78 {
79 if (g_base_info_get_type (info) == GI_INFO_TYPE_FUNCTION) {
80 GIFunctionInfoFlags flags = g_function_info_get_flags (info);
81
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;
85 } else {
86 PyObject *obj;
87
88 state->is_method = TRUE;
89 state->is_constructor = FALSE;
90
91 obj = PyDict_GetItemString (kwargs, "gtype");
92 if (obj == NULL) {
93 PyErr_SetString (PyExc_TypeError,
94 "need the GType of the implementor class");
95 return FALSE;
96 }
97
98 state->implementor_gtype = pyg_type_from_object (obj);
99 if (state->implementor_gtype == 0)
100 return FALSE;
101 }
102
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;
110
111 /* Check the argument count. */
112 state->n_py_args = PyTuple_Size (py_args);
113 g_assert (state->n_py_args >= 0);
114
115 state->error_arg_pos = -1;
116
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);
120
121 state->return_value = NULL;
122 state->closure = NULL;
123 state->return_type_info = NULL;
124 state->args = NULL;
125 state->in_args = NULL;
126 state->out_args = NULL;
127 state->out_values = NULL;
128 state->backup_args = NULL;
129
130 /* HACK: this gets marked FALSE whenever a C array in the args is
131 * not wrapped by a GArray
132 */
133 state->c_arrays_are_wrapped = TRUE;
134
135 return TRUE;
136 }
137
138 static gboolean
_prepare_invocation_state(struct invocation_state * state,GIFunctionInfo * function_info,PyObject * py_args)139 _prepare_invocation_state (struct invocation_state *state,
140 GIFunctionInfo *function_info, PyObject *py_args)
141 {
142 gsize i;
143
144 if (!_pygi_scan_for_callbacks (function_info,
145 state->is_method,
146 &state->callback_index, &state->user_data_index,
147 &state->destroy_notify_index))
148 return FALSE;
149
150 if (state->callback_index != G_MAXUINT8) {
151
152 if (!_pygi_create_callback (function_info,
153 state->is_method,
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))
159 return FALSE;
160
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;
165 }
166 }
167
168 if (state->is_method) {
169 /* The first argument is the instance. */
170 state->n_in_args += 1;
171 }
172
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.
175 */
176 for (i = 0; i < state->n_args; i++) {
177 GIDirection direction;
178 GITransfer transfer;
179 GITypeTag arg_type_tag;
180
181 state->arg_infos[i] = g_callable_info_get_arg ( (GICallableInfo *) function_info,
182 i);
183
184 state->arg_type_infos[i] = g_arg_info_get_type (state->arg_infos[i]);
185
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]);
189
190 if (direction == GI_DIRECTION_IN || direction == GI_DIRECTION_INOUT) {
191 state->n_in_args += 1;
192 }
193 if (direction == GI_DIRECTION_INOUT) {
194 state->n_backup_args += 1;
195 }
196 if (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT) {
197 state->n_out_args += 1;
198 }
199
200 switch (arg_type_tag) {
201 case GI_TYPE_TAG_ARRAY:
202 {
203 gint length_arg_pos;
204
205 length_arg_pos = g_type_info_get_array_length (state->arg_type_infos[i]);
206
207 if (length_arg_pos < 0) {
208 break;
209 }
210
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;
215 }
216
217 g_assert (length_arg_pos < state->n_args);
218 state->args_is_auxiliary[length_arg_pos] = TRUE;
219
220 if (direction == GI_DIRECTION_IN || direction == GI_DIRECTION_INOUT) {
221 state->n_aux_in_args += 1;
222 }
223 if (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT) {
224 state->n_aux_out_args += 1;
225 }
226
227 break;
228 }
229 case GI_TYPE_TAG_ERROR:
230 g_warn_if_fail (state->error_arg_pos < 0);
231 state->error_arg_pos = i;
232 break;
233 default:
234 break;
235 }
236 }
237
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);
240
241 if (state->return_type_tag == GI_TYPE_TAG_ARRAY) {
242 gint length_arg_pos;
243 length_arg_pos = g_type_info_get_array_length (state->return_type_info);
244
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;
249 }
250 }
251
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;
255 }
256
257 {
258 gsize n_py_args_expected;
259 Py_ssize_t py_args_pos;
260
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);
265
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);
271 return FALSE;
272 }
273
274 /* Check argument typestate-> */
275 py_args_pos = 0;
276 if (state->is_constructor || state->is_method) {
277 py_args_pos += 1;
278 }
279
280 for (i = 0; i < state->n_args; i++) {
281 GIDirection direction;
282 GITypeTag type_tag;
283 PyObject *py_arg;
284 gint retval;
285 gboolean allow_none;
286
287 direction = g_arg_info_get_direction (state->arg_infos[i]);
288 type_tag = g_type_info_get_tag (state->arg_type_infos[i]);
289
290 if (direction == GI_DIRECTION_OUT
291 || state->args_is_auxiliary[i]
292 || type_tag == GI_TYPE_TAG_ERROR) {
293 continue;
294 }
295
296 g_assert (py_args_pos < state->n_py_args);
297 py_arg = PyTuple_GET_ITEM (py_args, py_args_pos);
298
299 allow_none = g_arg_info_may_be_null (state->arg_infos[i]);
300
301 retval = _pygi_g_type_info_check_object (state->arg_type_infos[i],
302 py_arg,
303 allow_none);
304
305 if (retval < 0) {
306 return FALSE;
307 } else if (!retval) {
308 _PyGI_ERROR_PREFIX ("argument %zd: ", py_args_pos);
309 return FALSE;
310 }
311
312 py_args_pos += 1;
313 }
314
315 g_assert (py_args_pos == state->n_py_args);
316 }
317
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);
323
324 /* Bind args so we can use an unique index. */
325 {
326 gsize in_args_pos;
327 gsize out_args_pos;
328
329 in_args_pos = state->is_method ? 1 : 0;
330 out_args_pos = 0;
331
332 for (i = 0; i < state->n_args; i++) {
333 GIDirection direction;
334 GIBaseInfo *info;
335 gboolean is_caller_allocates;
336
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]);
339
340 switch (direction) {
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];
344 in_args_pos += 1;
345 break;
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);
349
350 state->in_args[in_args_pos].v_pointer = &state->out_values[out_args_pos];
351 in_args_pos += 1;
352 case GI_DIRECTION_OUT:
353 g_assert (out_args_pos < state->n_out_args);
354
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
358 */
359 if (is_caller_allocates) {
360 GITypeTag type_tag;
361
362 is_caller_allocates = FALSE;
363 type_tag = g_type_info_get_tag (state->arg_type_infos[i]);
364
365 if (type_tag == GI_TYPE_TAG_INTERFACE) {
366 GIInfoType info_type;
367
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);
371
372 if (info_type == GI_INFO_TYPE_STRUCT)
373 is_caller_allocates = TRUE;
374 }
375 }
376
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);
384
385 pygi_struct_foreign_convert_to_g_argument(
386 foreign_struct,
387 info,
388 GI_TRANSFER_EVERYTHING,
389 state->args[i]);
390
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);
394 } else {
395 gssize size = g_struct_info_get_size ( (GIStructInfo *) info);
396 state->args[i]->v_pointer = g_malloc0 (size);
397 }
398 } else {
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];
402 }
403
404 out_args_pos += 1;
405 }
406 }
407
408 g_assert (in_args_pos == state->n_in_args);
409 g_assert (out_args_pos == state->n_out_args);
410 }
411
412 /* Convert the input arguments. */
413 {
414 Py_ssize_t py_args_pos;
415 gsize backup_args_pos;
416
417 py_args_pos = 0;
418 backup_args_pos = 0;
419
420 if (state->is_constructor) {
421 /* Skip the first argument. */
422 py_args_pos += 1;
423 } else if (state->is_method) {
424 /* Get the instance. */
425 GIBaseInfo *container_info;
426 GIInfoType container_info_type;
427 PyObject *py_arg;
428 gint check_val;
429
430 container_info = g_base_info_get_container (function_info);
431 container_info_type = g_base_info_get_type (container_info);
432
433 g_assert (py_args_pos < state->n_py_args);
434 py_arg = PyTuple_GET_ITEM (py_args, py_args_pos);
435
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
439 */
440 check_val = _pygi_g_type_interface_check_object(container_info,
441 py_arg);
442 if (check_val < 0) {
443 return FALSE;
444 } else if (!check_val) {
445 _PyGI_ERROR_PREFIX ("instance: ");
446 return FALSE;
447 }
448
449 switch (container_info_type) {
450 case GI_INFO_TYPE_UNION:
451 case GI_INFO_TYPE_STRUCT:
452 {
453 GType type;
454
455 type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *) container_info);
456
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)) {
461 PyObject *result;
462 result = pygi_struct_foreign_convert_to_g_argument (
463 py_arg, container_info,
464 GI_TRANSFER_NOTHING,
465 &state->in_args[0]);
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);
469 } else {
470 PyErr_Format (PyExc_TypeError, "unable to convert an instance of '%s'", g_type_name (type));
471 return FALSE;
472 }
473
474 break;
475 }
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);
480 break;
481 default:
482 /* Other types don't have methods. */
483 g_assert_not_reached();
484 }
485
486 py_args_pos += 1;
487 }
488
489 for (i = 0; i < state->n_args; i++) {
490 GIDirection direction;
491
492 if (i == state->callback_index) {
493 if (state->closure)
494 state->args[i]->v_pointer = state->closure->closure;
495 else
496 /* Some callbacks params accept NULL */
497 state->args[i]->v_pointer = NULL;
498 py_args_pos++;
499 continue;
500 } else if (i == state->user_data_index) {
501 state->args[i]->v_pointer = state->closure;
502 py_args_pos++;
503 continue;
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;
509 }
510 continue;
511 }
512
513 if (state->args_is_auxiliary[i]) {
514 continue;
515 }
516
517 direction = g_arg_info_get_direction (state->arg_infos[i]);
518
519 if (direction == GI_DIRECTION_IN || direction == GI_DIRECTION_INOUT) {
520 PyObject *py_arg;
521 GITypeTag arg_type_tag;
522 GITransfer transfer;
523
524 arg_type_tag = g_type_info_get_tag (state->arg_type_infos[i]);
525
526 if (arg_type_tag == GI_TYPE_TAG_ERROR) {
527 GError **error;
528
529 error = g_slice_new (GError *);
530 *error = NULL;
531
532 state->args[i]->v_pointer = error;
533 continue;
534 }
535
536 transfer = g_arg_info_get_ownership_transfer (state->arg_infos[i]);
537
538 g_assert (py_args_pos < state->n_py_args);
539 py_arg = PyTuple_GET_ITEM (py_args, py_args_pos);
540
541 *state->args[i] = _pygi_argument_from_object (py_arg, state->arg_type_infos[i], transfer);
542
543 if (PyErr_Occurred()) {
544 /* TODO: release previous input arguments. */
545 return FALSE;
546 }
547
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;
553 }
554
555 if (arg_type_tag == GI_TYPE_TAG_ARRAY) {
556 GArray *array;
557 gssize length_arg_pos;
558
559 array = state->args[i]->v_pointer;
560
561 length_arg_pos = g_type_info_get_array_length (state->arg_type_infos[i]);
562 if (length_arg_pos >= 0) {
563 int len = 0;
564 /* Set the auxiliary argument holding the length. */
565 if (array)
566 len = array->len;
567
568 state->args[length_arg_pos]->v_size = len;
569 }
570
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;
575
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.
588 */
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);
593 }
594 }
595 }
596
597 py_args_pos += 1;
598 }
599 }
600
601 g_assert (py_args_pos == state->n_py_args);
602 g_assert (backup_args_pos == state->n_backup_args);
603 }
604
605 return TRUE;
606 }
607
608 static gboolean
_invoke_function(struct invocation_state * state,GICallableInfo * callable_info,PyObject * py_args)609 _invoke_function (struct invocation_state *state,
610 GICallableInfo *callable_info, PyObject *py_args)
611 {
612 GError *error;
613 gint retval;
614
615 error = NULL;
616
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,
620 state->in_args,
621 state->n_in_args,
622 state->out_args,
623 state->n_out_args,
624 &state->return_arg,
625 &error);
626 } else {
627 retval = g_vfunc_info_invoke ( (GIVFuncInfo *) callable_info,
628 state->implementor_gtype,
629 state->in_args,
630 state->n_in_args,
631 state->out_args,
632 state->n_out_args,
633 &state->return_arg,
634 &error);
635 }
636 pyg_end_allow_threads;
637
638 if (!retval) {
639 pyglib_error_check(&error);
640
641 /* TODO: release input arguments. */
642
643 return FALSE;
644 }
645
646 if (state->error_arg_pos >= 0) {
647 GError **error;
648
649 error = state->args[state->error_arg_pos]->v_pointer;
650
651 if (pyglib_error_check(error)) {
652 /* TODO: release input arguments. */
653
654 return FALSE;
655 }
656 }
657
658 return TRUE;
659 }
660
661 static gboolean
_process_invocation_state(struct invocation_state * state,GIFunctionInfo * function_info,PyObject * py_args)662 _process_invocation_state (struct invocation_state *state,
663 GIFunctionInfo *function_info, PyObject *py_args)
664 {
665 gsize i;
666
667 /* Convert the return value. */
668 if (state->is_constructor) {
669 PyTypeObject *py_type;
670 GIBaseInfo *info;
671 GIInfoType info_type;
672 GITransfer transfer;
673
674 if (state->return_arg.v_pointer == NULL) {
675 PyErr_SetString (PyExc_TypeError, "constructor returned NULL");
676 return FALSE;
677 }
678
679 g_assert (state->n_py_args > 0);
680 py_type = (PyTypeObject *) PyTuple_GET_ITEM (py_args, 0);
681
682 info = g_type_info_get_interface (state->return_type_info);
683 g_assert (info != NULL);
684
685 info_type = g_base_info_get_type (info);
686
687 transfer = g_callable_info_get_caller_owns ( (GICallableInfo *) function_info);
688
689 switch (info_type) {
690 case GI_INFO_TYPE_UNION:
691 case GI_INFO_TYPE_STRUCT:
692 {
693 GType type;
694
695 type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *) info);
696
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) );
714
715 state->return_value = _pygi_struct_new (py_type, state->return_arg.v_pointer, FALSE);
716 } else {
717 PyErr_Format (PyExc_TypeError, "cannot create '%s' instances", py_type->tp_name);
718 g_base_info_unref (info);
719 return FALSE;
720 }
721
722 break;
723 }
724 case GI_INFO_TYPE_OBJECT:
725 if (state->return_arg.v_pointer == NULL) {
726 PyErr_SetString (PyExc_TypeError, "constructor returned NULL");
727 break;
728 }
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);
733 }
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);
737 }
738 break;
739 default:
740 /* Other types don't have neither methods nor constructors. */
741 g_assert_not_reached();
742 }
743
744 g_base_info_unref (info);
745
746 if (state->return_value == NULL) {
747 /* TODO: release arguments. */
748 return FALSE;
749 }
750 } else {
751 GITransfer transfer;
752
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);
757 }
758
759 transfer = g_callable_info_get_caller_owns ( (GICallableInfo *) function_info);
760
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. */
764 return FALSE;
765 }
766
767 _pygi_argument_release (&state->return_arg, state->return_type_info, transfer, GI_DIRECTION_OUT);
768
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);
773 }
774 }
775
776 /* Convert output arguments and release arguments. */
777 {
778 gsize return_values_pos;
779
780 return_values_pos = 0;
781
782 if (state->n_return_values > 1) {
783 /* Return a tuple. */
784 PyObject *return_values;
785
786 return_values = PyTuple_New (state->n_return_values);
787 if (return_values == NULL) {
788 /* TODO: release arguments. */
789 return FALSE;
790 }
791
792 if (state->return_type_tag == GI_TYPE_TAG_VOID) {
793 /* The current return value is None. */
794 Py_DECREF (state->return_value);
795 } else {
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;
800 }
801
802 state->return_value = return_values;
803 }
804
805 for (i = 0; i < state->n_args; i++) {
806 GIDirection direction;
807 GITypeTag type_tag;
808 GITransfer transfer;
809
810 if (state->args_is_auxiliary[i]) {
811 /* Auxiliary arguments are handled at the same time as their relatives. */
812 continue;
813 }
814
815 direction = g_arg_info_get_direction (state->arg_infos[i]);
816 transfer = g_arg_info_get_ownership_transfer (state->arg_infos[i]);
817
818 type_tag = g_type_info_get_tag (state->arg_type_infos[i]);
819
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);
825 }
826
827 if (direction == GI_DIRECTION_INOUT || direction == GI_DIRECTION_OUT) {
828 /* Convert the argument. */
829 PyObject *obj;
830
831 /* If we created it, deallocate when it goes out of scope
832 * otherwise it is unsafe to deallocate random structures
833 * we are given
834 */
835 if (type_tag == GI_TYPE_TAG_INTERFACE) {
836 GIBaseInfo *info;
837 GIInfoType info_type;
838 GType type;
839
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);
844
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) );
860 }
861 }
862 }
863
864 obj = _pygi_argument_to_object (state->args[i], state->arg_type_infos[i], transfer);
865 if (obj == NULL) {
866 /* TODO: release arguments. */
867 return FALSE;
868 }
869
870 g_assert (return_values_pos < state->n_return_values);
871
872 if (state->n_return_values > 1) {
873 PyTuple_SET_ITEM (state->return_value, return_values_pos, obj);
874 } else {
875 /* The current return value is None. */
876 Py_DECREF (state->return_value);
877 state->return_value = obj;
878 }
879
880 return_values_pos += 1;
881 }
882
883 }
884
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.
891 */
892 state->c_arrays_are_wrapped = TRUE;
893 g_assert (state->n_return_values <= 1 || return_values_pos == state->n_return_values);
894 }
895
896 return TRUE;
897 }
898
899 static void
_free_invocation_state(struct invocation_state * state)900 _free_invocation_state (struct invocation_state *state)
901 {
902 gsize i;
903 gsize backup_args_pos;
904
905 if (state->return_type_info != NULL) {
906 g_base_info_unref ( (GIBaseInfo *) state->return_type_info);
907 }
908
909 if (state->closure != NULL) {
910 if (state->closure->scope == GI_SCOPE_TYPE_CALL)
911 _pygi_invoke_closure_free (state->closure);
912 }
913
914 /* release all arguments. */
915 backup_args_pos = 0;
916 for (i = 0; i < state->n_args; i++) {
917
918 if (state->args_is_auxiliary[i]) {
919 /* Auxiliary arguments are not released. */
920 continue;
921 }
922
923 if (state->arg_infos[i] != NULL
924 && state->arg_type_infos[i] != NULL) {
925 GIDirection direction;
926 GITypeTag type_tag;
927 GITransfer transfer;
928
929 direction = g_arg_info_get_direction (state->arg_infos[i]);
930 transfer = g_arg_info_get_ownership_transfer (state->arg_infos[i]);
931
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);
938 }
939 backup_args_pos += 1;
940 }
941 if (state->args != NULL && state->args[i] != NULL) {
942 type_tag = g_type_info_get_tag (state->arg_type_infos[i]);
943
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.
953 */
954 } else {
955 _pygi_argument_release (state->args[i], state->arg_type_infos[i],
956 transfer, direction);
957 }
958
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);
963 }
964 }
965
966 }
967
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]);
972 }
973 g_assert (backup_args_pos == state->n_backup_args);
974
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);
978
979 if (state->args != NULL) {
980 g_slice_free1 (sizeof (gpointer) * state->n_args, state->args);
981 }
982
983 if (state->in_args != NULL) {
984 g_slice_free1 (sizeof (GIArgument) * state->n_in_args, state->in_args);
985 }
986
987 if (state->out_args != NULL) {
988 g_slice_free1 (sizeof (GIArgument) * state->n_out_args, state->out_args);
989 }
990
991 if (state->out_values != NULL) {
992 g_slice_free1 (sizeof (GIArgument) * state->n_out_args, state->out_values);
993 }
994
995 if (state->backup_args != NULL) {
996 g_slice_free1 (sizeof (GIArgument) * state->n_backup_args, state->backup_args);
997 }
998
999 if (PyErr_Occurred()) {
1000 Py_CLEAR (state->return_value);
1001 }
1002 }
1003
1004
1005 PyObject *
_wrap_g_callable_info_invoke(PyGIBaseInfo * self,PyObject * py_args,PyObject * kwargs)1006 _wrap_g_callable_info_invoke (PyGIBaseInfo *self, PyObject *py_args,
1007 PyObject *kwargs)
1008 {
1009 struct invocation_state state = { 0, };
1010
1011 if (!_initialize_invocation_state (&state, self->info, py_args, kwargs)) {
1012 _free_invocation_state (&state);
1013 return NULL;
1014 }
1015
1016 if (!_prepare_invocation_state (&state, self->info, py_args)) {
1017 _free_invocation_state (&state);
1018 return NULL;
1019 }
1020
1021 if (!_invoke_function (&state, self->info, py_args)) {
1022 _free_invocation_state (&state);
1023 return NULL;
1024 }
1025
1026 if (!_process_invocation_state (&state, self->info, py_args)) {
1027 _free_invocation_state (&state);
1028 return NULL;
1029 }
1030
1031 _free_invocation_state (&state);
1032 return state.return_value;
1033 }
1034
1035