fiddle 1.0.9 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 05f04e2fc988a1635621c537e5836231c2ae496ed45990523be623b44c8557be
4
- data.tar.gz: b81aec1d67a6a08413245b483c6aed84052df7f5b907e8111bf1b8a47c2e69bd
3
+ metadata.gz: 47a26538269c86953175484808ab2a03de57e77437d780ccdb4522dad99a68da
4
+ data.tar.gz: a97effcdad9ee1662f66a622344c8b4a51cf4b7c70c6334c559f0151c15aff04
5
5
  SHA512:
6
- metadata.gz: 7b1c8640fb5a93f6b8c36eb3062f7b795cc10160176fe6d8e3f1370c5ce4ffd2e3036581ed4a3842a8eeb6d595219e8ee370c9c0d996e6213dfcb400fea10c58
7
- data.tar.gz: fcd3f9cf4d08f760065770d2529f95c17dc8c95f889d691824f98bad1cb03fbeee20dcf005493b4bc9b66850b7fecdf022b13aaa6c359949a2266696a313619f
6
+ metadata.gz: d589e00013a957389e90f0ed2c7af551708011f4080713cdaff31c466bab17b71e9204660bb226562df2e04577c84bba7dc9ec5b595eb6ad0b7edc2ffee8c430
7
+ data.tar.gz: '091e4325049304f5b2055ab3b9f31a70810e61bc312143f9989b3475227311617cdbe1fc574099cecb4d4d9a234c3104b744803476be4e741b6aa93fa69cf249'
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Fiddle
2
2
 
3
- [![Build Status](https://travis-ci.org/ruby/fiddle.svg?branch=master)](https://travis-ci.org/ruby/fiddle)
3
+ [![CI](https://github.com/ruby/fiddle/actions/workflows/ci.yml/badge.svg)](https://github.com/ruby/fiddle/actions/workflows/ci.yml)
4
4
 
5
5
  A libffi wrapper for Ruby.
6
6
 
data/Rakefile CHANGED
@@ -5,6 +5,18 @@ task :test do
5
5
  ruby("test/run.rb")
6
6
  end
7
7
 
8
+ namespace :version do
9
+ desc "Bump version"
10
+ task :bump do
11
+ version_rb_path = "lib/fiddle/version.rb"
12
+ version_rb = File.read(version_rb_path).gsub(/VERSION = "(.+?)"/) do
13
+ version = $1
14
+ "VERSION = \"#{version.succ}\""
15
+ end
16
+ File.write(version_rb_path, version_rb)
17
+ end
18
+ end
19
+
8
20
  require 'rake/extensiontask'
9
21
  Rake::ExtensionTask.new("fiddle")
10
22
  Rake::ExtensionTask.new("-test-/memory_view")
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 -TYPE_INT:
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 -TYPE_LONG:
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 -TYPE_CHAR:
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 -TYPE_SHORT:
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 -TYPE_LONG_LONG:
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 -TYPE_LONG:
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 -TYPE_CHAR:
161
- case -TYPE_SHORT:
162
- case -TYPE_INT:
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 -TYPE_LONG_LONG:
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
- initialize(int rbargc, VALUE argv[], VALUE self)
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(rbargc, argv, "21", &ret, &args, &abi))
241
- abi = INT2NUM(FFI_DEFAULT_ABI);
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
- rb_raise(rb_eRuntimeError, "error prepping CIF %d", result);
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
- (void *)self, cl->code);
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
- rb_sys_fail("mprotect");
304
+ rb_sys_fail("mprotect");
284
305
  }
285
306
  #endif
286
307
 
287
- if (FFI_OK != result)
288
- rb_raise(rb_eRuntimeError, "error prepping closure %d", result);
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
- to_i(VALUE self)
316
+ initialize_rescue(VALUE user_data, VALUE exception)
295
317
  {
296
- fiddle_closure * cl;
297
- void *code;
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
- TypedData_Get_Struct(self, fiddle_closure, &closure_data_type, cl);
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
- code = cl->code;
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
- return PTR2NUM(code);
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 */
@@ -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 -TYPE_CHAR:
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 -TYPE_SHORT:
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 -TYPE_INT:
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 -TYPE_LONG:
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 -TYPE_LONG_LONG:
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 -TYPE_CHAR:
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 -TYPE_SHORT:
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 -TYPE_INT:
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 -TYPE_LONG:
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 -TYPE_LONG_LONG:
303
+ case TYPE_ULONG_LONG:
304
304
  return ULL2NUM(retval.ulong_long);
305
305
  #endif
306
306
  case TYPE_FLOAT:
@@ -46,7 +46,7 @@ end
46
46
 
47
47
  libffi_version = nil
48
48
  have_libffi = false
49
- bundle = enable_config('bundled-libffi')
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
- # for https://github.com/ruby/fiddle
71
- extlibs_rb = File.expand_path("../../bin/extlibs.rb", $srcdir)
72
- if bundle && File.exist?(extlibs_rb)
73
- require "fileutils"
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
@@ -187,6 +171,7 @@ else
187
171
  end
188
172
 
189
173
  have_header 'sys/mman.h'
174
+ have_header 'link.h'
190
175
 
191
176
  if have_header "dlfcn.h"
192
177
  have_library "dl"
@@ -196,8 +181,10 @@ if have_header "dlfcn.h"
196
181
  end
197
182
 
198
183
  have_func "dlerror"
184
+ have_func "dlinfo"
185
+ have_const("RTLD_DI_LINKMAP", "dlfcn.h")
199
186
  elsif have_header "windows.h"
200
- %w{ LoadLibrary FreeLibrary GetProcAddress }.each do |func|
187
+ %w{ LoadLibrary FreeLibrary GetProcAddress GetModuleFileName }.each do |func|
201
188
  abort "missing function #{func}" unless have_func(func)
202
189
  end
203
190
 
@@ -222,12 +209,8 @@ types.each do |type, signed|
222
209
  end
223
210
  end
224
211
 
225
- if have_header("ruby/memory_view.h")
226
- have_type("rb_memory_view_t", ["ruby/memory_view.h"])
227
- end
228
-
229
212
  if libffi
230
- $LOCAL_LIBS.prepend("./#{libffi.a} ").strip! # to exts.mk
213
+ $LOCAL_LIBS.prepend("#{libffi.a} ").strip! # to exts.mk
231
214
  $INCFLAGS.gsub!(/-I#{libffi.dir}/, '-I$(LIBFFI_DIR)')
232
215
  end
233
216
  create_makefile 'fiddle' do |conf|