fiddle 1.1.0 → 1.1.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 53ccf1d87df1a91951377a4baf37bf13519b15a05dd4ae6f18789027ffa69a44
4
- data.tar.gz: 59c667cd8a70043e46e517b77700565e481d0ea69c8f7e85a5a27f98914ed357
3
+ metadata.gz: 47a26538269c86953175484808ab2a03de57e77437d780ccdb4522dad99a68da
4
+ data.tar.gz: a97effcdad9ee1662f66a622344c8b4a51cf4b7c70c6334c559f0151c15aff04
5
5
  SHA512:
6
- metadata.gz: a10f7c91bde1fe0b9d9c1cc57a0b0ea1c0001e59301496cb676893f0fc948bbae570a8c78ac523a84c43b977db17ff9c2c101e7154ece15ac2b66eb4cf561618
7
- data.tar.gz: 41be31921c03c6a153f24bfda7753c706ad0d68602fc6b59f8fe2ebe4d54282e3c0e029ff327ac2aa17bca9e66ccb593d133b6534bd677169b1a99d16ad8bfc8
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 -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
@@ -226,7 +210,7 @@ types.each do |type, signed|
226
210
  end
227
211
 
228
212
  if libffi
229
- $LOCAL_LIBS.prepend("./#{libffi.a} ").strip! # to exts.mk
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|