gobject-introspection 3.4.9 → 4.0.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/ext/gobject-introspection/rb-gi-arg-info.c +44 -1
- data/ext/gobject-introspection/rb-gi-arguments-in.c +31 -24
- data/ext/gobject-introspection/rb-gi-arguments-out.c +17 -17
- data/ext/gobject-introspection/rb-gi-arguments.c +2054 -104
- data/ext/gobject-introspection/rb-gi-callable-info.c +2 -2
- data/ext/gobject-introspection/rb-gi-callback.c +33 -13
- data/ext/gobject-introspection/rb-gi-constant-info.c +14 -10
- data/ext/gobject-introspection/rb-gi-conversions.h +1 -23
- data/ext/gobject-introspection/rb-gi-field-info.c +77 -76
- data/ext/gobject-introspection/rb-gi-function-info.c +57 -16
- data/ext/gobject-introspection/rb-gi-private-arg-info.h +3 -1
- data/ext/gobject-introspection/rb-gi-private-arguments.h +21 -3
- data/ext/gobject-introspection/rb-gi-private.h +6 -3
- data/ext/gobject-introspection/rb-gobject-introspection.c +5 -225
- data/lib/gobject-introspection/function-info.rb +2 -2
- data/lib/gobject-introspection/loader.rb +149 -75
- data/lib/gobject-introspection/type-tag.rb +115 -123
- data/test/test-loader.rb +29 -1
- metadata +8 -12
- data/ext/gobject-introspection/gobject-introspection-enum-types.c +0 -230
- data/ext/gobject-introspection/gobject-introspection-enum-types.h +0 -42
- data/ext/gobject-introspection/rb-gi-argument.c +0 -2051
- data/ext/gobject-introspection/rbgiversion.h +0 -24
@@ -1,6 +1,6 @@
|
|
1
1
|
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
|
2
2
|
/*
|
3
|
-
* Copyright (C) 2012-
|
3
|
+
* Copyright (C) 2012-2022 Ruby-GNOME Project Team
|
4
4
|
*
|
5
5
|
* This library is free software; you can redistribute it and/or
|
6
6
|
* modify it under the terms of the GNU Lesser General Public
|
@@ -50,12 +50,15 @@
|
|
50
50
|
# define RB_TYPE_P(object, type) (TYPE(object) == type)
|
51
51
|
#endif
|
52
52
|
|
53
|
+
/* GLib 2.60 or later defines this. */
|
54
|
+
#ifndef G_GNUC_FALLTHROUGH
|
55
|
+
# define G_GNUC_FALLTHROUGH
|
56
|
+
#endif
|
57
|
+
|
53
58
|
extern void Init_gobject_introspection(void);
|
54
59
|
|
55
60
|
gboolean rb_gi_is_debug_mode(void);
|
56
61
|
|
57
|
-
void rb_gi_argument_init (void);
|
58
|
-
|
59
62
|
void rb_gi_type_tag_init (VALUE rb_mGI);
|
60
63
|
void rb_gi_base_info_init (VALUE rb_mGI);
|
61
64
|
void rb_gi_callable_info_init (VALUE rb_mGI,
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
|
2
2
|
/*
|
3
|
-
* Copyright (C) 2012-
|
3
|
+
* Copyright (C) 2012-2022 Ruby-GNOME Project Team
|
4
4
|
*
|
5
5
|
* This library is free software; you can redistribute it and/or
|
6
6
|
* modify it under the terms of the GNU Lesser General Public
|
@@ -39,228 +39,12 @@ rb_gi_is_debug_mode(void)
|
|
39
39
|
return is_debug_mode;
|
40
40
|
}
|
41
41
|
|
42
|
-
static void
|
43
|
-
find_vfunc_info (GIBaseInfo *vfunc_info,
|
44
|
-
GType implementor_gtype,
|
45
|
-
gpointer *implementor_vtable_ret,
|
46
|
-
GIFieldInfo **field_info_ret)
|
47
|
-
{
|
48
|
-
GIBaseInfo *ancestor_info = NULL;
|
49
|
-
GIStructInfo *struct_info = NULL;
|
50
|
-
GIFieldInfo *field_info = NULL;
|
51
|
-
|
52
|
-
ancestor_info = g_base_info_get_container(vfunc_info);
|
53
|
-
// ancestor_gtype = g_registered_type_info_get_g_type (
|
54
|
-
// (GIRegisteredTypeInfo *) ancestor_info);
|
55
|
-
struct_info = g_object_info_get_class_struct((GIObjectInfo*) ancestor_info);
|
56
|
-
*implementor_vtable_ret = g_type_class_ref(implementor_gtype);
|
57
|
-
|
58
|
-
field_info = g_struct_info_find_field(
|
59
|
-
struct_info, g_base_info_get_name((GIBaseInfo*) vfunc_info));
|
60
|
-
|
61
|
-
if (field_info != NULL) {
|
62
|
-
GITypeInfo *type_info;
|
63
|
-
|
64
|
-
type_info = g_field_info_get_type (field_info);
|
65
|
-
if (g_type_info_get_tag (type_info) == GI_TYPE_TAG_INTERFACE) {
|
66
|
-
*field_info_ret = field_info;
|
67
|
-
} else {
|
68
|
-
g_base_info_unref (field_info);
|
69
|
-
}
|
70
|
-
g_base_info_unref (type_info);
|
71
|
-
}
|
72
|
-
|
73
|
-
g_base_info_unref (struct_info);
|
74
|
-
}
|
75
|
-
|
76
|
-
static VALUE
|
77
|
-
garg2rval(GIArgument *argument, GITypeTag type_tag)
|
78
|
-
{
|
79
|
-
switch (type_tag) {
|
80
|
-
case GI_TYPE_TAG_INT32:
|
81
|
-
return INT2FIX(argument->v_int32);
|
82
|
-
default:
|
83
|
-
rb_raise(rb_eTypeError, "garg2rval: not implemented");
|
84
|
-
break;
|
85
|
-
}
|
86
|
-
}
|
87
|
-
|
88
|
-
static void
|
89
|
-
rval2garg(VALUE value, GITypeTag type_tag, GIArgument *argument)
|
90
|
-
{
|
91
|
-
switch (type_tag) {
|
92
|
-
case GI_TYPE_TAG_INT32:
|
93
|
-
argument->v_int32 = FIX2INT(value);
|
94
|
-
break;
|
95
|
-
default:
|
96
|
-
rb_raise(rb_eTypeError, "rval2garg: not implemented");
|
97
|
-
break;
|
98
|
-
}
|
99
|
-
}
|
100
|
-
|
101
|
-
static void
|
102
|
-
rval2ffiarg(VALUE value, ffi_arg *arg)
|
103
|
-
{
|
104
|
-
switch (TYPE(value)) {
|
105
|
-
case T_NIL:
|
106
|
-
break;
|
107
|
-
case T_FIXNUM:
|
108
|
-
case T_DATA:
|
109
|
-
*arg = FIX2INT(value);
|
110
|
-
break;
|
111
|
-
default:
|
112
|
-
rb_raise(rb_eTypeError, "rval2ffiarg: not implemented");
|
113
|
-
break;
|
114
|
-
}
|
115
|
-
}
|
116
|
-
|
117
|
-
static void
|
118
|
-
ffi_callback(G_GNUC_UNUSED ffi_cif *cif,
|
119
|
-
void *ret,
|
120
|
-
void **raw_args,
|
121
|
-
void *raw_data)
|
122
|
-
{
|
123
|
-
GIArgument **args = NULL;
|
124
|
-
RBGIVFuncCallbackData *data = NULL;
|
125
|
-
GObject* receiver = NULL;
|
126
|
-
VALUE rb_receiver = 0;
|
127
|
-
gint n_args = 0, n_in_args = 0, n_out_args = 0;
|
128
|
-
size_t i = 0, j = 0;
|
129
|
-
VALUE *in_values = NULL;
|
130
|
-
VALUE rb_ret;
|
131
|
-
GIArgInfo arg_info;
|
132
|
-
GITypeInfo type_info;
|
133
|
-
GITypeTag type_tag;
|
134
|
-
GIDirection direction;
|
135
|
-
gboolean ret_type_is_void;
|
136
|
-
|
137
|
-
args = (GIArgument **) raw_args;
|
138
|
-
data = (RBGIVFuncCallbackData *) raw_data;
|
139
|
-
|
140
|
-
receiver = G_OBJECT(args[0]->v_pointer);
|
141
|
-
rb_receiver = GOBJ2RVAL(receiver);
|
142
|
-
|
143
|
-
n_args = g_callable_info_get_n_args(data->callable_info);
|
144
|
-
in_values = (VALUE *) malloc(n_args * sizeof(VALUE));
|
145
|
-
in_values[0] = data->name;
|
146
|
-
n_in_args++;
|
147
|
-
|
148
|
-
for (i = 1, j = 1; i < n_args; i++) {
|
149
|
-
g_callable_info_load_arg(data->callable_info, i, &arg_info);
|
150
|
-
g_arg_info_load_type(&arg_info, &type_info);
|
151
|
-
type_tag = g_type_info_get_tag(&type_info);
|
152
|
-
direction = g_arg_info_get_direction(&arg_info);
|
153
|
-
|
154
|
-
if (type_tag == GI_TYPE_TAG_VOID) continue;
|
155
|
-
|
156
|
-
if (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT)
|
157
|
-
n_out_args++;
|
158
|
-
|
159
|
-
if (direction == GI_DIRECTION_OUT) continue;
|
160
|
-
|
161
|
-
in_values[j] = garg2rval(args[i], type_tag);
|
162
|
-
j++; n_in_args++;
|
163
|
-
}
|
164
|
-
|
165
|
-
// result = rb_funcall(rb_receiver, id_send, 1, data->name);
|
166
|
-
rb_ret = rb_funcallv(rb_receiver, id_send, n_in_args, in_values);
|
167
|
-
|
168
|
-
g_callable_info_load_return_type(data->callable_info, &type_info);
|
169
|
-
ret_type_is_void = g_type_info_get_tag(&type_info) == GI_TYPE_TAG_VOID;
|
170
|
-
|
171
|
-
if (n_out_args == 0 && ret_type_is_void) {
|
172
|
-
// do nothing
|
173
|
-
} else if (n_out_args == 0) {
|
174
|
-
rval2ffiarg(rb_ret, ret);
|
175
|
-
} else if (n_out_args == 1 && ret_type_is_void) {
|
176
|
-
for (i = 1; i < n_args; i++) {
|
177
|
-
g_callable_info_load_arg(data->callable_info, i, &arg_info);
|
178
|
-
g_arg_info_load_type(&arg_info, &type_info);
|
179
|
-
type_tag = g_type_info_get_tag(&type_info);
|
180
|
-
direction = g_arg_info_get_direction(&arg_info);
|
181
|
-
|
182
|
-
if (type_tag == GI_TYPE_TAG_VOID || direction == GI_DIRECTION_IN)
|
183
|
-
continue;
|
184
|
-
|
185
|
-
rval2garg(rb_ret, type_tag, *(GIArgument **) args[i]);
|
186
|
-
break;
|
187
|
-
}
|
188
|
-
} else {
|
189
|
-
if (TYPE(rb_ret) != T_ARRAY) {
|
190
|
-
rb_raise(rb_eTypeError, "return type should be Array");
|
191
|
-
}
|
192
|
-
|
193
|
-
for (i = 1, j = 0; i < n_args; i++) {
|
194
|
-
g_callable_info_load_arg(data->callable_info, i, &arg_info);
|
195
|
-
g_arg_info_load_type(&arg_info, &type_info);
|
196
|
-
type_tag = g_type_info_get_tag(&type_info);
|
197
|
-
direction = g_arg_info_get_direction(&arg_info);
|
198
|
-
|
199
|
-
if (type_tag == GI_TYPE_TAG_VOID || direction == GI_DIRECTION_IN)
|
200
|
-
continue;
|
201
|
-
|
202
|
-
rval2garg(rb_ary_entry(rb_ret, j), type_tag, *(GIArgument **) args[i]);
|
203
|
-
j++;
|
204
|
-
}
|
205
|
-
}
|
206
|
-
|
207
|
-
free(in_values);
|
208
|
-
}
|
209
|
-
|
210
|
-
static VALUE
|
211
|
-
rb_gi_hook_up_vfunc(G_GNUC_UNUSED VALUE self,
|
212
|
-
VALUE rb_name,
|
213
|
-
VALUE rb_vfunc_info,
|
214
|
-
VALUE rb_gtype)
|
215
|
-
{
|
216
|
-
GIVFuncInfo *vfunc_info = NULL;
|
217
|
-
GType gtype = 0;
|
218
|
-
gpointer implementor_vtable = NULL;
|
219
|
-
GIFieldInfo *field_info = NULL;
|
220
|
-
|
221
|
-
vfunc_info = RVAL2GI_BASE_INFO(rb_vfunc_info);
|
222
|
-
gtype = NUM2LONG(rb_gtype);
|
223
|
-
g_assert(G_TYPE_IS_CLASSED(gtype));
|
224
|
-
|
225
|
-
find_vfunc_info(vfunc_info, gtype, &implementor_vtable, &field_info);
|
226
|
-
|
227
|
-
if (field_info != NULL) {
|
228
|
-
GITypeInfo *type_info = NULL;
|
229
|
-
GIBaseInfo *interface_info = NULL;
|
230
|
-
RBGIVFuncCallbackData *data = NULL;
|
231
|
-
gint offset = 0;
|
232
|
-
gpointer *method_ptr = NULL;
|
233
|
-
|
234
|
-
type_info = g_field_info_get_type(field_info);
|
235
|
-
|
236
|
-
interface_info = g_type_info_get_interface(type_info);
|
237
|
-
g_assert(g_base_info_get_type(interface_info) == GI_INFO_TYPE_CALLBACK);
|
238
|
-
|
239
|
-
data = ALLOC(RBGIVFuncCallbackData);
|
240
|
-
data->name = rb_name;
|
241
|
-
data->callable_info = g_base_info_ref(interface_info);
|
242
|
-
data->closure = g_callable_info_prepare_closure(
|
243
|
-
interface_info, &(data->cif), ffi_callback, data);
|
244
|
-
|
245
|
-
if (data->closure) {
|
246
|
-
offset = g_field_info_get_offset(field_info);
|
247
|
-
method_ptr = G_STRUCT_MEMBER_P(implementor_vtable, offset);
|
248
|
-
|
249
|
-
*method_ptr = data->closure;
|
250
|
-
}
|
251
|
-
|
252
|
-
g_base_info_unref (interface_info);
|
253
|
-
g_base_info_unref (type_info);
|
254
|
-
g_base_info_unref (field_info);
|
255
|
-
}
|
256
|
-
|
257
|
-
return Qnil;
|
258
|
-
}
|
259
|
-
|
260
42
|
void
|
261
43
|
Init_gobject_introspection(void)
|
262
44
|
{
|
263
|
-
|
45
|
+
#ifdef HAVE_RB_EXT_RACTOR_SAFE
|
46
|
+
rb_ext_ractor_safe(true);
|
47
|
+
#endif
|
264
48
|
|
265
49
|
id_send = rb_intern("__send__");
|
266
50
|
|
@@ -271,7 +55,7 @@ Init_gobject_introspection(void)
|
|
271
55
|
}
|
272
56
|
}
|
273
57
|
|
274
|
-
RG_TARGET_NAMESPACE = rb_define_module("GObjectIntrospection");
|
58
|
+
VALUE RG_TARGET_NAMESPACE = rb_define_module("GObjectIntrospection");
|
275
59
|
|
276
60
|
rb_define_const(RG_TARGET_NAMESPACE, "BUILD_VERSION",
|
277
61
|
rb_ary_new3(3,
|
@@ -279,8 +63,6 @@ Init_gobject_introspection(void)
|
|
279
63
|
INT2FIX(GI_MINOR_VERSION),
|
280
64
|
INT2FIX(GI_MICRO_VERSION)));
|
281
65
|
|
282
|
-
rb_gi_argument_init();
|
283
|
-
|
284
66
|
rb_gi_array_type_init(RG_TARGET_NAMESPACE);
|
285
67
|
rb_gi_type_tag_init(RG_TARGET_NAMESPACE);
|
286
68
|
rb_gi_base_info_init(RG_TARGET_NAMESPACE);
|
@@ -288,6 +70,4 @@ Init_gobject_introspection(void)
|
|
288
70
|
rb_gi_loader_init(RG_TARGET_NAMESPACE);
|
289
71
|
|
290
72
|
rb_gi_callback_init(RG_TARGET_NAMESPACE);
|
291
|
-
|
292
|
-
rb_define_module_function(RG_TARGET_NAMESPACE, "hook_up_vfunc", rb_gi_hook_up_vfunc, 3);
|
293
73
|
}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2019 Ruby-GNOME Project Team
|
1
|
+
# Copyright (C) 2019-2021 Ruby-GNOME Project Team
|
2
2
|
#
|
3
3
|
# This library is free software; you can redistribute it and/or
|
4
4
|
# modify it under the terms of the GNU Lesser General Public
|
@@ -18,7 +18,7 @@ module GObjectIntrospection
|
|
18
18
|
class FunctionInfo
|
19
19
|
def inspect
|
20
20
|
super.gsub(/>\z/) do
|
21
|
-
"
|
21
|
+
" lock_gvl_default=#{lock_gvl?.inspect}>"
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -24,6 +24,9 @@ module GObjectIntrospection
|
|
24
24
|
loader.version = options[:version]
|
25
25
|
loader.load(namespace)
|
26
26
|
end
|
27
|
+
|
28
|
+
def initialize_instance_post(object)
|
29
|
+
end
|
27
30
|
end
|
28
31
|
|
29
32
|
attr_accessor :version
|
@@ -35,14 +38,16 @@ module GObjectIntrospection
|
|
35
38
|
def load(namespace)
|
36
39
|
repository = Repository.default
|
37
40
|
repository.require(namespace, @version)
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
41
|
+
prepare_class(@base_module) do
|
42
|
+
pre_load(repository, namespace)
|
43
|
+
repository.each(namespace) do |info|
|
44
|
+
load_info(info) if info.is_a?(InterfaceInfo)
|
45
|
+
end
|
46
|
+
repository.each(namespace) do |info|
|
47
|
+
load_info(info) unless info.is_a?(InterfaceInfo)
|
48
|
+
end
|
49
|
+
post_load(repository, namespace)
|
44
50
|
end
|
45
|
-
post_load(repository, namespace)
|
46
51
|
end
|
47
52
|
|
48
53
|
private
|
@@ -85,23 +90,28 @@ module GObjectIntrospection
|
|
85
90
|
end
|
86
91
|
|
87
92
|
def define_module_function(target_module, name, function_info)
|
88
|
-
|
93
|
+
prepare_function_info_lock_gvl(function_info, target_module)
|
89
94
|
full_method_name = "#{target_module}\#.#{name}"
|
90
95
|
invoker = Invoker.new(function_info, name, full_method_name)
|
91
|
-
target_module
|
92
|
-
|
93
|
-
|
96
|
+
target_module::INVOKERS[name] = invoker
|
97
|
+
target_module.module_eval(<<-DEFINE_METHOD, __FILE__, __LINE__ + 1)
|
98
|
+
def #{name}(*arguments, &block)
|
99
|
+
INVOKERS["#{name}"].invoke(nil, arguments, block)
|
94
100
|
end
|
95
|
-
module_function(name)
|
96
|
-
|
101
|
+
module_function(:#{name})
|
102
|
+
DEFINE_METHOD
|
97
103
|
end
|
98
104
|
|
99
105
|
def define_singleton_method(klass, name, info)
|
100
|
-
|
106
|
+
prepare_function_info_lock_gvl(info, klass)
|
101
107
|
invoker = Invoker.new(info, name, "#{klass}.#{name}")
|
102
|
-
klass.singleton_class
|
103
|
-
|
104
|
-
|
108
|
+
singleton_class = klass.singleton_class
|
109
|
+
singleton_class::INVOKERS[name] = invoker
|
110
|
+
singleton_class.class_eval(<<-DEFINE_METHOD, __FILE__, __LINE__ + 1)
|
111
|
+
def #{name}(*arguments, &block)
|
112
|
+
INVOKERS["#{name}"].invoke(nil, arguments, block)
|
113
|
+
end
|
114
|
+
DEFINE_METHOD
|
105
115
|
end
|
106
116
|
|
107
117
|
def define_struct(info, options={})
|
@@ -116,8 +126,10 @@ module GObjectIntrospection
|
|
116
126
|
:parent => options[:parent],
|
117
127
|
:size => size)
|
118
128
|
end
|
119
|
-
|
120
|
-
|
129
|
+
prepare_class(klass) do
|
130
|
+
load_fields(info, klass)
|
131
|
+
load_methods(info, klass)
|
132
|
+
end
|
121
133
|
end
|
122
134
|
|
123
135
|
def load_struct_info(info)
|
@@ -129,7 +141,12 @@ module GObjectIntrospection
|
|
129
141
|
end
|
130
142
|
unless method_infos.empty?
|
131
143
|
base_class = @base_module.const_get(base_class_name)
|
132
|
-
|
144
|
+
singleton_class = base_class.singleton_class
|
145
|
+
invokers = singleton_class::INVOKERS.dup
|
146
|
+
singleton_class.__send__(:remove_const, :INVOKERS)
|
147
|
+
singleton_class.const_set(:INVOKERS, invokers)
|
148
|
+
load_methods_method(method_infos, singleton_class)
|
149
|
+
Ractor.make_shareable(singleton_class::INVOKERS) if defined?(Ractor)
|
133
150
|
end
|
134
151
|
else
|
135
152
|
return if info.gtype_struct?
|
@@ -152,7 +169,9 @@ module GObjectIntrospection
|
|
152
169
|
end
|
153
170
|
|
154
171
|
def load_enum_value(value_info, enum_module)
|
155
|
-
|
172
|
+
value = value_info.value
|
173
|
+
Ractor.make_shareable(value) if defined?(Ractor)
|
174
|
+
enum_module.const_set(value_info.name.upcase, value)
|
156
175
|
end
|
157
176
|
|
158
177
|
def define_enum(info)
|
@@ -216,9 +235,11 @@ module GObjectIntrospection
|
|
216
235
|
klass = self.class.define_class(info.gtype,
|
217
236
|
rubyish_class_name(info),
|
218
237
|
@base_module)
|
219
|
-
|
220
|
-
|
221
|
-
|
238
|
+
prepare_class(klass) do
|
239
|
+
load_virtual_functions(info, klass)
|
240
|
+
load_fields(info, klass)
|
241
|
+
load_methods(info, klass)
|
242
|
+
end
|
222
243
|
end
|
223
244
|
|
224
245
|
def load_fields(info, klass)
|
@@ -300,43 +321,46 @@ module GObjectIntrospection
|
|
300
321
|
def load_methods_constructor(infos, klass)
|
301
322
|
return if infos.empty?
|
302
323
|
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
invokers = []
|
324
|
+
klass.const_set(:LOADER_CLASS, self.class)
|
325
|
+
invokers = {}
|
326
|
+
klass.const_set(:INITIALIZE_INVOKERS, invokers)
|
307
327
|
infos.each do |info|
|
308
328
|
name = "initialize_#{info.name}"
|
309
|
-
|
329
|
+
prepare_function_info_lock_gvl(info, klass)
|
310
330
|
invoker = Invoker.new(info, name, "#{klass}\##{name}")
|
311
|
-
invokers
|
312
|
-
klass.
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
end
|
318
|
-
|
319
|
-
initialize = lambda do |receiver, arguments, block|
|
320
|
-
invokers.each do |invoker|
|
321
|
-
catch do |tag|
|
322
|
-
invoker.invoke(receiver, arguments.dup, block, tag)
|
323
|
-
call_initialize_post.call(receiver)
|
324
|
-
return
|
331
|
+
invokers[name] = invoker
|
332
|
+
klass.class_eval(<<-DEFINE_METHOD, __FILE__, __LINE__ + 1)
|
333
|
+
def #{name}(*arguments, &block)
|
334
|
+
invoker = INITIALIZE_INVOKERS["#{name}"]
|
335
|
+
invoker.invoke(self, arguments, block)
|
336
|
+
LOADER_CLASS.initialize_instance_post(self)
|
325
337
|
end
|
338
|
+
private :#{name}
|
339
|
+
DEFINE_METHOD
|
340
|
+
end
|
341
|
+
|
342
|
+
klass.class_eval(<<-DEFINE_METHOD, __FILE__, __LINE__ + 1)
|
343
|
+
def initialize(*arguments, &block)
|
344
|
+
invokers = INITIALIZE_INVOKERS
|
345
|
+
invokers.values.each do |invoker|
|
346
|
+
catch do |tag|
|
347
|
+
invoker.invoke(self, arguments.dup, block, tag)
|
348
|
+
LOADER_CLASS.initialize_instance_post(self)
|
349
|
+
return
|
350
|
+
end
|
351
|
+
end
|
352
|
+
message = "wrong arguments: "
|
353
|
+
message << "\#{self.class.name}#initialize("
|
354
|
+
message << arguments.collect(&:inspect).join(", ")
|
355
|
+
message << "): "
|
356
|
+
message << "available signatures"
|
357
|
+
invokers.each_value do |invoker|
|
358
|
+
message << ": \#{invoker.signature}"
|
359
|
+
end
|
360
|
+
raise ArgumentError, message
|
326
361
|
end
|
327
|
-
|
328
|
-
|
329
|
-
message << arguments.collect(&:inspect).join(", ")
|
330
|
-
message << "): "
|
331
|
-
message << "available signatures"
|
332
|
-
invokers.each do |invoker|
|
333
|
-
message << ": #{invoker.signature}"
|
334
|
-
end
|
335
|
-
raise ArgumentError, message
|
336
|
-
end
|
337
|
-
klass.__send__(:define_method, "initialize") do |*arguments, &block|
|
338
|
-
initialize.call(self, arguments, block)
|
339
|
-
end
|
362
|
+
DEFINE_METHOD
|
363
|
+
Ractor.make_shareable(klass::INITIALIZE_INVOKERS) if defined?(Ractor)
|
340
364
|
end
|
341
365
|
|
342
366
|
def load_virtual_functions(info, klass)
|
@@ -353,9 +377,6 @@ module GObjectIntrospection
|
|
353
377
|
name.scan(/[A-Z]+[a-z\d]+/).collect(&:downcase).join("_")
|
354
378
|
end
|
355
379
|
|
356
|
-
def initialize_post(object)
|
357
|
-
end
|
358
|
-
|
359
380
|
def rubyish_method_name(function_info, options={})
|
360
381
|
name = function_info.name
|
361
382
|
if options[:prefix]
|
@@ -498,8 +519,12 @@ module GObjectIntrospection
|
|
498
519
|
end
|
499
520
|
end
|
500
521
|
|
501
|
-
def
|
502
|
-
|
522
|
+
def prepare_function_info_lock_gvl(function_info, target_module)
|
523
|
+
# For backward compatiblity
|
524
|
+
if respond_to?(:should_unlock_gvl?)
|
525
|
+
function_info.lock_gvl_default =
|
526
|
+
!should_unlock_gvl?(function_info, target_module)
|
527
|
+
end
|
503
528
|
end
|
504
529
|
|
505
530
|
def load_methods_method(infos, klass)
|
@@ -522,12 +547,18 @@ module GObjectIntrospection
|
|
522
547
|
end
|
523
548
|
|
524
549
|
def define_method(info, klass, method_name)
|
525
|
-
|
550
|
+
return if method_name.empty?
|
551
|
+
prepare_function_info_lock_gvl(info, klass)
|
526
552
|
remove_existing_method(klass, method_name)
|
527
553
|
invoker = Invoker.new(info, method_name, "#{klass}\##{method_name}")
|
528
|
-
|
529
|
-
|
530
|
-
|
554
|
+
invokers = klass::INVOKERS
|
555
|
+
invokers[method_name] = invoker
|
556
|
+
klass.class_eval(<<-DEFINE_METHOD, __FILE__, __LINE__ + 1)
|
557
|
+
def #{method_name}(*arguments, &block)
|
558
|
+
invoker = INVOKERS["#{method_name}"]
|
559
|
+
invoker.invoke(self, arguments, block)
|
560
|
+
end
|
561
|
+
DEFINE_METHOD
|
531
562
|
end
|
532
563
|
|
533
564
|
def define_equal_style_setter(info, klass, method_name)
|
@@ -540,9 +571,11 @@ module GObjectIntrospection
|
|
540
571
|
|
541
572
|
def define_inspect(info, klass, method_name)
|
542
573
|
if method_name == "to_s" and info.n_args.zero?
|
543
|
-
klass.
|
544
|
-
|
545
|
-
|
574
|
+
klass.class_eval(<<-DEFINE_METHOD, __FILE__, __LINE__ + 1)
|
575
|
+
def inspect
|
576
|
+
super.gsub(/>\\z/) {" \#{to_s}>"}
|
577
|
+
end
|
578
|
+
DEFINE_METHOD
|
546
579
|
end
|
547
580
|
end
|
548
581
|
|
@@ -561,8 +594,10 @@ module GObjectIntrospection
|
|
561
594
|
self.class.define_interface(info.gtype,
|
562
595
|
rubyish_class_name(info),
|
563
596
|
@base_module)
|
564
|
-
|
565
|
-
|
597
|
+
prepare_class(interface_module) do
|
598
|
+
load_virtual_functions(info, interface_module)
|
599
|
+
load_methods(info, interface_module)
|
600
|
+
end
|
566
601
|
end
|
567
602
|
|
568
603
|
def load_constant_info(info)
|
@@ -576,8 +611,44 @@ module GObjectIntrospection
|
|
576
611
|
def load_union_info(info)
|
577
612
|
return if info.gtype == GLib::Type::NONE
|
578
613
|
klass = self.class.define_class(info.gtype, info.name, @base_module)
|
579
|
-
|
580
|
-
|
614
|
+
prepare_class(klass) do
|
615
|
+
load_fields(info, klass)
|
616
|
+
load_methods(info, klass)
|
617
|
+
end
|
618
|
+
end
|
619
|
+
|
620
|
+
def prepare_class(klass)
|
621
|
+
pre_prepare_class(klass)
|
622
|
+
yield
|
623
|
+
post_prepare_class(klass)
|
624
|
+
end
|
625
|
+
|
626
|
+
def pre_prepare_class(klass)
|
627
|
+
klass.const_set(:INVOKERS, {})
|
628
|
+
klass.singleton_class.const_set(:INVOKERS, {})
|
629
|
+
end
|
630
|
+
|
631
|
+
def post_prepare_class(klass)
|
632
|
+
return unless defined?(Ractor)
|
633
|
+
Ractor.make_shareable(klass::INVOKERS)
|
634
|
+
Ractor.make_shareable(klass.singleton_class::INVOKERS)
|
635
|
+
end
|
636
|
+
|
637
|
+
def define_methods_module(name)
|
638
|
+
mod = Module.new
|
639
|
+
@base_module.const_set(name, mod)
|
640
|
+
mod.const_set(:INVOKERS, {})
|
641
|
+
mod
|
642
|
+
end
|
643
|
+
|
644
|
+
def apply_methods_module(mod, target)
|
645
|
+
target.include(mod)
|
646
|
+
post_methods_module(mod)
|
647
|
+
end
|
648
|
+
|
649
|
+
def post_methods_module(mod)
|
650
|
+
return unless defined?(Ractor)
|
651
|
+
Ractor.make_shareable(mod::INVOKERS)
|
581
652
|
end
|
582
653
|
|
583
654
|
class Invoker
|
@@ -586,6 +657,7 @@ module GObjectIntrospection
|
|
586
657
|
@method_name = method_name
|
587
658
|
@full_method_name = full_method_name
|
588
659
|
@prepared = false
|
660
|
+
ensure_prepared if defined?(Ractor)
|
589
661
|
end
|
590
662
|
|
591
663
|
def invoke(receiver, arguments, block, abort_tag=nil)
|
@@ -645,10 +717,13 @@ module GObjectIntrospection
|
|
645
717
|
@valid_n_args_range = (@n_required_in_args..@n_in_args)
|
646
718
|
|
647
719
|
@in_arg_types = []
|
720
|
+
@in_arg_nils = []
|
648
721
|
@in_arg_nil_indexes = []
|
649
722
|
@in_args.each_with_index do |arg, i|
|
650
723
|
@in_arg_types << arg.type
|
651
|
-
|
724
|
+
may_be_null = arg.may_be_null?
|
725
|
+
@in_arg_nils << may_be_null
|
726
|
+
@in_arg_nil_indexes << i if may_be_null
|
652
727
|
end
|
653
728
|
|
654
729
|
@function_info_p = (@info.class == FunctionInfo)
|
@@ -700,7 +775,7 @@ module GObjectIntrospection
|
|
700
775
|
type = @in_arg_types[i]
|
701
776
|
converted_argument = type.try_convert(argument)
|
702
777
|
if converted_argument.nil?
|
703
|
-
next if argument.nil?
|
778
|
+
next if argument.nil? and @in_arg_nils[i]
|
704
779
|
if abort_tag
|
705
780
|
throw(abort_tag)
|
706
781
|
elsif @on_invalid == :fallback
|
@@ -769,7 +844,6 @@ module GObjectIntrospection
|
|
769
844
|
end
|
770
845
|
@virtual_function_implementor.implement(implementor_class.gtype,
|
771
846
|
name)
|
772
|
-
true
|
773
847
|
end
|
774
848
|
end
|
775
849
|
end
|