Imported Upstream version 3.9.91
[platform/upstream/python-gobject.git] / gi / pygi-invoke.c
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  * Copyright (C) 2011 John (J5) Palimier <johnp@redhat.com>
6  *
7  *   pygi-invoke.c: main invocation function
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
22  * USA
23  */
24
25 #include <pyglib.h>
26 #include "pygi-invoke.h"
27 #include "pygi-marshal-cleanup.h"
28
29 static inline gboolean
30 _invoke_callable (PyGIInvokeState *state,
31                   PyGICallableCache *cache,
32                   GICallableInfo *callable_info,
33                   GCallback function_ptr)
34 {
35     GError *error;
36     gint retval;
37
38     error = NULL;
39
40     Py_BEGIN_ALLOW_THREADS;
41
42     /* FIXME: use this for now but we can streamline the calls */
43     if (cache->function_type == PYGI_FUNCTION_TYPE_VFUNC)
44         retval = g_vfunc_info_invoke ( callable_info,
45                                        state->implementor_gtype,
46                                        state->in_args,
47                                        cache->n_from_py_args,
48                                        state->out_args,
49                                        cache->n_to_py_args,
50                                       &state->return_arg,
51                                       &error);
52     else if (g_base_info_get_type (callable_info) == GI_INFO_TYPE_CALLBACK)
53         retval = g_callable_info_invoke (callable_info,
54                                          function_ptr,
55                                          state->in_args,
56                                          cache->n_from_py_args,
57                                          state->out_args,
58                                          cache->n_to_py_args,
59                                          &state->return_arg,
60                                          FALSE,
61                                          FALSE,
62                                          &error);
63     else
64         retval = g_function_info_invoke ( callable_info,
65                                           state->in_args,
66                                           cache->n_from_py_args,
67                                           state->out_args,
68                                           cache->n_to_py_args,
69                                          &state->return_arg,
70                                          &error);
71     Py_END_ALLOW_THREADS;
72
73     if (!retval) {
74         g_assert (error != NULL);
75         pyglib_error_check (&error);
76
77         /* It is unclear if the error occured before or after the C
78          * function was invoked so for now assume success
79          * We eventually should marshal directly to FFI so we no longer
80          * have to use the reference implementation
81          */
82         pygi_marshal_cleanup_args_from_py_marshal_success (state, cache);
83
84         return FALSE;
85     }
86
87     if (state->error != NULL) {
88         if (pyglib_error_check (&(state->error))) {
89             /* even though we errored out, the call itself was successful,
90                so we assume the call processed all of the parameters */
91             pygi_marshal_cleanup_args_from_py_marshal_success (state, cache);
92             return FALSE;
93         }
94     }
95
96     return TRUE;
97 }
98
99 static gboolean
100 _check_for_unexpected_kwargs (const gchar *function_name,
101                               GHashTable  *arg_name_hash,
102                               PyObject    *py_kwargs)
103 {
104     PyObject *dict_key, *dict_value;
105     Py_ssize_t dict_iter_pos = 0;
106
107     while (PyDict_Next (py_kwargs, &dict_iter_pos, &dict_key, &dict_value)) {
108         PyObject *key;
109
110 #if PY_VERSION_HEX < 0x03000000
111         if (PyString_Check (dict_key)) {
112             Py_INCREF (dict_key);
113             key = dict_key;
114         } else
115 #endif
116         {
117             key = PyUnicode_AsUTF8String (dict_key);
118             if (key == NULL) {
119                 return FALSE;
120             }
121         }
122
123         if (g_hash_table_lookup (arg_name_hash, PyBytes_AsString(key)) == NULL) {
124             PyErr_Format (PyExc_TypeError,
125                           "%.200s() got an unexpected keyword argument '%.400s'",
126                           function_name,
127                           PyBytes_AsString (key));
128             Py_DECREF (key);
129             return FALSE;
130         }
131
132         Py_DECREF (key);
133     }
134     return TRUE;
135 }
136
137 /**
138  * _py_args_combine_and_check_length:
139  * @cache: PyGICallableCache
140  * @py_args: the tuple of positional arguments.
141  * @py_kwargs: the dict of keyword arguments to be merged with py_args.
142  *
143  * Returns: New value reference to the combined py_args and py_kwargs.
144  */
145 static PyObject *
146 _py_args_combine_and_check_length (PyGICallableCache *cache,
147                                    PyObject    *py_args,
148                                    PyObject    *py_kwargs)
149 {
150     PyObject *combined_py_args = NULL;
151     Py_ssize_t n_py_args, n_py_kwargs, i;
152     guint n_expected_args;
153     GSList *l;
154     const gchar *function_name = cache->name;
155
156     n_py_args = PyTuple_GET_SIZE (py_args);
157     if (py_kwargs == NULL)
158         n_py_kwargs = 0;
159     else
160         n_py_kwargs = PyDict_Size (py_kwargs);
161
162     /* Fast path, we already have the exact number of args and not kwargs. */
163     n_expected_args = g_slist_length (cache->arg_name_list);
164     if (n_py_kwargs == 0 && n_py_args == n_expected_args) {
165         Py_INCREF (py_args);
166         return py_args;
167     }
168
169     if (n_expected_args < n_py_args) {
170         PyErr_Format (PyExc_TypeError,
171                       "%.200s() takes exactly %d %sargument%s (%zd given)",
172                       function_name,
173                       n_expected_args,
174                       n_py_kwargs > 0 ? "non-keyword " : "",
175                       n_expected_args == 1 ? "" : "s",
176                       n_py_args);
177         return NULL;
178     }
179
180     if (n_py_kwargs > 0 && !_check_for_unexpected_kwargs (function_name,
181                                                           cache->arg_name_hash,
182                                                           py_kwargs)) {
183         return NULL;
184     }
185
186     /* will hold arguments from both py_args and py_kwargs
187      * when they are combined into a single tuple */
188     combined_py_args = PyTuple_New (n_expected_args);
189
190     for (i = 0; i < n_py_args; i++) {
191         PyObject *item = PyTuple_GET_ITEM (py_args, i);
192         Py_INCREF (item);
193         PyTuple_SET_ITEM (combined_py_args, i, item);
194     }
195
196     for (i = 0, l = cache->arg_name_list; i < n_expected_args && l; i++, l = l->next) {
197         PyObject *py_arg_item, *kw_arg_item = NULL;
198         const gchar *arg_name = l->data;
199
200         if (n_py_kwargs > 0 && arg_name != NULL) {
201             /* NULL means this argument has no keyword name */
202             /* ex. the first argument to a method or constructor */
203             kw_arg_item = PyDict_GetItemString (py_kwargs, arg_name);
204         }
205         py_arg_item = PyTuple_GET_ITEM (combined_py_args, i);
206
207         if (kw_arg_item != NULL && py_arg_item == NULL) {
208             Py_INCREF (kw_arg_item);
209             PyTuple_SET_ITEM (combined_py_args, i, kw_arg_item);
210
211         } else if (kw_arg_item == NULL && py_arg_item == NULL) {
212             PyErr_Format (PyExc_TypeError,
213                           "%.200s() takes exactly %d %sargument%s (%zd given)",
214                           function_name,
215                           n_expected_args,
216                           n_py_kwargs > 0 ? "non-keyword " : "",
217                           n_expected_args == 1 ? "" : "s",
218                           n_py_args);
219
220             Py_DECREF (combined_py_args);
221             return NULL;
222
223         } else if (kw_arg_item != NULL && py_arg_item != NULL) {
224             PyErr_Format (PyExc_TypeError,
225                           "%.200s() got multiple values for keyword argument '%.200s'",
226                           function_name,
227                           arg_name);
228
229             Py_DECREF (combined_py_args);
230             return NULL;
231         }
232     }
233
234     return combined_py_args;
235 }
236
237 static inline gboolean
238 _invoke_state_init_from_callable_cache (PyGIInvokeState *state,
239                                         PyGICallableCache *cache,
240                                         PyObject *py_args,
241                                         PyObject *kwargs)
242 {
243     PyObject *combined_args = NULL;
244     state->implementor_gtype = 0;
245
246     /* TODO: We don't use the class parameter sent in by  the structure
247      * so we remove it from the py_args tuple but we can keep it 
248      * around if we want to call actual gobject constructors
249      * in the future instead of calling g_object_new
250      */
251     if (cache->function_type == PYGI_FUNCTION_TYPE_CONSTRUCTOR) {
252         PyObject *constructor_class;
253         constructor_class = PyTuple_GetItem (py_args, 0);
254
255         if (constructor_class == NULL) {
256             PyErr_Clear ();
257             PyErr_Format (PyExc_TypeError,
258                           "Constructors require the class to be passed in as an argument, "
259                           "No arguments passed to the %s constructor.",
260                           cache->name);
261
262             return FALSE;
263         }
264     } else if (cache->function_type == PYGI_FUNCTION_TYPE_VFUNC) {
265         PyObject *py_gtype;
266         py_gtype = PyTuple_GetItem (py_args, 0);
267         if (py_gtype == NULL) {
268             PyErr_SetString (PyExc_TypeError,
269                              "need the GType of the implementor class");
270             return FALSE;
271         }
272
273         state->implementor_gtype = pyg_type_from_object (py_gtype);
274
275         if (state->implementor_gtype == 0)
276             return FALSE;
277     }
278
279     if  (cache->function_type == PYGI_FUNCTION_TYPE_CONSTRUCTOR ||
280             cache->function_type == PYGI_FUNCTION_TYPE_VFUNC) {
281
282         /* we could optimize this by using offsets instead of modifying the tuple but it makes the
283          * code more error prone and confusing so don't do that unless profiling shows
284          * significant gain
285          */
286         combined_args = PyTuple_GetSlice (py_args, 1, PyTuple_Size (py_args));
287     } else {
288         combined_args = py_args;
289         Py_INCREF (combined_args);
290     }
291
292     state->py_in_args = _py_args_combine_and_check_length (cache,
293                                                            combined_args,
294                                                            kwargs);
295     Py_DECREF (combined_args);
296
297     if (state->py_in_args == NULL) {
298         return FALSE;
299     }
300     state->n_py_in_args = PyTuple_Size (state->py_in_args);
301
302     state->args = g_slice_alloc0 (cache->n_args * sizeof (GIArgument *));
303     if (state->args == NULL && cache->n_args != 0) {
304         PyErr_NoMemory();
305         return FALSE;
306     }
307
308     state->args_data = g_slice_alloc0 (cache->n_args * sizeof (gpointer));
309     if (state->args_data == NULL && cache->n_args != 0) {
310         PyErr_NoMemory();
311         return FALSE;
312     }
313
314     state->in_args = g_slice_alloc0 (cache->n_from_py_args * sizeof(GIArgument));
315     if (state->in_args == NULL && cache->n_from_py_args != 0) {
316         PyErr_NoMemory ();
317         return FALSE;
318     }
319
320     state->out_values = g_slice_alloc0 (cache->n_to_py_args * sizeof(GIArgument));
321     if (state->out_values == NULL && cache->n_to_py_args != 0) {
322         PyErr_NoMemory ();
323         return FALSE;
324     }
325
326     state->out_args = g_slice_alloc0 (cache->n_to_py_args * sizeof(GIArgument));
327     if (state->out_args == NULL && cache->n_to_py_args != 0) {
328         PyErr_NoMemory ();
329         return FALSE;
330     }
331
332     state->error = NULL;
333
334     return TRUE;
335 }
336
337 static inline void
338 _invoke_state_clear (PyGIInvokeState *state, PyGICallableCache *cache)
339 {
340     g_slice_free1 (cache->n_args * sizeof(GIArgument *), state->args);
341     g_slice_free1 (cache->n_args * sizeof(gpointer), state->args_data);
342     g_slice_free1 (cache->n_from_py_args * sizeof(GIArgument), state->in_args);
343     g_slice_free1 (cache->n_to_py_args * sizeof(GIArgument), state->out_args);
344     g_slice_free1 (cache->n_to_py_args * sizeof(GIArgument), state->out_values);
345
346     Py_XDECREF (state->py_in_args);
347 }
348
349 static gboolean _caller_alloc (PyGIInvokeState *state,
350                                PyGIArgCache *arg_cache,
351                                gssize arg_count,
352                                gssize out_count)
353 {
354     if (arg_cache->type_tag == GI_TYPE_TAG_INTERFACE) {
355         PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
356
357         state->out_args[out_count].v_pointer = NULL;
358         state->args[arg_count] = &state->out_args[out_count];
359         if (g_type_is_a (iface_cache->g_type, G_TYPE_BOXED)) {
360             state->args[arg_count]->v_pointer =
361                 _pygi_boxed_alloc (iface_cache->interface_info, NULL);
362         } else if (iface_cache->g_type == G_TYPE_VALUE) {
363             state->args[arg_count]->v_pointer = g_slice_new0 (GValue);
364         } else if (iface_cache->is_foreign) {
365             PyObject *foreign_struct =
366                 pygi_struct_foreign_convert_from_g_argument (
367                     iface_cache->interface_info,
368                     NULL);
369
370                 pygi_struct_foreign_convert_to_g_argument (foreign_struct,
371                                                            iface_cache->interface_info,
372                                                            GI_TRANSFER_EVERYTHING,
373                                                            state->args[arg_count]);
374         } else {
375                 gssize size = g_struct_info_get_size(
376                     (GIStructInfo *)iface_cache->interface_info);
377                 state->args[arg_count]->v_pointer = g_malloc0 (size);
378         }
379     } else if (arg_cache->type_tag == GI_TYPE_TAG_ARRAY) {
380         PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache;
381
382         state->out_args[out_count].v_pointer = g_array_new (TRUE, TRUE, seq_cache->item_size);
383         state->args[arg_count] = &state->out_args[out_count];
384     } else {
385         return FALSE;
386     }
387
388     if (state->args[arg_count]->v_pointer == NULL)
389         return FALSE;
390
391
392     return TRUE;
393 }
394
395 static inline gboolean
396 _invoke_marshal_in_args (PyGIInvokeState *state, PyGICallableCache *cache)
397 {
398     gssize i, in_count, out_count;
399     in_count = 0;
400     out_count = 0;
401
402     if (state->n_py_in_args > cache->n_py_args) {
403         PyErr_Format (PyExc_TypeError,
404                       "%s() takes exactly %zd argument(s) (%zd given)",
405                       cache->name,
406                       cache->n_py_args,
407                       state->n_py_in_args);
408         return FALSE;
409     }
410
411     for (i = 0; i < cache->n_args; i++) {
412         GIArgument *c_arg;
413         PyGIArgCache *arg_cache = cache->args_cache[i];
414         PyObject *py_arg = NULL;
415
416         switch (arg_cache->direction) {
417             case PYGI_DIRECTION_FROM_PYTHON:
418                 state->args[i] = &(state->in_args[in_count]);
419                 in_count++;
420
421                 if (arg_cache->meta_type == PYGI_META_ARG_TYPE_CLOSURE) {
422                     state->args[i]->v_pointer = state->user_data;
423                     continue;
424                 } else if (arg_cache->meta_type != PYGI_META_ARG_TYPE_PARENT)
425                     continue;
426
427                 if (arg_cache->py_arg_index >= state->n_py_in_args) {
428                     PyErr_Format (PyExc_TypeError,
429                                   "%s() takes exactly %zd argument(s) (%zd given)",
430                                    cache->name,
431                                    cache->n_py_args,
432                                    state->n_py_in_args);
433
434                     /* clean up all of the args we have already marshalled,
435                      * since invoke will not be called
436                      */
437                     pygi_marshal_cleanup_args_from_py_parameter_fail (state,
438                                                                       cache,
439                                                                       i - 1);
440                     return FALSE;
441                 }
442
443                 py_arg =
444                     PyTuple_GET_ITEM (state->py_in_args,
445                                       arg_cache->py_arg_index);
446
447                 break;
448             case PYGI_DIRECTION_BIDIRECTIONAL:
449                 /* this will be filled in if it is an child value */
450                 if (state->in_args[in_count].v_pointer != NULL)
451                     state->out_values[out_count] = state->in_args[in_count];
452
453                 state->in_args[in_count].v_pointer = &state->out_values[out_count];
454                 in_count++;
455
456                 if (arg_cache->meta_type != PYGI_META_ARG_TYPE_CHILD) {
457                     if (arg_cache->py_arg_index >= state->n_py_in_args) {
458                         PyErr_Format (PyExc_TypeError,
459                                       "%s() takes exactly %zd argument(s) (%zd given)",
460                                        cache->name,
461                                        cache->n_py_args,
462                                        state->n_py_in_args);
463                         pygi_marshal_cleanup_args_from_py_parameter_fail (state,
464                                                                           cache,
465                                                                           i - 1);
466                         return FALSE;
467                     }
468
469                     py_arg =
470                         PyTuple_GET_ITEM (state->py_in_args,
471                                           arg_cache->py_arg_index);
472                 }
473             case PYGI_DIRECTION_TO_PYTHON:
474                 if (arg_cache->is_caller_allocates) {
475                     if (!_caller_alloc (state, arg_cache, i, out_count)) {
476                         PyErr_Format (PyExc_TypeError,
477                                       "Could not caller allocate argument %zd of callable %s",
478                                       i, cache->name);
479                         pygi_marshal_cleanup_args_from_py_parameter_fail (state,
480                                                                           cache,
481                                                                           i - 1);
482                         return FALSE;
483                     }
484                 } else {
485                     state->out_args[out_count].v_pointer = &state->out_values[out_count];
486                     state->args[i] = &state->out_values[out_count];
487                 }
488                 out_count++;
489                 break;
490         }
491
492         c_arg = state->args[i];
493         if (arg_cache->from_py_marshaller != NULL) {
494             gboolean success;
495             if (!arg_cache->allow_none && py_arg == Py_None) {
496                 PyErr_Format (PyExc_TypeError,
497                               "Argument %zd does not allow None as a value",
498                               i);
499
500                  pygi_marshal_cleanup_args_from_py_parameter_fail (state,
501                                                                    cache,
502                                                                    i - 1);
503                  return FALSE;
504             }
505             success = arg_cache->from_py_marshaller (state,
506                                                               cache,
507                                                               arg_cache,
508                                                               py_arg,
509                                                               c_arg);
510             if (!success) {
511                 pygi_marshal_cleanup_args_from_py_parameter_fail (state,
512                                                                   cache,
513                                                                   i - 1);
514                 return FALSE;
515             }
516
517         }
518
519     }
520
521     return TRUE;
522 }
523
524 static inline PyObject *
525 _invoke_marshal_out_args (PyGIInvokeState *state, PyGICallableCache *cache)
526 {
527     PyObject *py_out = NULL;
528     PyObject *py_return = NULL;
529     gssize total_out_args = cache->n_to_py_args;
530     gboolean has_return = FALSE;
531
532     if (cache->return_cache) {
533         if (!cache->return_cache->is_skipped) {
534             if (cache->function_type == PYGI_FUNCTION_TYPE_CONSTRUCTOR) {
535                 if (state->return_arg.v_pointer == NULL) {
536                     PyErr_SetString (PyExc_TypeError, "constructor returned NULL");
537                     pygi_marshal_cleanup_args_return_fail (state,
538                                                        cache);
539                     return NULL;
540                 }
541             }
542
543             py_return = cache->return_cache->to_py_marshaller ( state,
544                                                                 cache,
545                                                                 cache->return_cache,
546                                                                &state->return_arg);
547             if (py_return == NULL) {
548                 pygi_marshal_cleanup_args_return_fail (state,
549                                                        cache);
550                 return NULL;
551             }
552
553
554             if (cache->return_cache->type_tag != GI_TYPE_TAG_VOID) {
555                 total_out_args++;
556                 has_return = TRUE;
557             }
558         } else {
559             if (cache->return_cache->transfer == GI_TRANSFER_EVERYTHING) {
560                 PyGIMarshalCleanupFunc to_py_cleanup =
561                     cache->return_cache->to_py_cleanup;
562
563                 if (to_py_cleanup != NULL)
564                     to_py_cleanup ( state,
565                                     cache->return_cache,
566                                    &state->return_arg,
567                                     FALSE);
568             }
569         }
570     }
571
572     total_out_args -= cache->n_to_py_child_args;
573
574     if (cache->n_to_py_args - cache->n_to_py_child_args  == 0) {
575         if (cache->return_cache->is_skipped && state->error == NULL) {
576             /* we skip the return value and have no (out) arguments to return,
577              * so py_return should be NULL. But we must not return NULL,
578              * otherwise Python will expect an exception.
579              */
580             g_assert (py_return == NULL);
581             Py_INCREF(Py_None);
582             py_return = Py_None;
583         }
584
585         py_out = py_return;
586     } else if (total_out_args == 1) {
587         /* if we get here there is one out arg an no return */
588         PyGIArgCache *arg_cache = (PyGIArgCache *)cache->to_py_args->data;
589         py_out = arg_cache->to_py_marshaller (state,
590                                               cache,
591                                               arg_cache,
592                                               state->args[arg_cache->c_arg_index]);
593         if (py_out == NULL) {
594             pygi_marshal_cleanup_args_to_py_parameter_fail (state,
595                                                             cache,
596                                                             0);
597             return NULL;
598         }
599
600     } else {
601         gssize py_arg_index = 0;
602         GSList *cache_item = cache->to_py_args;
603         /* return a tuple */
604         py_out = PyTuple_New (total_out_args);
605         if (has_return) {
606             PyTuple_SET_ITEM (py_out, py_arg_index, py_return);
607             py_arg_index++;
608         }
609
610         for(; py_arg_index < total_out_args; py_arg_index++) {
611             PyGIArgCache *arg_cache = (PyGIArgCache *)cache_item->data;
612             PyObject *py_obj = arg_cache->to_py_marshaller (state,
613                                                             cache,
614                                                             arg_cache,
615                                                             state->args[arg_cache->c_arg_index]);
616
617             if (py_obj == NULL) {
618                 if (has_return)
619                     py_arg_index--;
620  
621                 pygi_marshal_cleanup_args_to_py_parameter_fail (state,
622                                                                 cache,
623                                                                 py_arg_index);
624                 Py_DECREF (py_out);
625                 return NULL;
626             }
627
628             PyTuple_SET_ITEM (py_out, py_arg_index, py_obj);
629             cache_item = cache_item->next;
630         }
631     }
632     return py_out;
633 }
634
635 PyObject *
636 pygi_callable_info_invoke (GIBaseInfo *info, PyObject *py_args,
637                            PyObject *kwargs, PyGICallableCache *cache,
638                            GCallback function_ptr, gpointer user_data)
639 {
640     PyGIInvokeState state = { 0, };
641     PyObject *ret = NULL;
642
643     if (!_invoke_state_init_from_callable_cache (&state, cache, py_args, kwargs))
644         goto err;
645
646     if (cache->function_type == PYGI_FUNCTION_TYPE_CCALLBACK)
647         state.user_data = user_data;
648
649     if (!_invoke_marshal_in_args (&state, cache))
650         goto err;
651
652     if (!_invoke_callable (&state, cache, info, function_ptr))
653         goto err;
654
655     pygi_marshal_cleanup_args_from_py_marshal_success (&state, cache);
656
657     ret = _invoke_marshal_out_args (&state, cache);
658     if (ret)
659         pygi_marshal_cleanup_args_to_py_marshal_success (&state, cache);
660 err:
661     _invoke_state_clear (&state, cache);
662     return ret;
663 }
664
665 PyObject *
666 _wrap_g_callable_info_invoke (PyGIBaseInfo *self, PyObject *py_args,
667                               PyObject *kwargs)
668 {
669     if (self->cache == NULL) {
670         self->cache = _pygi_callable_cache_new (self->info, FALSE);
671         if (self->cache == NULL)
672             return NULL;
673     }
674
675     return pygi_callable_info_invoke (self->info, py_args, kwargs, self->cache, NULL, NULL);
676 }