1 /* -*- Mode: C; c-basic-offset: 4 -*-
2 * vim: tabstop=4 shiftwidth=4 expandtab
4 * Copyright (C) 2005-2009 Johan Dahlin <johan@gnome.org>
5 * Copyright (C) 2011 John (J5) Palimier <johnp@redhat.com>
7 * pygi-invoke.c: main invocation function
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.
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.
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
26 #include "pygi-invoke.h"
27 #include "pygi-marshal-cleanup.h"
29 static inline gboolean
30 _invoke_callable (PyGIInvokeState *state,
31 PyGICallableCache *cache,
32 GICallableInfo *callable_info,
33 GCallback function_ptr)
40 pyg_begin_allow_threads;
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,
47 cache->n_from_py_args,
52 else if (g_base_info_get_type (callable_info) == GI_INFO_TYPE_CALLBACK)
53 retval = g_callable_info_invoke (callable_info,
56 cache->n_from_py_args,
64 retval = g_function_info_invoke ( callable_info,
66 cache->n_from_py_args,
71 pyg_end_allow_threads;
74 g_assert (error != NULL);
75 pyglib_error_check (&error);
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
82 pygi_marshal_cleanup_args_from_py_marshal_success (state, cache);
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);
100 _check_for_unexpected_kwargs (const gchar *function_name,
101 GHashTable *arg_name_hash,
104 PyObject *dict_key, *dict_value;
105 Py_ssize_t dict_iter_pos = 0;
107 while (PyDict_Next (py_kwargs, &dict_iter_pos, &dict_key, &dict_value)) {
110 #if PY_VERSION_HEX < 0x03000000
111 if (PyString_Check (dict_key)) {
112 Py_INCREF (dict_key);
117 key = PyUnicode_AsUTF8String (dict_key);
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'",
127 PyBytes_AsString (key));
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.
149 * Returns: The py_args and py_kwargs combined into one tuple.
152 _py_args_combine_and_check_length (const gchar *function_name,
153 GSList *arg_name_list,
154 GHashTable *arg_name_hash,
158 PyObject *combined_py_args = NULL;
159 Py_ssize_t n_py_args, n_py_kwargs, i;
160 guint n_expected_args;
163 n_py_args = PyTuple_GET_SIZE (py_args);
164 if (py_kwargs == NULL)
167 n_py_kwargs = PyDict_Size (py_kwargs);
169 n_expected_args = g_slist_length (arg_name_list);
170 if (n_py_kwargs == 0 && n_py_args == n_expected_args) {
174 if (n_expected_args < n_py_args) {
175 PyErr_Format (PyExc_TypeError,
176 "%.200s() takes exactly %d %sargument%s (%zd given)",
179 n_py_kwargs > 0 ? "non-keyword " : "",
180 n_expected_args == 1 ? "" : "s",
187 if (n_py_kwargs > 0 && !_check_for_unexpected_kwargs (function_name,
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);
198 for (i = 0; i < n_py_args; i++) {
199 PyObject *item = PyTuple_GET_ITEM (py_args, i);
201 PyTuple_SET_ITEM (combined_py_args, i, item);
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;
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);
215 py_arg_item = PyTuple_GET_ITEM (combined_py_args, i);
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);
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)",
226 n_py_kwargs > 0 ? "non-keyword " : "",
227 n_expected_args == 1 ? "" : "s",
230 Py_DECREF (combined_py_args);
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'",
239 Py_DECREF (combined_py_args);
244 return combined_py_args;
247 static inline gboolean
248 _invoke_state_init_from_callable_cache (PyGIInvokeState *state,
249 PyGICallableCache *cache,
253 state->implementor_gtype = 0;
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
260 if (cache->function_type == PYGI_FUNCTION_TYPE_CONSTRUCTOR) {
261 PyObject *constructor_class;
262 constructor_class = PyTuple_GetItem (py_args, 0);
264 if (constructor_class == NULL) {
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.",
273 } else if (cache->function_type == PYGI_FUNCTION_TYPE_VFUNC) {
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");
282 state->implementor_gtype = pyg_type_from_object (py_gtype);
284 if (state->implementor_gtype == 0)
288 if (cache->function_type == PYGI_FUNCTION_TYPE_CONSTRUCTOR ||
289 cache->function_type == PYGI_FUNCTION_TYPE_VFUNC) {
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
295 state->py_in_args = PyTuple_GetSlice (py_args, 1, PyTuple_Size (py_args));
297 state->py_in_args = py_args;
298 Py_INCREF (state->py_in_args);
301 state->py_in_args = _py_args_combine_and_check_length (cache->name,
302 cache->arg_name_list,
303 cache->arg_name_hash,
307 if (state->py_in_args == NULL) {
310 state->n_py_in_args = PyTuple_Size (state->py_in_args);
312 state->args = g_slice_alloc0 (cache->n_args * sizeof (GIArgument *));
313 if (state->args == NULL && cache->n_args != 0) {
318 state->args_data = g_slice_alloc0 (cache->n_args * sizeof (gpointer));
319 if (state->args_data == NULL && cache->n_args != 0) {
324 state->in_args = g_slice_alloc0 (cache->n_from_py_args * sizeof(GIArgument));
325 if (state->in_args == NULL && cache->n_from_py_args != 0) {
330 state->out_values = g_slice_alloc0 (cache->n_to_py_args * sizeof(GIArgument));
331 if (state->out_values == NULL && cache->n_to_py_args != 0) {
336 state->out_args = g_slice_alloc0 (cache->n_to_py_args * sizeof(GIArgument));
337 if (state->out_args == NULL && cache->n_to_py_args != 0) {
348 _invoke_state_clear (PyGIInvokeState *state, PyGICallableCache *cache)
350 g_slice_free1 (cache->n_args * sizeof(GIArgument *), state->args);
351 g_slice_free1 (cache->n_args * sizeof(gpointer), state->args_data);
352 g_slice_free1 (cache->n_from_py_args * sizeof(GIArgument), state->in_args);
353 g_slice_free1 (cache->n_to_py_args * sizeof(GIArgument), state->out_args);
354 g_slice_free1 (cache->n_to_py_args * sizeof(GIArgument), state->out_values);
356 Py_XDECREF (state->py_in_args);
359 static gboolean _caller_alloc (PyGIInvokeState *state,
360 PyGIArgCache *arg_cache,
364 if (arg_cache->type_tag == GI_TYPE_TAG_INTERFACE) {
365 PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
367 state->out_args[out_count].v_pointer = NULL;
368 state->args[arg_count] = &state->out_args[out_count];
369 if (iface_cache->g_type == G_TYPE_BOXED) {
370 state->args[arg_count]->v_pointer =
371 _pygi_boxed_alloc (iface_cache->interface_info, NULL);
372 } else if (iface_cache->g_type == G_TYPE_VALUE) {
373 state->args[arg_count]->v_pointer = g_slice_new0 (GValue);
374 } else if (iface_cache->is_foreign) {
375 PyObject *foreign_struct =
376 pygi_struct_foreign_convert_from_g_argument (
377 iface_cache->interface_info,
380 pygi_struct_foreign_convert_to_g_argument (foreign_struct,
381 iface_cache->interface_info,
382 GI_TRANSFER_EVERYTHING,
383 state->args[arg_count]);
385 gssize size = g_struct_info_get_size(
386 (GIStructInfo *)iface_cache->interface_info);
387 state->args[arg_count]->v_pointer = g_malloc0 (size);
389 } else if (arg_cache->type_tag == GI_TYPE_TAG_ARRAY) {
390 PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache;
392 state->out_args[out_count].v_pointer = g_array_new (TRUE, TRUE, seq_cache->item_size);
393 state->args[arg_count] = &state->out_args[out_count];
398 if (state->args[arg_count]->v_pointer == NULL)
405 static inline gboolean
406 _invoke_marshal_in_args (PyGIInvokeState *state, PyGICallableCache *cache)
408 gssize i, in_count, out_count;
412 if (state->n_py_in_args > cache->n_py_args) {
413 PyErr_Format (PyExc_TypeError,
414 "%s() takes exactly %zd argument(s) (%zd given)",
417 state->n_py_in_args);
421 for (i = 0; i < cache->n_args; i++) {
423 PyGIArgCache *arg_cache = cache->args_cache[i];
424 PyObject *py_arg = NULL;
426 switch (arg_cache->direction) {
427 case PYGI_DIRECTION_FROM_PYTHON:
428 state->args[i] = &(state->in_args[in_count]);
431 if (arg_cache->meta_type == PYGI_META_ARG_TYPE_CLOSURE) {
432 state->args[i]->v_pointer = state->user_data;
434 } else if (arg_cache->meta_type != PYGI_META_ARG_TYPE_PARENT)
437 if (arg_cache->py_arg_index >= state->n_py_in_args) {
438 PyErr_Format (PyExc_TypeError,
439 "%s() takes exactly %zd argument(s) (%zd given)",
442 state->n_py_in_args);
444 /* clean up all of the args we have already marshalled,
445 * since invoke will not be called
447 pygi_marshal_cleanup_args_from_py_parameter_fail (state,
454 PyTuple_GET_ITEM (state->py_in_args,
455 arg_cache->py_arg_index);
458 case PYGI_DIRECTION_BIDIRECTIONAL:
459 /* this will be filled in if it is an child value */
460 if (state->in_args[in_count].v_pointer != NULL)
461 state->out_values[out_count] = state->in_args[in_count];
463 state->in_args[in_count].v_pointer = &state->out_values[out_count];
466 if (arg_cache->meta_type != PYGI_META_ARG_TYPE_CHILD) {
467 if (arg_cache->py_arg_index >= state->n_py_in_args) {
468 PyErr_Format (PyExc_TypeError,
469 "%s() takes exactly %zd argument(s) (%zd given)",
472 state->n_py_in_args);
473 pygi_marshal_cleanup_args_from_py_parameter_fail (state,
480 PyTuple_GET_ITEM (state->py_in_args,
481 arg_cache->py_arg_index);
483 case PYGI_DIRECTION_TO_PYTHON:
484 if (arg_cache->is_caller_allocates) {
485 if (!_caller_alloc (state, arg_cache, i, out_count)) {
486 PyErr_Format (PyExc_TypeError,
487 "Could not caller allocate argument %zd of callable %s",
489 pygi_marshal_cleanup_args_from_py_parameter_fail (state,
495 state->out_args[out_count].v_pointer = &state->out_values[out_count];
496 state->args[i] = &state->out_values[out_count];
502 c_arg = state->args[i];
503 if (arg_cache->from_py_marshaller != NULL) {
504 if (!arg_cache->allow_none && py_arg == Py_None) {
505 PyErr_Format (PyExc_TypeError,
506 "Argument %zd does not allow None as a value",
509 pygi_marshal_cleanup_args_from_py_parameter_fail (state,
514 gboolean success = arg_cache->from_py_marshaller (state,
520 pygi_marshal_cleanup_args_from_py_parameter_fail (state,
533 static inline PyObject *
534 _invoke_marshal_out_args (PyGIInvokeState *state, PyGICallableCache *cache)
536 PyObject *py_out = NULL;
537 PyObject *py_return = NULL;
538 gssize total_out_args = cache->n_to_py_args;
539 gboolean has_return = FALSE;
541 if (cache->return_cache) {
542 if (!cache->return_cache->is_skipped) {
543 if (cache->function_type == PYGI_FUNCTION_TYPE_CONSTRUCTOR) {
544 if (state->return_arg.v_pointer == NULL) {
545 PyErr_SetString (PyExc_TypeError, "constructor returned NULL");
546 pygi_marshal_cleanup_args_return_fail (state,
552 py_return = cache->return_cache->to_py_marshaller ( state,
556 if (py_return == NULL) {
557 pygi_marshal_cleanup_args_return_fail (state,
563 if (cache->return_cache->type_tag != GI_TYPE_TAG_VOID) {
568 if (cache->return_cache->transfer == GI_TRANSFER_EVERYTHING) {
569 PyGIMarshalCleanupFunc to_py_cleanup =
570 cache->return_cache->to_py_cleanup;
572 if (to_py_cleanup != NULL)
573 to_py_cleanup ( state,
581 total_out_args -= cache->n_to_py_child_args;
583 if (cache->n_to_py_args - cache->n_to_py_child_args == 0) {
584 if (cache->return_cache->is_skipped && state->error == NULL) {
585 /* we skip the return value and have no (out) arguments to return,
586 * so py_return should be NULL. But we must not return NULL,
587 * otherwise Python will expect an exception.
589 g_assert (py_return == NULL);
595 } else if (total_out_args == 1) {
596 /* if we get here there is one out arg an no return */
597 PyGIArgCache *arg_cache = (PyGIArgCache *)cache->to_py_args->data;
598 py_out = arg_cache->to_py_marshaller (state,
601 state->args[arg_cache->c_arg_index]);
602 if (py_out == NULL) {
603 pygi_marshal_cleanup_args_to_py_parameter_fail (state,
610 gssize py_arg_index = 0;
611 GSList *cache_item = cache->to_py_args;
613 py_out = PyTuple_New (total_out_args);
615 PyTuple_SET_ITEM (py_out, py_arg_index, py_return);
619 for(; py_arg_index < total_out_args; py_arg_index++) {
620 PyGIArgCache *arg_cache = (PyGIArgCache *)cache_item->data;
621 PyObject *py_obj = arg_cache->to_py_marshaller (state,
624 state->args[arg_cache->c_arg_index]);
626 if (py_obj == NULL) {
630 pygi_marshal_cleanup_args_to_py_parameter_fail (state,
637 PyTuple_SET_ITEM (py_out, py_arg_index, py_obj);
638 cache_item = cache_item->next;
645 pygi_callable_info_invoke (GIBaseInfo *info, PyObject *py_args,
646 PyObject *kwargs, PyGICallableCache *cache,
647 GCallback function_ptr, gpointer user_data)
649 PyGIInvokeState state = { 0, };
650 PyObject *ret = NULL;
652 if (!_invoke_state_init_from_callable_cache (&state, cache, py_args, kwargs))
655 if (cache->function_type == PYGI_FUNCTION_TYPE_CCALLBACK)
656 state.user_data = user_data;
658 if (!_invoke_marshal_in_args (&state, cache))
661 if (!_invoke_callable (&state, cache, info, function_ptr))
664 pygi_marshal_cleanup_args_from_py_marshal_success (&state, cache);
666 ret = _invoke_marshal_out_args (&state, cache);
668 pygi_marshal_cleanup_args_to_py_marshal_success (&state, cache);
670 _invoke_state_clear (&state, cache);
675 _wrap_g_callable_info_invoke (PyGIBaseInfo *self, PyObject *py_args,
678 if (self->cache == NULL) {
679 self->cache = _pygi_callable_cache_new (self->info, FALSE);
680 if (self->cache == NULL)
684 return pygi_callable_info_invoke (self->info, py_args, kwargs, self->cache, NULL, NULL);