fiddle 1.1.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/fiddle/closure.c +104 -31
- data/ext/fiddle/conversions.c +10 -10
- data/ext/fiddle/extconf.rb +6 -22
- data/ext/fiddle/fiddle.c +174 -40
- data/ext/fiddle/fiddle.h +21 -0
- data/ext/fiddle/handle.c +55 -4
- data/fiddle.gemspec +0 -3
- data/lib/fiddle/closure.rb +25 -0
- data/lib/fiddle/cparser.rb +9 -9
- data/lib/fiddle/pack.rb +18 -17
- data/lib/fiddle/version.rb +1 -1
- data/lib/fiddle.rb +34 -1
- metadata +6 -9
- data/bin/downloader.rb +0 -331
- data/bin/extlibs.rb +0 -262
- data/ext/fiddle/extlibs +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 47a26538269c86953175484808ab2a03de57e77437d780ccdb4522dad99a68da
|
4
|
+
data.tar.gz: a97effcdad9ee1662f66a622344c8b4a51cf4b7c70c6334c559f0151c15aff04
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d589e00013a957389e90f0ed2c7af551708011f4080713cdaff31c466bab17b71e9204660bb226562df2e04577c84bba7dc9ec5b595eb6ad0b7edc2ffee8c430
|
7
|
+
data.tar.gz: '091e4325049304f5b2055ab3b9f31a70810e61bc312143f9989b3475227311617cdbe1fc574099cecb4d4d9a234c3104b744803476be4e741b6aa93fa69cf249'
|
data/ext/fiddle/closure.c
CHANGED
@@ -56,6 +56,8 @@ closure_memsize(const void * ptr)
|
|
56
56
|
const rb_data_type_t closure_data_type = {
|
57
57
|
"fiddle/closure",
|
58
58
|
{0, dealloc, closure_memsize,},
|
59
|
+
0, 0,
|
60
|
+
RUBY_TYPED_FREE_IMMEDIATELY,
|
59
61
|
};
|
60
62
|
|
61
63
|
struct callback_args {
|
@@ -90,7 +92,7 @@ with_gvl_callback(void *ptr)
|
|
90
92
|
case TYPE_INT:
|
91
93
|
rb_ary_push(params, INT2NUM(*(int *)x->args[i]));
|
92
94
|
break;
|
93
|
-
case
|
95
|
+
case TYPE_UINT:
|
94
96
|
rb_ary_push(params, UINT2NUM(*(unsigned int *)x->args[i]));
|
95
97
|
break;
|
96
98
|
case TYPE_VOIDP:
|
@@ -101,19 +103,19 @@ with_gvl_callback(void *ptr)
|
|
101
103
|
case TYPE_LONG:
|
102
104
|
rb_ary_push(params, LONG2NUM(*(long *)x->args[i]));
|
103
105
|
break;
|
104
|
-
case
|
106
|
+
case TYPE_ULONG:
|
105
107
|
rb_ary_push(params, ULONG2NUM(*(unsigned long *)x->args[i]));
|
106
108
|
break;
|
107
109
|
case TYPE_CHAR:
|
108
110
|
rb_ary_push(params, INT2NUM(*(signed char *)x->args[i]));
|
109
111
|
break;
|
110
|
-
case
|
112
|
+
case TYPE_UCHAR:
|
111
113
|
rb_ary_push(params, UINT2NUM(*(unsigned char *)x->args[i]));
|
112
114
|
break;
|
113
115
|
case TYPE_SHORT:
|
114
116
|
rb_ary_push(params, INT2NUM(*(signed short *)x->args[i]));
|
115
117
|
break;
|
116
|
-
case
|
118
|
+
case TYPE_USHORT:
|
117
119
|
rb_ary_push(params, UINT2NUM(*(unsigned short *)x->args[i]));
|
118
120
|
break;
|
119
121
|
case TYPE_DOUBLE:
|
@@ -126,7 +128,7 @@ with_gvl_callback(void *ptr)
|
|
126
128
|
case TYPE_LONG_LONG:
|
127
129
|
rb_ary_push(params, LL2NUM(*(LONG_LONG *)x->args[i]));
|
128
130
|
break;
|
129
|
-
case
|
131
|
+
case TYPE_ULONG_LONG:
|
130
132
|
rb_ary_push(params, ULL2NUM(*(unsigned LONG_LONG *)x->args[i]));
|
131
133
|
break;
|
132
134
|
#endif
|
@@ -149,7 +151,7 @@ with_gvl_callback(void *ptr)
|
|
149
151
|
case TYPE_LONG:
|
150
152
|
*(long *)x->resp = NUM2LONG(ret);
|
151
153
|
break;
|
152
|
-
case
|
154
|
+
case TYPE_ULONG:
|
153
155
|
*(unsigned long *)x->resp = NUM2ULONG(ret);
|
154
156
|
break;
|
155
157
|
case TYPE_CHAR:
|
@@ -157,9 +159,9 @@ with_gvl_callback(void *ptr)
|
|
157
159
|
case TYPE_INT:
|
158
160
|
*(ffi_sarg *)x->resp = NUM2INT(ret);
|
159
161
|
break;
|
160
|
-
case
|
161
|
-
case
|
162
|
-
case
|
162
|
+
case TYPE_UCHAR:
|
163
|
+
case TYPE_USHORT:
|
164
|
+
case TYPE_UINT:
|
163
165
|
*(ffi_arg *)x->resp = NUM2UINT(ret);
|
164
166
|
break;
|
165
167
|
case TYPE_VOIDP:
|
@@ -175,7 +177,7 @@ with_gvl_callback(void *ptr)
|
|
175
177
|
case TYPE_LONG_LONG:
|
176
178
|
*(LONG_LONG *)x->resp = NUM2LL(ret);
|
177
179
|
break;
|
178
|
-
case
|
180
|
+
case TYPE_ULONG_LONG:
|
179
181
|
*(unsigned LONG_LONG *)x->resp = NUM2ULL(ret);
|
180
182
|
break;
|
181
183
|
#endif
|
@@ -224,9 +226,27 @@ allocate(VALUE klass)
|
|
224
226
|
return i;
|
225
227
|
}
|
226
228
|
|
229
|
+
static fiddle_closure *
|
230
|
+
get_raw(VALUE self)
|
231
|
+
{
|
232
|
+
fiddle_closure *closure;
|
233
|
+
TypedData_Get_Struct(self, fiddle_closure, &closure_data_type, closure);
|
234
|
+
if (!closure) {
|
235
|
+
rb_raise(rb_eArgError, "already freed: %+"PRIsVALUE, self);
|
236
|
+
}
|
237
|
+
return closure;
|
238
|
+
}
|
239
|
+
|
240
|
+
typedef struct {
|
241
|
+
VALUE self;
|
242
|
+
int argc;
|
243
|
+
VALUE *argv;
|
244
|
+
} initialize_data;
|
245
|
+
|
227
246
|
static VALUE
|
228
|
-
|
247
|
+
initialize_body(VALUE user_data)
|
229
248
|
{
|
249
|
+
initialize_data *data = (initialize_data *)user_data;
|
230
250
|
VALUE ret;
|
231
251
|
VALUE args;
|
232
252
|
VALUE normalized_args;
|
@@ -237,14 +257,14 @@ initialize(int rbargc, VALUE argv[], VALUE self)
|
|
237
257
|
ffi_status result;
|
238
258
|
int i, argc;
|
239
259
|
|
240
|
-
if (2 == rb_scan_args(
|
241
|
-
|
260
|
+
if (2 == rb_scan_args(data->argc, data->argv, "21", &ret, &args, &abi))
|
261
|
+
abi = INT2NUM(FFI_DEFAULT_ABI);
|
242
262
|
|
243
263
|
Check_Type(args, T_ARRAY);
|
244
264
|
|
245
265
|
argc = RARRAY_LENINT(args);
|
246
266
|
|
247
|
-
TypedData_Get_Struct(self, fiddle_closure, &closure_data_type, cl);
|
267
|
+
TypedData_Get_Struct(data->self, fiddle_closure, &closure_data_type, cl);
|
248
268
|
|
249
269
|
cl->argv = (ffi_type **)xcalloc(argc + 1, sizeof(ffi_type *));
|
250
270
|
|
@@ -257,8 +277,8 @@ initialize(int rbargc, VALUE argv[], VALUE self)
|
|
257
277
|
cl->argv[argc] = NULL;
|
258
278
|
|
259
279
|
ret = rb_fiddle_type_ensure(ret);
|
260
|
-
rb_iv_set(self, "@ctype", ret);
|
261
|
-
rb_iv_set(self, "@args", normalized_args);
|
280
|
+
rb_iv_set(data->self, "@ctype", ret);
|
281
|
+
rb_iv_set(data->self, "@args", normalized_args);
|
262
282
|
|
263
283
|
cif = &cl->cif;
|
264
284
|
pcl = cl->pcl;
|
@@ -269,38 +289,75 @@ initialize(int rbargc, VALUE argv[], VALUE self)
|
|
269
289
|
rb_fiddle_int_to_ffi_type(NUM2INT(ret)),
|
270
290
|
cl->argv);
|
271
291
|
|
272
|
-
if (FFI_OK != result)
|
273
|
-
|
292
|
+
if (FFI_OK != result) {
|
293
|
+
rb_raise(rb_eRuntimeError, "error prepping CIF %d", result);
|
294
|
+
}
|
274
295
|
|
275
296
|
#if USE_FFI_CLOSURE_ALLOC
|
276
297
|
result = ffi_prep_closure_loc(pcl, cif, callback,
|
277
|
-
|
298
|
+
(void *)(data->self), cl->code);
|
278
299
|
#else
|
279
|
-
result = ffi_prep_closure(pcl, cif, callback, (void *)self);
|
300
|
+
result = ffi_prep_closure(pcl, cif, callback, (void *)(data->self));
|
280
301
|
cl->code = (void *)pcl;
|
281
302
|
i = mprotect(pcl, sizeof(*pcl), PROT_READ | PROT_EXEC);
|
282
303
|
if (i) {
|
283
|
-
|
304
|
+
rb_sys_fail("mprotect");
|
284
305
|
}
|
285
306
|
#endif
|
286
307
|
|
287
|
-
if (FFI_OK != result)
|
288
|
-
|
308
|
+
if (FFI_OK != result) {
|
309
|
+
rb_raise(rb_eRuntimeError, "error prepping closure %d", result);
|
310
|
+
}
|
289
311
|
|
290
|
-
return self;
|
312
|
+
return data->self;
|
291
313
|
}
|
292
314
|
|
293
315
|
static VALUE
|
294
|
-
|
316
|
+
initialize_rescue(VALUE user_data, VALUE exception)
|
295
317
|
{
|
296
|
-
|
297
|
-
|
318
|
+
initialize_data *data = (initialize_data *)user_data;
|
319
|
+
dealloc(RTYPEDDATA_DATA(data->self));
|
320
|
+
RTYPEDDATA_DATA(data->self) = NULL;
|
321
|
+
rb_exc_raise(exception);
|
322
|
+
return data->self;
|
323
|
+
}
|
298
324
|
|
299
|
-
|
325
|
+
static VALUE
|
326
|
+
initialize(int argc, VALUE *argv, VALUE self)
|
327
|
+
{
|
328
|
+
initialize_data data;
|
329
|
+
data.self = self;
|
330
|
+
data.argc = argc;
|
331
|
+
data.argv = argv;
|
332
|
+
return rb_rescue(initialize_body, (VALUE)&data,
|
333
|
+
initialize_rescue, (VALUE)&data);
|
334
|
+
}
|
300
335
|
|
301
|
-
|
336
|
+
static VALUE
|
337
|
+
to_i(VALUE self)
|
338
|
+
{
|
339
|
+
fiddle_closure *closure = get_raw(self);
|
340
|
+
return PTR2NUM(closure->code);
|
341
|
+
}
|
302
342
|
|
303
|
-
|
343
|
+
static VALUE
|
344
|
+
closure_free(VALUE self)
|
345
|
+
{
|
346
|
+
fiddle_closure *closure;
|
347
|
+
TypedData_Get_Struct(self, fiddle_closure, &closure_data_type, closure);
|
348
|
+
if (closure) {
|
349
|
+
dealloc(closure);
|
350
|
+
RTYPEDDATA_DATA(self) = NULL;
|
351
|
+
}
|
352
|
+
return RUBY_Qnil;
|
353
|
+
}
|
354
|
+
|
355
|
+
static VALUE
|
356
|
+
closure_freed_p(VALUE self)
|
357
|
+
{
|
358
|
+
fiddle_closure *closure;
|
359
|
+
TypedData_Get_Struct(self, fiddle_closure, &closure_data_type, closure);
|
360
|
+
return closure ? RUBY_Qfalse : RUBY_Qtrue;
|
304
361
|
}
|
305
362
|
|
306
363
|
void
|
@@ -353,8 +410,24 @@ Init_fiddle_closure(void)
|
|
353
410
|
/*
|
354
411
|
* Document-method: to_i
|
355
412
|
*
|
356
|
-
* Returns the memory address for this closure
|
413
|
+
* Returns the memory address for this closure.
|
357
414
|
*/
|
358
415
|
rb_define_method(cFiddleClosure, "to_i", to_i, 0);
|
416
|
+
|
417
|
+
/*
|
418
|
+
* Document-method: free
|
419
|
+
*
|
420
|
+
* Free this closure explicitly. You can't use this closure anymore.
|
421
|
+
*
|
422
|
+
* If this closure is already freed, this does nothing.
|
423
|
+
*/
|
424
|
+
rb_define_method(cFiddleClosure, "free", closure_free, 0);
|
425
|
+
|
426
|
+
/*
|
427
|
+
* Document-method: freed?
|
428
|
+
*
|
429
|
+
* Whether this closure was freed explicitly.
|
430
|
+
*/
|
431
|
+
rb_define_method(cFiddleClosure, "freed?", closure_freed_p, 0);
|
359
432
|
}
|
360
433
|
/* vim: set noet sw=4 sts=4 */
|
data/ext/fiddle/conversions.c
CHANGED
@@ -211,32 +211,32 @@ rb_fiddle_value_to_generic(int type, VALUE *src, fiddle_generic *dst)
|
|
211
211
|
case TYPE_CHAR:
|
212
212
|
dst->schar = (signed char)NUM2INT(*src);
|
213
213
|
break;
|
214
|
-
case
|
214
|
+
case TYPE_UCHAR:
|
215
215
|
dst->uchar = (unsigned char)NUM2UINT(*src);
|
216
216
|
break;
|
217
217
|
case TYPE_SHORT:
|
218
218
|
dst->sshort = (unsigned short)NUM2INT(*src);
|
219
219
|
break;
|
220
|
-
case
|
220
|
+
case TYPE_USHORT:
|
221
221
|
dst->sshort = (signed short)NUM2UINT(*src);
|
222
222
|
break;
|
223
223
|
case TYPE_INT:
|
224
224
|
dst->sint = NUM2INT(*src);
|
225
225
|
break;
|
226
|
-
case
|
226
|
+
case TYPE_UINT:
|
227
227
|
dst->uint = NUM2UINT(*src);
|
228
228
|
break;
|
229
229
|
case TYPE_LONG:
|
230
230
|
dst->slong = NUM2LONG(*src);
|
231
231
|
break;
|
232
|
-
case
|
232
|
+
case TYPE_ULONG:
|
233
233
|
dst->ulong = NUM2ULONG(*src);
|
234
234
|
break;
|
235
235
|
#if HAVE_LONG_LONG
|
236
236
|
case TYPE_LONG_LONG:
|
237
237
|
dst->slong_long = NUM2LL(*src);
|
238
238
|
break;
|
239
|
-
case
|
239
|
+
case TYPE_ULONG_LONG:
|
240
240
|
dst->ulong_long = NUM2ULL(*src);
|
241
241
|
break;
|
242
242
|
#endif
|
@@ -283,24 +283,24 @@ rb_fiddle_generic_to_value(VALUE rettype, fiddle_generic retval)
|
|
283
283
|
PTR2NUM((void *)retval.pointer));
|
284
284
|
case TYPE_CHAR:
|
285
285
|
return INT2NUM((signed char)retval.fffi_sarg);
|
286
|
-
case
|
286
|
+
case TYPE_UCHAR:
|
287
287
|
return INT2NUM((unsigned char)retval.fffi_arg);
|
288
288
|
case TYPE_SHORT:
|
289
289
|
return INT2NUM((signed short)retval.fffi_sarg);
|
290
|
-
case
|
290
|
+
case TYPE_USHORT:
|
291
291
|
return INT2NUM((unsigned short)retval.fffi_arg);
|
292
292
|
case TYPE_INT:
|
293
293
|
return INT2NUM((signed int)retval.fffi_sarg);
|
294
|
-
case
|
294
|
+
case TYPE_UINT:
|
295
295
|
return UINT2NUM((unsigned int)retval.fffi_arg);
|
296
296
|
case TYPE_LONG:
|
297
297
|
return LONG2NUM(retval.slong);
|
298
|
-
case
|
298
|
+
case TYPE_ULONG:
|
299
299
|
return ULONG2NUM(retval.ulong);
|
300
300
|
#if HAVE_LONG_LONG
|
301
301
|
case TYPE_LONG_LONG:
|
302
302
|
return LL2NUM(retval.slong_long);
|
303
|
-
case
|
303
|
+
case TYPE_ULONG_LONG:
|
304
304
|
return ULL2NUM(retval.ulong_long);
|
305
305
|
#endif
|
306
306
|
case TYPE_FLOAT:
|
data/ext/fiddle/extconf.rb
CHANGED
@@ -46,7 +46,7 @@ end
|
|
46
46
|
|
47
47
|
libffi_version = nil
|
48
48
|
have_libffi = false
|
49
|
-
bundle =
|
49
|
+
bundle = with_config("libffi-source-dir")
|
50
50
|
unless bundle
|
51
51
|
dir_config 'libffi'
|
52
52
|
|
@@ -67,27 +67,11 @@ unless bundle
|
|
67
67
|
end
|
68
68
|
|
69
69
|
unless have_libffi
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
require_relative "../../bin/extlibs"
|
75
|
-
extlibs = ExtLibs.new
|
76
|
-
cache_dir = File.expand_path("../../tmp/.download_cache", $srcdir)
|
77
|
-
ext_dir = File.expand_path("../../ext", $srcdir)
|
78
|
-
Dir.glob("#{$srcdir}/libffi-*/").each{|dir| FileUtils.rm_rf(dir)}
|
79
|
-
extlibs.run(["--cache=#{cache_dir}", ext_dir])
|
80
|
-
end
|
81
|
-
if bundle != false
|
82
|
-
libffi_package_name = Dir.glob("#{$srcdir}/libffi-*/")
|
83
|
-
.map {|n| File.basename(n)}
|
84
|
-
.max_by {|n| n.scan(/\d+/).map(&:to_i)}
|
85
|
-
end
|
86
|
-
unless libffi_package_name
|
87
|
-
raise "missing libffi. Please install libffi."
|
70
|
+
if bundle
|
71
|
+
libffi_srcdir = libffi_package_name = bundle
|
72
|
+
else
|
73
|
+
raise "missing libffi. Please install libffi or use --with-libffi-source-dir with libffi source location."
|
88
74
|
end
|
89
|
-
|
90
|
-
libffi_srcdir = "#{$srcdir}/#{libffi_package_name}"
|
91
75
|
ffi_header = 'ffi.h'
|
92
76
|
libffi = Struct.new(*%I[dir srcdir builddir include lib a cflags ldflags opt arch]).new
|
93
77
|
libffi.dir = libffi_package_name
|
@@ -226,7 +210,7 @@ types.each do |type, signed|
|
|
226
210
|
end
|
227
211
|
|
228
212
|
if libffi
|
229
|
-
$LOCAL_LIBS.prepend("
|
213
|
+
$LOCAL_LIBS.prepend("#{libffi.a} ").strip! # to exts.mk
|
230
214
|
$INCFLAGS.gsub!(/-I#{libffi.dir}/, '-I$(LIBFFI_DIR)')
|
231
215
|
end
|
232
216
|
create_makefile 'fiddle' do |conf|
|