gobject-introspection 3.4.9 → 3.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/gobject-introspection/rb-gi-arg-info.c +44 -1
- data/ext/gobject-introspection/rb-gi-arguments-in.c +22 -19
- data/ext/gobject-introspection/rb-gi-arguments-out.c +17 -17
- data/ext/gobject-introspection/rb-gi-arguments.c +1908 -53
- data/ext/gobject-introspection/rb-gi-callback.c +8 -2
- 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 +19 -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 +144 -73
- data/lib/gobject-introspection/type-tag.rb +115 -123
- data/test/test-loader.rb +14 -0
- metadata +5 -6
- data/ext/gobject-introspection/rb-gi-argument.c +0 -2051
@@ -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 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)
|
@@ -769,7 +841,6 @@ module GObjectIntrospection
|
|
769
841
|
end
|
770
842
|
@virtual_function_implementor.implement(implementor_class.gtype,
|
771
843
|
name)
|
772
|
-
true
|
773
844
|
end
|
774
845
|
end
|
775
846
|
end
|