fiddle 1.0.9 → 1.1.2

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: 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|