pygi-cache.c 28.4 KB
Newer Older
1 2 3 4
/* -*- Mode: C; c-basic-offset: 4 -*-
 * vim: tabstop=4 shiftwidth=4 expandtab
 *
 * Copyright (C) 2011 John (J5) Palmieri <johnp@redhat.com>
5
 * Copyright (C) 2013 Simon Feltman <sfeltman@gnome.org>
6 7 8 9 10 11 12 13 14 15 16 17
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19
 */
20

21 22
#include <girepository.h>

23
#include "pyglib.h"
24
#include "pygi-info.h"
25
#include "pygi-cache.h"
26
#include "pygi-marshal-cleanup.h"
27
#include "pygi-type.h"
28
#include "pygi-hashtable.h"
29
#include "pygi-basictype.h"
30
#include "pygi-list.h"
31
#include "pygi-array.h"
32
#include "pygi-closure.h"
33
#include "pygi-error.h"
34
#include "pygi-object.h"
35
#include "pygi-struct-marshal.h"
36
#include "pygi-enum-marshal.h"
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58


/* _arg_info_default_value
 * info:
 * arg: (out): GIArgument to fill in with default value.
 *
 * This is currently a place holder API which only supports "allow-none" pointer args.
 * Once defaults are part of the GI API, we can replace this with: g_arg_info_default_value
 * https://bugzilla.gnome.org/show_bug.cgi?id=558620
 *
 * Returns: TRUE if the given argument supports a default value and was filled in.
 */
static gboolean
_arg_info_default_value (GIArgInfo *info, GIArgument *arg)
{
    if (g_arg_info_may_be_null (info)) {
        arg->v_pointer = NULL;
        return TRUE;
    }
    return FALSE;
}

59 60 61 62 63 64 65 66 67 68 69
/* pygi_arg_base_setup:
 * arg_cache: argument cache to initialize
 * type_info: source for type related attributes to cache
 * arg_info: (allow-none): source for argument related attributes to cache
 * transfer: transfer mode to store in the argument cache
 * direction: marshaling direction to store in the cache
 *
 * Initializer for PyGIArgCache
 *
 * Returns: TRUE on success and FALSE on failure
 */
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
gboolean
pygi_arg_base_setup (PyGIArgCache *arg_cache,
                     GITypeInfo   *type_info,
                     GIArgInfo    *arg_info,  /* may be NULL for return arguments */
                     GITransfer    transfer,
                     PyGIDirection direction)
{
    arg_cache->direction = direction;
    arg_cache->transfer = transfer;
    arg_cache->py_arg_index = -1;
    arg_cache->c_arg_index = -1;

    if (type_info != NULL) {
        arg_cache->is_pointer = g_type_info_is_pointer (type_info);
        arg_cache->type_tag = g_type_info_get_tag (type_info);
        g_base_info_ref ( (GIBaseInfo *) type_info);
        arg_cache->type_info = type_info;
    }

    if (arg_info != NULL) {
        if (!arg_cache->has_default) {
            /* It is possible has_default was set somewhere else */
            arg_cache->has_default = _arg_info_default_value (arg_info,
                                                              &arg_cache->default_value);
        }
        arg_cache->arg_name = g_base_info_get_name ((GIBaseInfo *) arg_info);
        arg_cache->allow_none = g_arg_info_may_be_null (arg_info);

        if (arg_cache->type_tag == GI_TYPE_TAG_INTERFACE || arg_cache->type_tag == GI_TYPE_TAG_ARRAY)
            arg_cache->is_caller_allocates = g_arg_info_is_caller_allocates (arg_info);
        else
            arg_cache->is_caller_allocates = FALSE;
    }
    return TRUE;
}

106
void
107
pygi_arg_cache_free (PyGIArgCache *cache)
John (J5) Palmieri's avatar
John (J5) Palmieri committed
108 109 110 111
{
    if (cache == NULL)
        return;

112
    if (cache->type_info != NULL)
113
        g_base_info_unref ( (GIBaseInfo *)cache->type_info);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
114
    if (cache->destroy_notify)
115
        cache->destroy_notify (cache);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
116
    else
117
        g_slice_free (PyGIArgCache, cache);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
118 119
}

120
void
121
pygi_callable_cache_free (PyGICallableCache *cache)
122 123 124 125 126 127 128 129 130 131
{
    if (cache == NULL)
        return;

    g_slist_free (cache->to_py_args);
    g_slist_free (cache->arg_name_list);
    g_hash_table_destroy (cache->arg_name_hash);
    g_ptr_array_unref (cache->args_cache);

    if (cache->return_cache != NULL)
132
        pygi_arg_cache_free (cache->return_cache);
133

134
    g_function_invoker_destroy (&cache->invoker);
135 136 137 138 139 140
    g_slice_free (PyGICallableCache, cache);
}


/* PyGIInterfaceCache */

John (J5) Palmieri's avatar
John (J5) Palmieri committed
141
static void
142
_interface_cache_free_func (PyGIInterfaceCache *cache)
143 144
{
    if (cache != NULL) {
145
        Py_XDECREF (cache->py_type);
146
        if (cache->type_name != NULL)
147
            g_free (cache->type_name);
148
        if (cache->interface_info != NULL)
149 150
            g_base_info_unref ( (GIBaseInfo *)cache->interface_info);
        g_slice_free (PyGIInterfaceCache, cache);
151 152 153
    }
}

154 155 156 157 158 159 160 161 162 163 164 165
/* pygi_arg_interface_setup:
 * arg_cache: argument cache to initialize
 * type_info: source for type related attributes to cache
 * arg_info: (allow-none): source for argument related attributes to cache
 * transfer: transfer mode to store in the argument cache
 * direction: marshaling direction to store in the cache
 * iface_info: interface info to cache
 *
 * Initializer for PyGIInterfaceCache
 *
 * Returns: TRUE on success and FALSE on failure
 */
166 167 168 169 170 171 172
gboolean
pygi_arg_interface_setup (PyGIInterfaceCache *iface_cache,
                          GITypeInfo         *type_info,
                          GIArgInfo          *arg_info,    /* may be NULL for return arguments */
                          GITransfer          transfer,
                          PyGIDirection       direction,
                          GIInterfaceInfo    *iface_info)
173
{
174 175 176 177 178 179
    if (!pygi_arg_base_setup ((PyGIArgCache *)iface_cache,
                              type_info,
                              arg_info,
                              transfer,
                              direction)) {
        return FALSE;
John (J5) Palmieri's avatar
John (J5) Palmieri committed
180
    }
181

182
    ( (PyGIArgCache *)iface_cache)->destroy_notify = (GDestroyNotify)_interface_cache_free_func;
183

184 185 186 187 188 189
    g_base_info_ref ( (GIBaseInfo *)iface_info);
    iface_cache->interface_info = iface_info;
    iface_cache->arg_cache.type_tag = GI_TYPE_TAG_INTERFACE;
    iface_cache->type_name = _pygi_g_base_info_get_fullname (iface_info);
    iface_cache->g_type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *)iface_info);
    iface_cache->py_type = _pygi_type_import_by_gi_info ( (GIBaseInfo *) iface_info);
190

191 192 193
    if (iface_cache->py_type == NULL) {
        return FALSE;
    }
194

195
    return TRUE;
196 197
}

198 199 200 201 202 203
PyGIArgCache *
pygi_arg_interface_new_from_info (GITypeInfo         *type_info,
                                  GIArgInfo          *arg_info,    /* may be NULL for return arguments */
                                  GITransfer          transfer,
                                  PyGIDirection       direction,
                                  GIInterfaceInfo    *iface_info)
204 205
{
    PyGIInterfaceCache *ic;
John (J5) Palmieri's avatar
John (J5) Palmieri committed
206

207
    ic = g_slice_new0 (PyGIInterfaceCache);
208 209 210 211 212 213
    if (!pygi_arg_interface_setup (ic,
                                   type_info,
                                   arg_info,
                                   transfer,
                                   direction,
                                   iface_info)) {
214
        pygi_arg_cache_free ((PyGIArgCache *)ic);
215
        return NULL;
216
    }
217

218 219 220 221 222 223 224 225 226
    return (PyGIArgCache *)ic;
}

/* PyGISequenceCache */

static void
_sequence_cache_free_func (PyGISequenceCache *cache)
{
    if (cache != NULL) {
227
        pygi_arg_cache_free (cache->item_cache);
228 229
        g_slice_free (PyGISequenceCache, cache);
    }
230 231
}

232 233 234 235 236 237 238 239 240 241 242 243 244
/* pygi_arg_sequence_setup:
 * sc: sequence cache to initialize
 * type_info: source for type related attributes to cache
 * arg_info: (allow-none): source for argument related attributes to cache
 * transfer: transfer mode to store in the argument cache
 * direction: marshaling direction to store in the cache
 * iface_info: interface info to cache
 *
 * Initializer for PyGISequenceCache used for holding list and array argument
 * caches.
 *
 * Returns: TRUE on success and FALSE on failure
 */
245 246 247 248 249 250
gboolean
pygi_arg_sequence_setup (PyGISequenceCache  *sc,
                         GITypeInfo         *type_info,
                         GIArgInfo          *arg_info,    /* may be NULL for return arguments */
                         GITransfer          transfer,
                         PyGIDirection       direction)
251 252
{
    GITypeInfo *item_type_info;
253
    GITransfer item_transfer;
254

255 256 257 258 259 260 261
    if (!pygi_arg_base_setup ((PyGIArgCache *)sc,
                              type_info,
                              arg_info,
                              transfer,
                              direction)) {
        return FALSE;
    }
262

263
    sc->arg_cache.destroy_notify = (GDestroyNotify)_sequence_cache_free_func;
264
    item_type_info = g_type_info_get_param_type (type_info, 0);
265 266
    item_transfer =
        transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer;
267

268 269 270 271 272 273
    sc->item_cache = pygi_arg_cache_new (item_type_info,
                                         NULL,
                                         item_transfer,
                                         direction,
                                         0, 0,
                                         NULL);
274

275 276
    g_base_info_unref ( (GIBaseInfo *)item_type_info);

277
    if (sc->item_cache == NULL) {
278 279 280 281 282 283
        return FALSE;
    }

    return TRUE;
}

284
PyGIArgCache *
285
pygi_arg_cache_alloc (void)
286
{
287
    return g_slice_new0 (PyGIArgCache);
288
}
289

290
static PyGIArgCache *
291 292 293 294 295 296
_arg_cache_new_for_interface (GIInterfaceInfo   *iface_info,
                              GITypeInfo        *type_info,
                              GIArgInfo         *arg_info,
                              GITransfer         transfer,
                              PyGIDirection      direction,
                              PyGICallableCache *callable_cache)
297
{
298
    GIInfoType info_type;
299

300 301
    info_type = g_base_info_get_type ( (GIBaseInfo *)iface_info);

302 303 304 305 306 307 308 309
    switch (info_type) {
        case GI_INFO_TYPE_CALLBACK:
            return pygi_arg_callback_new_from_info (type_info,
                                                    arg_info,
                                                    transfer,
                                                    direction,
                                                    iface_info,
                                                    callable_cache);
310 311 312 313 314 315 316
        case GI_INFO_TYPE_OBJECT:
        case GI_INFO_TYPE_INTERFACE:
            return pygi_arg_gobject_new_from_info (type_info,
                                                   arg_info,
                                                   transfer,
                                                   direction,
                                                   iface_info);
317 318 319 320 321 322 323 324
        case GI_INFO_TYPE_BOXED:
        case GI_INFO_TYPE_STRUCT:
        case GI_INFO_TYPE_UNION:
            return pygi_arg_struct_new_from_info (type_info,
                                                  arg_info,
                                                  transfer,
                                                  direction,
                                                  iface_info);
325
        case GI_INFO_TYPE_ENUM:
326 327 328 329 330
            return pygi_arg_enum_new_from_info (type_info,
                                                arg_info,
                                                transfer,
                                                direction,
                                                iface_info);
331
        case GI_INFO_TYPE_FLAGS:
332 333 334 335 336
            return pygi_arg_flags_new_from_info (type_info,
                                                 arg_info,
                                                 transfer,
                                                 direction,
                                                 iface_info);
337
        default:
338
            g_assert_not_reached ();
339 340
    }

341
    return NULL;
342 343
}

344
PyGIArgCache *
345 346 347 348 349 350 351
pygi_arg_cache_new (GITypeInfo *type_info,
                    GIArgInfo *arg_info,     /* may be null */
                    GITransfer transfer,
                    PyGIDirection direction,
                    gssize c_arg_index,
                    gssize py_arg_index,
                    PyGICallableCache *callable_cache)
352
{
353
    PyGIArgCache *arg_cache = NULL;
354
    GITypeTag type_tag;
355

356 357
    type_tag = g_type_info_get_tag (type_info);

358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
    switch (type_tag) {
       case GI_TYPE_TAG_VOID:
       case GI_TYPE_TAG_BOOLEAN:
       case GI_TYPE_TAG_INT8:
       case GI_TYPE_TAG_UINT8:
       case GI_TYPE_TAG_INT16:
       case GI_TYPE_TAG_UINT16:
       case GI_TYPE_TAG_INT32:
       case GI_TYPE_TAG_UINT32:
       case GI_TYPE_TAG_INT64:
       case GI_TYPE_TAG_UINT64:
       case GI_TYPE_TAG_FLOAT:
       case GI_TYPE_TAG_DOUBLE:
       case GI_TYPE_TAG_UNICHAR:
       case GI_TYPE_TAG_GTYPE:
       case GI_TYPE_TAG_UTF8:
374
       case GI_TYPE_TAG_FILENAME:
375 376 377 378 379
           arg_cache = pygi_arg_basic_type_new_from_info (type_info,
                                                          arg_info,
                                                          transfer,
                                                          direction);
           break;
380

381 382
       case GI_TYPE_TAG_ARRAY:
           {
383 384 385 386
               arg_cache = pygi_arg_garray_new_from_info (type_info,
                                                          arg_info,
                                                          transfer,
                                                          direction);
387
               if (arg_cache == NULL)
388 389 390 391 392 393 394 395
                   return NULL;

               pygi_arg_garray_len_arg_setup (arg_cache,
                                              type_info,
                                              callable_cache,
                                              direction,
                                              c_arg_index,
                                              &py_arg_index);
396
           }
397 398
           break;

399
       case GI_TYPE_TAG_GLIST:
400 401 402 403 404
           arg_cache = pygi_arg_glist_new_from_info (type_info,
                                                     arg_info,
                                                     transfer,
                                                     direction);
           break;
405

406
       case GI_TYPE_TAG_GSLIST:
407 408 409 410 411 412 413 414
           arg_cache = pygi_arg_gslist_new_from_info (type_info,
                                                      arg_info,
                                                      transfer,
                                                      direction);
           break;

       case GI_TYPE_TAG_GHASH:
           arg_cache = pygi_arg_hash_table_new_from_info (type_info,
415 416 417
                                                          arg_info,
                                                          transfer,
                                                          direction);
418
           break;
419

420
       case GI_TYPE_TAG_INTERFACE:
421
           {
422
               GIInterfaceInfo *interface_info = g_type_info_get_interface (type_info);
423
               arg_cache = _arg_cache_new_for_interface (interface_info,
424
                                                         type_info,
425 426 427
                                                         arg_info,
                                                         transfer,
                                                         direction,
428
                                                         callable_cache);
429 430

               g_base_info_unref ( (GIBaseInfo *)interface_info);
431
           }
432
           break;
433

434 435 436 437 438
       case GI_TYPE_TAG_ERROR:
           arg_cache = pygi_arg_gerror_new_from_info (type_info,
                                                      arg_info,
                                                      transfer,
                                                      direction);
439 440 441
           break;
    }

442 443 444 445 446 447
    if (arg_cache != NULL) {
        arg_cache->py_arg_index = py_arg_index;
        arg_cache->c_arg_index = c_arg_index;
    }

    return arg_cache;
448 449
}

450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466
static PyGIDirection
_pygi_get_direction (PyGICallableCache *callable_cache, GIDirection gi_direction)
{
    /* For vfuncs and callbacks our marshalling directions are reversed */
    if (gi_direction == GI_DIRECTION_INOUT) {
        return PYGI_DIRECTION_BIDIRECTIONAL;
    } else if (gi_direction == GI_DIRECTION_IN) {
        if (callable_cache->function_type == PYGI_FUNCTION_TYPE_CALLBACK)
            return PYGI_DIRECTION_TO_PYTHON;
        return PYGI_DIRECTION_FROM_PYTHON;
    } else {
        if (callable_cache->function_type == PYGI_FUNCTION_TYPE_CALLBACK)
            return PYGI_DIRECTION_FROM_PYTHON;
        return PYGI_DIRECTION_TO_PYTHON;
    }
}

467 468
/* Generate the cache for the callable's arguments */
static gboolean
469 470
_args_cache_generate (GICallableInfo *callable_info,
                      PyGICallableCache *callable_cache)
471
{
472 473
    gssize arg_index = 0;
    gssize i;
474
    GITypeInfo *return_info;
475
    GITransfer return_transfer;
476
    PyGIArgCache *return_cache;
477
    PyGIDirection return_direction;
Chun-wei Fan's avatar
Chun-wei Fan committed
478
	gssize last_explicit_arg_index;
479

480 481
    /* Return arguments are always considered out */
    return_direction = _pygi_get_direction (callable_cache, GI_DIRECTION_OUT);
482

483
    /* cache the return arg */
John (J5) Palmieri's avatar
John (J5) Palmieri committed
484
    return_info =
485
        g_callable_info_get_return_type (callable_info);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
486
    return_transfer =
487
        g_callable_info_get_caller_owns (callable_info);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
488
    return_cache =
489 490 491 492 493 494 495
        pygi_arg_cache_new (return_info,
                            NULL,
                            return_transfer,
                            return_direction,
                            -1,
                            -1,
                            callable_cache);
496 497
    if (return_cache == NULL)
        return FALSE;
498

499
    return_cache->is_skipped = g_callable_info_skip_return (callable_info);
500 501
    callable_cache->return_cache = return_cache;
    g_base_info_unref (return_info);
502

503
    /* first arg is the instance */
504 505
    if (callable_cache->function_type == PYGI_FUNCTION_TYPE_METHOD ||
            callable_cache->function_type == PYGI_FUNCTION_TYPE_VFUNC) {
506 507 508
        GIInterfaceInfo *interface_info;
        PyGIArgCache *instance_cache;

509
        interface_info = g_base_info_get_container ( (GIBaseInfo *)callable_info);
510 511

        instance_cache =
512
            _arg_cache_new_for_interface (interface_info,
513
                                          NULL,
514 515
                                          NULL,
                                          GI_TRANSFER_NOTHING,
516
                                          PYGI_DIRECTION_FROM_PYTHON,
517
                                          callable_cache);
518

519
        g_base_info_unref ( (GIBaseInfo *)interface_info);
520 521 522 523

        if (instance_cache == NULL)
            return FALSE;

524 525 526
        /* Because we are not supplied a GITypeInfo for instance arguments,
         * assume some defaults. */
        instance_cache->is_pointer = TRUE;
527 528
        instance_cache->py_arg_index = 0;
        instance_cache->c_arg_index = 0;
529

530
        _pygi_callable_cache_set_arg (callable_cache, arg_index, instance_cache);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
531

532
        arg_index++;
533
        callable_cache->n_py_args++;
534 535
    }

536

537
    for (i=0; arg_index < _pygi_callable_cache_args_len (callable_cache); arg_index++, i++) {
538
        PyGIArgCache *arg_cache = NULL;
539
        GIArgInfo *arg_info;
540
        PyGIDirection direction;
541

542 543 544 545
        arg_info = g_callable_info_get_arg (callable_info, i);

        if (g_arg_info_get_closure (arg_info) == i) {

546
            arg_cache = pygi_arg_cache_alloc ();
547
            _pygi_callable_cache_set_arg (callable_cache, arg_index, arg_cache);
548

549 550
            direction = PYGI_DIRECTION_FROM_PYTHON;
            arg_cache->direction = direction;
551 552 553
            arg_cache->meta_type = PYGI_META_ARG_TYPE_CLOSURE;
            arg_cache->c_arg_index = i;

554
        } else {
555
            GITypeInfo *type_info;
556

557 558 559 560 561 562 563 564 565 566
            direction = _pygi_get_direction (callable_cache,
                                             g_arg_info_get_direction (arg_info));
            type_info = g_arg_info_get_type (arg_info);

            /* must be an child arg filled in by its owner
             * and continue
             * fill in it's c_arg_index, add to the in count
             */
            arg_cache = _pygi_callable_cache_get_arg (callable_cache, arg_index);
            if (arg_cache != NULL) {
567 568 569 570
                /* ensure c_arg_index always aligns with callable_cache->args_cache
                 * and all of the various PyGIInvokeState arrays. */
                arg_cache->c_arg_index = arg_index;

571 572 573 574
                if (arg_cache->meta_type == PYGI_META_ARG_TYPE_CHILD_WITH_PYARG) {
                    arg_cache->py_arg_index = callable_cache->n_py_args;
                    callable_cache->n_py_args++;
                }
575

576 577 578
                if (direction & PYGI_DIRECTION_TO_PYTHON) {
                    callable_cache->n_to_py_args++;
                }
John (J5) Palmieri's avatar
John (J5) Palmieri committed
579

580
                arg_cache->type_tag = g_type_info_get_tag (type_info);
581

582
            } else {
583 584 585 586
                GITransfer transfer;
                gssize py_arg_index = -1;
                transfer = g_arg_info_get_ownership_transfer (arg_info);

587 588 589 590
                if (direction & PYGI_DIRECTION_FROM_PYTHON) {
                    py_arg_index = callable_cache->n_py_args;
                    callable_cache->n_py_args++;
                }
591

592
                arg_cache =
593 594 595 596 597 598 599
                    pygi_arg_cache_new (type_info,
                                        arg_info,
                                        transfer,
                                        direction,
                                        arg_index,
                                        py_arg_index,
                                        callable_cache);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
600

601 602 603 604 605
                if (arg_cache == NULL) {
                    g_base_info_unref( (GIBaseInfo *)type_info);
                    g_base_info_unref( (GIBaseInfo *)arg_info);
                    return FALSE;
                }
606

607 608 609

                if (direction & PYGI_DIRECTION_TO_PYTHON) {
                    callable_cache->n_to_py_args++;
610

611 612 613
                    callable_cache->to_py_args =
                        g_slist_append (callable_cache->to_py_args, arg_cache);
                }
614

615 616
                _pygi_callable_cache_set_arg (callable_cache, arg_index, arg_cache);
            }
617

618
            g_base_info_unref (type_info);
619
        }
620

621 622 623
        /* Ensure arguments always have a name when available */
        arg_cache->arg_name = g_base_info_get_name ((GIBaseInfo *) arg_info);

624
        g_base_info_unref ( (GIBaseInfo *)arg_info);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
625

626
    }
627

628 629 630 631 632 633
    if (callable_cache->arg_name_hash == NULL) {
        callable_cache->arg_name_hash = g_hash_table_new (g_str_hash, g_str_equal);
    } else {
        g_hash_table_remove_all (callable_cache->arg_name_hash);
    }
    callable_cache->n_py_required_args = 0;
634 635
    callable_cache->user_data_varargs_index = -1;

Chun-wei Fan's avatar
Chun-wei Fan committed
636
    last_explicit_arg_index = -1;
637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666

    /* Reverse loop through all the arguments to setup arg_name_list/hash
     * and find the number of required arguments */
    for (i=((gssize)_pygi_callable_cache_args_len (callable_cache))-1; i >= 0; i--) {
        PyGIArgCache *arg_cache = _pygi_callable_cache_get_arg (callable_cache, i);

        if (arg_cache->meta_type != PYGI_META_ARG_TYPE_CHILD &&
                arg_cache->meta_type != PYGI_META_ARG_TYPE_CLOSURE &&
                arg_cache->direction & PYGI_DIRECTION_FROM_PYTHON) {

            /* Setup arg_name_list and arg_name_hash */
            gpointer arg_name = (gpointer)arg_cache->arg_name;
            callable_cache->arg_name_list = g_slist_prepend (callable_cache->arg_name_list,
                                                             arg_name);
            if (arg_name != NULL) {
                g_hash_table_insert (callable_cache->arg_name_hash,
                                     arg_name,
                                     GINT_TO_POINTER(i));
            }

            /* The first tail argument without a default will force all the preceding
             * argument defaults off. This limits support of default args to the
             * tail of an args list.
             */
            if (callable_cache->n_py_required_args > 0) {
                arg_cache->has_default = FALSE;
                callable_cache->n_py_required_args += 1;
            } else if (!arg_cache->has_default) {
                callable_cache->n_py_required_args += 1;
            }
667 668 669 670 671 672 673 674 675 676 677

            if (last_explicit_arg_index == -1) {
                last_explicit_arg_index = i;

                /* If the last "from python" argument in the args list is a child
                 * with pyarg (currently only callback user_data). Set it to eat
                 * variable args in the callable cache.
                 */
                if (arg_cache->meta_type == PYGI_META_ARG_TYPE_CHILD_WITH_PYARG)
                    callable_cache->user_data_varargs_index = i;
            }
678 679
        }
    }
680

681
    return TRUE;
682 683
}

684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720
static gboolean
_setup_invoker (GICallableInfo *callable_info,
                GIInfoType info_type,
                GIFunctionInvoker *invoker,
                GCallback function_ptr)
{
    GError *error = NULL;

    if (info_type == GI_INFO_TYPE_FUNCTION) {
        if (g_function_info_prep_invoker ((GIFunctionInfo *)callable_info,
                                          invoker,
                                          &error)) {
            return TRUE;
        }
        if (!pyglib_error_check (&error)) {
            PyErr_Format (PyExc_RuntimeError,
                          "unknown error creating invoker for %s",
                          g_base_info_get_name ((GIBaseInfo *)callable_info));
        }
        return FALSE;

    } else {
        if (!g_function_invoker_new_for_address (function_ptr,
                                                 (GIFunctionInfo *)callable_info,
                                                 invoker,
                                                 &error)) {
            if (!pyglib_error_check (&error)) {
                PyErr_Format (PyExc_RuntimeError,
                              "unknown error creating invoker for %s",
                              g_base_info_get_name ((GIBaseInfo *)callable_info));
            }
            return FALSE;
        }
    }
    return TRUE;
}

721
PyGICallableCache *
722 723 724
pygi_callable_cache_new (GICallableInfo *callable_info,
                         GCallback function_ptr,
                         gboolean is_ccallback)
725
{
726
    gint n_args;
727
    PyGICallableCache *cache;
728
    GIInfoType type = g_base_info_get_type ( (GIBaseInfo *)callable_info);
729

730 731
    cache = g_slice_new0 (PyGICallableCache);

732 733 734
    if (cache == NULL)
        return NULL;

735
    cache->name = g_base_info_get_name ((GIBaseInfo *)callable_info);
736
    cache->throws = g_callable_info_can_throw_gerror ((GIBaseInfo *)callable_info);
737

738 739 740 741 742
    if (g_base_info_is_deprecated (callable_info)) {
        const gchar *deprecated = g_base_info_get_attribute (callable_info, "deprecated");
        gchar *warning;
        if (deprecated != NULL)
            warning = g_strdup_printf ("%s.%s is deprecated: %s",
743
                                       g_base_info_get_namespace (callable_info), cache->name,
744 745 746
                                       deprecated);
        else
            warning = g_strdup_printf ("%s.%s is deprecated",
747
                                       g_base_info_get_namespace (callable_info), cache->name);
748
        PyErr_WarnEx(PyExc_DeprecationWarning, warning, 0);
749
        g_free (warning);
750 751
    }

752 753 754 755 756 757 758 759 760 761 762 763
    if (type == GI_INFO_TYPE_FUNCTION) {
        GIFunctionInfoFlags flags;

        flags = g_function_info_get_flags ( (GIFunctionInfo *)callable_info);

        if (flags & GI_FUNCTION_IS_CONSTRUCTOR)
            cache->function_type = PYGI_FUNCTION_TYPE_CONSTRUCTOR;
        else if (flags & GI_FUNCTION_IS_METHOD)
            cache->function_type = PYGI_FUNCTION_TYPE_METHOD;
    } else if (type == GI_INFO_TYPE_VFUNC) {
        cache->function_type = PYGI_FUNCTION_TYPE_VFUNC;
    } else if (type == GI_INFO_TYPE_CALLBACK) {
764 765 766 767
        if (is_ccallback)
            cache->function_type = PYGI_FUNCTION_TYPE_CCALLBACK;
        else
            cache->function_type = PYGI_FUNCTION_TYPE_CALLBACK;
768 769 770 771
    } else {
        cache->function_type = PYGI_FUNCTION_TYPE_METHOD;
    }

772
    n_args = g_callable_info_get_n_args (callable_info);
773 774 775 776

    /* if we are a method or vfunc make sure the instance parameter is counted */
    if (cache->function_type == PYGI_FUNCTION_TYPE_METHOD ||
            cache->function_type == PYGI_FUNCTION_TYPE_VFUNC)
777
        n_args++;
778

779
    if (n_args >= 0) {
780
        cache->args_cache = g_ptr_array_new_full (n_args, (GDestroyNotify) pygi_arg_cache_free);
781 782
        g_ptr_array_set_size (cache->args_cache, n_args);
    }
783

784
    if (!_args_cache_generate (callable_info, cache))
785 786
        goto err;

787 788 789 790
    if (!_setup_invoker (callable_info, type, &cache->invoker, function_ptr)) {
        goto err;
    }

791
    return cache;
792
err:
793
    pygi_callable_cache_free (cache);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
794
    return NULL;
795
}