pygi-cache.c 29.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/* -*- Mode: C; c-basic-offset: 4 -*-
 * vim: tabstop=4 shiftwidth=4 expandtab
 *
 * Copyright (C) 2011 John (J5) Palmieri <johnp@redhat.com>
 *
 * 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
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
 * USA
 */
21

22 23
#include <girepository.h>

24
#include "pygi-info.h"
25
#include "pygi-cache.h"
26 27
#include "pygi-marshal-to-py.h"
#include "pygi-marshal-from-py.h"
28
#include "pygi-marshal-cleanup.h"
29
#include "pygi-type.h"
30
#include "pygi-hashtable.h"
31
#include "pygi-basictype.h"
32
#include "pygi-list.h"
33
#include "pygi-array.h"
34
#include "pygi-closure.h"
35
#include "pygi-error.h"
36

37 38

PyGIArgCache * _arg_cache_new_for_interface (GIInterfaceInfo *iface_info,
39
                                             GITypeInfo *type_info,
40 41
                                             GIArgInfo *arg_info,
                                             GITransfer transfer,
42
                                             PyGIDirection direction,
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 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 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
                                             /* will be removed */
                                             PyGICallableCache *callable_cache);


/* _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;
}

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;
}


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)
{
    if (!pygi_arg_base_setup ((PyGIArgCache *)iface_cache,
                              type_info,
                              arg_info,
                              transfer,
                              direction)) {
        return FALSE;
    }

    g_base_info_ref ( (GIBaseInfo *)iface_info);
    iface_cache->interface_info = iface_info;
    iface_cache->arg_cache.type_tag = GI_TYPE_TAG_INTERFACE;

    return TRUE;
}

127

128
/* cleanup */
129
void
130
_pygi_arg_cache_free (PyGIArgCache *cache)
John (J5) Palmieri's avatar
John (J5) Palmieri committed
131 132 133 134
{
    if (cache == NULL)
        return;

135
    if (cache->type_info != NULL)
136
        g_base_info_unref ( (GIBaseInfo *)cache->type_info);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
137
    if (cache->destroy_notify)
138
        cache->destroy_notify (cache);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
139
    else
140
        g_slice_free (PyGIArgCache, cache);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
141 142 143
}

static void
144
_interface_cache_free_func (PyGIInterfaceCache *cache)
145 146
{
    if (cache != NULL) {
147
        Py_XDECREF (cache->py_type);
148
        if (cache->type_name != NULL)
149
            g_free (cache->type_name);
150
        if (cache->interface_info != NULL)
151 152
            g_base_info_unref ( (GIBaseInfo *)cache->interface_info);
        g_slice_free (PyGIInterfaceCache, cache);
153 154 155 156
    }
}


157
static void
158
_sequence_cache_free_func (PyGISequenceCache *cache)
159
{
John (J5) Palmieri's avatar
John (J5) Palmieri committed
160
    if (cache != NULL) {
161 162
        _pygi_arg_cache_free (cache->item_cache);
        g_slice_free (PyGISequenceCache, cache);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
163
    }
164 165 166
}

void
167
_pygi_callable_cache_free (PyGICallableCache *cache)
168
{
169 170 171
    if (cache == NULL)
        return;

172
    g_slist_free (cache->to_py_args);
173 174
    g_slist_free (cache->arg_name_list);
    g_hash_table_destroy (cache->arg_name_hash);
175
    g_ptr_array_unref (cache->args_cache);
176

177
    if (cache->return_cache != NULL)
178
        _pygi_arg_cache_free (cache->return_cache);
179

180
    g_slice_free (PyGICallableCache, cache);
181 182 183 184
}

/* cache generation */

185 186
static PyGIInterfaceCache *
_interface_cache_new (GIInterfaceInfo *iface_info)
187 188
{
    PyGIInterfaceCache *ic;
John (J5) Palmieri's avatar
John (J5) Palmieri committed
189

190 191
    ic = g_slice_new0 (PyGIInterfaceCache);
    ( (PyGIArgCache *)ic)->destroy_notify = (GDestroyNotify)_interface_cache_free_func;
192
    ic->g_type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *)iface_info);
193
    ic->py_type = _pygi_type_import_by_gi_info ( (GIBaseInfo *) iface_info);
194 195 196 197

    if (ic->py_type == NULL)
        return NULL;

198
    ic->type_name = _pygi_g_base_info_get_fullname (iface_info);
199 200 201
    return ic;
}

202 203 204 205 206 207
gboolean
pygi_arg_sequence_setup (PyGISequenceCache  *sc,
                         GITypeInfo         *type_info,
                         GIArgInfo          *arg_info,    /* may be NULL for return arguments */
                         GITransfer          transfer,
                         PyGIDirection       direction)
208 209
{
    GITypeInfo *item_type_info;
210
    GITransfer item_transfer;
211

212 213 214 215 216 217 218
    if (!pygi_arg_base_setup ((PyGIArgCache *)sc,
                              type_info,
                              arg_info,
                              transfer,
                              direction)) {
        return FALSE;
    }
219

220
    sc->arg_cache.destroy_notify = (GDestroyNotify)_sequence_cache_free_func;
221
    item_type_info = g_type_info_get_param_type (type_info, 0);
222 223
    item_transfer =
        transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer;
224

225 226 227 228
    sc->item_cache = _arg_cache_new (item_type_info,
                                     NULL,
                                     item_transfer,
                                     direction,
229 230
                                     0, 0,
                                     NULL);
231

232 233
    g_base_info_unref ( (GIBaseInfo *)item_type_info);

234
    if (sc->item_cache == NULL) {
235 236 237 238 239 240
        return FALSE;
    }

    return TRUE;
}

241
PyGIArgCache *
242
_arg_cache_alloc (void)
243
{
244
    return g_slice_new0 (PyGIArgCache);
245
}
246

247
static void
248 249
_arg_cache_from_py_interface_union_setup (PyGIArgCache *arg_cache,
                                          GITransfer transfer)
250
{
251
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_struct_cache_adapter;
252 253
}

254
static void
255 256
_arg_cache_to_py_interface_union_setup (PyGIArgCache *arg_cache,
                                        GITransfer transfer)
257
{
258
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_struct_cache_adapter;
259 260
}

261
static void
262 263 264
_arg_cache_from_py_interface_struct_setup (PyGIArgCache *arg_cache,
                                           GIInterfaceInfo *iface_info,
                                           GITransfer transfer)
265
{
266
    PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
267
    iface_cache->is_foreign = g_struct_info_is_foreign ( (GIStructInfo*)iface_info);
268
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_struct_cache_adapter;
269 270

    if (iface_cache->g_type == G_TYPE_VALUE)
271
        arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_struct_gvalue;
272
    else if (iface_cache->is_foreign)
273
        arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_struct_foreign;
274
}
275

276
static void
277 278 279
_arg_cache_to_py_interface_struct_setup (PyGIArgCache *arg_cache,
                                         GIInterfaceInfo *iface_info,
                                         GITransfer transfer)
280 281
{
    PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
282
    iface_cache->is_foreign = g_struct_info_is_foreign ( (GIStructInfo*)iface_info);
283
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_struct_cache_adapter;
284 285

    if (iface_cache->is_foreign)
286
        arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_interface_struct_foreign;
287 288
}

289
static void
290 291
_arg_cache_from_py_interface_object_setup (PyGIArgCache *arg_cache,
                                           GITransfer transfer)
292
{
293 294
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_object;
    arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_object;
295 296
}

297
static void
298 299
_arg_cache_to_py_interface_object_setup (PyGIArgCache *arg_cache,
                                         GITransfer transfer)
300
{
301
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_object_cache_adapter;
302
    arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_interface_object;
303 304
}

305
static void
306 307
_arg_cache_from_py_interface_enum_setup (PyGIArgCache *arg_cache,
                                         GITransfer transfer)
308
{
309
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_enum;
310 311
}

312
static void
313 314
_arg_cache_to_py_interface_enum_setup (PyGIArgCache *arg_cache,
                                       GITransfer transfer)
315
{
316
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_enum;
317
}
318

319
static void
320 321
_arg_cache_from_py_interface_flags_setup (PyGIArgCache *arg_cache,
                                          GITransfer transfer)
322
{
323
    arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_flags;
324 325
}

326
static void
327 328
_arg_cache_to_py_interface_flags_setup (PyGIArgCache *arg_cache,
                                        GITransfer transfer)
329
{
330
    arg_cache->to_py_marshaller = _pygi_marshal_to_py_interface_flags;
331 332
}

333

334
PyGIArgCache *
335 336 337 338 339 340
_arg_cache_new_for_interface (GIInterfaceInfo   *iface_info,
                              GITypeInfo        *type_info,
                              GIArgInfo         *arg_info,
                              GITransfer         transfer,
                              PyGIDirection      direction,
                              PyGICallableCache *callable_cache)
341
{
342
    PyGIArgCache *arg_cache = NULL;
343
    GIInfoType info_type;
344

345 346
    info_type = g_base_info_get_type ( (GIBaseInfo *)iface_info);

347 348 349 350 351 352 353 354 355
    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);
356
        }
357 358
        default:
            ;  /* pass through to old model of setup */
359 360
    }

361 362 363 364
    arg_cache = (PyGIArgCache *)_interface_cache_new (iface_info);
    if (arg_cache == NULL)
        return NULL;

365 366
    switch (info_type) {
        case GI_INFO_TYPE_UNION:
367
            if (direction & PYGI_DIRECTION_FROM_PYTHON)
368
               _arg_cache_from_py_interface_union_setup (arg_cache, transfer);
369

370
            if (direction & PYGI_DIRECTION_TO_PYTHON)
371
               _arg_cache_to_py_interface_union_setup (arg_cache, transfer);
372

373
            break;
374
        case GI_INFO_TYPE_BOXED:
375
        case GI_INFO_TYPE_STRUCT:
376
            if (direction & PYGI_DIRECTION_FROM_PYTHON)
377 378 379 380
               _arg_cache_from_py_interface_struct_setup (arg_cache,
                                                          iface_info,
                                                          transfer);

381
            if (direction & PYGI_DIRECTION_TO_PYTHON)
382 383 384
               _arg_cache_to_py_interface_struct_setup (arg_cache,
                                                        iface_info,
                                                        transfer);
385 386 387
            break;
        case GI_INFO_TYPE_OBJECT:
        case GI_INFO_TYPE_INTERFACE:
388
            if (direction & PYGI_DIRECTION_FROM_PYTHON)
389
               _arg_cache_from_py_interface_object_setup (arg_cache, transfer);
390

391
            if (direction & PYGI_DIRECTION_TO_PYTHON)
392
               _arg_cache_to_py_interface_object_setup (arg_cache, transfer);
393

394 395
            break;
        case GI_INFO_TYPE_ENUM:
396
            if (direction & PYGI_DIRECTION_FROM_PYTHON)
397
               _arg_cache_from_py_interface_enum_setup (arg_cache, transfer);
398

399
            if (direction & PYGI_DIRECTION_TO_PYTHON)
400
               _arg_cache_to_py_interface_enum_setup (arg_cache, transfer);
401

402 403
            break;
        case GI_INFO_TYPE_FLAGS:
404
            if (direction & PYGI_DIRECTION_FROM_PYTHON)
405
               _arg_cache_from_py_interface_flags_setup (arg_cache, transfer);
406

407
            if (direction & PYGI_DIRECTION_TO_PYTHON)
408
               _arg_cache_to_py_interface_flags_setup (arg_cache, transfer);
409

410 411
            break;
        default:
412
            g_assert_not_reached ();
413 414
    }

415 416 417 418 419 420
    pygi_arg_interface_setup ((PyGIInterfaceCache *)arg_cache,
                              type_info,
                              arg_info,
                              transfer,
                              direction,
                              iface_info);
421 422

    return arg_cache;
423 424
}

425
PyGIArgCache *
426
_arg_cache_new (GITypeInfo *type_info,
427
                GIArgInfo *arg_info,     /* may be null */
428
                GITransfer transfer,
429
                PyGIDirection direction,
430
                gssize c_arg_index,
431 432
                gssize py_arg_index,
                PyGICallableCache *callable_cache)
433
{
434
    PyGIArgCache *arg_cache = NULL;
435
    GITypeTag type_tag;
436

437 438
    type_tag = g_type_info_get_tag (type_info);

439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454
    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:
455
       case GI_TYPE_TAG_FILENAME:
456 457 458 459 460
           arg_cache = pygi_arg_basic_type_new_from_info (type_info,
                                                          arg_info,
                                                          transfer,
                                                          direction);
           break;
461

462 463
       case GI_TYPE_TAG_ARRAY:
           {
464 465 466 467
               arg_cache = pygi_arg_garray_new_from_info (type_info,
                                                          arg_info,
                                                          transfer,
                                                          direction);
468
               if (arg_cache == NULL)
469 470 471 472 473 474 475 476
                   return NULL;

               pygi_arg_garray_len_arg_setup (arg_cache,
                                              type_info,
                                              callable_cache,
                                              direction,
                                              c_arg_index,
                                              &py_arg_index);
477
           }
478 479
           break;

480
       case GI_TYPE_TAG_GLIST:
481 482 483 484 485
           arg_cache = pygi_arg_glist_new_from_info (type_info,
                                                     arg_info,
                                                     transfer,
                                                     direction);
           break;
486

487
       case GI_TYPE_TAG_GSLIST:
488 489 490 491 492 493 494 495
           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,
496 497 498
                                                          arg_info,
                                                          transfer,
                                                          direction);
499
           break;
500

501
       case GI_TYPE_TAG_INTERFACE:
502
           {
503
               GIInterfaceInfo *interface_info = g_type_info_get_interface (type_info);
504
               arg_cache = _arg_cache_new_for_interface (interface_info,
505
                                                         type_info,
506 507 508
                                                         arg_info,
                                                         transfer,
                                                         direction,
509
                                                         callable_cache);
510 511

               g_base_info_unref ( (GIBaseInfo *)interface_info);
512
           }
513
           break;
514

515 516 517 518 519
       case GI_TYPE_TAG_ERROR:
           arg_cache = pygi_arg_gerror_new_from_info (type_info,
                                                      arg_info,
                                                      transfer,
                                                      direction);
520 521 522
           break;
    }

523 524 525 526 527 528
    if (arg_cache != NULL) {
        arg_cache->py_arg_index = py_arg_index;
        arg_cache->c_arg_index = c_arg_index;
    }

    return arg_cache;
529 530
}

531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547
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;
    }
}

548 549
/* Generate the cache for the callable's arguments */
static gboolean
550 551
_args_cache_generate (GICallableInfo *callable_info,
                      PyGICallableCache *callable_cache)
552
{
553 554
    gssize arg_index = 0;
    gssize i;
555
    GITypeInfo *return_info;
556
    GITransfer return_transfer;
557
    PyGIArgCache *return_cache;
558 559
    PyGIDirection return_direction;

560 561
    /* Return arguments are always considered out */
    return_direction = _pygi_get_direction (callable_cache, GI_DIRECTION_OUT);
562

563
    /* cache the return arg */
John (J5) Palmieri's avatar
John (J5) Palmieri committed
564
    return_info =
565
        g_callable_info_get_return_type (callable_info);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
566
    return_transfer =
567
        g_callable_info_get_caller_owns (callable_info);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
568
    return_cache =
569 570 571
        _arg_cache_new (return_info,
                        NULL,
                        return_transfer,
572
                        return_direction,
573
                        -1,
574 575
                        -1,
                        callable_cache);
576 577
    if (return_cache == NULL)
        return FALSE;
578

579
    return_cache->is_skipped = g_callable_info_skip_return (callable_info);
580 581
    callable_cache->return_cache = return_cache;
    g_base_info_unref (return_info);
582

583
    /* first arg is the instance */
584 585
    if (callable_cache->function_type == PYGI_FUNCTION_TYPE_METHOD ||
            callable_cache->function_type == PYGI_FUNCTION_TYPE_VFUNC) {
586 587 588
        GIInterfaceInfo *interface_info;
        PyGIArgCache *instance_cache;

589
        interface_info = g_base_info_get_container ( (GIBaseInfo *)callable_info);
590 591

        instance_cache =
592
            _arg_cache_new_for_interface (interface_info,
593
                                          NULL,
594 595
                                          NULL,
                                          GI_TRANSFER_NOTHING,
596
                                          PYGI_DIRECTION_FROM_PYTHON,
597
                                          callable_cache);
598

599
        g_base_info_unref ( (GIBaseInfo *)interface_info);
600 601 602 603

        if (instance_cache == NULL)
            return FALSE;

604 605 606
        /* Because we are not supplied a GITypeInfo for instance arguments,
         * assume some defaults. */
        instance_cache->is_pointer = TRUE;
607 608
        instance_cache->py_arg_index = 0;
        instance_cache->c_arg_index = 0;
609

610
        _pygi_callable_cache_set_arg (callable_cache, arg_index, instance_cache);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
611

612
        arg_index++;
613
        callable_cache->n_from_py_args++;
614
        callable_cache->n_py_args++;
615 616
    }

617

618
    for (i=0; arg_index < _pygi_callable_cache_args_len (callable_cache); arg_index++, i++) {
619
        PyGIArgCache *arg_cache = NULL;
620
        GIArgInfo *arg_info;
621
        PyGIDirection direction;
622

623 624 625 626 627
        arg_info = g_callable_info_get_arg (callable_info, i);

        if (g_arg_info_get_closure (arg_info) == i) {

            arg_cache = _arg_cache_alloc ();
628
            _pygi_callable_cache_set_arg (callable_cache, arg_index, arg_cache);
629

630 631
            direction = PYGI_DIRECTION_FROM_PYTHON;
            arg_cache->direction = direction;
632 633 634 635 636
            arg_cache->meta_type = PYGI_META_ARG_TYPE_CLOSURE;
            arg_cache->c_arg_index = i;

            callable_cache->n_from_py_args++;

637
        } else {
638
            GITypeInfo *type_info;
639

640 641 642 643 644 645 646 647 648 649 650 651 652 653
            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) {
                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++;
                }
654

655 656 657 658
                if (direction & PYGI_DIRECTION_FROM_PYTHON) {
                    arg_cache->c_arg_index = callable_cache->n_from_py_args;
                    callable_cache->n_from_py_args++;
                }
659

660 661 662
                if (direction & PYGI_DIRECTION_TO_PYTHON) {
                    callable_cache->n_to_py_args++;
                }
John (J5) Palmieri's avatar
John (J5) Palmieri committed
663

664
                arg_cache->type_tag = g_type_info_get_tag (type_info);
665

666
            } else {
667 668 669 670
                GITransfer transfer;
                gssize py_arg_index = -1;
                transfer = g_arg_info_get_ownership_transfer (arg_info);

671 672 673 674 675
                if (direction & PYGI_DIRECTION_FROM_PYTHON) {
                    py_arg_index = callable_cache->n_py_args;
                    callable_cache->n_from_py_args++;
                    callable_cache->n_py_args++;
                }
676

677 678 679 680 681 682
                arg_cache =
                    _arg_cache_new (type_info,
                                    arg_info,
                                    transfer,
                                    direction,
                                    arg_index,
683 684
                                    py_arg_index,
                                    callable_cache);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
685

686 687 688 689 690
                if (arg_cache == NULL) {
                    g_base_info_unref( (GIBaseInfo *)type_info);
                    g_base_info_unref( (GIBaseInfo *)arg_info);
                    return FALSE;
                }
691

692 693 694

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

696 697 698
                    callable_cache->to_py_args =
                        g_slist_append (callable_cache->to_py_args, arg_cache);
                }
699

700 701
                _pygi_callable_cache_set_arg (callable_cache, arg_index, arg_cache);
            }
702

703
            g_base_info_unref (type_info);
704
        }
705

706 707 708
        /* Ensure arguments always have a name when available */
        arg_cache->arg_name = g_base_info_get_name ((GIBaseInfo *) arg_info);

709
        g_base_info_unref ( (GIBaseInfo *)arg_info);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
710

711
    }
712

713 714 715 716 717 718
    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;
719 720 721
    callable_cache->user_data_varargs_index = -1;

    gssize last_explicit_arg_index = -1;
722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751

    /* 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;
            }
752 753 754 755 756 757 758 759 760 761 762

            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;
            }
763 764
        }
    }
765

766
    return TRUE;
767 768
}

769
PyGICallableCache *
770
_pygi_callable_cache_new (GICallableInfo *callable_info, gboolean is_ccallback)
771
{
772
    gint n_args;
773
    PyGICallableCache *cache;
774
    GIInfoType type = g_base_info_get_type ( (GIBaseInfo *)callable_info);
775

776 777
    cache = g_slice_new0 (PyGICallableCache);

778 779 780
    if (cache == NULL)
        return NULL;

781 782
    cache->name = g_base_info_get_name ((GIBaseInfo *)callable_info);

783 784 785 786 787
    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",
788
                                       g_base_info_get_namespace (callable_info), cache->name,
789 790 791
                                       deprecated);
        else
            warning = g_strdup_printf ("%s.%s is deprecated",
792
                                       g_base_info_get_namespace (callable_info), cache->name);
793
        PyErr_WarnEx(PyExc_DeprecationWarning, warning, 0);
794
        g_free (warning);
795 796
    }

797 798 799 800 801 802 803 804 805 806 807 808
    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) {
809 810 811 812
        if (is_ccallback)
            cache->function_type = PYGI_FUNCTION_TYPE_CCALLBACK;
        else
            cache->function_type = PYGI_FUNCTION_TYPE_CALLBACK;
813 814 815 816
    } else {
        cache->function_type = PYGI_FUNCTION_TYPE_METHOD;
    }

817
    n_args = g_callable_info_get_n_args (callable_info);
818 819 820 821

    /* 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)
822
        n_args++;
823

824 825 826 827
    if (n_args >= 0) {
        cache->args_cache = g_ptr_array_new_full (n_args, (GDestroyNotify) _pygi_arg_cache_free);
        g_ptr_array_set_size (cache->args_cache, n_args);
    }
828

829
    if (!_args_cache_generate (callable_info, cache))
830 831
        goto err;

832
    return cache;
833
err:
834
    _pygi_callable_cache_free (cache);
John (J5) Palmieri's avatar
John (J5) Palmieri committed
835
    return NULL;
836
}