fiddle 1.0.3 → 1.0.8
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 +1 -0
- data/ext/fiddle/closure.c +20 -6
- data/ext/fiddle/conversions.c +44 -0
- data/ext/fiddle/conversions.h +0 -1
- data/ext/fiddle/depend +2 -0
- data/ext/fiddle/extconf.rb +51 -3
- data/ext/fiddle/fiddle.c +88 -0
- data/ext/fiddle/fiddle.h +61 -31
- data/ext/fiddle/function.c +56 -20
- data/ext/fiddle/memory_view.c +254 -0
- data/ext/fiddle/pointer.c +41 -0
- data/fiddle.gemspec +1 -0
- data/lib/fiddle.rb +12 -0
- data/lib/fiddle/cparser.rb +66 -26
- data/lib/fiddle/function.rb +5 -0
- data/lib/fiddle/types.rb +18 -17
- data/lib/fiddle/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f60ecd26479775fa123a883a89a39ebae034c408e99bd0bc33a4d802cc04c648
|
4
|
+
data.tar.gz: 7466888aaca2242fd13af7c6663212d4c7404c4e5336626baea9c2519a068c7f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bd4349a30d8aa6b0113261cb3f53e2dee46b56b1ea72617abfbf921f31b13161897f39277358aa8e1bf3d6329d41b4b260f198ac850916eb677e7a46a21ee299
|
7
|
+
data.tar.gz: 99dd69a25bb75de362d244ebc0d4d338710b93195ce417356e44e9d7415ec7a1c0e553da2406a3ae3c5d907d705ad40e9bb9ab46eb7c95fc2ddd0aee7ea42df5
|
data/Rakefile
CHANGED
data/ext/fiddle/closure.c
CHANGED
@@ -130,6 +130,10 @@ with_gvl_callback(void *ptr)
|
|
130
130
|
rb_ary_push(params, ULL2NUM(*(unsigned LONG_LONG *)x->args[i]));
|
131
131
|
break;
|
132
132
|
#endif
|
133
|
+
case TYPE_CONST_STRING:
|
134
|
+
rb_ary_push(params,
|
135
|
+
rb_str_new_cstr(*((const char **)(x->args[i]))));
|
136
|
+
break;
|
133
137
|
default:
|
134
138
|
rb_raise(rb_eRuntimeError, "closure args: %d", type);
|
135
139
|
}
|
@@ -175,6 +179,10 @@ with_gvl_callback(void *ptr)
|
|
175
179
|
*(unsigned LONG_LONG *)x->resp = NUM2ULL(ret);
|
176
180
|
break;
|
177
181
|
#endif
|
182
|
+
case TYPE_CONST_STRING:
|
183
|
+
/* Dangerous. Callback must keep reference of the String. */
|
184
|
+
*((const char **)(x->resp)) = StringValueCStr(ret);
|
185
|
+
break;
|
178
186
|
default:
|
179
187
|
rb_raise(rb_eRuntimeError, "closure retval: %d", type);
|
180
188
|
}
|
@@ -221,6 +229,7 @@ initialize(int rbargc, VALUE argv[], VALUE self)
|
|
221
229
|
{
|
222
230
|
VALUE ret;
|
223
231
|
VALUE args;
|
232
|
+
VALUE normalized_args;
|
224
233
|
VALUE abi;
|
225
234
|
fiddle_closure * cl;
|
226
235
|
ffi_cif * cif;
|
@@ -239,21 +248,26 @@ initialize(int rbargc, VALUE argv[], VALUE self)
|
|
239
248
|
|
240
249
|
cl->argv = (ffi_type **)xcalloc(argc + 1, sizeof(ffi_type *));
|
241
250
|
|
251
|
+
normalized_args = rb_ary_new_capa(argc);
|
242
252
|
for (i = 0; i < argc; i++) {
|
243
|
-
|
244
|
-
|
253
|
+
VALUE arg = rb_fiddle_type_ensure(RARRAY_AREF(args, i));
|
254
|
+
rb_ary_push(normalized_args, arg);
|
255
|
+
cl->argv[i] = rb_fiddle_int_to_ffi_type(NUM2INT(arg));
|
245
256
|
}
|
246
257
|
cl->argv[argc] = NULL;
|
247
258
|
|
259
|
+
ret = rb_fiddle_type_ensure(ret);
|
248
260
|
rb_iv_set(self, "@ctype", ret);
|
249
|
-
rb_iv_set(self, "@args",
|
261
|
+
rb_iv_set(self, "@args", normalized_args);
|
250
262
|
|
251
263
|
cif = &cl->cif;
|
252
264
|
pcl = cl->pcl;
|
253
265
|
|
254
|
-
result = ffi_prep_cif(cif,
|
255
|
-
|
256
|
-
|
266
|
+
result = ffi_prep_cif(cif,
|
267
|
+
NUM2INT(abi),
|
268
|
+
argc,
|
269
|
+
rb_fiddle_int_to_ffi_type(NUM2INT(ret)),
|
270
|
+
cl->argv);
|
257
271
|
|
258
272
|
if (FFI_OK != result)
|
259
273
|
rb_raise(rb_eRuntimeError, "error prepping CIF %d", result);
|
data/ext/fiddle/conversions.c
CHANGED
@@ -22,6 +22,18 @@ rb_fiddle_type_ensure(VALUE type)
|
|
22
22
|
ID long_id;
|
23
23
|
#ifdef TYPE_LONG_LONG
|
24
24
|
ID long_long_id;
|
25
|
+
#endif
|
26
|
+
#ifdef TYPE_INT8_T
|
27
|
+
ID int8_t_id;
|
28
|
+
#endif
|
29
|
+
#ifdef TYPE_INT16_T
|
30
|
+
ID int16_t_id;
|
31
|
+
#endif
|
32
|
+
#ifdef TYPE_INT32_T
|
33
|
+
ID int32_t_id;
|
34
|
+
#endif
|
35
|
+
#ifdef TYPE_INT64_T
|
36
|
+
ID int64_t_id;
|
25
37
|
#endif
|
26
38
|
ID float_id;
|
27
39
|
ID double_id;
|
@@ -40,6 +52,18 @@ rb_fiddle_type_ensure(VALUE type)
|
|
40
52
|
RUBY_CONST_ID(long_id, "long");
|
41
53
|
#ifdef TYPE_LONG_LONG
|
42
54
|
RUBY_CONST_ID(long_long_id, "long_long");
|
55
|
+
#endif
|
56
|
+
#ifdef TYPE_INT8_T
|
57
|
+
RUBY_CONST_ID(int8_t_id, "int8_t");
|
58
|
+
#endif
|
59
|
+
#ifdef TYPE_INT16_T
|
60
|
+
RUBY_CONST_ID(int16_t_id, "int16_t");
|
61
|
+
#endif
|
62
|
+
#ifdef TYPE_INT32_T
|
63
|
+
RUBY_CONST_ID(int32_t_id, "int32_t");
|
64
|
+
#endif
|
65
|
+
#ifdef TYPE_INT64_T
|
66
|
+
RUBY_CONST_ID(int64_t_id, "int64_t");
|
43
67
|
#endif
|
44
68
|
RUBY_CONST_ID(float_id, "float");
|
45
69
|
RUBY_CONST_ID(double_id, "double");
|
@@ -72,6 +96,26 @@ rb_fiddle_type_ensure(VALUE type)
|
|
72
96
|
else if (type_id == long_long_id) {
|
73
97
|
return INT2NUM(TYPE_LONG_LONG);
|
74
98
|
}
|
99
|
+
#endif
|
100
|
+
#ifdef TYPE_INT8_T
|
101
|
+
else if (type_id == int8_t_id) {
|
102
|
+
return INT2NUM(TYPE_INT8_T);
|
103
|
+
}
|
104
|
+
#endif
|
105
|
+
#ifdef TYPE_INT16_T
|
106
|
+
else if (type_id == int16_t_id) {
|
107
|
+
return INT2NUM(TYPE_INT16_T);
|
108
|
+
}
|
109
|
+
#endif
|
110
|
+
#ifdef TYPE_INT32_T
|
111
|
+
else if (type_id == int32_t_id) {
|
112
|
+
return INT2NUM(TYPE_INT32_T);
|
113
|
+
}
|
114
|
+
#endif
|
115
|
+
#ifdef TYPE_INT64_T
|
116
|
+
else if (type_id == int64_t_id) {
|
117
|
+
return INT2NUM(TYPE_INT64_T);
|
118
|
+
}
|
75
119
|
#endif
|
76
120
|
else if (type_id == float_id) {
|
77
121
|
return INT2NUM(TYPE_FLOAT);
|
data/ext/fiddle/conversions.h
CHANGED
@@ -24,7 +24,6 @@ typedef union
|
|
24
24
|
void * pointer; /* ffi_type_pointer */
|
25
25
|
} fiddle_generic;
|
26
26
|
|
27
|
-
/* Deprecated. Use rb_fiddle_*() version. */
|
28
27
|
VALUE rb_fiddle_type_ensure(VALUE type);
|
29
28
|
ffi_type * rb_fiddle_int_to_ffi_type(int type);
|
30
29
|
void rb_fiddle_value_to_generic(int type, VALUE *src, fiddle_generic *dst);
|
data/ext/fiddle/depend
CHANGED
data/ext/fiddle/extconf.rb
CHANGED
@@ -3,6 +3,47 @@ require 'mkmf'
|
|
3
3
|
|
4
4
|
# :stopdoc:
|
5
5
|
|
6
|
+
def gcc?
|
7
|
+
RbConfig::CONFIG["GCC"] == "yes"
|
8
|
+
end
|
9
|
+
|
10
|
+
def disable_optimization_build_flag(flags)
|
11
|
+
if gcc?
|
12
|
+
expanded_flags = RbConfig.expand(flags.dup)
|
13
|
+
optimization_option_pattern = /(^|\s)?-O\d(\s|$)?/
|
14
|
+
if optimization_option_pattern.match?(expanded_flags)
|
15
|
+
expanded_flags.gsub(optimization_option_pattern, '\\1-Og\\2')
|
16
|
+
else
|
17
|
+
flags + " -Og"
|
18
|
+
end
|
19
|
+
else
|
20
|
+
flags
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def enable_debug_build_flag(flags)
|
25
|
+
if gcc?
|
26
|
+
expanded_flags = RbConfig.expand(flags.dup)
|
27
|
+
debug_option_pattern = /(^|\s)-g(?:gdb)?\d?(\s|$)/
|
28
|
+
if debug_option_pattern.match?(expanded_flags)
|
29
|
+
expanded_flags.gsub(debug_option_pattern, '\\1-ggdb3\\2')
|
30
|
+
else
|
31
|
+
flags + " -ggdb3"
|
32
|
+
end
|
33
|
+
else
|
34
|
+
flags
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
checking_for(checking_message("--enable-debug-build option")) do
|
39
|
+
enable_debug_build = enable_config("debug-build", false)
|
40
|
+
if enable_debug_build
|
41
|
+
$CFLAGS = disable_optimization_build_flag($CFLAGS)
|
42
|
+
$CFLAGS = enable_debug_build_flag($CFLAGS)
|
43
|
+
end
|
44
|
+
enable_debug_build
|
45
|
+
end
|
46
|
+
|
6
47
|
libffi_version = nil
|
7
48
|
have_libffi = false
|
8
49
|
bundle = enable_config('bundled-libffi')
|
@@ -137,8 +178,10 @@ else
|
|
137
178
|
have_func('ffi_closure_alloc', ffi_header)
|
138
179
|
end
|
139
180
|
|
140
|
-
if
|
141
|
-
|
181
|
+
if libffi_version
|
182
|
+
if (libffi_version <=> [3, 0, 11]) >= 0
|
183
|
+
$defs << "-DHAVE_FFI_PREP_CIF_VAR"
|
184
|
+
end
|
142
185
|
else
|
143
186
|
have_func('ffi_prep_cif_var', ffi_header)
|
144
187
|
end
|
@@ -157,6 +200,8 @@ elsif have_header "windows.h"
|
|
157
200
|
%w{ LoadLibrary FreeLibrary GetProcAddress }.each do |func|
|
158
201
|
abort "missing function #{func}" unless have_func(func)
|
159
202
|
end
|
203
|
+
|
204
|
+
have_library "ws2_32"
|
160
205
|
end
|
161
206
|
|
162
207
|
have_const('FFI_STDCALL', ffi_header)
|
@@ -177,11 +222,14 @@ types.each do |type, signed|
|
|
177
222
|
end
|
178
223
|
end
|
179
224
|
|
225
|
+
if have_header("ruby/memory_view.h")
|
226
|
+
have_type("rb_memory_view_t", ["ruby/memory_view.h"])
|
227
|
+
end
|
228
|
+
|
180
229
|
if libffi
|
181
230
|
$LOCAL_LIBS.prepend("./#{libffi.a} ").strip! # to exts.mk
|
182
231
|
$INCFLAGS.gsub!(/-I#{libffi.dir}/, '-I$(LIBFFI_DIR)')
|
183
232
|
end
|
184
|
-
$INCFLAGS << " -I$(top_srcdir)"
|
185
233
|
create_makefile 'fiddle' do |conf|
|
186
234
|
if !libffi
|
187
235
|
next conf << "LIBFFI_CLEAN = none\n"
|
data/ext/fiddle/fiddle.c
CHANGED
@@ -7,6 +7,10 @@ VALUE rb_eFiddleError;
|
|
7
7
|
void Init_fiddle_pointer(void);
|
8
8
|
void Init_fiddle_pinned(void);
|
9
9
|
|
10
|
+
#ifdef FIDDLE_MEMORY_VIEW
|
11
|
+
void Init_fiddle_memory_view(void);
|
12
|
+
#endif
|
13
|
+
|
10
14
|
/*
|
11
15
|
* call-seq: Fiddle.malloc(size)
|
12
16
|
*
|
@@ -204,6 +208,38 @@ Init_fiddle(void)
|
|
204
208
|
rb_define_const(mFiddle, "TYPE_LONG_LONG", INT2NUM(TYPE_LONG_LONG));
|
205
209
|
#endif
|
206
210
|
|
211
|
+
#ifdef TYPE_INT8_T
|
212
|
+
/* Document-const: TYPE_INT8_T
|
213
|
+
*
|
214
|
+
* C type - int8_t
|
215
|
+
*/
|
216
|
+
rb_define_const(mFiddle, "TYPE_INT8_T", INT2NUM(TYPE_INT8_T));
|
217
|
+
#endif
|
218
|
+
|
219
|
+
#ifdef TYPE_INT16_T
|
220
|
+
/* Document-const: TYPE_INT16_T
|
221
|
+
*
|
222
|
+
* C type - int16_t
|
223
|
+
*/
|
224
|
+
rb_define_const(mFiddle, "TYPE_INT16_T", INT2NUM(TYPE_INT16_T));
|
225
|
+
#endif
|
226
|
+
|
227
|
+
#ifdef TYPE_INT32_T
|
228
|
+
/* Document-const: TYPE_INT32_T
|
229
|
+
*
|
230
|
+
* C type - int32_t
|
231
|
+
*/
|
232
|
+
rb_define_const(mFiddle, "TYPE_INT32_T", INT2NUM(TYPE_INT32_T));
|
233
|
+
#endif
|
234
|
+
|
235
|
+
#ifdef TYPE_INT64_T
|
236
|
+
/* Document-const: TYPE_INT64_T
|
237
|
+
*
|
238
|
+
* C type - int64_t
|
239
|
+
*/
|
240
|
+
rb_define_const(mFiddle, "TYPE_INT64_T", INT2NUM(TYPE_INT64_T));
|
241
|
+
#endif
|
242
|
+
|
207
243
|
/* Document-const: TYPE_FLOAT
|
208
244
|
*
|
209
245
|
* C type - float
|
@@ -298,6 +334,30 @@ Init_fiddle(void)
|
|
298
334
|
rb_define_const(mFiddle, "ALIGN_LONG_LONG", INT2NUM(ALIGN_LONG_LONG));
|
299
335
|
#endif
|
300
336
|
|
337
|
+
/* Document-const: ALIGN_INT8_T
|
338
|
+
*
|
339
|
+
* The alignment size of a int8_t
|
340
|
+
*/
|
341
|
+
rb_define_const(mFiddle, "ALIGN_INT8_T", INT2NUM(ALIGN_INT8_T));
|
342
|
+
|
343
|
+
/* Document-const: ALIGN_INT16_T
|
344
|
+
*
|
345
|
+
* The alignment size of a int16_t
|
346
|
+
*/
|
347
|
+
rb_define_const(mFiddle, "ALIGN_INT16_T", INT2NUM(ALIGN_INT16_T));
|
348
|
+
|
349
|
+
/* Document-const: ALIGN_INT32_T
|
350
|
+
*
|
351
|
+
* The alignment size of a int32_t
|
352
|
+
*/
|
353
|
+
rb_define_const(mFiddle, "ALIGN_INT32_T", INT2NUM(ALIGN_INT32_T));
|
354
|
+
|
355
|
+
/* Document-const: ALIGN_INT64_T
|
356
|
+
*
|
357
|
+
* The alignment size of a int64_t
|
358
|
+
*/
|
359
|
+
rb_define_const(mFiddle, "ALIGN_INT64_T", INT2NUM(ALIGN_INT64_T));
|
360
|
+
|
301
361
|
/* Document-const: ALIGN_FLOAT
|
302
362
|
*
|
303
363
|
* The alignment size of a float
|
@@ -388,6 +448,30 @@ Init_fiddle(void)
|
|
388
448
|
rb_define_const(mFiddle, "SIZEOF_LONG_LONG", INT2NUM(sizeof(LONG_LONG)));
|
389
449
|
#endif
|
390
450
|
|
451
|
+
/* Document-const: SIZEOF_INT8_T
|
452
|
+
*
|
453
|
+
* size of a int8_t
|
454
|
+
*/
|
455
|
+
rb_define_const(mFiddle, "SIZEOF_INT8_T", INT2NUM(sizeof(int8_t)));
|
456
|
+
|
457
|
+
/* Document-const: SIZEOF_INT16_T
|
458
|
+
*
|
459
|
+
* size of a int16_t
|
460
|
+
*/
|
461
|
+
rb_define_const(mFiddle, "SIZEOF_INT16_T", INT2NUM(sizeof(int16_t)));
|
462
|
+
|
463
|
+
/* Document-const: SIZEOF_INT32_T
|
464
|
+
*
|
465
|
+
* size of a int32_t
|
466
|
+
*/
|
467
|
+
rb_define_const(mFiddle, "SIZEOF_INT32_T", INT2NUM(sizeof(int32_t)));
|
468
|
+
|
469
|
+
/* Document-const: SIZEOF_INT64_T
|
470
|
+
*
|
471
|
+
* size of a int64_t
|
472
|
+
*/
|
473
|
+
rb_define_const(mFiddle, "SIZEOF_INT64_T", INT2NUM(sizeof(int64_t)));
|
474
|
+
|
391
475
|
/* Document-const: SIZEOF_FLOAT
|
392
476
|
*
|
393
477
|
* size of a float
|
@@ -461,5 +545,9 @@ Init_fiddle(void)
|
|
461
545
|
Init_fiddle_handle();
|
462
546
|
Init_fiddle_pointer();
|
463
547
|
Init_fiddle_pinned();
|
548
|
+
|
549
|
+
#ifdef FIDDLE_MEMORY_VIEW
|
550
|
+
Init_fiddle_memory_view();
|
551
|
+
#endif
|
464
552
|
}
|
465
553
|
/* vim: set noet sws=4 sw=4: */
|
data/ext/fiddle/fiddle.h
CHANGED
@@ -58,38 +58,38 @@
|
|
58
58
|
# error "CHAR_BIT not supported"
|
59
59
|
#endif
|
60
60
|
|
61
|
-
#
|
62
|
-
#
|
63
|
-
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
#
|
67
|
-
#
|
68
|
-
#
|
69
|
-
#
|
61
|
+
#if SIZEOF_SHORT == 2
|
62
|
+
# define ffi_type_ushort ffi_type_uint16
|
63
|
+
# define ffi_type_sshort ffi_type_sint16
|
64
|
+
#elif SIZEOF_SHORT == 4
|
65
|
+
# define ffi_type_ushort ffi_type_uint32
|
66
|
+
# define ffi_type_sshort ffi_type_sint32
|
67
|
+
#else
|
68
|
+
# error "short size not supported"
|
69
|
+
#endif
|
70
70
|
|
71
|
-
#
|
72
|
-
#
|
73
|
-
#
|
74
|
-
#
|
75
|
-
#
|
76
|
-
#
|
77
|
-
#
|
78
|
-
#
|
79
|
-
#
|
80
|
-
#
|
81
|
-
#
|
82
|
-
#
|
71
|
+
#if SIZEOF_INT == 2
|
72
|
+
# define ffi_type_uint ffi_type_uint16
|
73
|
+
# define ffi_type_sint ffi_type_sint16
|
74
|
+
#elif SIZEOF_INT == 4
|
75
|
+
# define ffi_type_uint ffi_type_uint32
|
76
|
+
# define ffi_type_sint ffi_type_sint32
|
77
|
+
#elif SIZEOF_INT == 8
|
78
|
+
# define ffi_type_uint ffi_type_uint64
|
79
|
+
# define ffi_type_sint ffi_type_sint64
|
80
|
+
#else
|
81
|
+
# error "int size not supported"
|
82
|
+
#endif
|
83
83
|
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
#
|
90
|
-
#
|
91
|
-
#
|
92
|
-
#
|
84
|
+
#if SIZEOF_LONG == 4
|
85
|
+
# define ffi_type_ulong ffi_type_uint32
|
86
|
+
# define ffi_type_slong ffi_type_sint32
|
87
|
+
#elif SIZEOF_LONG == 8
|
88
|
+
# define ffi_type_ulong ffi_type_uint64
|
89
|
+
# define ffi_type_slong ffi_type_sint64
|
90
|
+
#else
|
91
|
+
# error "long size not supported"
|
92
|
+
#endif
|
93
93
|
|
94
94
|
#if HAVE_LONG_LONG
|
95
95
|
# if SIZEOF_LONG_LONG == 8
|
@@ -118,6 +118,27 @@
|
|
118
118
|
#define TYPE_VARIADIC 9
|
119
119
|
#define TYPE_CONST_STRING 10
|
120
120
|
|
121
|
+
#define TYPE_INT8_T TYPE_CHAR
|
122
|
+
#if SIZEOF_SHORT == 2
|
123
|
+
# define TYPE_INT16_T TYPE_SHORT
|
124
|
+
#elif SIZEOF_INT == 2
|
125
|
+
# define TYPE_INT16_T TYPE_INT
|
126
|
+
#endif
|
127
|
+
#if SIZEOF_SHORT == 4
|
128
|
+
# define TYPE_INT32_T TYPE_SHORT
|
129
|
+
#elif SIZEOF_INT == 4
|
130
|
+
# define TYPE_INT32_T TYPE_INT
|
131
|
+
#elif SIZEOF_LONG == 4
|
132
|
+
# define TYPE_INT32_T TYPE_LONG
|
133
|
+
#endif
|
134
|
+
#if SIZEOF_INT == 8
|
135
|
+
# define TYPE_INT64_T TYPE_INT
|
136
|
+
#elif SIZEOF_LONG == 8
|
137
|
+
# define TYPE_INT64_T TYPE_LONG
|
138
|
+
#elif defined(TYPE_LONG_LONG)
|
139
|
+
# define TYPE_INT64_T TYPE_LONG_LONG
|
140
|
+
#endif
|
141
|
+
|
121
142
|
#ifndef TYPE_SSIZE_T
|
122
143
|
# if SIZEOF_SIZE_T == SIZEOF_INT
|
123
144
|
# define TYPE_SSIZE_T TYPE_INT
|
@@ -153,8 +174,8 @@
|
|
153
174
|
#define ALIGN_OF(type) offsetof(struct {char align_c; type align_x;}, align_x)
|
154
175
|
|
155
176
|
#define ALIGN_VOIDP ALIGN_OF(void*)
|
156
|
-
#define ALIGN_SHORT ALIGN_OF(short)
|
157
177
|
#define ALIGN_CHAR ALIGN_OF(char)
|
178
|
+
#define ALIGN_SHORT ALIGN_OF(short)
|
158
179
|
#define ALIGN_INT ALIGN_OF(int)
|
159
180
|
#define ALIGN_LONG ALIGN_OF(long)
|
160
181
|
#if HAVE_LONG_LONG
|
@@ -163,6 +184,15 @@
|
|
163
184
|
#define ALIGN_FLOAT ALIGN_OF(float)
|
164
185
|
#define ALIGN_DOUBLE ALIGN_OF(double)
|
165
186
|
|
187
|
+
#define ALIGN_INT8_T ALIGN_OF(int8_t)
|
188
|
+
#define ALIGN_INT16_T ALIGN_OF(int16_t)
|
189
|
+
#define ALIGN_INT32_T ALIGN_OF(int32_t)
|
190
|
+
#define ALIGN_INT64_T ALIGN_OF(int64_t)
|
191
|
+
|
192
|
+
#ifdef HAVE_TYPE_RB_MEMORY_VIEW_T
|
193
|
+
# define FIDDLE_MEMORY_VIEW
|
194
|
+
#endif
|
195
|
+
|
166
196
|
extern VALUE mFiddle;
|
167
197
|
extern VALUE rb_eFiddleDLError;
|
168
198
|
|
data/ext/fiddle/function.c
CHANGED
@@ -77,18 +77,6 @@ rb_fiddle_new_function(VALUE address, VALUE arg_types, VALUE ret_type)
|
|
77
77
|
return rb_class_new_instance(3, argv, cFiddleFunction);
|
78
78
|
}
|
79
79
|
|
80
|
-
static int
|
81
|
-
parse_keyword_arg_i(VALUE key, VALUE value, VALUE self)
|
82
|
-
{
|
83
|
-
if (key == ID2SYM(rb_intern("name"))) {
|
84
|
-
rb_iv_set(self, "@name", value);
|
85
|
-
} else {
|
86
|
-
rb_raise(rb_eArgError, "unknown keyword: %"PRIsVALUE,
|
87
|
-
RB_OBJ_STRING(key));
|
88
|
-
}
|
89
|
-
return ST_CONTINUE;
|
90
|
-
}
|
91
|
-
|
92
80
|
static VALUE
|
93
81
|
normalize_argument_types(const char *name,
|
94
82
|
VALUE arg_types,
|
@@ -134,15 +122,40 @@ static VALUE
|
|
134
122
|
initialize(int argc, VALUE argv[], VALUE self)
|
135
123
|
{
|
136
124
|
ffi_cif * cif;
|
137
|
-
VALUE ptr, arg_types, ret_type, abi,
|
125
|
+
VALUE ptr, arg_types, ret_type, abi, kwargs;
|
126
|
+
VALUE name = Qnil;
|
127
|
+
VALUE need_gvl = Qfalse;
|
138
128
|
int c_ret_type;
|
139
129
|
bool is_variadic = false;
|
140
130
|
ffi_abi c_ffi_abi;
|
141
131
|
void *cfunc;
|
142
132
|
|
143
|
-
rb_scan_args(argc, argv, "31:", &ptr, &arg_types, &ret_type, &abi, &
|
133
|
+
rb_scan_args(argc, argv, "31:", &ptr, &arg_types, &ret_type, &abi, &kwargs);
|
144
134
|
rb_iv_set(self, "@closure", ptr);
|
145
135
|
|
136
|
+
if (!NIL_P(kwargs)) {
|
137
|
+
enum {
|
138
|
+
kw_name,
|
139
|
+
kw_need_gvl,
|
140
|
+
kw_max_,
|
141
|
+
};
|
142
|
+
static ID kw[kw_max_];
|
143
|
+
VALUE args[kw_max_];
|
144
|
+
if (!kw[0]) {
|
145
|
+
kw[kw_name] = rb_intern_const("name");
|
146
|
+
kw[kw_need_gvl] = rb_intern_const("need_gvl");
|
147
|
+
}
|
148
|
+
rb_get_kwargs(kwargs, kw, 0, kw_max_, args);
|
149
|
+
if (args[kw_name] != Qundef) {
|
150
|
+
name = args[kw_name];
|
151
|
+
}
|
152
|
+
if (args[kw_need_gvl] != Qundef) {
|
153
|
+
need_gvl = args[kw_need_gvl];
|
154
|
+
}
|
155
|
+
}
|
156
|
+
rb_iv_set(self, "@name", name);
|
157
|
+
rb_iv_set(self, "@need_gvl", need_gvl);
|
158
|
+
|
146
159
|
ptr = rb_Integer(ptr);
|
147
160
|
cfunc = NUM2PTR(ptr);
|
148
161
|
PTR2NUM(cfunc);
|
@@ -170,8 +183,6 @@ initialize(int argc, VALUE argv[], VALUE self)
|
|
170
183
|
rb_iv_set(self, "@abi", abi);
|
171
184
|
rb_iv_set(self, "@is_variadic", is_variadic ? Qtrue : Qfalse);
|
172
185
|
|
173
|
-
if (!NIL_P(kwds)) rb_hash_foreach(kwds, parse_keyword_arg_i, self);
|
174
|
-
|
175
186
|
TypedData_Get_Struct(self, ffi_cif, &function_data_type, cif);
|
176
187
|
cif->arg_types = NULL;
|
177
188
|
|
@@ -205,6 +216,7 @@ function_call(int argc, VALUE argv[], VALUE self)
|
|
205
216
|
VALUE arg_types;
|
206
217
|
VALUE cPointer;
|
207
218
|
VALUE is_variadic;
|
219
|
+
VALUE need_gvl;
|
208
220
|
int n_arg_types;
|
209
221
|
int n_fixed_args = 0;
|
210
222
|
int n_call_args = 0;
|
@@ -218,6 +230,7 @@ function_call(int argc, VALUE argv[], VALUE self)
|
|
218
230
|
arg_types = rb_iv_get(self, "@argument_types");
|
219
231
|
cPointer = rb_const_get(mFiddle, rb_intern("Pointer"));
|
220
232
|
is_variadic = rb_iv_get(self, "@is_variadic");
|
233
|
+
need_gvl = rb_iv_get(self, "@need_gvl");
|
221
234
|
|
222
235
|
n_arg_types = RARRAY_LENINT(arg_types);
|
223
236
|
n_fixed_args = n_arg_types;
|
@@ -355,12 +368,24 @@ function_call(int argc, VALUE argv[], VALUE self)
|
|
355
368
|
args.values[i_call] = NULL;
|
356
369
|
args.fn = (void(*)(void))NUM2PTR(cfunc);
|
357
370
|
|
358
|
-
(
|
371
|
+
if (RTEST(need_gvl)) {
|
372
|
+
ffi_call(args.cif, args.fn, &(args.retval), args.values);
|
373
|
+
}
|
374
|
+
else {
|
375
|
+
(void)rb_thread_call_without_gvl(nogvl_ffi_call, &args, 0, 0);
|
376
|
+
}
|
359
377
|
|
360
|
-
|
378
|
+
{
|
379
|
+
int errno_keep = errno;
|
361
380
|
#if defined(_WIN32)
|
362
|
-
|
381
|
+
int socket_error = WSAGetLastError();
|
382
|
+
rb_funcall(mFiddle, rb_intern("win32_last_error="), 1,
|
383
|
+
INT2NUM(errno_keep));
|
384
|
+
rb_funcall(mFiddle, rb_intern("win32_last_socket_error="), 1,
|
385
|
+
INT2NUM(socket_error));
|
363
386
|
#endif
|
387
|
+
rb_funcall(mFiddle, rb_intern("last_error="), 1, INT2NUM(errno_keep));
|
388
|
+
}
|
364
389
|
|
365
390
|
ALLOCV_END(alloc_buffer);
|
366
391
|
|
@@ -433,6 +458,10 @@ Init_fiddle_function(void)
|
|
433
458
|
* Caller must ensure the underlying function is called in a
|
434
459
|
* thread-safe manner if running in a multi-threaded process.
|
435
460
|
*
|
461
|
+
* Note that it is not thread-safe to use this method to
|
462
|
+
* directly or indirectly call many Ruby C-extension APIs unless
|
463
|
+
* you don't pass +need_gvl: true+ to Fiddle::Function#new.
|
464
|
+
*
|
436
465
|
* For an example see Fiddle::Function
|
437
466
|
*
|
438
467
|
*/
|
@@ -440,13 +469,20 @@ Init_fiddle_function(void)
|
|
440
469
|
|
441
470
|
/*
|
442
471
|
* Document-method: new
|
443
|
-
* call-seq: new(ptr,
|
472
|
+
* call-seq: new(ptr,
|
473
|
+
* args,
|
474
|
+
* ret_type,
|
475
|
+
* abi = DEFAULT,
|
476
|
+
* name: nil,
|
477
|
+
* need_gvl: false)
|
444
478
|
*
|
445
479
|
* Constructs a Function object.
|
446
480
|
* * +ptr+ is a referenced function, of a Fiddle::Handle
|
447
481
|
* * +args+ is an Array of arguments, passed to the +ptr+ function
|
448
482
|
* * +ret_type+ is the return type of the function
|
449
483
|
* * +abi+ is the ABI of the function
|
484
|
+
* * +name+ is the name of the function
|
485
|
+
* * +need_gvl+ is whether GVL is needed to call the function
|
450
486
|
*
|
451
487
|
*/
|
452
488
|
rb_define_method(cFiddleFunction, "initialize", initialize, -1);
|
@@ -0,0 +1,254 @@
|
|
1
|
+
#include <stdbool.h>
|
2
|
+
#include <ruby/ruby.h>
|
3
|
+
|
4
|
+
#ifdef HAVE_RUBY_MEMORY_VIEW_H
|
5
|
+
# include <ruby/memory_view.h>
|
6
|
+
#endif
|
7
|
+
|
8
|
+
#if SIZEOF_INTPTR_T == SIZEOF_LONG_LONG
|
9
|
+
# define INTPTR2NUM LL2NUM
|
10
|
+
# define UINTPTR2NUM ULL2NUM
|
11
|
+
#elif SIZEOF_INTPTR_T == SIZEOF_LONG
|
12
|
+
# define INTPTR2NUM LONG2NUM
|
13
|
+
# define UINTPTR2NUM ULONG2NUM
|
14
|
+
#else
|
15
|
+
# define INTPTR2NUM INT2NUM
|
16
|
+
# define UINTPTR2NUM UINT2NUM
|
17
|
+
#endif
|
18
|
+
|
19
|
+
#include <fiddle.h>
|
20
|
+
|
21
|
+
#ifdef FIDDLE_MEMORY_VIEW
|
22
|
+
VALUE rb_cMemoryView = Qnil;
|
23
|
+
|
24
|
+
struct memview_data {
|
25
|
+
rb_memory_view_t view;
|
26
|
+
rb_memory_view_item_component_t *members;
|
27
|
+
size_t n_members;
|
28
|
+
};
|
29
|
+
|
30
|
+
static void
|
31
|
+
fiddle_memview_mark(void *ptr)
|
32
|
+
{
|
33
|
+
const struct memview_data *data = ptr;
|
34
|
+
rb_gc_mark(data->view.obj);
|
35
|
+
}
|
36
|
+
|
37
|
+
static void
|
38
|
+
fiddle_memview_free(void *ptr)
|
39
|
+
{
|
40
|
+
struct memview_data *data = ptr;
|
41
|
+
rb_memory_view_release(&data->view);
|
42
|
+
if (data->members)
|
43
|
+
xfree(data->members);
|
44
|
+
xfree(ptr);
|
45
|
+
}
|
46
|
+
|
47
|
+
static size_t
|
48
|
+
fiddle_memview_memsize(const void *ptr)
|
49
|
+
{
|
50
|
+
const struct memview_data *data = ptr;
|
51
|
+
return sizeof(*data) + sizeof(rb_memory_view_item_component_t)*data->n_members + (size_t)data->view.byte_size;
|
52
|
+
}
|
53
|
+
|
54
|
+
static const rb_data_type_t fiddle_memview_data_type = {
|
55
|
+
"fiddle/memory_view",
|
56
|
+
{fiddle_memview_mark, fiddle_memview_free, fiddle_memview_memsize,},
|
57
|
+
};
|
58
|
+
|
59
|
+
static VALUE
|
60
|
+
rb_fiddle_memview_s_allocate(VALUE klass)
|
61
|
+
{
|
62
|
+
struct memview_data *data;
|
63
|
+
VALUE obj = TypedData_Make_Struct(klass, struct memview_data, &fiddle_memview_data_type, data);
|
64
|
+
data->view.obj = Qnil;
|
65
|
+
data->members = NULL;
|
66
|
+
data->n_members = 0;
|
67
|
+
return obj;
|
68
|
+
}
|
69
|
+
|
70
|
+
static VALUE
|
71
|
+
rb_fiddle_memview_initialize(VALUE obj, VALUE target)
|
72
|
+
{
|
73
|
+
struct memview_data *data;
|
74
|
+
TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
|
75
|
+
|
76
|
+
if (!rb_memory_view_get(target, &data->view, 0)) {
|
77
|
+
rb_raise(rb_eArgError, "Unable to get a memory view from %+"PRIsVALUE, target);
|
78
|
+
}
|
79
|
+
|
80
|
+
return Qnil;
|
81
|
+
}
|
82
|
+
|
83
|
+
static VALUE
|
84
|
+
rb_fiddle_memview_get_obj(VALUE obj)
|
85
|
+
{
|
86
|
+
struct memview_data *data;
|
87
|
+
TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
|
88
|
+
|
89
|
+
return data->view.obj;
|
90
|
+
}
|
91
|
+
|
92
|
+
static VALUE
|
93
|
+
rb_fiddle_memview_get_byte_size(VALUE obj)
|
94
|
+
{
|
95
|
+
struct memview_data *data;
|
96
|
+
TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
|
97
|
+
|
98
|
+
if (NIL_P(data->view.obj)) return Qnil;
|
99
|
+
return SSIZET2NUM(data->view.byte_size);
|
100
|
+
}
|
101
|
+
|
102
|
+
static VALUE
|
103
|
+
rb_fiddle_memview_get_readonly(VALUE obj)
|
104
|
+
{
|
105
|
+
struct memview_data *data;
|
106
|
+
TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
|
107
|
+
|
108
|
+
if (NIL_P(data->view.obj)) return Qnil;
|
109
|
+
return data->view.readonly ? Qtrue : Qfalse;
|
110
|
+
}
|
111
|
+
|
112
|
+
static VALUE
|
113
|
+
rb_fiddle_memview_get_format(VALUE obj)
|
114
|
+
{
|
115
|
+
struct memview_data *data;
|
116
|
+
TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
|
117
|
+
|
118
|
+
if (NIL_P(data->view.obj)) return Qnil;
|
119
|
+
return data->view.format == NULL ? Qnil : rb_str_new_cstr(data->view.format);
|
120
|
+
}
|
121
|
+
|
122
|
+
static VALUE
|
123
|
+
rb_fiddle_memview_get_item_size(VALUE obj)
|
124
|
+
{
|
125
|
+
struct memview_data *data;
|
126
|
+
TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
|
127
|
+
|
128
|
+
if (NIL_P(data->view.obj)) return Qnil;
|
129
|
+
return SSIZET2NUM(data->view.item_size);
|
130
|
+
}
|
131
|
+
|
132
|
+
static VALUE
|
133
|
+
rb_fiddle_memview_get_ndim(VALUE obj)
|
134
|
+
{
|
135
|
+
struct memview_data *data;
|
136
|
+
TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
|
137
|
+
|
138
|
+
if (NIL_P(data->view.obj)) return Qnil;
|
139
|
+
return SSIZET2NUM(data->view.ndim);
|
140
|
+
}
|
141
|
+
|
142
|
+
static VALUE
|
143
|
+
rb_fiddle_memview_get_shape(VALUE obj)
|
144
|
+
{
|
145
|
+
struct memview_data *data;
|
146
|
+
TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
|
147
|
+
|
148
|
+
if (NIL_P(data->view.obj)) return Qnil;
|
149
|
+
if (data->view.shape == NULL) return Qnil;
|
150
|
+
|
151
|
+
const ssize_t ndim = data->view.ndim;
|
152
|
+
VALUE shape = rb_ary_new_capa(ndim);
|
153
|
+
ssize_t i;
|
154
|
+
for (i = 0; i < ndim; ++i) {
|
155
|
+
rb_ary_push(shape, SSIZET2NUM(data->view.shape[i]));
|
156
|
+
}
|
157
|
+
return shape;
|
158
|
+
}
|
159
|
+
|
160
|
+
static VALUE
|
161
|
+
rb_fiddle_memview_get_strides(VALUE obj)
|
162
|
+
{
|
163
|
+
struct memview_data *data;
|
164
|
+
TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
|
165
|
+
|
166
|
+
if (NIL_P(data->view.obj)) return Qnil;
|
167
|
+
if (data->view.strides == NULL) return Qnil;
|
168
|
+
|
169
|
+
const ssize_t ndim = data->view.ndim;
|
170
|
+
VALUE strides = rb_ary_new_capa(ndim);
|
171
|
+
ssize_t i;
|
172
|
+
for (i = 0; i < ndim; ++i) {
|
173
|
+
rb_ary_push(strides, SSIZET2NUM(data->view.strides[i]));
|
174
|
+
}
|
175
|
+
return strides;
|
176
|
+
}
|
177
|
+
|
178
|
+
static VALUE
|
179
|
+
rb_fiddle_memview_get_sub_offsets(VALUE obj)
|
180
|
+
{
|
181
|
+
struct memview_data *data;
|
182
|
+
TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
|
183
|
+
|
184
|
+
if (NIL_P(data->view.obj)) return Qnil;
|
185
|
+
if (data->view.sub_offsets == NULL) return Qnil;
|
186
|
+
|
187
|
+
const ssize_t ndim = data->view.ndim;
|
188
|
+
VALUE sub_offsets = rb_ary_new_capa(ndim);
|
189
|
+
ssize_t i;
|
190
|
+
for (i = 0; i < ndim; ++i) {
|
191
|
+
rb_ary_push(sub_offsets, SSIZET2NUM(data->view.sub_offsets[i]));
|
192
|
+
}
|
193
|
+
return sub_offsets;
|
194
|
+
}
|
195
|
+
|
196
|
+
static VALUE
|
197
|
+
rb_fiddle_memview_aref(int argc, VALUE *argv, VALUE obj)
|
198
|
+
{
|
199
|
+
struct memview_data *data;
|
200
|
+
TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
|
201
|
+
|
202
|
+
if (NIL_P(data->view.obj)) return Qnil;
|
203
|
+
|
204
|
+
const ssize_t ndim = data->view.ndim;
|
205
|
+
if (argc != ndim) {
|
206
|
+
rb_raise(rb_eIndexError, "wrong number of index (%d for %"PRIdSIZE")", argc, ndim);
|
207
|
+
}
|
208
|
+
|
209
|
+
VALUE indices_v = 0;
|
210
|
+
ssize_t *indices = ALLOCV_N(ssize_t, indices_v, ndim);
|
211
|
+
|
212
|
+
ssize_t i;
|
213
|
+
for (i = 0; i < ndim; ++i) {
|
214
|
+
ssize_t x = NUM2SSIZET(argv[i]);
|
215
|
+
indices[i] = x;
|
216
|
+
}
|
217
|
+
|
218
|
+
uint8_t *ptr = rb_memory_view_get_item_pointer(&data->view, indices);
|
219
|
+
ALLOCV_END(indices_v);
|
220
|
+
|
221
|
+
if (data->view.format == NULL) {
|
222
|
+
return INT2FIX(*ptr);
|
223
|
+
}
|
224
|
+
|
225
|
+
if (!data->members) {
|
226
|
+
const char *err;
|
227
|
+
if (rb_memory_view_parse_item_format(data->view.format, &data->members, &data->n_members, &err) < 0) {
|
228
|
+
rb_raise(rb_eRuntimeError, "Unable to recognize item format at %"PRIdSIZE" in \"%s\"",
|
229
|
+
err - data->view.format, data->view.format);
|
230
|
+
}
|
231
|
+
}
|
232
|
+
|
233
|
+
return rb_memory_view_extract_item_members(ptr, data->members, data->n_members);
|
234
|
+
}
|
235
|
+
|
236
|
+
void
|
237
|
+
Init_fiddle_memory_view(void)
|
238
|
+
{
|
239
|
+
rb_cMemoryView = rb_define_class_under(mFiddle, "MemoryView", rb_cObject);
|
240
|
+
rb_define_alloc_func(rb_cMemoryView, rb_fiddle_memview_s_allocate);
|
241
|
+
rb_define_method(rb_cMemoryView, "initialize", rb_fiddle_memview_initialize, 1);
|
242
|
+
rb_define_method(rb_cMemoryView, "obj", rb_fiddle_memview_get_obj, 0);
|
243
|
+
rb_define_method(rb_cMemoryView, "byte_size", rb_fiddle_memview_get_byte_size, 0);
|
244
|
+
rb_define_method(rb_cMemoryView, "readonly?", rb_fiddle_memview_get_readonly, 0);
|
245
|
+
rb_define_method(rb_cMemoryView, "format", rb_fiddle_memview_get_format, 0);
|
246
|
+
rb_define_method(rb_cMemoryView, "item_size", rb_fiddle_memview_get_item_size, 0);
|
247
|
+
rb_define_method(rb_cMemoryView, "ndim", rb_fiddle_memview_get_ndim, 0);
|
248
|
+
rb_define_method(rb_cMemoryView, "shape", rb_fiddle_memview_get_shape, 0);
|
249
|
+
rb_define_method(rb_cMemoryView, "strides", rb_fiddle_memview_get_strides, 0);
|
250
|
+
rb_define_method(rb_cMemoryView, "sub_offsets", rb_fiddle_memview_get_sub_offsets, 0);
|
251
|
+
rb_define_method(rb_cMemoryView, "[]", rb_fiddle_memview_aref, -1);
|
252
|
+
}
|
253
|
+
|
254
|
+
#endif /* FIDDLE_MEMORY_VIEW */
|
data/ext/fiddle/pointer.c
CHANGED
@@ -5,6 +5,11 @@
|
|
5
5
|
#include <stdbool.h>
|
6
6
|
#include <ruby/ruby.h>
|
7
7
|
#include <ruby/io.h>
|
8
|
+
|
9
|
+
#ifdef HAVE_RUBY_MEMORY_VIEW_H
|
10
|
+
# include <ruby/memory_view.h>
|
11
|
+
#endif
|
12
|
+
|
8
13
|
#include <ctype.h>
|
9
14
|
#include <fiddle.h>
|
10
15
|
|
@@ -87,6 +92,38 @@ static const rb_data_type_t fiddle_ptr_data_type = {
|
|
87
92
|
{fiddle_ptr_mark, fiddle_ptr_free, fiddle_ptr_memsize,},
|
88
93
|
};
|
89
94
|
|
95
|
+
#ifdef FIDDLE_MEMORY_VIEW
|
96
|
+
static struct ptr_data *
|
97
|
+
fiddle_ptr_check_memory_view(VALUE obj)
|
98
|
+
{
|
99
|
+
struct ptr_data *data;
|
100
|
+
TypedData_Get_Struct(obj, struct ptr_data, &fiddle_ptr_data_type, data);
|
101
|
+
if (data->ptr == NULL || data->size == 0) return NULL;
|
102
|
+
return data;
|
103
|
+
}
|
104
|
+
|
105
|
+
static bool
|
106
|
+
fiddle_ptr_memory_view_available_p(VALUE obj)
|
107
|
+
{
|
108
|
+
return fiddle_ptr_check_memory_view(obj) != NULL;
|
109
|
+
}
|
110
|
+
|
111
|
+
static bool
|
112
|
+
fiddle_ptr_get_memory_view(VALUE obj, rb_memory_view_t *view, int flags)
|
113
|
+
{
|
114
|
+
struct ptr_data *data = fiddle_ptr_check_memory_view(obj);
|
115
|
+
rb_memory_view_init_as_byte_array(view, obj, data->ptr, data->size, true);
|
116
|
+
|
117
|
+
return true;
|
118
|
+
}
|
119
|
+
|
120
|
+
static const rb_memory_view_entry_t fiddle_ptr_memory_view_entry = {
|
121
|
+
fiddle_ptr_get_memory_view,
|
122
|
+
NULL,
|
123
|
+
fiddle_ptr_memory_view_available_p
|
124
|
+
};
|
125
|
+
#endif
|
126
|
+
|
90
127
|
static VALUE
|
91
128
|
rb_fiddle_ptr_new2(VALUE klass, void *ptr, long size, freefunc_t func)
|
92
129
|
{
|
@@ -795,6 +832,10 @@ Init_fiddle_pointer(void)
|
|
795
832
|
rb_define_method(rb_cPointer, "size", rb_fiddle_ptr_size_get, 0);
|
796
833
|
rb_define_method(rb_cPointer, "size=", rb_fiddle_ptr_size_set, 1);
|
797
834
|
|
835
|
+
#ifdef FIDDLE_MEMORY_VIEW
|
836
|
+
rb_memory_view_register(rb_cPointer, &fiddle_ptr_memory_view_entry);
|
837
|
+
#endif
|
838
|
+
|
798
839
|
/* Document-const: NULL
|
799
840
|
*
|
800
841
|
* A NULL pointer
|
data/fiddle.gemspec
CHANGED
data/lib/fiddle.rb
CHANGED
@@ -17,6 +17,18 @@ module Fiddle
|
|
17
17
|
def self.win32_last_error= error
|
18
18
|
Thread.current[:__FIDDLE_WIN32_LAST_ERROR__] = error
|
19
19
|
end
|
20
|
+
|
21
|
+
# Returns the last win32 socket +Error+ of the current executing
|
22
|
+
# +Thread+ or nil if none
|
23
|
+
def self.win32_last_socket_error
|
24
|
+
Thread.current[:__FIDDLE_WIN32_LAST_SOCKET_ERROR__]
|
25
|
+
end
|
26
|
+
|
27
|
+
# Sets the last win32 socket +Error+ of the current executing
|
28
|
+
# +Thread+ to +error+
|
29
|
+
def self.win32_last_socket_error= error
|
30
|
+
Thread.current[:__FIDDLE_WIN32_LAST_SOCKET_ERROR__] = error
|
31
|
+
end
|
20
32
|
end
|
21
33
|
|
22
34
|
# Returns the last +Error+ of the current executing +Thread+ or nil if none
|
data/lib/fiddle/cparser.rb
CHANGED
@@ -148,52 +148,92 @@ module Fiddle
|
|
148
148
|
#
|
149
149
|
def parse_ctype(ty, tymap=nil)
|
150
150
|
tymap ||= {}
|
151
|
-
|
152
|
-
when Array
|
151
|
+
if ty.is_a?(Array)
|
153
152
|
return [parse_ctype(ty[0], tymap), ty[1]]
|
153
|
+
end
|
154
|
+
ty = ty.gsub(/\Aconst\s+/, "")
|
155
|
+
case ty
|
154
156
|
when 'void'
|
155
157
|
return TYPE_VOID
|
156
|
-
when
|
157
|
-
|
158
|
-
return TYPE_LONG_LONG
|
159
|
-
else
|
158
|
+
when /\A(?:(?:signed\s+)?long\s+long(?:\s+int\s+)?|int64_t)(?:\s+\w+)?\z/
|
159
|
+
unless Fiddle.const_defined?(:TYPE_LONG_LONG)
|
160
160
|
raise(RuntimeError, "unsupported type: #{ty}")
|
161
161
|
end
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
else
|
162
|
+
return TYPE_LONG_LONG
|
163
|
+
when /\A(?:unsigned\s+long\s+long(?:\s+int\s+)?|uint64_t)(?:\s+\w+)?\z/
|
164
|
+
unless Fiddle.const_defined?(:TYPE_LONG_LONG)
|
166
165
|
raise(RuntimeError, "unsupported type: #{ty}")
|
167
166
|
end
|
168
|
-
|
167
|
+
return -TYPE_LONG_LONG
|
168
|
+
when /\A(?:signed\s+)?long(?:\s+int\s+)?(?:\s+\w+)?\z/
|
169
169
|
return TYPE_LONG
|
170
|
-
when
|
170
|
+
when /\Aunsigned\s+long(?:\s+int\s+)?(?:\s+\w+)?\z/
|
171
171
|
return -TYPE_LONG
|
172
|
-
when
|
172
|
+
when /\A(?:signed\s+)?int(?:\s+\w+)?\z/
|
173
173
|
return TYPE_INT
|
174
|
-
when
|
174
|
+
when /\A(?:unsigned\s+int|uint)(?:\s+\w+)?\z/
|
175
175
|
return -TYPE_INT
|
176
|
-
when
|
176
|
+
when /\A(?:signed\s+)?short(?:\s+int\s+)?(?:\s+\w+)?\z/
|
177
177
|
return TYPE_SHORT
|
178
|
-
when
|
178
|
+
when /\Aunsigned\s+short(?:\s+int\s+)?(?:\s+\w+)?\z/
|
179
179
|
return -TYPE_SHORT
|
180
|
-
when
|
180
|
+
when /\A(?:signed\s+)?char(?:\s+\w+)?\z/
|
181
181
|
return TYPE_CHAR
|
182
|
-
when
|
182
|
+
when /\Aunsigned\s+char(?:\s+\w+)?\z/
|
183
183
|
return -TYPE_CHAR
|
184
|
-
when
|
184
|
+
when /\Aint8_t(?:\s+\w+)?\z/
|
185
|
+
unless Fiddle.const_defined?(:TYPE_INT8_T)
|
186
|
+
raise(RuntimeError, "unsupported type: #{ty}")
|
187
|
+
end
|
188
|
+
return TYPE_INT8_T
|
189
|
+
when /\Auint8_t(?:\s+\w+)?\z/
|
190
|
+
unless Fiddle.const_defined?(:TYPE_INT8_T)
|
191
|
+
raise(RuntimeError, "unsupported type: #{ty}")
|
192
|
+
end
|
193
|
+
return -TYPE_INT8_T
|
194
|
+
when /\Aint16_t(?:\s+\w+)?\z/
|
195
|
+
unless Fiddle.const_defined?(:TYPE_INT16_T)
|
196
|
+
raise(RuntimeError, "unsupported type: #{ty}")
|
197
|
+
end
|
198
|
+
return TYPE_INT16_T
|
199
|
+
when /\Auint16_t(?:\s+\w+)?\z/
|
200
|
+
unless Fiddle.const_defined?(:TYPE_INT16_T)
|
201
|
+
raise(RuntimeError, "unsupported type: #{ty}")
|
202
|
+
end
|
203
|
+
return -TYPE_INT16_T
|
204
|
+
when /\Aint32_t(?:\s+\w+)?\z/
|
205
|
+
unless Fiddle.const_defined?(:TYPE_INT32_T)
|
206
|
+
raise(RuntimeError, "unsupported type: #{ty}")
|
207
|
+
end
|
208
|
+
return TYPE_INT32_T
|
209
|
+
when /\Auint32_t(?:\s+\w+)?\z/
|
210
|
+
unless Fiddle.const_defined?(:TYPE_INT32_T)
|
211
|
+
raise(RuntimeError, "unsupported type: #{ty}")
|
212
|
+
end
|
213
|
+
return -TYPE_INT32_T
|
214
|
+
when /\Aint64_t(?:\s+\w+)?\z/
|
215
|
+
unless Fiddle.const_defined?(:TYPE_INT64_T)
|
216
|
+
raise(RuntimeError, "unsupported type: #{ty}")
|
217
|
+
end
|
218
|
+
return TYPE_INT64_T
|
219
|
+
when /\Auint64_t(?:\s+\w+)?\z/
|
220
|
+
unless Fiddle.const_defined?(:TYPE_INT64_T)
|
221
|
+
raise(RuntimeError, "unsupported type: #{ty}")
|
222
|
+
end
|
223
|
+
return -TYPE_INT64_T
|
224
|
+
when /\Afloat(?:\s+\w+)?\z/
|
185
225
|
return TYPE_FLOAT
|
186
|
-
when
|
226
|
+
when /\Adouble(?:\s+\w+)?\z/
|
187
227
|
return TYPE_DOUBLE
|
188
|
-
when
|
228
|
+
when /\Asize_t(?:\s+\w+)?\z/
|
189
229
|
return TYPE_SIZE_T
|
190
|
-
when
|
230
|
+
when /\Assize_t(?:\s+\w+)?\z/
|
191
231
|
return TYPE_SSIZE_T
|
192
|
-
when
|
232
|
+
when /\Aptrdiff_t(?:\s+\w+)?\z/
|
193
233
|
return TYPE_PTRDIFF_T
|
194
|
-
when
|
234
|
+
when /\Aintptr_t(?:\s+\w+)?\z/
|
195
235
|
return TYPE_INTPTR_T
|
196
|
-
when
|
236
|
+
when /\Auintptr_t(?:\s+\w+)?\z/
|
197
237
|
return TYPE_UINTPTR_T
|
198
238
|
when /\*/, /\[[\s\d]*\]/
|
199
239
|
return TYPE_VOIDP
|
@@ -213,7 +253,7 @@ module Fiddle
|
|
213
253
|
|
214
254
|
def split_arguments(arguments, sep=',')
|
215
255
|
return [] if arguments.strip == 'void'
|
216
|
-
arguments.scan(/([\w\*\s]+\(\*\w*\)\(.*?\)|[\w\*\s\[\]]+|\.\.\.)(?:#{sep}\s
|
256
|
+
arguments.scan(/([\w\*\s]+\(\*\w*\)\(.*?\)|[\w\*\s\[\]]+|\.\.\.)(?:#{sep}\s*|\z)/).collect {|m| m[0]}
|
217
257
|
end
|
218
258
|
|
219
259
|
def compact(signature)
|
data/lib/fiddle/function.rb
CHANGED
data/lib/fiddle/types.rb
CHANGED
@@ -27,28 +27,29 @@ module Fiddle
|
|
27
27
|
# * WORD
|
28
28
|
module Win32Types
|
29
29
|
def included(m) # :nodoc:
|
30
|
+
# https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types
|
30
31
|
m.module_eval{
|
31
|
-
typealias "
|
32
|
-
typealias "PDWORD", "unsigned long *"
|
33
|
-
typealias "DWORD32", "unsigned long"
|
34
|
-
typealias "DWORD64", "unsigned long long"
|
35
|
-
typealias "WORD", "unsigned short"
|
36
|
-
typealias "PWORD", "unsigned short *"
|
32
|
+
typealias "ATOM", "WORD"
|
37
33
|
typealias "BOOL", "int"
|
38
|
-
typealias "ATOM", "int"
|
39
34
|
typealias "BYTE", "unsigned char"
|
40
|
-
typealias "
|
35
|
+
typealias "DWORD", "unsigned long"
|
36
|
+
typealias "DWORD32", "uint32_t"
|
37
|
+
typealias "DWORD64", "uint64_t"
|
38
|
+
typealias "HANDLE", "PVOID"
|
39
|
+
typealias "HDC", "HANDLE"
|
40
|
+
typealias "HINSTANCE", "HANDLE"
|
41
|
+
typealias "HWND", "HANDLE"
|
42
|
+
typealias "LPCSTR", "const char *"
|
43
|
+
typealias "LPSTR", "char *"
|
44
|
+
typealias "PBYTE", "BYTE *"
|
45
|
+
typealias "PDWORD", "DWORD *"
|
46
|
+
typealias "PHANDLE", "HANDLE *"
|
47
|
+
typealias "PVOID", "void *"
|
48
|
+
typealias "PWORD", "WORD *"
|
49
|
+
typealias "UCHAR", "unsigned char"
|
41
50
|
typealias "UINT", "unsigned int"
|
42
51
|
typealias "ULONG", "unsigned long"
|
43
|
-
typealias "
|
44
|
-
typealias "HANDLE", "uintptr_t"
|
45
|
-
typealias "PHANDLE", "void*"
|
46
|
-
typealias "PVOID", "void*"
|
47
|
-
typealias "LPCSTR", "char*"
|
48
|
-
typealias "LPSTR", "char*"
|
49
|
-
typealias "HINSTANCE", "unsigned int"
|
50
|
-
typealias "HDC", "unsigned int"
|
51
|
-
typealias "HWND", "unsigned int"
|
52
|
+
typealias "WORD", "unsigned short"
|
52
53
|
}
|
53
54
|
end
|
54
55
|
module_function :included
|
data/lib/fiddle/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fiddle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aaron Patterson
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2021-04-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -79,6 +79,7 @@ files:
|
|
79
79
|
- ext/fiddle/function.c
|
80
80
|
- ext/fiddle/function.h
|
81
81
|
- ext/fiddle/handle.c
|
82
|
+
- ext/fiddle/memory_view.c
|
82
83
|
- ext/fiddle/pinned.c
|
83
84
|
- ext/fiddle/pointer.c
|
84
85
|
- ext/fiddle/win32/fficonfig.h
|
@@ -117,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
117
118
|
- !ruby/object:Gem::Version
|
118
119
|
version: '0'
|
119
120
|
requirements: []
|
120
|
-
rubygems_version: 3.
|
121
|
+
rubygems_version: 3.3.0.dev
|
121
122
|
signing_key:
|
122
123
|
specification_version: 4
|
123
124
|
summary: A libffi wrapper for Ruby.
|