fiddle 1.0.3 → 1.0.8
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|