Imported Upstream version 3.3.1
[platform/upstream/pygobject2.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     pyg_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     pyg_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  * @function_name: the name of the function being called. Used for error messages.
140  * @arg_name_list: a list of the string names for each argument. The length
141  *                 of this list is the number of required arguments for the
142  *                 function. If an argument has no name, NULL is put in its
143  *                 position in the list.
144  * @py_args: the tuple of positional arguments. A referece is stolen, and this
145              tuple will be either decreffed or returned as is.
146  * @py_kwargs: the dict of keyword arguments to be merged with py_args.
147  *             A reference is borrowed.
148  *
149  * Returns: The py_args and py_kwargs combined into one tuple.
150  */
151 static PyObject *
152 _py_args_combine_and_check_length (const gchar *function_name,
153                                    GSList      *arg_name_list,
154                                    GHashTable  *arg_name_hash,
155                                    PyObject    *py_args,
156                                    PyObject    *py_kwargs)
157 {
158     PyObject *combined_py_args = NULL;
159     Py_ssize_t n_py_args, n_py_kwargs, i;
160     guint n_expected_args;
161     GSList *l;
162
163     n_py_args = PyTuple_GET_SIZE (py_args);
164     if (py_kwargs == NULL)
165         n_py_kwargs = 0;
166     else
167         n_py_kwargs = PyDict_Size (py_kwargs);
168
169     n_expected_args = g_slist_length (arg_name_list);
170     if (n_py_kwargs == 0 && n_py_args == n_expected_args) {
171         return py_args;
172     }
173
174     if (n_expected_args < n_py_args) {
175         PyErr_Format (PyExc_TypeError,
176                       "%.200s() takes exactly %d %sargument%s (%zd given)",
177                       function_name,
178                       n_expected_args,
179                       n_py_kwargs > 0 ? "non-keyword " : "",
180                       n_expected_args == 1 ? "" : "s",
181                       n_py_args);
182
183         Py_DECREF (py_args);
184         return NULL;
185     }
186
187     if (n_py_kwargs > 0 && !_check_for_unexpected_kwargs (function_name,
188                                                           arg_name_hash,
189                                                           py_kwargs)) {
190         Py_DECREF (py_args);
191         return NULL;
192     }
193
194     /* will hold arguments from both py_args and py_kwargs
195      * when they are combined into a single tuple */
196     combined_py_args = PyTuple_New (n_expected_args);
197
198     for (i = 0; i < n_py_args; i++) {
199         PyObject *item = PyTuple_GET_ITEM (py_args, i);
200         Py_INCREF (item);
201         PyTuple_SET_ITEM (combined_py_args, i, item);
202     }
203
204     Py_CLEAR(py_args);
205
206     for (i = 0, l = arg_name_list; i < n_expected_args && l; i++, l = l->next) {
207         PyObject *py_arg_item, *kw_arg_item = NULL;
208         const gchar *arg_name = l->data;
209
210         if (n_py_kwargs > 0 && arg_name != NULL) {
211             /* NULL means this argument has no keyword name */
212             /* ex. the first argument to a method or constructor */
213             kw_arg_item = PyDict_GetItemString (py_kwargs, arg_name);
214         }
215         py_arg_item = PyTuple_GET_ITEM (combined_py_args, i);
216
217         if (kw_arg_item != NULL && py_arg_item == NULL) {
218             Py_INCREF (kw_arg_item);
219             PyTuple_SET_ITEM (combined_py_args, i, kw_arg_item);
220
221         } else if (kw_arg_item == NULL && py_arg_item == NULL) {
222             PyErr_Format (PyExc_TypeError,
223                           "%.200s() takes exactly %d %sargument%s (%zd given)",
224                           function_name,
225                           n_expected_args,
226                           n_py_kwargs > 0 ? "non-keyword " : "",
227                           n_expected_args == 1 ? "" : "s",
228                           n_py_args);
229
230             Py_DECREF (combined_py_args);
231             return NULL;
232
233         } else if (kw_arg_item != NULL && py_arg_item != NULL) {
234             PyErr_Format (PyExc_TypeError,
235                           "%.200s() got multiple values for keyword argument '%.200s'",
236                           function_name,
237                           arg_name);
238
239             Py_DECREF (combined_py_args);
240             return NULL;
241         }
242     }
243
244     return combined_py_args;
245 }
246
247 static inline gboolean
248 _invoke_state_init_from_callable_cache (PyGIInvokeState *state,
249                                         PyGICallableCache *cache,
250                                         PyObject *py_args,
251                                         PyObject *kwargs)
252 {
253     state->implementor_gtype = 0;
254
255     /* TODO: We don't use the class parameter sent in by  the structure
256      * so we remove it from the py_args tuple but we can keep it 
257      * around if we want to call actual gobject constructors
258      * in the future instead of calling g_object_new
259      */
260     if (cache->function_type == PYGI_FUNCTION_TYPE_CONSTRUCTOR) {
261         PyObject *constructor_class;
262         constructor_class = PyTuple_GetItem (py_args, 0);
263
264         if (constructor_class == NULL) {
265             PyErr_Clear ();
266             PyErr_Format (PyExc_TypeError,
267                           "Constructors require the class to be passed in as an argument, "
268                           "No arguments passed to the %s constructor.",
269                           cache->name);
270
271             return FALSE;
272         }
273     } else if (cache->function_type == PYGI_FUNCTION_TYPE_VFUNC) {
274         PyObject *py_gtype;
275         py_gtype = PyTuple_GetItem (py_args, 0);
276         if (py_gtype == NULL) {
277             PyErr_SetString (PyExc_TypeError,
278                              "need the GType of the implementor class");
279             return FALSE;
280         }
281
282         state->implementor_gtype = pyg_type_from_object (py_gtype);
283
284         if (state->implementor_gtype == 0)
285             return FALSE;
286     }
287
288     if  (cache->function_type == PYGI_FUNCTION_TYPE_CONSTRUCTOR ||
289             cache->function_type == PYGI_FUNCTION_TYPE_VFUNC) {
290
291         /* we could optimize this by using offsets instead of modifying the tuple but it makes the
292          * code more error prone and confusing so don't do that unless profiling shows
293          * significant gain
294          */
295         state->py_in_args = PyTuple_GetSlice (py_args, 1, PyTuple_Size (py_args));
296     } else {
297         state->py_in_args = py_args;
298         Py_INCREF (state->py_in_args);
299     }
300
301     state->py_in_args = _py_args_combine_and_check_length (cache->name,
302                                                            cache->arg_name_list,
303                                                            cache->arg_name_hash,
304                                                            state->py_in_args,
305                                                            kwargs);
306
307     if (state->py_in_args == NULL) {
308         return FALSE;
309     }
310     state->n_py_in_args = PyTuple_Size (state->py_in_args);
311
312     state->args = g_slice_alloc0 (cache->n_args * sizeof (GIArgument *));
313     if (state->args == NULL && cache->n_args != 0) {
314         PyErr_NoMemory();
315         return FALSE;
316     }
317
318     state->in_args = g_slice_alloc0 (cache->n_from_py_args * sizeof(GIArgument));
319     if (state->in_args == NULL && cache->n_from_py_args != 0) {
320         PyErr_NoMemory ();
321         return FALSE;
322     }
323
324     state->out_values = g_slice_alloc0 (cache->n_to_py_args * sizeof(GIArgument));
325     if (state->out_values == NULL && cache->n_to_py_args != 0) {
326         PyErr_NoMemory ();
327         return FALSE;
328     }
329
330     state->out_args = g_slice_alloc0 (cache->n_to_py_args * sizeof(GIArgument));
331     if (state->out_args == NULL && cache->n_to_py_args != 0) {
332         PyErr_NoMemory ();
333         return FALSE;
334     }
335
336     state->error = NULL;
337
338     return TRUE;
339 }
340
341 static inline void
342 _invoke_state_clear (PyGIInvokeState *state, PyGICallableCache *cache)
343 {
344     g_slice_free1 (cache->n_args * sizeof(GIArgument *), state->args);
345     g_slice_free1 (cache->n_from_py_args * sizeof(GIArgument), state->in_args);
346     g_slice_free1 (cache->n_to_py_args * sizeof(GIArgument), state->out_args);
347     g_slice_free1 (cache->n_to_py_args * sizeof(GIArgument), state->out_values);
348
349     Py_XDECREF (state->py_in_args);
350 }
351
352 static gboolean _caller_alloc (PyGIInvokeState *state,
353                                PyGIArgCache *arg_cache,
354                                gssize arg_count,
355                                gssize out_count)
356 {
357     PyGIInterfaceCache *iface_cache;
358
359     g_assert (arg_cache->type_tag == GI_TYPE_TAG_INTERFACE);
360
361     iface_cache = (PyGIInterfaceCache *)arg_cache;
362
363     state->out_args[out_count].v_pointer = NULL;
364     state->args[arg_count] = &state->out_args[out_count];
365     if (iface_cache->g_type == G_TYPE_BOXED) {
366         state->args[arg_count]->v_pointer =
367             _pygi_boxed_alloc (iface_cache->interface_info, NULL);
368     } else if (iface_cache->g_type == G_TYPE_VALUE) {
369         state->args[arg_count]->v_pointer = g_slice_new0 (GValue);
370     } else if (iface_cache->is_foreign) {
371         PyObject *foreign_struct =
372             pygi_struct_foreign_convert_from_g_argument (
373                 iface_cache->interface_info,
374                 NULL);
375
376             pygi_struct_foreign_convert_to_g_argument (foreign_struct,
377                                                        iface_cache->interface_info,
378                                                        GI_TRANSFER_EVERYTHING,
379                                                        state->args[arg_count]);
380     } else {
381             gssize size = g_struct_info_get_size(
382                 (GIStructInfo *)iface_cache->interface_info);
383             state->args[arg_count]->v_pointer = g_malloc0 (size);
384     }
385
386     if (state->args[arg_count]->v_pointer == NULL)
387         return FALSE;
388
389
390     return TRUE;
391 }
392
393 static inline gboolean
394 _invoke_marshal_in_args (PyGIInvokeState *state, PyGICallableCache *cache)
395 {
396     gssize i, in_count, out_count;
397     in_count = 0;
398     out_count = 0;
399
400     if (state->n_py_in_args > cache->n_py_args) {
401         PyErr_Format (PyExc_TypeError,
402                       "%s() takes exactly %zd argument(s) (%zd given)",
403                       cache->name,
404                       cache->n_py_args,
405                       state->n_py_in_args);
406         return FALSE;
407     }
408
409     for (i = 0; i < cache->n_args; i++) {
410         GIArgument *c_arg;
411         PyGIArgCache *arg_cache = cache->args_cache[i];
412         PyObject *py_arg = NULL;
413
414         switch (arg_cache->direction) {
415             case PYGI_DIRECTION_FROM_PYTHON:
416                 state->args[i] = &(state->in_args[in_count]);
417                 in_count++;
418
419                 if (arg_cache->meta_type == PYGI_META_ARG_TYPE_CLOSURE) {
420                     state->args[i]->v_pointer = state->user_data;
421                     continue;
422                 } else if (arg_cache->meta_type != PYGI_META_ARG_TYPE_PARENT)
423                     continue;
424
425                 if (arg_cache->py_arg_index >= state->n_py_in_args) {
426                     PyErr_Format (PyExc_TypeError,
427                                   "%s() takes exactly %zd argument(s) (%zd given)",
428                                    cache->name,
429                                    cache->n_py_args,
430                                    state->n_py_in_args);
431
432                     /* clean up all of the args we have already marshalled,
433                      * since invoke will not be called
434                      */
435                     pygi_marshal_cleanup_args_from_py_parameter_fail (state,
436                                                                       cache,
437                                                                       i - 1);
438                     return FALSE;
439                 }
440
441                 py_arg =
442                     PyTuple_GET_ITEM (state->py_in_args,
443                                       arg_cache->py_arg_index);
444
445                 break;
446             case PYGI_DIRECTION_BIDIRECTIONAL:
447                 /* this will be filled in if it is an child value */
448                 if (state->in_args[in_count].v_pointer != NULL)
449                     state->out_values[out_count] = state->in_args[in_count];
450
451                 state->in_args[in_count].v_pointer = &state->out_values[out_count];
452                 in_count++;
453
454                 if (arg_cache->meta_type != PYGI_META_ARG_TYPE_CHILD) {
455                     if (arg_cache->py_arg_index >= state->n_py_in_args) {
456                         PyErr_Format (PyExc_TypeError,
457                                       "%s() takes exactly %zd argument(s) (%zd given)",
458                                        cache->name,
459                                        cache->n_py_args,
460                                        state->n_py_in_args);
461                         pygi_marshal_cleanup_args_from_py_parameter_fail (state,
462                                                                           cache,
463                                                                           i - 1);
464                         return FALSE;
465                     }
466
467                     py_arg =
468                         PyTuple_GET_ITEM (state->py_in_args,
469                                           arg_cache->py_arg_index);
470                 }
471             case PYGI_DIRECTION_TO_PYTHON:
472                 if (arg_cache->is_caller_allocates) {
473                     if (!_caller_alloc (state, arg_cache, i, out_count)) {
474                         PyErr_Format (PyExc_TypeError,
475                                       "Could not caller allocate argument %zd of callable %s",
476                                       i, cache->name);
477                         pygi_marshal_cleanup_args_from_py_parameter_fail (state,
478                                                                           cache,
479                                                                           i - 1);
480                         return FALSE;
481                     }
482                 } else {
483                     state->out_args[out_count].v_pointer = &state->out_values[out_count];
484                     state->args[i] = &state->out_values[out_count];
485                 }
486                 out_count++;
487                 break;
488         }
489
490         c_arg = state->args[i];
491         if (arg_cache->from_py_marshaller != NULL) {
492             if (!arg_cache->allow_none && py_arg == Py_None) {
493                 PyErr_Format (PyExc_TypeError,
494                               "Argument %zd does not allow None as a value",
495                               i);
496
497                  pygi_marshal_cleanup_args_from_py_parameter_fail (state,
498                                                                    cache,
499                                                                    i - 1);
500                  return FALSE;
501             }
502             gboolean success = arg_cache->from_py_marshaller (state,
503                                                               cache,
504                                                               arg_cache,
505                                                               py_arg,
506                                                               c_arg);
507             if (!success) {
508                 pygi_marshal_cleanup_args_from_py_parameter_fail (state,
509                                                                   cache,
510                                                                   i - 1);
511                 return FALSE;
512             }
513
514         }
515
516     }
517
518     return TRUE;
519 }
520
521 static inline PyObject *
522 _invoke_marshal_out_args (PyGIInvokeState *state, PyGICallableCache *cache)
523 {
524     PyObject *py_out = NULL;
525     PyObject *py_return = NULL;
526     gssize total_out_args = cache->n_to_py_args;
527     gboolean has_return = FALSE;
528
529     if (cache->return_cache) {
530         if (!cache->return_cache->is_skipped) {
531             if (cache->function_type == PYGI_FUNCTION_TYPE_CONSTRUCTOR) {
532                 if (state->return_arg.v_pointer == NULL) {
533                     PyErr_SetString (PyExc_TypeError, "constructor returned NULL");
534                     pygi_marshal_cleanup_args_return_fail (state,
535                                                        cache);
536                     return NULL;
537                 }
538             }
539
540             py_return = cache->return_cache->to_py_marshaller ( state,
541                                                                 cache,
542                                                                 cache->return_cache,
543                                                                &state->return_arg);
544             if (py_return == NULL) {
545                 pygi_marshal_cleanup_args_return_fail (state,
546                                                        cache);
547                 return NULL;
548             }
549
550
551             if (cache->return_cache->type_tag != GI_TYPE_TAG_VOID) {
552                 total_out_args++;
553                 has_return = TRUE;
554             }
555         } else {
556             if (cache->return_cache->transfer == GI_TRANSFER_EVERYTHING) {
557                 PyGIMarshalCleanupFunc to_py_cleanup =
558                     cache->return_cache->to_py_cleanup;
559
560                 if (to_py_cleanup != NULL)
561                     to_py_cleanup ( state,
562                                     cache->return_cache,
563                                    &state->return_arg,
564                                     FALSE);
565             }
566         }
567     }
568
569     total_out_args -= cache->n_to_py_child_args;
570
571     if (cache->n_to_py_args - cache->n_to_py_child_args  == 0) {
572         if (cache->return_cache->is_skipped && state->error == NULL) {
573             /* we skip the return value and have no (out) arguments to return,
574              * so py_return should be NULL. But we must not return NULL,
575              * otherwise Python will expect an exception.
576              */
577             g_assert (py_return == NULL);
578             Py_INCREF(Py_None);
579             py_return = Py_None;
580         }
581
582         py_out = py_return;
583     } else if (total_out_args == 1) {
584         /* if we get here there is one out arg an no return */
585         PyGIArgCache *arg_cache = (PyGIArgCache *)cache->to_py_args->data;
586         py_out = arg_cache->to_py_marshaller (state,
587                                               cache,
588                                               arg_cache,
589                                               state->args[arg_cache->c_arg_index]);
590         if (py_out == NULL) {
591             pygi_marshal_cleanup_args_to_py_parameter_fail (state,
592                                                             cache,
593                                                             0);
594             return NULL;
595         }
596
597     } else {
598         gssize py_arg_index = 0;
599         GSList *cache_item = cache->to_py_args;
600         /* return a tuple */
601         py_out = PyTuple_New (total_out_args);
602         if (has_return) {
603             PyTuple_SET_ITEM (py_out, py_arg_index, py_return);
604             py_arg_index++;
605         }
606
607         for(; py_arg_index < total_out_args; py_arg_index++) {
608             PyGIArgCache *arg_cache = (PyGIArgCache *)cache_item->data;
609             PyObject *py_obj = arg_cache->to_py_marshaller (state,
610                                                             cache,
611                                                             arg_cache,
612                                                             state->args[arg_cache->c_arg_index]);
613
614             if (py_obj == NULL) {
615                 if (has_return)
616                     py_arg_index--;
617  
618                 pygi_marshal_cleanup_args_to_py_parameter_fail (state,
619                                                                 cache,
620                                                                 py_arg_index);
621                 Py_DECREF (py_out);
622                 return NULL;
623             }
624
625             PyTuple_SET_ITEM (py_out, py_arg_index, py_obj);
626             cache_item = cache_item->next;
627         }
628     }
629     return py_out;
630 }
631
632 PyObject *
633 pygi_callable_info_invoke (GIBaseInfo *info, PyObject *py_args,
634                            PyObject *kwargs, PyGICallableCache *cache,
635                            GCallback function_ptr, gpointer user_data)
636 {
637     PyGIInvokeState state = { 0, };
638     PyObject *ret = NULL;
639
640     if (!_invoke_state_init_from_callable_cache (&state, cache, py_args, kwargs))
641         goto err;
642
643     if (cache->function_type == PYGI_FUNCTION_TYPE_CCALLBACK)
644         state.user_data = user_data;
645
646     if (!_invoke_marshal_in_args (&state, cache))
647         goto err;
648
649     if (!_invoke_callable (&state, cache, info, function_ptr))
650         goto err;
651
652     pygi_marshal_cleanup_args_from_py_marshal_success (&state, cache);
653
654     ret = _invoke_marshal_out_args (&state, cache);
655     if (ret)
656         pygi_marshal_cleanup_args_to_py_marshal_success (&state, cache);
657 err:
658     _invoke_state_clear (&state, cache);
659     return ret;
660 }
661
662 PyObject *
663 _wrap_g_callable_info_invoke (PyGIBaseInfo *self, PyObject *py_args,
664                               PyObject *kwargs)
665 {
666     if (self->cache == NULL) {
667         self->cache = _pygi_callable_cache_new (self->info, FALSE);
668         if (self->cache == NULL)
669             return NULL;
670     }
671
672     return pygi_callable_info_invoke (self->info, py_args, kwargs, self->cache, NULL, NULL);
673 }