gobject-introspection 3.0.9 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Rakefile +2 -2
- data/ext/gobject-introspection/rb-gi-argument.c +205 -47
- data/ext/gobject-introspection/rb-gi-constructor-info.c +9 -15
- data/ext/gobject-introspection/rb-gi-function-info.c +147 -46
- data/ext/gobject-introspection/rb-gi-method-info.c +5 -3
- data/ext/gobject-introspection/rb-gi-private.h +3 -1
- data/lib/gi.rb +19 -0
- data/lib/gobject-introspection.rb +10 -0
- data/lib/gobject-introspection/callable-info.rb +19 -5
- data/lib/gobject-introspection/loader.rb +113 -82
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7ea59f2198f3d8205e9cb2b841a2d46e5b740c43
|
4
|
+
data.tar.gz: d47e0988e95066f8b437f929be7dd436fb7ca7ad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b394a4d695ab3a752a43df3b088ea32798f49cb33c72ba96465c2ccf7e11de2ab84cfbf22f39ea404eec406e4372ed5f4e458f60013286ca2a7a9506f83af45
|
7
|
+
data.tar.gz: a808106e4e8782e6ddb715b9adfe7cfc4b4f6f984352be5af94aef6a315fa8639d2993c917561a2ffb21142598dc1694ff88e7280f5777b9f6340e04cd37630e
|
data/Rakefile
CHANGED
@@ -32,7 +32,7 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
|
|
32
32
|
:name => "glib",
|
33
33
|
:download_site => :gnome,
|
34
34
|
:label => "GLib",
|
35
|
-
:version => "2.
|
35
|
+
:version => "2.50.2",
|
36
36
|
:compression_method => "xz",
|
37
37
|
:windows => {
|
38
38
|
:build => false,
|
@@ -47,7 +47,7 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
|
|
47
47
|
:name => "gobject-introspection",
|
48
48
|
:download_site => :gnome,
|
49
49
|
:label => "gobject-introspection",
|
50
|
-
:version => "1.
|
50
|
+
:version => "1.50.0",
|
51
51
|
:compression_method => "xz",
|
52
52
|
:windows => {
|
53
53
|
:configure_args => [
|
@@ -537,27 +537,6 @@ rb_gi_array_argument_to_ruby(GIArgument *array_argument,
|
|
537
537
|
return rb_array;
|
538
538
|
}
|
539
539
|
|
540
|
-
static VALUE
|
541
|
-
interface_variant_to_ruby(GVariant *variant)
|
542
|
-
{
|
543
|
-
VALUE rb_value = Qnil;
|
544
|
-
const GVariantType *type;
|
545
|
-
|
546
|
-
type = g_variant_get_type(variant);
|
547
|
-
if (g_variant_type_equal(type, G_VARIANT_TYPE_STRING)) {
|
548
|
-
const char *value;
|
549
|
-
g_variant_get(variant, "s", &value);
|
550
|
-
rb_value = CSTR2RVAL(value);
|
551
|
-
} else {
|
552
|
-
rb_raise(rb_eNotImpError,
|
553
|
-
"TODO: GIArgument(interface)[GVariant][%.*s] -> Ruby",
|
554
|
-
(int)g_variant_type_get_string_length(type),
|
555
|
-
g_variant_type_peek_string(type));
|
556
|
-
}
|
557
|
-
|
558
|
-
return rb_value;
|
559
|
-
}
|
560
|
-
|
561
540
|
static VALUE
|
562
541
|
rb_gi_argument_to_ruby_interface(GIArgument *argument,
|
563
542
|
gboolean duplicate,
|
@@ -599,7 +578,7 @@ rb_gi_argument_to_ruby_interface(GIArgument *argument,
|
|
599
578
|
rb_interface = rb_enc_str_new(data, size, rb_ascii8bit_encoding());
|
600
579
|
} else if (gtype == G_TYPE_VARIANT) {
|
601
580
|
GVariant *variant = argument->v_pointer;
|
602
|
-
rb_interface =
|
581
|
+
rb_interface = rbg_variant_to_ruby(variant);
|
603
582
|
} else {
|
604
583
|
rb_interface = BOXED2RVAL(argument->v_pointer, gtype);
|
605
584
|
}
|
@@ -1214,6 +1193,58 @@ rb_gi_argument_to_ruby(GIArgument *argument,
|
|
1214
1193
|
return rb_argument;
|
1215
1194
|
}
|
1216
1195
|
|
1196
|
+
static void
|
1197
|
+
rb_gi_out_argument_init_array_c(GIArgument *argument,
|
1198
|
+
G_GNUC_UNUSED GIArgInfo *arg_info,
|
1199
|
+
G_GNUC_UNUSED GITypeInfo *array_type_info,
|
1200
|
+
GITypeInfo *element_type_info)
|
1201
|
+
{
|
1202
|
+
GITypeTag element_type_tag;
|
1203
|
+
|
1204
|
+
element_type_tag = g_type_info_get_tag(element_type_info);
|
1205
|
+
|
1206
|
+
switch (element_type_tag) {
|
1207
|
+
case GI_TYPE_TAG_VOID:
|
1208
|
+
case GI_TYPE_TAG_BOOLEAN:
|
1209
|
+
case GI_TYPE_TAG_INT8:
|
1210
|
+
case GI_TYPE_TAG_UINT8:
|
1211
|
+
case GI_TYPE_TAG_INT16:
|
1212
|
+
case GI_TYPE_TAG_UINT16:
|
1213
|
+
case GI_TYPE_TAG_INT32:
|
1214
|
+
case GI_TYPE_TAG_UINT32:
|
1215
|
+
case GI_TYPE_TAG_INT64:
|
1216
|
+
case GI_TYPE_TAG_UINT64:
|
1217
|
+
case GI_TYPE_TAG_FLOAT:
|
1218
|
+
case GI_TYPE_TAG_DOUBLE:
|
1219
|
+
case GI_TYPE_TAG_GTYPE:
|
1220
|
+
g_base_info_unref(element_type_info);
|
1221
|
+
rb_raise(rb_eNotImpError,
|
1222
|
+
"TODO: allocates GIArgument(array)[c][%s] for output",
|
1223
|
+
g_type_tag_to_string(element_type_tag));
|
1224
|
+
break;
|
1225
|
+
case GI_TYPE_TAG_UTF8:
|
1226
|
+
argument->v_pointer = xmalloc(sizeof(gchar **));
|
1227
|
+
break;
|
1228
|
+
case GI_TYPE_TAG_FILENAME:
|
1229
|
+
case GI_TYPE_TAG_ARRAY:
|
1230
|
+
case GI_TYPE_TAG_INTERFACE:
|
1231
|
+
case GI_TYPE_TAG_GLIST:
|
1232
|
+
case GI_TYPE_TAG_GSLIST:
|
1233
|
+
case GI_TYPE_TAG_GHASH:
|
1234
|
+
case GI_TYPE_TAG_ERROR:
|
1235
|
+
case GI_TYPE_TAG_UNICHAR:
|
1236
|
+
g_base_info_unref(element_type_info);
|
1237
|
+
rb_raise(rb_eNotImpError,
|
1238
|
+
"TODO: allocates GIArgument(array)[c][%s] for output",
|
1239
|
+
g_type_tag_to_string(element_type_tag));
|
1240
|
+
break;
|
1241
|
+
default:
|
1242
|
+
g_base_info_unref(element_type_info);
|
1243
|
+
g_assert_not_reached();
|
1244
|
+
break;
|
1245
|
+
}
|
1246
|
+
}
|
1247
|
+
|
1217
1248
|
static void
|
1218
1249
|
rb_gi_out_argument_init_array_array_interface(GIArgument *argument,
|
1219
1250
|
G_GNUC_UNUSED GIArgInfo *arg_info,
|
@@ -1348,16 +1379,18 @@ rb_gi_out_argument_init_array(GIArgument *argument, GIArgInfo *arg_info,
|
|
1348
1379
|
{
|
1349
1380
|
GIArrayType array_type;
|
1350
1381
|
GITypeInfo *element_type_info;
|
1382
|
+
GITypeTag element_type_tag;
|
1351
1383
|
|
1352
1384
|
array_type = g_type_info_get_array_type(array_type_info);
|
1353
1385
|
element_type_info = g_type_info_get_param_type(array_type_info, 0);
|
1386
|
+
element_type_tag = g_type_info_get_tag(element_type_info);
|
1354
1387
|
|
1355
1388
|
switch (array_type) {
|
1356
1389
|
case GI_ARRAY_TYPE_C:
|
1357
|
-
|
1358
|
-
|
1359
|
-
|
1360
|
-
|
1390
|
+
rb_gi_out_argument_init_array_c(argument,
|
1391
|
+
arg_info,
|
1392
|
+
array_type_info,
|
1393
|
+
element_type_info);
|
1361
1394
|
break;
|
1362
1395
|
case GI_ARRAY_TYPE_ARRAY:
|
1363
1396
|
rb_gi_out_argument_init_array_array(argument,
|
@@ -1369,13 +1402,13 @@ rb_gi_out_argument_init_array(GIArgument *argument, GIArgInfo *arg_info,
|
|
1369
1402
|
g_base_info_unref(element_type_info);
|
1370
1403
|
rb_raise(rb_eNotImpError,
|
1371
1404
|
"TODO: allocates GIArgument(array)[ptr-array][%s] for output",
|
1372
|
-
g_type_tag_to_string(
|
1405
|
+
g_type_tag_to_string(element_type_tag));
|
1373
1406
|
break;
|
1374
1407
|
case GI_ARRAY_TYPE_BYTE_ARRAY:
|
1375
1408
|
g_base_info_unref(element_type_info);
|
1376
1409
|
rb_raise(rb_eNotImpError,
|
1377
1410
|
"TODO: allocates GIArgument(array)[byte-array][%s] for output",
|
1378
|
-
g_type_tag_to_string(
|
1411
|
+
g_type_tag_to_string(element_type_tag));
|
1379
1412
|
break;
|
1380
1413
|
default:
|
1381
1414
|
g_base_info_unref(element_type_info);
|
@@ -1709,35 +1742,101 @@ rb_gi_out_argument_to_ruby(GIArgument *argument,
|
|
1709
1742
|
args_metadata);
|
1710
1743
|
}
|
1711
1744
|
|
1745
|
+
|
1746
|
+
static void
|
1747
|
+
rb_gi_out_argument_fin_array_c(GIArgument *argument,
|
1748
|
+
G_GNUC_UNUSED GIArgInfo *arg_info,
|
1749
|
+
G_GNUC_UNUSED GITypeInfo *array_type_info,
|
1750
|
+
GITypeInfo *element_type_info)
|
1751
|
+
{
|
1752
|
+
GITypeTag element_type_tag;
|
1753
|
+
|
1754
|
+
element_type_tag = g_type_info_get_tag(element_type_info);
|
1755
|
+
|
1756
|
+
switch (element_type_tag) {
|
1757
|
+
case GI_TYPE_TAG_VOID:
|
1758
|
+
case GI_TYPE_TAG_BOOLEAN:
|
1759
|
+
case GI_TYPE_TAG_INT8:
|
1760
|
+
case GI_TYPE_TAG_UINT8:
|
1761
|
+
case GI_TYPE_TAG_INT16:
|
1762
|
+
case GI_TYPE_TAG_UINT16:
|
1763
|
+
case GI_TYPE_TAG_INT32:
|
1764
|
+
case GI_TYPE_TAG_UINT32:
|
1765
|
+
case GI_TYPE_TAG_INT64:
|
1766
|
+
case GI_TYPE_TAG_UINT64:
|
1767
|
+
case GI_TYPE_TAG_FLOAT:
|
1768
|
+
case GI_TYPE_TAG_DOUBLE:
|
1769
|
+
case GI_TYPE_TAG_GTYPE:
|
1770
|
+
g_base_info_unref(element_type_info);
|
1771
|
+
rb_raise(rb_eNotImpError,
|
1772
|
+
"TODO: free out GIArgument(array)[c][%s]",
|
1773
|
+
g_type_tag_to_string(element_type_tag));
|
1774
|
+
break;
|
1775
|
+
case GI_TYPE_TAG_UTF8:
|
1776
|
+
xfree(argument->v_pointer);
|
1777
|
+
break;
|
1778
|
+
case GI_TYPE_TAG_FILENAME:
|
1779
|
+
case GI_TYPE_TAG_ARRAY:
|
1780
|
+
case GI_TYPE_TAG_INTERFACE:
|
1781
|
+
case GI_TYPE_TAG_GLIST:
|
1782
|
+
case GI_TYPE_TAG_GSLIST:
|
1783
|
+
case GI_TYPE_TAG_GHASH:
|
1784
|
+
case GI_TYPE_TAG_ERROR:
|
1785
|
+
case GI_TYPE_TAG_UNICHAR:
|
1786
|
+
g_base_info_unref(element_type_info);
|
1787
|
+
rb_raise(rb_eNotImpError,
|
1788
|
+
"TODO: free out GIArgument(array)[c][%s]",
|
1789
|
+
g_type_tag_to_string(element_type_tag));
|
1790
|
+
break;
|
1791
|
+
default:
|
1792
|
+
g_base_info_unref(element_type_info);
|
1793
|
+
g_assert_not_reached();
|
1794
|
+
break;
|
1795
|
+
}
|
1796
|
+
}
|
1797
|
+
|
1712
1798
|
static void
|
1713
1799
|
rb_gi_out_argument_fin_array(GIArgument *argument,
|
1714
|
-
|
1800
|
+
GIArgInfo *arg_info,
|
1715
1801
|
GITypeInfo *array_type_info)
|
1716
1802
|
{
|
1717
1803
|
GIArrayType array_type;
|
1804
|
+
GITypeInfo *element_type_info;
|
1805
|
+
GITypeTag element_type_tag;
|
1718
1806
|
|
1719
1807
|
array_type = g_type_info_get_array_type(array_type_info);
|
1808
|
+
element_type_info = g_type_info_get_param_type(array_type_info, 0);
|
1809
|
+
element_type_tag = g_type_info_get_tag(element_type_info);
|
1720
1810
|
|
1721
1811
|
switch (array_type) {
|
1722
1812
|
case GI_ARRAY_TYPE_C:
|
1723
|
-
|
1724
|
-
|
1813
|
+
rb_gi_out_argument_fin_array_c(argument,
|
1814
|
+
arg_info,
|
1815
|
+
array_type_info,
|
1816
|
+
element_type_info);
|
1725
1817
|
break;
|
1726
1818
|
case GI_ARRAY_TYPE_ARRAY:
|
1727
1819
|
g_array_free(argument->v_pointer, TRUE);
|
1728
1820
|
break;
|
1729
1821
|
case GI_ARRAY_TYPE_PTR_ARRAY:
|
1822
|
+
g_base_info_unref(element_type_info);
|
1730
1823
|
rb_raise(rb_eNotImpError,
|
1731
|
-
"TODO: free out GIArgument(array)[ptr-array]"
|
1824
|
+
"TODO: free out GIArgument(array)[ptr-array][%s]",
|
1825
|
+
g_type_tag_to_string(element_type_tag));
|
1732
1826
|
break;
|
1733
1827
|
case GI_ARRAY_TYPE_BYTE_ARRAY:
|
1828
|
+
g_base_info_unref(element_type_info);
|
1734
1829
|
rb_raise(rb_eNotImpError,
|
1735
|
-
"TODO: free out GIArgument(array)[byte-array]"
|
1830
|
+
"TODO: free out GIArgument(array)[byte-array][%s]",
|
1831
|
+
g_type_tag_to_string(element_type_tag));
|
1736
1832
|
break;
|
1737
1833
|
default:
|
1834
|
+
g_base_info_unref(element_type_info);
|
1738
1835
|
g_assert_not_reached();
|
1739
1836
|
break;
|
1740
1837
|
}
|
1838
|
+
|
1839
|
+
g_base_info_unref(element_type_info);
|
1741
1840
|
}
|
1742
1841
|
|
1743
1842
|
void
|
@@ -2265,6 +2364,7 @@ rb_gi_return_argument_free_everything(GIArgument *argument,
|
|
2265
2364
|
type_tag = g_type_info_get_tag(type_info);
|
2266
2365
|
switch (type_tag) {
|
2267
2366
|
case GI_TYPE_TAG_VOID:
|
2367
|
+
break;
|
2268
2368
|
case GI_TYPE_TAG_BOOLEAN:
|
2269
2369
|
case GI_TYPE_TAG_INT8:
|
2270
2370
|
case GI_TYPE_TAG_UINT8:
|
@@ -2633,16 +2733,16 @@ rb_gi_value_argument_from_ruby(GIArgument *argument, GITypeInfo *type_info,
|
|
2633
2733
|
argument->v_boolean = RVAL2CBOOL(rb_argument);
|
2634
2734
|
break;
|
2635
2735
|
case GI_TYPE_TAG_INT8:
|
2636
|
-
argument->v_int8 =
|
2736
|
+
argument->v_int8 = NUM2CHR(rb_argument);
|
2637
2737
|
break;
|
2638
2738
|
case GI_TYPE_TAG_UINT8:
|
2639
|
-
argument->v_uint8 =
|
2739
|
+
argument->v_uint8 = (guint8)NUM2CHR(rb_argument);
|
2640
2740
|
break;
|
2641
2741
|
case GI_TYPE_TAG_INT16:
|
2642
|
-
argument->v_int16 =
|
2742
|
+
argument->v_int16 = NUM2SHORT(rb_argument);
|
2643
2743
|
break;
|
2644
2744
|
case GI_TYPE_TAG_UINT16:
|
2645
|
-
argument->v_uint16 =
|
2745
|
+
argument->v_uint16 = NUM2USHORT(rb_argument);
|
2646
2746
|
break;
|
2647
2747
|
case GI_TYPE_TAG_INT32:
|
2648
2748
|
argument->v_int32 = NUM2INT(rb_argument);
|
@@ -3005,6 +3105,38 @@ set_in_array_length_argument(GIArgument *argument,
|
|
3005
3105
|
}
|
3006
3106
|
}
|
3007
3107
|
|
3108
|
+
static void
|
3109
|
+
set_in_array_int8_arguments_from_ruby(GIArgument *array_argument,
|
3110
|
+
VALUE rb_number_array)
|
3111
|
+
{
|
3112
|
+
gint8 *numbers;
|
3113
|
+
gint i, n_args;
|
3114
|
+
|
3115
|
+
n_args = RARRAY_LEN(rb_number_array);
|
3116
|
+
numbers = ALLOC_N(gint8, n_args);
|
3117
|
+
for (i = 0; i < n_args; i++) {
|
3118
|
+
numbers[i] = NUM2CHR(RARRAY_PTR(rb_number_array)[i]);
|
3119
|
+
}
|
3120
|
+
|
3121
|
+
array_argument->v_pointer = numbers;
|
3122
|
+
}
|
3123
|
+
|
3124
|
+
static void
|
3125
|
+
set_in_array_uint8_arguments_from_ruby(GIArgument *array_argument,
|
3126
|
+
VALUE rb_number_array)
|
3127
|
+
{
|
3128
|
+
guint8 *numbers;
|
3129
|
+
gint i, n_args;
|
3130
|
+
|
3131
|
+
n_args = RARRAY_LEN(rb_number_array);
|
3132
|
+
numbers = ALLOC_N(guint8, n_args);
|
3133
|
+
for (i = 0; i < n_args; i++) {
|
3134
|
+
numbers[i] = (guint8)NUM2CHR(RARRAY_PTR(rb_number_array)[i]);
|
3135
|
+
}
|
3136
|
+
|
3137
|
+
array_argument->v_pointer = numbers;
|
3138
|
+
}
|
3139
|
+
|
3008
3140
|
static void
|
3009
3141
|
set_in_array_int16_arguments_from_ruby(GIArgument *array_argument,
|
3010
3142
|
VALUE rb_number_array)
|
@@ -3015,7 +3147,7 @@ set_in_array_int16_arguments_from_ruby(GIArgument *array_argument,
|
|
3015
3147
|
n_args = RARRAY_LEN(rb_number_array);
|
3016
3148
|
numbers = ALLOC_N(gint16, n_args);
|
3017
3149
|
for (i = 0; i < n_args; i++) {
|
3018
|
-
numbers[i] =
|
3150
|
+
numbers[i] = NUM2SHORT(RARRAY_PTR(rb_number_array)[i]);
|
3019
3151
|
}
|
3020
3152
|
|
3021
3153
|
array_argument->v_pointer = numbers;
|
@@ -3031,7 +3163,7 @@ set_in_array_uint16_arguments_from_ruby(GIArgument *array_argument,
|
|
3031
3163
|
n_args = RARRAY_LEN(rb_number_array);
|
3032
3164
|
numbers = ALLOC_N(guint16, n_args);
|
3033
3165
|
for (i = 0; i < n_args; i++) {
|
3034
|
-
numbers[i] =
|
3166
|
+
numbers[i] = NUM2USHORT(RARRAY_PTR(rb_number_array)[i]);
|
3035
3167
|
}
|
3036
3168
|
|
3037
3169
|
array_argument->v_pointer = numbers;
|
@@ -3296,10 +3428,28 @@ in_array_c_argument_from_ruby(GIArgument *array_argument,
|
|
3296
3428
|
g_type_tag_to_string(element_type_tag));
|
3297
3429
|
break;
|
3298
3430
|
case GI_TYPE_TAG_INT8:
|
3431
|
+
if (RB_TYPE_P(rb_argument, RUBY_T_STRING)) {
|
3432
|
+
array_argument->v_pointer = RSTRING_PTR(rb_argument);
|
3433
|
+
set_in_array_length_argument(length_argument, length_type_info,
|
3434
|
+
RSTRING_LEN(rb_argument));
|
3435
|
+
} else {
|
3436
|
+
rb_argument = rbg_to_array(rb_argument);
|
3437
|
+
set_in_array_int8_arguments_from_ruby(array_argument, rb_argument);
|
3438
|
+
set_in_array_length_argument(length_argument, length_type_info,
|
3439
|
+
RARRAY_LEN(rb_argument));
|
3440
|
+
}
|
3441
|
+
break;
|
3299
3442
|
case GI_TYPE_TAG_UINT8:
|
3300
|
-
|
3301
|
-
|
3302
|
-
|
3443
|
+
if (RB_TYPE_P(rb_argument, RUBY_T_STRING)) {
|
3444
|
+
array_argument->v_pointer = RSTRING_PTR(rb_argument);
|
3445
|
+
set_in_array_length_argument(length_argument, length_type_info,
|
3446
|
+
RSTRING_LEN(rb_argument));
|
3447
|
+
} else {
|
3448
|
+
rb_argument = rbg_to_array(rb_argument);
|
3449
|
+
set_in_array_uint8_arguments_from_ruby(array_argument, rb_argument);
|
3450
|
+
set_in_array_length_argument(length_argument, length_type_info,
|
3451
|
+
RARRAY_LEN(rb_argument));
|
3452
|
+
}
|
3303
3453
|
break;
|
3304
3454
|
case GI_TYPE_TAG_INT16:
|
3305
3455
|
rb_argument = rbg_to_array(rb_argument);
|
@@ -3571,7 +3721,8 @@ rb_gi_in_array_argument_from_ruby(GIArgument *array_argument,
|
|
3571
3721
|
}
|
3572
3722
|
|
3573
3723
|
static void
|
3574
|
-
rb_gi_value_argument_free_array_c(
|
3724
|
+
rb_gi_value_argument_free_array_c(VALUE rb_argument,
|
3725
|
+
GIArgument *argument,
|
3575
3726
|
G_GNUC_UNUSED GITypeInfo *type_info,
|
3576
3727
|
GITypeInfo *element_type_info)
|
3577
3728
|
{
|
@@ -3587,7 +3738,11 @@ rb_gi_value_argument_free_array_c(GIArgument *argument,
|
|
3587
3738
|
break;
|
3588
3739
|
case GI_TYPE_TAG_INT8:
|
3589
3740
|
case GI_TYPE_TAG_UINT8:
|
3590
|
-
|
3741
|
+
if (RB_TYPE_P(rb_argument, RUBY_T_STRING)) {
|
3742
|
+
/* Do nothing */
|
3743
|
+
} else {
|
3744
|
+
xfree(argument->v_pointer);
|
3745
|
+
}
|
3591
3746
|
break;
|
3592
3747
|
case GI_TYPE_TAG_INT16:
|
3593
3748
|
case GI_TYPE_TAG_UINT16:
|
@@ -3627,7 +3782,9 @@ rb_gi_value_argument_free_array_c(GIArgument *argument,
|
|
3627
3782
|
}
|
3628
3783
|
|
3629
3784
|
static void
|
3630
|
-
rb_gi_value_argument_free_array(
|
3785
|
+
rb_gi_value_argument_free_array(VALUE rb_argument,
|
3786
|
+
GIArgument *argument,
|
3787
|
+
GITypeInfo *type_info)
|
3631
3788
|
{
|
3632
3789
|
GIArrayType array_type;
|
3633
3790
|
GITypeInfo *element_type_info;
|
@@ -3636,7 +3793,8 @@ rb_gi_value_argument_free_array(GIArgument *argument, GITypeInfo *type_info)
|
|
3636
3793
|
element_type_info = g_type_info_get_param_type(type_info, 0);
|
3637
3794
|
switch (array_type) {
|
3638
3795
|
case GI_ARRAY_TYPE_C:
|
3639
|
-
rb_gi_value_argument_free_array_c(
|
3796
|
+
rb_gi_value_argument_free_array_c(rb_argument,
|
3797
|
+
argument,
|
3640
3798
|
type_info,
|
3641
3799
|
element_type_info);
|
3642
3800
|
break;
|
@@ -3706,7 +3864,7 @@ rb_gi_value_argument_free(VALUE rb_argument,
|
|
3706
3864
|
case GI_TYPE_TAG_FILENAME:
|
3707
3865
|
break;
|
3708
3866
|
case GI_TYPE_TAG_ARRAY:
|
3709
|
-
rb_gi_value_argument_free_array(argument, type_info);
|
3867
|
+
rb_gi_value_argument_free_array(rb_argument, argument, type_info);
|
3710
3868
|
break;
|
3711
3869
|
case GI_TYPE_TAG_INTERFACE:
|
3712
3870
|
rb_gi_value_argument_free_interface(rb_argument, argument, type_info);
|
@@ -86,37 +86,31 @@ initialize_receiver(VALUE receiver, GITypeInfo *info, GIArgument *value)
|
|
86
86
|
}
|
87
87
|
|
88
88
|
static VALUE
|
89
|
-
rg_invoke(VALUE self, VALUE
|
89
|
+
rg_invoke(VALUE self, VALUE rb_receiver, VALUE rb_arguments)
|
90
90
|
{
|
91
91
|
GIFunctionInfo *info;
|
92
92
|
GICallableInfo *callable_info;
|
93
|
-
VALUE receiver;
|
94
93
|
GIArgument return_value;
|
95
94
|
GITypeInfo return_value_info;
|
96
95
|
|
97
96
|
info = SELF(self);
|
98
97
|
callable_info = (GICallableInfo *)info;
|
99
98
|
|
100
|
-
|
101
|
-
|
102
|
-
if (NIL_P(receiver)) {
|
103
|
-
receiver = rb_hash_delete(rb_options, rb_str_new_cstr("receiver"));
|
104
|
-
}
|
105
|
-
if (NIL_P(receiver)) {
|
106
|
-
rb_raise(rb_eArgError,
|
107
|
-
"receiver is missing: %s",
|
108
|
-
RBG_INSPECT(rb_options));
|
99
|
+
if (NIL_P(rb_receiver)) {
|
100
|
+
rb_raise(rb_eArgError, "receiver is missing");
|
109
101
|
}
|
110
102
|
/* TODO: use rb_protect */
|
111
103
|
rb_gi_function_info_invoke_raw(info,
|
112
|
-
|
104
|
+
self,
|
105
|
+
Qnil,
|
106
|
+
rb_arguments,
|
113
107
|
&return_value,
|
114
108
|
NULL);
|
115
109
|
|
116
110
|
g_callable_info_load_return_type(callable_info, &return_value_info);
|
117
|
-
initialize_receiver(
|
111
|
+
initialize_receiver(rb_receiver, &return_value_info, &return_value);
|
118
112
|
|
119
|
-
return
|
113
|
+
return rb_receiver;
|
120
114
|
}
|
121
115
|
|
122
116
|
void
|
@@ -129,5 +123,5 @@ rb_gi_constructor_info_init(VALUE rb_mGI, VALUE rb_cGIFunctionInfo)
|
|
129
123
|
"ConstructorInfo", rb_mGI,
|
130
124
|
rb_cGIFunctionInfo);
|
131
125
|
|
132
|
-
RG_DEF_METHOD(invoke,
|
126
|
+
RG_DEF_METHOD(invoke, 2);
|
133
127
|
}
|
@@ -59,6 +59,21 @@ gi_function_info_get_type(void)
|
|
59
59
|
return type;
|
60
60
|
}
|
61
61
|
|
62
|
+
static VALUE
|
63
|
+
rg_set_unlock_gvl(VALUE self, VALUE rb_boolean)
|
64
|
+
{
|
65
|
+
return rb_iv_set(self, "unlock_gvl", rb_boolean);
|
66
|
+
}
|
67
|
+
|
68
|
+
static VALUE
|
69
|
+
rg_unlock_gvl_p(VALUE self)
|
70
|
+
{
|
71
|
+
if (!RVAL2CBOOL(rb_ivar_defined(self, rb_intern("unlock_gvl")))) {
|
72
|
+
rb_iv_set(self, "unlock_gvl", Qfalse);
|
73
|
+
}
|
74
|
+
return rb_iv_get(self, "unlock_gvl");
|
75
|
+
}
|
76
|
+
|
62
77
|
static VALUE
|
63
78
|
rg_symbol(VALUE self)
|
64
79
|
{
|
@@ -665,10 +680,12 @@ out_argument_to_raw_data_interface(GICallableInfo *callable_info,
|
|
665
680
|
GIArgument *argument,
|
666
681
|
gpointer result,
|
667
682
|
GITypeInfo *type_info,
|
668
|
-
G_GNUC_UNUSED GITransfer transfer /* TODO
|
683
|
+
G_GNUC_UNUSED GITransfer transfer /* TODO */,
|
684
|
+
gboolean is_return_value)
|
669
685
|
{
|
670
686
|
GIBaseInfo *interface_info;
|
671
687
|
GIInfoType interface_type;
|
688
|
+
GIFFIReturnValue *ffi_return_value = result;
|
672
689
|
|
673
690
|
interface_info = g_type_info_get_interface(type_info);
|
674
691
|
interface_type = g_base_info_get_type(interface_info);
|
@@ -687,7 +704,11 @@ out_argument_to_raw_data_interface(GICallableInfo *callable_info,
|
|
687
704
|
g_base_info_get_name(interface_info));
|
688
705
|
break;
|
689
706
|
case GI_INFO_TYPE_ENUM:
|
690
|
-
|
707
|
+
if (is_return_value) {
|
708
|
+
ffi_return_value->v_ulong = argument->v_int;
|
709
|
+
} else {
|
710
|
+
*((gint *)result) = argument->v_int;
|
711
|
+
}
|
691
712
|
break;
|
692
713
|
case GI_INFO_TYPE_FLAGS:
|
693
714
|
case GI_INFO_TYPE_OBJECT:
|
@@ -725,15 +746,50 @@ out_argument_to_raw_data_interface(GICallableInfo *callable_info,
|
|
725
746
|
g_base_info_unref(interface_info);
|
726
747
|
}
|
727
748
|
|
749
|
+
/*
|
750
|
+
We need to cast from different type for return value. (We don't
|
751
|
+
need it for out arguments.) Because of libffi specification:
|
752
|
+
|
753
|
+
https://github.com/libffi/libffi/blob/master/doc/libffi.texi#L190
|
754
|
+
|
755
|
+
@var{rvalue} is a pointer to a chunk of memory that will hold the
|
756
|
+
result of the function call. This must be large enough to hold the
|
757
|
+
result, no smaller than the system register size (generally 32 or 64
|
758
|
+
bits), and must be suitably aligned; it is the caller's responsibility
|
759
|
+
to ensure this. If @var{cif} declares that the function returns
|
760
|
+
@code{void} (using @code{ffi_type_void}), then @var{rvalue} is
|
761
|
+
ignored.
|
762
|
+
|
763
|
+
https://github.com/libffi/libffi/blob/master/doc/libffi.texi#L198
|
764
|
+
|
765
|
+
In most situations, @samp{libffi} will handle promotion according to
|
766
|
+
the ABI. However, for historical reasons, there is a special case
|
767
|
+
with return values that must be handled by your code. In particular,
|
768
|
+
for integral (not @code{struct}) types that are narrower than the
|
769
|
+
system register size, the return value will be widened by
|
770
|
+
@samp{libffi}. @samp{libffi} provides a type, @code{ffi_arg}, that
|
771
|
+
can be used as the return type. For example, if the CIF was defined
|
772
|
+
with a return type of @code{char}, @samp{libffi} will try to store a
|
773
|
+
full @code{ffi_arg} into the return value.
|
774
|
+
|
775
|
+
See also:
|
776
|
+
* https://github.com/ruby-gnome2/ruby-gnome2/issues/758#issuecomment-243149237
|
777
|
+
* https://github.com/libffi/libffi/pull/216
|
778
|
+
|
779
|
+
This ffi_return_value case implementation is based on
|
780
|
+
gi_type_info_extract_ffi_return_value().
|
781
|
+
*/
|
728
782
|
static void
|
729
783
|
out_argument_to_raw_data(GICallableInfo *callable_info,
|
730
784
|
VALUE rb_result,
|
731
785
|
gpointer result,
|
732
786
|
GITypeInfo *type_info,
|
733
|
-
GITransfer transfer
|
787
|
+
GITransfer transfer,
|
788
|
+
gboolean is_return_value)
|
734
789
|
{
|
735
790
|
GIArgument argument;
|
736
791
|
GITypeTag type_tag;
|
792
|
+
GIFFIReturnValue *ffi_return_value = result;
|
737
793
|
|
738
794
|
rb_gi_value_argument_from_ruby(&argument,
|
739
795
|
type_info,
|
@@ -745,25 +801,53 @@ out_argument_to_raw_data(GICallableInfo *callable_info,
|
|
745
801
|
g_assert_not_reached();
|
746
802
|
break;
|
747
803
|
case GI_TYPE_TAG_BOOLEAN:
|
748
|
-
|
804
|
+
if (is_return_value) {
|
805
|
+
ffi_return_value->v_ulong = argument.v_boolean;
|
806
|
+
} else {
|
807
|
+
*((gboolean *)result) = argument.v_boolean;
|
808
|
+
}
|
749
809
|
break;
|
750
810
|
case GI_TYPE_TAG_INT8:
|
751
|
-
|
811
|
+
if (is_return_value) {
|
812
|
+
ffi_return_value->v_long = argument.v_int8;
|
813
|
+
} else {
|
814
|
+
*((gint8 *)result) = argument.v_int8;
|
815
|
+
}
|
752
816
|
break;
|
753
817
|
case GI_TYPE_TAG_UINT8:
|
754
|
-
|
818
|
+
if (is_return_value) {
|
819
|
+
ffi_return_value->v_ulong = argument.v_uint8;
|
820
|
+
} else {
|
821
|
+
*((guint8 *)result) = argument.v_uint8;
|
822
|
+
}
|
755
823
|
break;
|
756
824
|
case GI_TYPE_TAG_INT16:
|
757
|
-
|
825
|
+
if (is_return_value) {
|
826
|
+
ffi_return_value->v_long = argument.v_int16;
|
827
|
+
} else {
|
828
|
+
*((gint16 *)result) = argument.v_int16;
|
829
|
+
}
|
758
830
|
break;
|
759
831
|
case GI_TYPE_TAG_UINT16:
|
760
|
-
|
832
|
+
if (is_return_value) {
|
833
|
+
ffi_return_value->v_ulong = argument.v_uint16;
|
834
|
+
} else {
|
835
|
+
*((guint16 *)result) = argument.v_uint16;
|
836
|
+
}
|
761
837
|
break;
|
762
838
|
case GI_TYPE_TAG_INT32:
|
763
|
-
|
839
|
+
if (is_return_value) {
|
840
|
+
ffi_return_value->v_long = argument.v_int32;
|
841
|
+
} else {
|
842
|
+
*((gint32 *)result) = argument.v_int32;
|
843
|
+
}
|
764
844
|
break;
|
765
845
|
case GI_TYPE_TAG_UINT32:
|
766
|
-
|
846
|
+
if (is_return_value) {
|
847
|
+
ffi_return_value->v_ulong = argument.v_uint32;
|
848
|
+
} else {
|
849
|
+
*((guint32 *)result) = argument.v_uint32;
|
850
|
+
}
|
767
851
|
break;
|
768
852
|
case GI_TYPE_TAG_INT64:
|
769
853
|
*((gint64 *)result) = argument.v_int64;
|
@@ -778,32 +862,57 @@ out_argument_to_raw_data(GICallableInfo *callable_info,
|
|
778
862
|
*((gdouble *)result) = argument.v_double;
|
779
863
|
break;
|
780
864
|
case GI_TYPE_TAG_GTYPE:
|
781
|
-
|
865
|
+
if (is_return_value) {
|
866
|
+
ffi_return_value->v_ulong = argument.v_size;
|
867
|
+
} else {
|
868
|
+
*((gsize *)result) = argument.v_size;
|
869
|
+
}
|
782
870
|
break;
|
783
871
|
case GI_TYPE_TAG_UTF8:
|
784
872
|
case GI_TYPE_TAG_FILENAME:
|
785
|
-
|
873
|
+
if (is_return_value) {
|
874
|
+
ffi_return_value->v_ulong = (gulong)(argument.v_string);
|
875
|
+
} else {
|
876
|
+
*((gchar **)result) = argument.v_string;
|
877
|
+
}
|
786
878
|
break;
|
787
879
|
case GI_TYPE_TAG_ARRAY:
|
788
|
-
|
880
|
+
if (is_return_value) {
|
881
|
+
ffi_return_value->v_ulong = (gulong)(argument.v_pointer);
|
882
|
+
} else {
|
883
|
+
*((gpointer *)result) = argument.v_pointer;
|
884
|
+
}
|
789
885
|
break;
|
790
886
|
case GI_TYPE_TAG_INTERFACE:
|
791
887
|
out_argument_to_raw_data_interface(callable_info,
|
792
888
|
&argument,
|
793
889
|
result,
|
794
890
|
type_info,
|
795
|
-
transfer
|
891
|
+
transfer,
|
892
|
+
is_return_value);
|
796
893
|
break;
|
797
894
|
case GI_TYPE_TAG_GLIST:
|
798
895
|
case GI_TYPE_TAG_GSLIST:
|
799
896
|
case GI_TYPE_TAG_GHASH:
|
800
|
-
|
897
|
+
if (is_return_value) {
|
898
|
+
ffi_return_value->v_ulong = (gulong)(argument.v_pointer);
|
899
|
+
} else {
|
900
|
+
*((gpointer *)result) = argument.v_pointer;
|
901
|
+
}
|
801
902
|
break;
|
802
903
|
case GI_TYPE_TAG_ERROR:
|
803
|
-
|
904
|
+
if (is_return_value) {
|
905
|
+
ffi_return_value->v_ulong = (gulong)(argument.v_pointer);
|
906
|
+
} else {
|
907
|
+
*((GError **)result) = argument.v_pointer;
|
908
|
+
}
|
804
909
|
break;
|
805
910
|
case GI_TYPE_TAG_UNICHAR:
|
806
|
-
|
911
|
+
if (is_return_value) {
|
912
|
+
ffi_return_value->v_ulong = argument.v_uint32;
|
913
|
+
} else {
|
914
|
+
*((gunichar *)result) = argument.v_uint32;
|
915
|
+
}
|
807
916
|
break;
|
808
917
|
default:
|
809
918
|
g_assert_not_reached();
|
@@ -834,13 +943,15 @@ out_arguments_to_raw_data(GICallableInfo *callable_info,
|
|
834
943
|
rb_return_value,
|
835
944
|
result,
|
836
945
|
return_type_info,
|
837
|
-
transfer
|
946
|
+
transfer,
|
947
|
+
TRUE);
|
838
948
|
} else {
|
839
949
|
out_argument_to_raw_data(callable_info,
|
840
950
|
RARRAY_AREF(rb_results, i_rb_result),
|
841
951
|
result,
|
842
952
|
return_type_info,
|
843
|
-
transfer
|
953
|
+
transfer,
|
954
|
+
TRUE);
|
844
955
|
i_rb_result++;
|
845
956
|
}
|
846
957
|
}
|
@@ -866,7 +977,8 @@ out_arguments_to_raw_data(GICallableInfo *callable_info,
|
|
866
977
|
RARRAY_AREF(rb_results, i_rb_result),
|
867
978
|
argument->v_pointer,
|
868
979
|
type_info,
|
869
|
-
transfer
|
980
|
+
transfer,
|
981
|
+
FALSE);
|
870
982
|
i_rb_result++;
|
871
983
|
g_base_info_unref(type_info);
|
872
984
|
}
|
@@ -1194,7 +1306,7 @@ arguments_free(VALUE rb_arguments,
|
|
1194
1306
|
GIArgument *argument;
|
1195
1307
|
|
1196
1308
|
rb_arg_index = metadata->rb_arg_index;
|
1197
|
-
if (
|
1309
|
+
if (RARRAY_LEN(rb_arguments) > rb_arg_index) {
|
1198
1310
|
rb_argument = RARRAY_PTR(rb_arguments)[rb_arg_index];
|
1199
1311
|
}
|
1200
1312
|
argument = &(g_array_index(in_args, GIArgument, in_arg_index));
|
@@ -1267,8 +1379,12 @@ gobject_based_p(GIBaseInfo *info)
|
|
1267
1379
|
}
|
1268
1380
|
|
1269
1381
|
VALUE
|
1270
|
-
rb_gi_function_info_invoke_raw(GIFunctionInfo *info,
|
1271
|
-
|
1382
|
+
rb_gi_function_info_invoke_raw(GIFunctionInfo *info,
|
1383
|
+
VALUE rb_info,
|
1384
|
+
VALUE rb_receiver,
|
1385
|
+
VALUE rb_arguments,
|
1386
|
+
GIArgument *return_value,
|
1387
|
+
VALUE *rb_return_value)
|
1272
1388
|
{
|
1273
1389
|
GICallableInfo *callable_info;
|
1274
1390
|
GIArgument receiver;
|
@@ -1278,26 +1394,9 @@ rb_gi_function_info_invoke_raw(GIFunctionInfo *info, VALUE rb_options,
|
|
1278
1394
|
gboolean succeeded;
|
1279
1395
|
GError *error = NULL;
|
1280
1396
|
gboolean unlock_gvl = FALSE;
|
1281
|
-
VALUE rb_receiver, rb_arguments, rb_unlock_gvl;
|
1282
1397
|
gboolean rb_receiver_is_class = FALSE;
|
1283
1398
|
|
1284
|
-
|
1285
|
-
rb_receiver = Qnil;
|
1286
|
-
rb_arguments = rb_options;
|
1287
|
-
rb_unlock_gvl = Qnil;
|
1288
|
-
} else if (NIL_P(rb_options)) {
|
1289
|
-
rb_receiver = Qnil;
|
1290
|
-
rb_arguments = rb_ary_new();
|
1291
|
-
rb_unlock_gvl = Qnil;
|
1292
|
-
} else {
|
1293
|
-
rb_options = rbg_check_hash_type(rb_options);
|
1294
|
-
rbg_scan_options(rb_options,
|
1295
|
-
"receiver", &rb_receiver,
|
1296
|
-
"arguments", &rb_arguments,
|
1297
|
-
"unlock_gvl", &rb_unlock_gvl,
|
1298
|
-
NULL);
|
1299
|
-
}
|
1300
|
-
|
1399
|
+
unlock_gvl = RVAL2CBOOL(rb_funcall(rb_info, rb_intern("unlock_gvl?"), 0));
|
1301
1400
|
if (NIL_P(rb_receiver)) {
|
1302
1401
|
receiver.v_pointer = NULL;
|
1303
1402
|
} else {
|
@@ -1314,9 +1413,6 @@ rb_gi_function_info_invoke_raw(GIFunctionInfo *info, VALUE rb_options,
|
|
1314
1413
|
}
|
1315
1414
|
}
|
1316
1415
|
rb_arguments = rbg_to_array(rb_arguments);
|
1317
|
-
if (!NIL_P(rb_unlock_gvl) && RVAL2CBOOL(rb_unlock_gvl)) {
|
1318
|
-
unlock_gvl = TRUE;
|
1319
|
-
}
|
1320
1416
|
|
1321
1417
|
callable_info = (GICallableInfo *)info;
|
1322
1418
|
arguments_init(&in_args, &out_args, &args_metadata);
|
@@ -1382,7 +1478,7 @@ rb_gi_function_info_invoke_raw(GIFunctionInfo *info, VALUE rb_options,
|
|
1382
1478
|
}
|
1383
1479
|
|
1384
1480
|
static VALUE
|
1385
|
-
rg_invoke(VALUE self, VALUE
|
1481
|
+
rg_invoke(VALUE self, VALUE rb_arguments)
|
1386
1482
|
{
|
1387
1483
|
GIFunctionInfo *info;
|
1388
1484
|
VALUE rb_out_args;
|
@@ -1391,7 +1487,9 @@ rg_invoke(VALUE self, VALUE rb_options)
|
|
1391
1487
|
info = SELF(self);
|
1392
1488
|
/* TODO: use rb_protect() */
|
1393
1489
|
rb_out_args = rb_gi_function_info_invoke_raw(info,
|
1394
|
-
|
1490
|
+
self,
|
1491
|
+
Qnil,
|
1492
|
+
rb_arguments,
|
1395
1493
|
NULL,
|
1396
1494
|
&rb_return_value);
|
1397
1495
|
|
@@ -1426,6 +1524,9 @@ rb_gi_function_info_init(VALUE rb_mGI, VALUE rb_cGICallableInfo)
|
|
1426
1524
|
callback_finders = g_ptr_array_new();
|
1427
1525
|
rb_gi_callback_register_finder(source_func_callback_finder);
|
1428
1526
|
|
1527
|
+
RG_DEF_METHOD(set_unlock_gvl, 1);
|
1528
|
+
RG_DEF_METHOD_P(unlock_gvl, 0);
|
1529
|
+
|
1429
1530
|
RG_DEF_METHOD(symbol, 0);
|
1430
1531
|
RG_DEF_METHOD(flags, 0);
|
1431
1532
|
RG_DEF_METHOD(property, 0);
|
@@ -36,7 +36,7 @@ gi_method_info_get_type(void)
|
|
36
36
|
}
|
37
37
|
|
38
38
|
static VALUE
|
39
|
-
rg_invoke(VALUE self, VALUE
|
39
|
+
rg_invoke(VALUE self, VALUE rb_receiver, VALUE rb_arguments)
|
40
40
|
{
|
41
41
|
GIFunctionInfo *info;
|
42
42
|
VALUE rb_out_args;
|
@@ -46,7 +46,9 @@ rg_invoke(VALUE self, VALUE rb_options)
|
|
46
46
|
|
47
47
|
/* TODO: use rb_protect */
|
48
48
|
rb_out_args = rb_gi_function_info_invoke_raw(info,
|
49
|
-
|
49
|
+
self,
|
50
|
+
rb_receiver,
|
51
|
+
rb_arguments,
|
50
52
|
NULL,
|
51
53
|
&rb_return_value);
|
52
54
|
|
@@ -76,5 +78,5 @@ rb_gi_method_info_init(VALUE rb_mGI, VALUE rb_cGIFunctionInfo)
|
|
76
78
|
G_DEF_CLASS_WITH_PARENT(GI_TYPE_METHOD_INFO, "MethodInfo", rb_mGI,
|
77
79
|
rb_cGIFunctionInfo);
|
78
80
|
|
79
|
-
RG_DEF_METHOD(invoke,
|
81
|
+
RG_DEF_METHOD(invoke, 2);
|
80
82
|
}
|
@@ -93,7 +93,9 @@ void rb_gi_repository_init (VALUE rb_mGI);
|
|
93
93
|
void rb_gi_loader_init (VALUE rb_mGI);
|
94
94
|
|
95
95
|
VALUE rb_gi_function_info_invoke_raw (GIFunctionInfo *info,
|
96
|
-
VALUE
|
96
|
+
VALUE rb_info,
|
97
|
+
VALUE rb_receiver,
|
98
|
+
VALUE rb_arguments,
|
97
99
|
GIArgument *return_value,
|
98
100
|
VALUE *rb_return_value);
|
99
101
|
|
data/lib/gi.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# Copyright (C) 2016 Ruby-GNOME2 Project Team
|
2
|
+
#
|
3
|
+
# This library is free software; you can redistribute it and/or
|
4
|
+
# modify it under the terms of the GNU Lesser General Public
|
5
|
+
# License as published by the Free Software Foundation; either
|
6
|
+
# version 2.1 of the License, or (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This library is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
11
|
+
# Lesser General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU Lesser General Public
|
14
|
+
# License along with this library; if not, write to the Free Software
|
15
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
16
|
+
|
17
|
+
require "gobject-introspection"
|
18
|
+
|
19
|
+
GI = GObjectIntrospection
|
@@ -47,6 +47,16 @@ GObjectIntrospection.prepend_typelib_path(vendor_girepository_dir)
|
|
47
47
|
|
48
48
|
module GObjectIntrospection
|
49
49
|
LOG_DOMAIN = "GObjectIntrospection"
|
50
|
+
|
51
|
+
class << self
|
52
|
+
def load(namespace, options={})
|
53
|
+
base_module = Module.new
|
54
|
+
loader = Loader.new(base_module)
|
55
|
+
loader.version = options[:version]
|
56
|
+
loader.load(namespace)
|
57
|
+
base_module
|
58
|
+
end
|
59
|
+
end
|
50
60
|
end
|
51
61
|
GLib::Log.set_log_domain(GObjectIntrospection::LOG_DOMAIN)
|
52
62
|
|
@@ -41,11 +41,7 @@ module GObjectIntrospection
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def require_callback?
|
44
|
-
|
45
|
-
arg.direction == Direction::IN and
|
46
|
-
arg.scope != ScopeType::INVALID and
|
47
|
-
!arg.may_be_null?
|
48
|
-
end
|
44
|
+
(@require_callback ||= compute_require_callback) == :required
|
49
45
|
end
|
50
46
|
|
51
47
|
def out_args
|
@@ -63,6 +59,12 @@ module GObjectIntrospection
|
|
63
59
|
out_args.size
|
64
60
|
end
|
65
61
|
|
62
|
+
def have_return_value?
|
63
|
+
return true if return_type.tag != TypeTag::VOID
|
64
|
+
return true if return_type.pointer?
|
65
|
+
not n_out_args.zero?
|
66
|
+
end
|
67
|
+
|
66
68
|
private
|
67
69
|
def compute_in_args
|
68
70
|
array_length_indexes = []
|
@@ -103,5 +105,17 @@ module GObjectIntrospection
|
|
103
105
|
end
|
104
106
|
end
|
105
107
|
end
|
108
|
+
|
109
|
+
def compute_require_callback
|
110
|
+
args.each do |arg|
|
111
|
+
if arg.direction == Direction::IN and
|
112
|
+
arg.scope != ScopeType::INVALID and
|
113
|
+
!arg.may_be_null?
|
114
|
+
return :required
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
:not_required
|
119
|
+
end
|
106
120
|
end
|
107
121
|
end
|
@@ -78,44 +78,33 @@ module GObjectIntrospection
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def define_module_function(target_module, name, function_info)
|
81
|
-
unlock_gvl = should_unlock_gvl?(function_info, target_module)
|
82
|
-
|
83
|
-
|
84
|
-
method_name = "#{target_module}\#.#{name}"
|
85
|
-
validate_arguments(function_info, method_name, arguments)
|
86
|
-
[arguments, block]
|
87
|
-
end
|
81
|
+
function_info.unlock_gvl = should_unlock_gvl?(function_info, target_module)
|
82
|
+
method_name = "#{target_module}\#.#{name}"
|
83
|
+
arguments_builder = ArgumentsBuilder.new(function_info, method_name)
|
88
84
|
target_module.module_eval do
|
89
85
|
define_method(name) do |*arguments, &block|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
},
|
95
|
-
&block)
|
86
|
+
arguments_builder.build(arguments, block)
|
87
|
+
arguments = arguments_builder.arguments
|
88
|
+
block = arguments_builder.block
|
89
|
+
function_info.invoke(arguments, &block)
|
96
90
|
end
|
97
91
|
module_function(name)
|
98
92
|
end
|
99
93
|
end
|
100
94
|
|
101
95
|
def define_singleton_method(klass, name, info)
|
102
|
-
unlock_gvl = should_unlock_gvl?(info, klass)
|
103
|
-
|
104
|
-
|
105
|
-
validate_arguments(info, "#{klass}.#{name}", arguments)
|
106
|
-
[arguments, block]
|
107
|
-
end
|
96
|
+
info.unlock_gvl = should_unlock_gvl?(info, klass)
|
97
|
+
arguments_builder = ArgumentsBuilder.new(info, "#{klass}.#{name}")
|
98
|
+
require_callback_p = info.require_callback?
|
108
99
|
singleton_class = (class << klass; self; end)
|
109
100
|
singleton_class.__send__(:define_method, name) do |*arguments, &block|
|
110
|
-
|
111
|
-
|
101
|
+
arguments_builder.build(arguments, block)
|
102
|
+
arguments = arguments_builder.arguments
|
103
|
+
block = arguments_builder.block
|
104
|
+
if block.nil? and require_callback_p
|
112
105
|
to_enum(name, *arguments)
|
113
106
|
else
|
114
|
-
info.invoke(
|
115
|
-
:arguments => arguments,
|
116
|
-
:unlock_gvl => unlock_gvl,
|
117
|
-
},
|
118
|
-
&block)
|
107
|
+
info.invoke(arguments, &block)
|
119
108
|
end
|
120
109
|
end
|
121
110
|
end
|
@@ -286,25 +275,18 @@ module GObjectIntrospection
|
|
286
275
|
def load_constructor_infos(infos, klass)
|
287
276
|
return if infos.empty?
|
288
277
|
|
289
|
-
prepare = lambda do |info, method_name, arguments, &block|
|
290
|
-
arguments, block = build_arguments(info, arguments, &block)
|
291
|
-
validate_arguments(info, "#{klass}\##{method_name}", arguments)
|
292
|
-
[arguments, block]
|
293
|
-
end
|
294
278
|
call_initialize_post = lambda do |object|
|
295
279
|
initialize_post(object)
|
296
280
|
end
|
297
281
|
infos.each do |info|
|
298
282
|
name = "initialize_#{info.name}"
|
299
|
-
unlock_gvl = should_unlock_gvl?(info, klass)
|
283
|
+
info.unlock_gvl = should_unlock_gvl?(info, klass)
|
284
|
+
arguments_builder = ArgumentsBuilder.new(info, "#{klass}\##{name}")
|
300
285
|
klass.__send__(:define_method, name) do |*arguments, &block|
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
:unlock_gvl => unlock_gvl,
|
306
|
-
},
|
307
|
-
&block)
|
286
|
+
arguments_builder.build(arguments, block)
|
287
|
+
arguments = arguments_builder.arguments
|
288
|
+
block = arguments_builder.block
|
289
|
+
info.invoke(self, arguments, &block)
|
308
290
|
call_initialize_post.call(self)
|
309
291
|
end
|
310
292
|
klass.__send__(:private, name)
|
@@ -320,30 +302,8 @@ module GObjectIntrospection
|
|
320
302
|
end
|
321
303
|
|
322
304
|
def initialize_post(object)
|
323
|
-
|
324
|
-
|
325
|
-
def build_arguments(info, arguments, &block)
|
326
|
-
last_in_arg = info.in_args.last
|
327
|
-
if block and last_in_arg and last_in_arg.gclosure?
|
328
|
-
[arguments + [block], nil]
|
329
|
-
else
|
330
|
-
[arguments, block]
|
331
|
-
end
|
332
|
-
end
|
333
|
-
|
334
|
-
def validate_arguments(info, method_name, arguments)
|
335
|
-
n_in_args = info.n_in_args
|
336
|
-
n_required_in_args = info.n_required_in_args
|
337
|
-
return if (n_required_in_args..n_in_args).cover?(arguments.size)
|
338
|
-
|
339
|
-
detail = "#{arguments.size} for "
|
340
|
-
if n_in_args == n_required_in_args
|
341
|
-
detail << "#{n_in_args}"
|
342
|
-
else
|
343
|
-
detail << "#{n_required_in_args}..#{n_in_args}"
|
344
|
-
end
|
345
|
-
message = "#{method_name}: wrong number of arguments (#{detail})"
|
346
|
-
raise ArgumentError, message
|
305
|
+
return unless object.is_a?(GLib::Object)
|
306
|
+
self.class.reference_gobject(object, :sink => true)
|
347
307
|
end
|
348
308
|
|
349
309
|
def find_suitable_callable_info(infos, arguments)
|
@@ -453,7 +413,7 @@ module GObjectIntrospection
|
|
453
413
|
case return_type_tag
|
454
414
|
when TypeTag::BOOLEAN
|
455
415
|
case name
|
456
|
-
when /\A(?:is|get_is)_/
|
416
|
+
when /\A(?:is|get_is|can_be)_/
|
457
417
|
"#{$POSTMATCH}?"
|
458
418
|
when /\Aget_/
|
459
419
|
if function_info.n_in_args.zero?
|
@@ -539,33 +499,29 @@ module GObjectIntrospection
|
|
539
499
|
end
|
540
500
|
|
541
501
|
def define_method(info, klass, method_name)
|
542
|
-
unlock_gvl = should_unlock_gvl?(info, klass)
|
502
|
+
info.unlock_gvl = should_unlock_gvl?(info, klass)
|
543
503
|
remove_existing_method(klass, method_name)
|
544
504
|
function_info_p = (info.class == FunctionInfo)
|
545
|
-
|
546
|
-
|
547
|
-
prepare = lambda do |arguments, &block|
|
548
|
-
arguments, block = build_arguments(info, arguments, &block)
|
549
|
-
validate_arguments(info, "#{klass}\##{method_name}", arguments)
|
550
|
-
[arguments, block]
|
551
|
-
end
|
505
|
+
have_return_value_p = info.have_return_value?
|
506
|
+
arguments_builder = ArgumentsBuilder.new(info, "#{klass}\##{method_name}")
|
552
507
|
require_callback_p = info.require_callback?
|
553
508
|
klass.__send__(:define_method, method_name) do |*arguments, &block|
|
554
|
-
arguments
|
555
|
-
|
509
|
+
arguments.unshift(self) if function_info_p
|
510
|
+
arguments_builder.build(arguments, block)
|
511
|
+
arguments = arguments_builder.arguments
|
512
|
+
block = arguments_builder.block
|
556
513
|
if block.nil? and require_callback_p
|
557
514
|
to_enum(method_name, *arguments)
|
558
515
|
else
|
559
|
-
|
560
|
-
|
561
|
-
:unlock_gvl => unlock_gvl,
|
562
|
-
}
|
563
|
-
options[:receiver] = self unless function_info_p
|
564
|
-
return_value = info.invoke(options, &block)
|
565
|
-
if no_return_value_p
|
566
|
-
self
|
516
|
+
if function_info_p
|
517
|
+
return_value = info.invoke(arguments, &block)
|
567
518
|
else
|
519
|
+
return_value = info.invoke(self, arguments, &block)
|
520
|
+
end
|
521
|
+
if have_return_value_p
|
568
522
|
return_value
|
523
|
+
else
|
524
|
+
self
|
569
525
|
end
|
570
526
|
end
|
571
527
|
end
|
@@ -609,5 +565,80 @@ module GObjectIntrospection
|
|
609
565
|
load_fields(info, klass)
|
610
566
|
load_methods(info, klass)
|
611
567
|
end
|
568
|
+
|
569
|
+
class ArgumentsBuilder
|
570
|
+
attr_reader :arguments
|
571
|
+
attr_reader :block
|
572
|
+
def initialize(info, method_name)
|
573
|
+
@info = info
|
574
|
+
@method_name = method_name
|
575
|
+
|
576
|
+
@prepared = false
|
577
|
+
|
578
|
+
@arguments = nil
|
579
|
+
@block = nil
|
580
|
+
end
|
581
|
+
|
582
|
+
def build(arguments, block)
|
583
|
+
prepare
|
584
|
+
|
585
|
+
@arguments = arguments
|
586
|
+
@block = block
|
587
|
+
|
588
|
+
build_arguments
|
589
|
+
validate_arguments
|
590
|
+
end
|
591
|
+
|
592
|
+
private
|
593
|
+
def prepare
|
594
|
+
return if @prepared
|
595
|
+
|
596
|
+
@in_args = @info.in_args
|
597
|
+
@n_in_args = @in_args.size
|
598
|
+
@n_required_in_args = @info.n_required_in_args
|
599
|
+
@last_in_arg = @in_args.last
|
600
|
+
if @last_in_arg
|
601
|
+
@last_in_arg_is_gclosure = @last_in_arg.gclosure?
|
602
|
+
else
|
603
|
+
@last_in_arg_is_gclosure = false
|
604
|
+
end
|
605
|
+
@valid_n_args_range = (@n_required_in_args..@n_in_args)
|
606
|
+
|
607
|
+
@prepared = true
|
608
|
+
end
|
609
|
+
|
610
|
+
def build_arguments
|
611
|
+
if @block and @last_in_arg_is_gclosure
|
612
|
+
@arguments << @block
|
613
|
+
@block = nil
|
614
|
+
end
|
615
|
+
|
616
|
+
n_missing_arguments = @n_in_args - @arguments.size
|
617
|
+
if n_missing_arguments > 0
|
618
|
+
nil_indexes = []
|
619
|
+
@in_args.each_with_index do |arg, i|
|
620
|
+
nil_indexes << i if arg.may_be_null?
|
621
|
+
end
|
622
|
+
return if nil_indexes.size < n_missing_arguments
|
623
|
+
nil_indexes.each_with_index do |nil_index, i|
|
624
|
+
next if i <= n_missing_arguments
|
625
|
+
@arguments.insert(nil_index, nil)
|
626
|
+
end
|
627
|
+
end
|
628
|
+
end
|
629
|
+
|
630
|
+
def validate_arguments
|
631
|
+
return if @valid_n_args_range.cover?(@arguments.size)
|
632
|
+
|
633
|
+
detail = "#{@arguments.size} for "
|
634
|
+
if @n_in_args == @n_required_in_args
|
635
|
+
detail << "#{@n_in_args}"
|
636
|
+
else
|
637
|
+
detail << "#{@n_required_in_args}..#{@n_in_args}"
|
638
|
+
end
|
639
|
+
message = "#{@method_name}: wrong number of arguments (#{detail})"
|
640
|
+
raise ArgumentError, message
|
641
|
+
end
|
642
|
+
end
|
612
643
|
end
|
613
644
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gobject-introspection
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- The Ruby-GNOME2 Project Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-11-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: glib2
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 3.0
|
19
|
+
version: 3.1.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 3.0
|
26
|
+
version: 3.1.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: test-unit
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -85,6 +85,7 @@ files:
|
|
85
85
|
- ext/gobject-introspection/rb-gobject-introspection.h
|
86
86
|
- ext/gobject-introspection/rbgiversion.h
|
87
87
|
- extconf.rb
|
88
|
+
- lib/gi.rb
|
88
89
|
- lib/gobject-introspection.rb
|
89
90
|
- lib/gobject-introspection/arg-info.rb
|
90
91
|
- lib/gobject-introspection/boxed-info.rb
|