fiddle 1.0.9 → 1.1.2

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: 17a63516f0bbb623b730ccaa32e98df18c1b3c447b99027b82125ab788363175
4
+ data.tar.gz: 6b834175e32765e9a13edfb4f32390b48d8914d5bbe8e0b50b215f409b4ee192
5
5
  SHA512:
6
- metadata.gz: 7b1c8640fb5a93f6b8c36eb3062f7b795cc10160176fe6d8e3f1370c5ce4ffd2e3036581ed4a3842a8eeb6d595219e8ee370c9c0d996e6213dfcb400fea10c58
7
- data.tar.gz: fcd3f9cf4d08f760065770d2529f95c17dc8c95f889d691824f98bad1cb03fbeee20dcf005493b4bc9b66850b7fecdf022b13aaa6c359949a2266696a313619f
6
+ metadata.gz: 0c0bf76f5288d9241daa1ec0f2dae597a33a428afb893d7cf274cfd6c247c99eb93280f4fe1883b2fbabeb844cae9e272df2209feaba69cd781b689f772fb3f6
7
+ data.tar.gz: '038a55b29aafc16824c2d0498be0e22851c0f5e97956ee961220cd606dcb55a6615cdaca8ec0481e1fb6e9a4d28ec544ac86e78cf640c0e0cb551e65266b0a7d'
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
@@ -1,4 +1,5 @@
1
1
  #include <fiddle.h>
2
+ #include <stdbool.h>
2
3
  #include <ruby/thread.h>
3
4
 
4
5
  int ruby_thread_has_gvl_p(void); /* from internal.h */
@@ -54,8 +55,13 @@ closure_memsize(const void * ptr)
54
55
  }
55
56
 
56
57
  const rb_data_type_t closure_data_type = {
57
- "fiddle/closure",
58
- {0, dealloc, closure_memsize,},
58
+ .wrap_struct_name = "fiddle/closure",
59
+ .function = {
60
+ .dmark = 0,
61
+ .dfree = dealloc,
62
+ .dsize = closure_memsize
63
+ },
64
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
59
65
  };
60
66
 
61
67
  struct callback_args {
@@ -90,7 +96,7 @@ with_gvl_callback(void *ptr)
90
96
  case TYPE_INT:
91
97
  rb_ary_push(params, INT2NUM(*(int *)x->args[i]));
92
98
  break;
93
- case -TYPE_INT:
99
+ case TYPE_UINT:
94
100
  rb_ary_push(params, UINT2NUM(*(unsigned int *)x->args[i]));
95
101
  break;
96
102
  case TYPE_VOIDP:
@@ -101,19 +107,19 @@ with_gvl_callback(void *ptr)
101
107
  case TYPE_LONG:
102
108
  rb_ary_push(params, LONG2NUM(*(long *)x->args[i]));
103
109
  break;
104
- case -TYPE_LONG:
110
+ case TYPE_ULONG:
105
111
  rb_ary_push(params, ULONG2NUM(*(unsigned long *)x->args[i]));
106
112
  break;
107
113
  case TYPE_CHAR:
108
114
  rb_ary_push(params, INT2NUM(*(signed char *)x->args[i]));
109
115
  break;
110
- case -TYPE_CHAR:
116
+ case TYPE_UCHAR:
111
117
  rb_ary_push(params, UINT2NUM(*(unsigned char *)x->args[i]));
112
118
  break;
113
119
  case TYPE_SHORT:
114
120
  rb_ary_push(params, INT2NUM(*(signed short *)x->args[i]));
115
121
  break;
116
- case -TYPE_SHORT:
122
+ case TYPE_USHORT:
117
123
  rb_ary_push(params, UINT2NUM(*(unsigned short *)x->args[i]));
118
124
  break;
119
125
  case TYPE_DOUBLE:
@@ -126,7 +132,7 @@ with_gvl_callback(void *ptr)
126
132
  case TYPE_LONG_LONG:
127
133
  rb_ary_push(params, LL2NUM(*(LONG_LONG *)x->args[i]));
128
134
  break;
129
- case -TYPE_LONG_LONG:
135
+ case TYPE_ULONG_LONG:
130
136
  rb_ary_push(params, ULL2NUM(*(unsigned LONG_LONG *)x->args[i]));
131
137
  break;
132
138
  #endif
@@ -134,6 +140,20 @@ with_gvl_callback(void *ptr)
134
140
  rb_ary_push(params,
135
141
  rb_str_new_cstr(*((const char **)(x->args[i]))));
136
142
  break;
143
+ case TYPE_BOOL:
144
+ if (sizeof(bool) == sizeof(char)) {
145
+ rb_ary_push(params, CBOOL2RBBOOL(*(unsigned char *)x->args[i]));
146
+ } else if (sizeof(bool) == sizeof(short)) {
147
+ rb_ary_push(params, CBOOL2RBBOOL(*(unsigned short *)x->args[i]));
148
+ } else if (sizeof(bool) == sizeof(int)) {
149
+ rb_ary_push(params, CBOOL2RBBOOL(*(unsigned int *)x->args[i]));
150
+ } else if (sizeof(bool) == sizeof(long)) {
151
+ rb_ary_push(params, CBOOL2RBBOOL(*(unsigned long *)x->args[i]));
152
+ } else {
153
+ rb_raise(rb_eNotImpError, "bool isn't supported: %u",
154
+ (unsigned int)sizeof(bool));
155
+ }
156
+ break;
137
157
  default:
138
158
  rb_raise(rb_eRuntimeError, "closure args: %d", type);
139
159
  }
@@ -149,7 +169,7 @@ with_gvl_callback(void *ptr)
149
169
  case TYPE_LONG:
150
170
  *(long *)x->resp = NUM2LONG(ret);
151
171
  break;
152
- case -TYPE_LONG:
172
+ case TYPE_ULONG:
153
173
  *(unsigned long *)x->resp = NUM2ULONG(ret);
154
174
  break;
155
175
  case TYPE_CHAR:
@@ -157,9 +177,9 @@ with_gvl_callback(void *ptr)
157
177
  case TYPE_INT:
158
178
  *(ffi_sarg *)x->resp = NUM2INT(ret);
159
179
  break;
160
- case -TYPE_CHAR:
161
- case -TYPE_SHORT:
162
- case -TYPE_INT:
180
+ case TYPE_UCHAR:
181
+ case TYPE_USHORT:
182
+ case TYPE_UINT:
163
183
  *(ffi_arg *)x->resp = NUM2UINT(ret);
164
184
  break;
165
185
  case TYPE_VOIDP:
@@ -175,7 +195,7 @@ with_gvl_callback(void *ptr)
175
195
  case TYPE_LONG_LONG:
176
196
  *(LONG_LONG *)x->resp = NUM2LL(ret);
177
197
  break;
178
- case -TYPE_LONG_LONG:
198
+ case TYPE_ULONG_LONG:
179
199
  *(unsigned LONG_LONG *)x->resp = NUM2ULL(ret);
180
200
  break;
181
201
  #endif
@@ -183,6 +203,13 @@ with_gvl_callback(void *ptr)
183
203
  /* Dangerous. Callback must keep reference of the String. */
184
204
  *((const char **)(x->resp)) = StringValueCStr(ret);
185
205
  break;
206
+ case TYPE_BOOL:
207
+ if (sizeof(bool) == sizeof(long)) {
208
+ *(unsigned long *)x->resp = RB_TEST(ret);
209
+ } else {
210
+ *(ffi_arg *)x->resp = RB_TEST(ret);
211
+ }
212
+ break;
186
213
  default:
187
214
  rb_raise(rb_eRuntimeError, "closure retval: %d", type);
188
215
  }
@@ -224,9 +251,27 @@ allocate(VALUE klass)
224
251
  return i;
225
252
  }
226
253
 
254
+ static fiddle_closure *
255
+ get_raw(VALUE self)
256
+ {
257
+ fiddle_closure *closure;
258
+ TypedData_Get_Struct(self, fiddle_closure, &closure_data_type, closure);
259
+ if (!closure) {
260
+ rb_raise(rb_eArgError, "already freed: %+"PRIsVALUE, self);
261
+ }
262
+ return closure;
263
+ }
264
+
265
+ typedef struct {
266
+ VALUE self;
267
+ int argc;
268
+ VALUE *argv;
269
+ } initialize_data;
270
+
227
271
  static VALUE
228
- initialize(int rbargc, VALUE argv[], VALUE self)
272
+ initialize_body(VALUE user_data)
229
273
  {
274
+ initialize_data *data = (initialize_data *)user_data;
230
275
  VALUE ret;
231
276
  VALUE args;
232
277
  VALUE normalized_args;
@@ -237,14 +282,14 @@ initialize(int rbargc, VALUE argv[], VALUE self)
237
282
  ffi_status result;
238
283
  int i, argc;
239
284
 
240
- if (2 == rb_scan_args(rbargc, argv, "21", &ret, &args, &abi))
241
- abi = INT2NUM(FFI_DEFAULT_ABI);
285
+ if (2 == rb_scan_args(data->argc, data->argv, "21", &ret, &args, &abi))
286
+ abi = INT2NUM(FFI_DEFAULT_ABI);
242
287
 
243
288
  Check_Type(args, T_ARRAY);
244
289
 
245
290
  argc = RARRAY_LENINT(args);
246
291
 
247
- TypedData_Get_Struct(self, fiddle_closure, &closure_data_type, cl);
292
+ TypedData_Get_Struct(data->self, fiddle_closure, &closure_data_type, cl);
248
293
 
249
294
  cl->argv = (ffi_type **)xcalloc(argc + 1, sizeof(ffi_type *));
250
295
 
@@ -257,8 +302,8 @@ initialize(int rbargc, VALUE argv[], VALUE self)
257
302
  cl->argv[argc] = NULL;
258
303
 
259
304
  ret = rb_fiddle_type_ensure(ret);
260
- rb_iv_set(self, "@ctype", ret);
261
- rb_iv_set(self, "@args", normalized_args);
305
+ rb_iv_set(data->self, "@ctype", ret);
306
+ rb_iv_set(data->self, "@args", normalized_args);
262
307
 
263
308
  cif = &cl->cif;
264
309
  pcl = cl->pcl;
@@ -269,38 +314,75 @@ initialize(int rbargc, VALUE argv[], VALUE self)
269
314
  rb_fiddle_int_to_ffi_type(NUM2INT(ret)),
270
315
  cl->argv);
271
316
 
272
- if (FFI_OK != result)
273
- rb_raise(rb_eRuntimeError, "error prepping CIF %d", result);
317
+ if (FFI_OK != result) {
318
+ rb_raise(rb_eRuntimeError, "error prepping CIF %d", result);
319
+ }
274
320
 
275
321
  #if USE_FFI_CLOSURE_ALLOC
276
322
  result = ffi_prep_closure_loc(pcl, cif, callback,
277
- (void *)self, cl->code);
323
+ (void *)(data->self), cl->code);
278
324
  #else
279
- result = ffi_prep_closure(pcl, cif, callback, (void *)self);
325
+ result = ffi_prep_closure(pcl, cif, callback, (void *)(data->self));
280
326
  cl->code = (void *)pcl;
281
327
  i = mprotect(pcl, sizeof(*pcl), PROT_READ | PROT_EXEC);
282
328
  if (i) {
283
- rb_sys_fail("mprotect");
329
+ rb_sys_fail("mprotect");
284
330
  }
285
331
  #endif
286
332
 
287
- if (FFI_OK != result)
288
- rb_raise(rb_eRuntimeError, "error prepping closure %d", result);
333
+ if (FFI_OK != result) {
334
+ rb_raise(rb_eRuntimeError, "error prepping closure %d", result);
335
+ }
289
336
 
290
- return self;
337
+ return data->self;
291
338
  }
292
339
 
293
340
  static VALUE
294
- to_i(VALUE self)
341
+ initialize_rescue(VALUE user_data, VALUE exception)
295
342
  {
296
- fiddle_closure * cl;
297
- void *code;
343
+ initialize_data *data = (initialize_data *)user_data;
344
+ dealloc(RTYPEDDATA_DATA(data->self));
345
+ RTYPEDDATA_DATA(data->self) = NULL;
346
+ rb_exc_raise(exception);
347
+ return data->self;
348
+ }
349
+
350
+ static VALUE
351
+ initialize(int argc, VALUE *argv, VALUE self)
352
+ {
353
+ initialize_data data;
354
+ data.self = self;
355
+ data.argc = argc;
356
+ data.argv = argv;
357
+ return rb_rescue(initialize_body, (VALUE)&data,
358
+ initialize_rescue, (VALUE)&data);
359
+ }
298
360
 
299
- TypedData_Get_Struct(self, fiddle_closure, &closure_data_type, cl);
361
+ static VALUE
362
+ to_i(VALUE self)
363
+ {
364
+ fiddle_closure *closure = get_raw(self);
365
+ return PTR2NUM(closure->code);
366
+ }
300
367
 
301
- code = cl->code;
368
+ static VALUE
369
+ closure_free(VALUE self)
370
+ {
371
+ fiddle_closure *closure;
372
+ TypedData_Get_Struct(self, fiddle_closure, &closure_data_type, closure);
373
+ if (closure) {
374
+ dealloc(closure);
375
+ RTYPEDDATA_DATA(self) = NULL;
376
+ }
377
+ return RUBY_Qnil;
378
+ }
302
379
 
303
- return PTR2NUM(code);
380
+ static VALUE
381
+ closure_freed_p(VALUE self)
382
+ {
383
+ fiddle_closure *closure;
384
+ TypedData_Get_Struct(self, fiddle_closure, &closure_data_type, closure);
385
+ return closure ? RUBY_Qfalse : RUBY_Qtrue;
304
386
  }
305
387
 
306
388
  void
@@ -353,8 +435,24 @@ Init_fiddle_closure(void)
353
435
  /*
354
436
  * Document-method: to_i
355
437
  *
356
- * Returns the memory address for this closure
438
+ * Returns the memory address for this closure.
357
439
  */
358
440
  rb_define_method(cFiddleClosure, "to_i", to_i, 0);
441
+
442
+ /*
443
+ * Document-method: free
444
+ *
445
+ * Free this closure explicitly. You can't use this closure anymore.
446
+ *
447
+ * If this closure is already freed, this does nothing.
448
+ */
449
+ rb_define_method(cFiddleClosure, "free", closure_free, 0);
450
+
451
+ /*
452
+ * Document-method: freed?
453
+ *
454
+ * Whether this closure was freed explicitly.
455
+ */
456
+ rb_define_method(cFiddleClosure, "freed?", closure_freed_p, 0);
359
457
  }
360
458
  /* vim: set noet sw=4 sts=4 */
@@ -1,3 +1,5 @@
1
+ #include <stdbool.h>
2
+
1
3
  #include <fiddle.h>
2
4
 
3
5
  VALUE
@@ -44,6 +46,7 @@ rb_fiddle_type_ensure(VALUE type)
44
46
  ID ptrdiff_t_id;
45
47
  ID intptr_t_id;
46
48
  ID uintptr_t_id;
49
+ ID bool_id;
47
50
  RUBY_CONST_ID(void_id, "void");
48
51
  RUBY_CONST_ID(voidp_id, "voidp");
49
52
  RUBY_CONST_ID(char_id, "char");
@@ -74,6 +77,7 @@ rb_fiddle_type_ensure(VALUE type)
74
77
  RUBY_CONST_ID(ptrdiff_t_id, "ptrdiff_t");
75
78
  RUBY_CONST_ID(intptr_t_id, "intptr_t");
76
79
  RUBY_CONST_ID(uintptr_t_id, "uintptr_t");
80
+ RUBY_CONST_ID(bool_id, "bool");
77
81
  if (type_id == void_id) {
78
82
  return INT2NUM(TYPE_VOID);
79
83
  }
@@ -144,6 +148,9 @@ rb_fiddle_type_ensure(VALUE type)
144
148
  else if (type_id == uintptr_t_id) {
145
149
  return INT2NUM(TYPE_UINTPTR_T);
146
150
  }
151
+ else if (type_id == bool_id) {
152
+ return INT2NUM(TYPE_BOOL);
153
+ }
147
154
  else {
148
155
  type = original_type;
149
156
  }
@@ -187,6 +194,20 @@ rb_fiddle_int_to_ffi_type(int type)
187
194
  return &ffi_type_double;
188
195
  case TYPE_CONST_STRING:
189
196
  return &ffi_type_pointer;
197
+ case TYPE_BOOL:
198
+ signed_p = 0;
199
+ if (sizeof(bool) == sizeof(char)) {
200
+ return rb_ffi_type_of(char);
201
+ } else if (sizeof(bool) == sizeof(short)) {
202
+ return rb_ffi_type_of(short);
203
+ } else if (sizeof(bool) == sizeof(int)) {
204
+ return rb_ffi_type_of(int);
205
+ } else if (sizeof(bool) == sizeof(long)) {
206
+ return rb_ffi_type_of(long);
207
+ } else {
208
+ rb_raise(rb_eNotImpError, "bool isn't supported: %u",
209
+ (unsigned int)sizeof(bool));
210
+ }
190
211
  default:
191
212
  rb_raise(rb_eRuntimeError, "unknown type %d", type);
192
213
  }
@@ -209,34 +230,38 @@ rb_fiddle_value_to_generic(int type, VALUE *src, fiddle_generic *dst)
209
230
  dst->pointer = NUM2PTR(rb_Integer(*src));
210
231
  break;
211
232
  case TYPE_CHAR:
212
- dst->schar = (signed char)NUM2INT(*src);
233
+ if (RB_TYPE_P(*src, RUBY_T_STRING) && RSTRING_LEN(*src) == 1) {
234
+ dst->schar = RSTRING_PTR(*src)[0];
235
+ } else {
236
+ dst->schar = (signed char)NUM2INT(*src);
237
+ }
213
238
  break;
214
- case -TYPE_CHAR:
239
+ case TYPE_UCHAR:
215
240
  dst->uchar = (unsigned char)NUM2UINT(*src);
216
241
  break;
217
242
  case TYPE_SHORT:
218
243
  dst->sshort = (unsigned short)NUM2INT(*src);
219
244
  break;
220
- case -TYPE_SHORT:
245
+ case TYPE_USHORT:
221
246
  dst->sshort = (signed short)NUM2UINT(*src);
222
247
  break;
223
248
  case TYPE_INT:
224
249
  dst->sint = NUM2INT(*src);
225
250
  break;
226
- case -TYPE_INT:
251
+ case TYPE_UINT:
227
252
  dst->uint = NUM2UINT(*src);
228
253
  break;
229
254
  case TYPE_LONG:
230
255
  dst->slong = NUM2LONG(*src);
231
256
  break;
232
- case -TYPE_LONG:
257
+ case TYPE_ULONG:
233
258
  dst->ulong = NUM2ULONG(*src);
234
259
  break;
235
260
  #if HAVE_LONG_LONG
236
261
  case TYPE_LONG_LONG:
237
262
  dst->slong_long = NUM2LL(*src);
238
263
  break;
239
- case -TYPE_LONG_LONG:
264
+ case TYPE_ULONG_LONG:
240
265
  dst->ulong_long = NUM2ULL(*src);
241
266
  break;
242
267
  #endif
@@ -254,8 +279,23 @@ rb_fiddle_value_to_generic(int type, VALUE *src, fiddle_generic *dst)
254
279
  dst->pointer = rb_string_value_cstr(src);
255
280
  }
256
281
  break;
282
+ case TYPE_BOOL:
283
+ if (sizeof(bool) == sizeof(char)) {
284
+ dst->uchar = RB_TEST(*src);
285
+ } else if (sizeof(bool) == sizeof(short)) {
286
+ dst->ushort = RB_TEST(*src);
287
+ } else if (sizeof(bool) == sizeof(int)) {
288
+ dst->uint = RB_TEST(*src);
289
+ } else if (sizeof(bool) == sizeof(long)) {
290
+ dst->ulong = RB_TEST(*src);
291
+ } else {
292
+ rb_raise(rb_eNotImpError, "bool isn't supported: %u",
293
+ (unsigned int)sizeof(bool));
294
+ }
295
+ break;
257
296
  default:
258
297
  rb_raise(rb_eRuntimeError, "unknown type %d", type);
298
+ break;
259
299
  }
260
300
  }
261
301
 
@@ -283,24 +323,24 @@ rb_fiddle_generic_to_value(VALUE rettype, fiddle_generic retval)
283
323
  PTR2NUM((void *)retval.pointer));
284
324
  case TYPE_CHAR:
285
325
  return INT2NUM((signed char)retval.fffi_sarg);
286
- case -TYPE_CHAR:
326
+ case TYPE_UCHAR:
287
327
  return INT2NUM((unsigned char)retval.fffi_arg);
288
328
  case TYPE_SHORT:
289
329
  return INT2NUM((signed short)retval.fffi_sarg);
290
- case -TYPE_SHORT:
330
+ case TYPE_USHORT:
291
331
  return INT2NUM((unsigned short)retval.fffi_arg);
292
332
  case TYPE_INT:
293
333
  return INT2NUM((signed int)retval.fffi_sarg);
294
- case -TYPE_INT:
334
+ case TYPE_UINT:
295
335
  return UINT2NUM((unsigned int)retval.fffi_arg);
296
336
  case TYPE_LONG:
297
337
  return LONG2NUM(retval.slong);
298
- case -TYPE_LONG:
338
+ case TYPE_ULONG:
299
339
  return ULONG2NUM(retval.ulong);
300
340
  #if HAVE_LONG_LONG
301
341
  case TYPE_LONG_LONG:
302
342
  return LL2NUM(retval.slong_long);
303
- case -TYPE_LONG_LONG:
343
+ case TYPE_ULONG_LONG:
304
344
  return ULL2NUM(retval.ulong_long);
305
345
  #endif
306
346
  case TYPE_FLOAT:
@@ -314,6 +354,19 @@ rb_fiddle_generic_to_value(VALUE rettype, fiddle_generic retval)
314
354
  else {
315
355
  return Qnil;
316
356
  }
357
+ case TYPE_BOOL:
358
+ if (sizeof(bool) == sizeof(char)) {
359
+ return CBOOL2RBBOOL((unsigned char)retval.fffi_arg);
360
+ } else if (sizeof(bool) == sizeof(short)) {
361
+ return CBOOL2RBBOOL((unsigned short)retval.fffi_arg);
362
+ } else if (sizeof(bool) == sizeof(int)) {
363
+ return CBOOL2RBBOOL((unsigned int)retval.fffi_arg);
364
+ } else if (sizeof(bool) == sizeof(long)) {
365
+ return CBOOL2RBBOOL(retval.ulong);
366
+ } else {
367
+ rb_raise(rb_eNotImpError, "bool isn't supported: %u",
368
+ (unsigned int)sizeof(bool));
369
+ }
317
370
  default:
318
371
  rb_raise(rb_eRuntimeError, "unknown type %d", type);
319
372
  }
@@ -50,4 +50,6 @@ VALUE generic_to_value(VALUE rettype, fiddle_generic retval);
50
50
  # define NUM2PTR(x) ((void*)(NUM2ULL(x)))
51
51
  #endif
52
52
 
53
+ #define CBOOL2RBBOOL(cbool) ((cbool) ? RUBY_Qtrue : RUBY_Qfalse)
54
+
53
55
  #endif
@@ -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
 
@@ -63,31 +63,20 @@ unless bundle
63
63
  end
64
64
  if have_ffi_header && (have_library('ffi') || have_library('libffi'))
65
65
  have_libffi = true
66
+ checking_for("undefined FFI_GO_CLOSURES is used") do
67
+ if egrep_cpp(/warning: 'FFI_GO_CLOSURES' is not defined/, cpp_include(ffi_header), "2>&1")
68
+ $defs.push('-DFFI_GO_CLOSURES=0')
69
+ end
70
+ end
66
71
  end
67
72
  end
68
73
 
69
74
  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."
75
+ if bundle
76
+ libffi_srcdir = libffi_package_name = bundle
77
+ else
78
+ raise "missing libffi. Please install libffi or use --with-libffi-source-dir with libffi source location."
88
79
  end
89
-
90
- libffi_srcdir = "#{$srcdir}/#{libffi_package_name}"
91
80
  ffi_header = 'ffi.h'
92
81
  libffi = Struct.new(*%I[dir srcdir builddir include lib a cflags ldflags opt arch]).new
93
82
  libffi.dir = libffi_package_name
@@ -187,6 +176,7 @@ else
187
176
  end
188
177
 
189
178
  have_header 'sys/mman.h'
179
+ have_header 'link.h'
190
180
 
191
181
  if have_header "dlfcn.h"
192
182
  have_library "dl"
@@ -196,8 +186,10 @@ if have_header "dlfcn.h"
196
186
  end
197
187
 
198
188
  have_func "dlerror"
189
+ have_func "dlinfo"
190
+ have_const("RTLD_DI_LINKMAP", "dlfcn.h")
199
191
  elsif have_header "windows.h"
200
- %w{ LoadLibrary FreeLibrary GetProcAddress }.each do |func|
192
+ %w{ LoadLibrary FreeLibrary GetProcAddress GetModuleFileName }.each do |func|
201
193
  abort "missing function #{func}" unless have_func(func)
202
194
  end
203
195
 
@@ -222,12 +214,8 @@ types.each do |type, signed|
222
214
  end
223
215
  end
224
216
 
225
- if have_header("ruby/memory_view.h")
226
- have_type("rb_memory_view_t", ["ruby/memory_view.h"])
227
- end
228
-
229
217
  if libffi
230
- $LOCAL_LIBS.prepend("./#{libffi.a} ").strip! # to exts.mk
218
+ $LOCAL_LIBS.prepend("#{libffi.a} ").strip! # to exts.mk
231
219
  $INCFLAGS.gsub!(/-I#{libffi.dir}/, '-I$(LIBFFI_DIR)')
232
220
  end
233
221
  create_makefile 'fiddle' do |conf|