ffi 1.12.2 → 1.13.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/.appveyor.yml +3 -0
  3. data/.github/workflows/ci.yml +64 -0
  4. data/.travis.yml +19 -5
  5. data/CHANGELOG.md +41 -0
  6. data/Gemfile +4 -2
  7. data/Rakefile +24 -43
  8. data/ext/ffi_c/Buffer.c +2 -2
  9. data/ext/ffi_c/Call.c +1 -7
  10. data/ext/ffi_c/ClosurePool.c +11 -14
  11. data/ext/ffi_c/Function.c +8 -23
  12. data/ext/ffi_c/FunctionInfo.c +1 -2
  13. data/ext/ffi_c/LongDouble.c +5 -3
  14. data/ext/ffi_c/LongDouble.h +0 -4
  15. data/ext/ffi_c/MemoryPointer.c +1 -1
  16. data/ext/ffi_c/MethodHandle.c +18 -24
  17. data/ext/ffi_c/MethodHandle.h +3 -2
  18. data/ext/ffi_c/Platform.c +1 -0
  19. data/ext/ffi_c/Pointer.c +1 -1
  20. data/ext/ffi_c/StructLayout.c +7 -2
  21. data/ext/ffi_c/Thread.c +0 -3
  22. data/ext/ffi_c/Thread.h +0 -3
  23. data/ext/ffi_c/compat.h +4 -0
  24. data/ext/ffi_c/extconf.rb +16 -19
  25. data/ext/ffi_c/libffi/.travis.yml +4 -0
  26. data/ext/ffi_c/libffi/.travis/build.sh +4 -0
  27. data/ext/ffi_c/libffi/Makefile.am +2 -1
  28. data/ext/ffi_c/libffi/README.md +7 -1
  29. data/ext/ffi_c/libffi/configure.ac +25 -9
  30. data/ext/ffi_c/libffi/include/ffi.h.in +8 -0
  31. data/ext/ffi_c/libffi/libffi.map.in +8 -12
  32. data/ext/ffi_c/libffi/libtool-version +1 -1
  33. data/ext/ffi_c/libffi/src/aarch64/ffi.c +6 -0
  34. data/ext/ffi_c/libffi/src/aarch64/sysv.S +13 -2
  35. data/ext/ffi_c/libffi/src/closures.c +10 -4
  36. data/ext/ffi_c/libffi/src/pa/ffi.c +46 -91
  37. data/ext/ffi_c/libffi/src/pa/ffitarget.h +1 -6
  38. data/ext/ffi_c/libffi/src/pa/hpux32.S +4 -2
  39. data/ext/ffi_c/libffi/src/pa/linux.S +4 -2
  40. data/ext/ffi_c/libffi/src/powerpc/sysv.S +5 -7
  41. data/ext/ffi_c/libffi/src/x86/ffi.c +7 -4
  42. data/ext/ffi_c/libffi/src/x86/ffi64.c +10 -8
  43. data/ext/ffi_c/libffi/src/x86/ffitarget.h +15 -2
  44. data/ext/ffi_c/libffi/src/x86/ffiw64.c +10 -8
  45. data/ext/ffi_c/libffi/src/x86/sysv.S +13 -4
  46. data/ext/ffi_c/libffi/src/x86/unix64.S +58 -2
  47. data/ext/ffi_c/libffi/src/x86/win64.S +4 -1
  48. data/ffi.gemspec +1 -1
  49. data/lib/ffi.rb +10 -2
  50. data/lib/ffi/library.rb +5 -1
  51. data/lib/ffi/platform.rb +6 -2
  52. data/lib/ffi/platform/arm-linux/types.conf +32 -4
  53. data/lib/ffi/platform/i386-windows/types.conf +26 -79
  54. data/lib/ffi/platform/powerpc-linux/types.conf +32 -2
  55. data/lib/ffi/platform/powerpc-openbsd/types.conf +156 -0
  56. data/lib/ffi/platform/sparcv9-openbsd/types.conf +156 -0
  57. data/lib/ffi/platform/x86_64-darwin/types.conf +4 -0
  58. data/lib/ffi/platform/x86_64-dragonflybsd/types.conf +4 -22
  59. data/lib/ffi/platform/x86_64-linux/types.conf +21 -0
  60. data/lib/ffi/platform/x86_64-windows/types.conf +10 -78
  61. data/lib/ffi/pointer.rb +19 -12
  62. data/lib/ffi/struct.rb +8 -2
  63. data/lib/ffi/tools/types_generator.rb +2 -0
  64. data/lib/ffi/version.rb +1 -1
  65. data/samples/getlogin.rb +1 -1
  66. data/samples/getpid.rb +1 -1
  67. data/samples/gettimeofday.rb +8 -8
  68. data/samples/hello.rb +2 -1
  69. data/samples/inotify.rb +1 -1
  70. data/samples/pty.rb +1 -2
  71. data/samples/qsort.rb +0 -1
  72. metadata +6 -4
  73. data/samples/sample_helper.rb +0 -6
@@ -99,26 +99,8 @@ static VALUE async_cb_event(void *);
99
99
  static VALUE async_cb_call(void *);
100
100
  #endif
101
101
 
102
- #ifdef HAVE_RUBY_THREAD_HAS_GVL_P
103
102
  extern int ruby_thread_has_gvl_p(void);
104
- #define rbffi_thread_has_gvl_p(frame) ruby_thread_has_gvl_p()
105
- #else
106
- static int rbffi_thread_has_gvl_p(rbffi_frame_t *frame)
107
- {
108
- return frame != NULL && frame->has_gvl;
109
- }
110
- #endif
111
-
112
- #ifdef HAVE_RUBY_NATIVE_THREAD_P
113
103
  extern int ruby_native_thread_p(void);
114
- #define rbffi_native_thread_p(frame) ruby_native_thread_p()
115
- #else
116
- static int rbffi_native_thread_p(rbffi_frame_t *frame)
117
- {
118
- return frame != NULL;
119
- }
120
- #endif
121
-
122
104
 
123
105
  VALUE rbffi_FunctionClass = Qnil;
124
106
 
@@ -476,8 +458,8 @@ callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data)
476
458
 
477
459
  if (cb.frame != NULL) cb.frame->exc = Qnil;
478
460
 
479
- if (rbffi_native_thread_p(cb.frame)) {
480
- if(rbffi_thread_has_gvl_p(cb.frame)) {
461
+ if (ruby_native_thread_p()) {
462
+ if(ruby_thread_has_gvl_p()) {
481
463
  callback_with_gvl(&cb);
482
464
  } else {
483
465
  rb_thread_call_with_gvl(callback_with_gvl, &cb);
@@ -721,7 +703,7 @@ invoke_callback(VALUE data)
721
703
  param = rb_float_new(*(double *) parameters[i]);
722
704
  break;
723
705
  case NATIVE_LONGDOUBLE:
724
- param = rbffi_longdouble_new(*(long double *) parameters[i]);
706
+ param = rbffi_longdouble_new(*(long double *) parameters[i]);
725
707
  break;
726
708
  case NATIVE_STRING:
727
709
  param = (*(void **) parameters[i] != NULL) ? rb_str_new2(*(char **) parameters[i]) : Qnil;
@@ -793,6 +775,9 @@ invoke_callback(VALUE data)
793
775
  case NATIVE_FLOAT64:
794
776
  *((double *) retval) = NUM2DBL(rbReturnValue);
795
777
  break;
778
+ case NATIVE_LONGDOUBLE:
779
+ *((long double *) retval) = rbffi_num2longdouble(rbReturnValue);
780
+ break;
796
781
  case NATIVE_POINTER:
797
782
  if (TYPE(rbReturnValue) == T_DATA && rb_obj_is_kind_of(rbReturnValue, rbffi_PointerClass)) {
798
783
  *((void **) retval) = ((AbstractMemory *) DATA_PTR(rbReturnValue))->address;
@@ -864,9 +849,9 @@ callback_prep(void* ctx, void* code, Closure* closure, char* errmsg, size_t errm
864
849
  FunctionType* fnInfo = (FunctionType *) ctx;
865
850
  ffi_status ffiStatus;
866
851
 
867
- ffiStatus = ffi_prep_closure(code, &fnInfo->ffi_cif, callback_invoke, closure);
852
+ ffiStatus = ffi_prep_closure_loc(code, &fnInfo->ffi_cif, callback_invoke, closure, code);
868
853
  if (ffiStatus != FFI_OK) {
869
- snprintf(errmsg, errmsgsize, "ffi_prep_closure failed. status=%#x", ffiStatus);
854
+ snprintf(errmsg, errmsgsize, "ffi_prep_closure_loc failed. status=%#x", ffiStatus);
870
855
  return false;
871
856
  }
872
857
 
@@ -172,7 +172,7 @@ fntype_initialize(int argc, VALUE* argv, VALUE self)
172
172
  VALUE typeName = rb_funcall2(rbReturnType, rb_intern("inspect"), 0, NULL);
173
173
  rb_raise(rb_eTypeError, "Invalid return type (%s)", RSTRING_PTR(typeName));
174
174
  }
175
-
175
+
176
176
  if (rb_obj_is_kind_of(fnInfo->rbReturnType, rbffi_StructByValueClass)) {
177
177
  fnInfo->hasStruct = true;
178
178
  }
@@ -180,7 +180,6 @@ fntype_initialize(int argc, VALUE* argv, VALUE self)
180
180
  Data_Get_Struct(fnInfo->rbReturnType, Type, fnInfo->returnType);
181
181
  fnInfo->ffiReturnType = fnInfo->returnType->ffiType;
182
182
 
183
-
184
183
  #if defined(X86_WIN32)
185
184
  rbConventionStr = (rbConvention != Qnil) ? rb_funcall2(rbConvention, rb_intern("to_s"), 0, NULL) : Qnil;
186
185
  fnInfo->abi = (rbConventionStr != Qnil && strcmp(StringValueCStr(rbConventionStr), "stdcall") == 0)
@@ -3,7 +3,7 @@
3
3
  #include <stdarg.h>
4
4
  #include <float.h>
5
5
 
6
- #if defined (__CYGWIN__) || defined(__INTERIX)
6
+ #if defined (__CYGWIN__) || defined(__INTERIX) || defined(_MSC_VER)
7
7
  # define strtold(str, endptr) ((long double) strtod((str), (endptr)))
8
8
  #endif /* defined (__CYGWIN__) */
9
9
 
@@ -21,7 +21,7 @@ rbffi_longdouble_new(long double ld)
21
21
 
22
22
  if (RTEST(rb_cBigDecimal) && rb_cBigDecimal != rb_cObject) {
23
23
  char buf[128];
24
- return rb_funcall(rb_cBigDecimal, rb_intern("new"), 1, rb_str_new(buf, sprintf(buf, "%.35Le", ld)));
24
+ return rb_funcall(rb_mKernel, rb_intern("BigDecimal"), 1, rb_str_new(buf, sprintf(buf, "%.35Le", ld)));
25
25
  }
26
26
 
27
27
  /* Fall through to handling as a float */
@@ -41,7 +41,9 @@ rbffi_num2longdouble(VALUE value)
41
41
 
42
42
  if (RTEST(rb_cBigDecimal) && rb_cBigDecimal != rb_cObject && RTEST(rb_obj_is_kind_of(value, rb_cBigDecimal))) {
43
43
  VALUE s = rb_funcall(value, rb_intern("to_s"), 1, rb_str_new2("E"));
44
- return strtold(RSTRING_PTR(s), NULL);
44
+ long double ret = strtold(RSTRING_PTR(s), NULL);
45
+ RB_GC_GUARD(s);
46
+ return ret;
45
47
  }
46
48
 
47
49
  /* Fall through to handling as a float */
@@ -36,10 +36,6 @@
36
36
  extern "C" {
37
37
  #endif
38
38
 
39
- #ifdef _MSC_VER
40
- #define strtold strtod
41
- #endif
42
-
43
39
  extern VALUE rbffi_longdouble_new(long double ld);
44
40
  extern long double rbffi_num2longdouble(VALUE value);
45
41
 
@@ -112,7 +112,7 @@ memptr_malloc(VALUE self, long size, long count, bool clear)
112
112
  p->memory.typeSize = (int) size;
113
113
  p->memory.size = msize;
114
114
  /* ensure the memory is aligned on at least a 8 byte boundary */
115
- p->memory.address = (char *) (((uintptr_t) p->storage + 0x7) & (uintptr_t) ~0x7UL);;
115
+ p->memory.address = (char *) (((uintptr_t) p->storage + 0x7) & (uintptr_t) ~0x7ULL);
116
116
  p->allocated = true;
117
117
 
118
118
  if (clear && p->memory.size > 0) {
@@ -68,9 +68,6 @@
68
68
  #ifndef roundup
69
69
  # define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
70
70
  #endif
71
- #ifdef _WIN32
72
- typedef char* caddr_t;
73
- #endif
74
71
 
75
72
  #ifdef USE_RAW
76
73
  # define METHOD_CLOSURE ffi_raw_closure
@@ -123,20 +120,15 @@ rbffi_MethodHandle_Free(MethodHandle* handle)
123
120
  }
124
121
  }
125
122
 
126
- void*
127
- rbffi_MethodHandle_CodeAddress(MethodHandle* handle)
123
+ rbffi_function_anyargs rbffi_MethodHandle_CodeAddress(MethodHandle* handle)
128
124
  {
129
- return handle->closure->code;
125
+ return (rbffi_function_anyargs) handle->closure->code;
130
126
  }
131
127
 
132
128
  #ifndef CUSTOM_TRAMPOLINE
133
129
  static void attached_method_invoke(ffi_cif* cif, void* retval, METHOD_PARAMS parameters, void* user_data);
134
130
 
135
- static ffi_type* methodHandleParamTypes[] = {
136
- &ffi_type_sint,
137
- &ffi_type_pointer,
138
- &ffi_type_ulong,
139
- };
131
+ static ffi_type* methodHandleParamTypes[3];
140
132
 
141
133
  static ffi_cif mh_cif;
142
134
 
@@ -148,10 +140,10 @@ prep_trampoline(void* ctx, void* code, Closure* closure, char* errmsg, size_t er
148
140
  #if defined(USE_RAW)
149
141
  ffiStatus = ffi_prep_raw_closure(code, &mh_cif, attached_method_invoke, closure);
150
142
  #else
151
- ffiStatus = ffi_prep_closure(code, &mh_cif, attached_method_invoke, closure);
143
+ ffiStatus = ffi_prep_closure_loc(code, &mh_cif, attached_method_invoke, closure, code);
152
144
  #endif
153
145
  if (ffiStatus != FFI_OK) {
154
- snprintf(errmsg, errmsgsize, "ffi_prep_closure failed. status=%#x", ffiStatus);
146
+ snprintf(errmsg, errmsgsize, "ffi_prep_closure_loc failed. status=%#x", ffiStatus);
155
147
  return false;
156
148
  }
157
149
 
@@ -237,7 +229,7 @@ custom_trampoline(int argc, VALUE* argv, VALUE self, Closure* handle)
237
229
 
238
230
  #elif defined(__i386__) && 0
239
231
 
240
- static VALUE custom_trampoline(caddr_t args, Closure*);
232
+ static VALUE custom_trampoline(void *args, Closure*);
241
233
  #define TRAMPOLINE_CTX_MAGIC (0xfee1dead)
242
234
  #define TRAMPOLINE_FUN_MAGIC (0xbeefcafe)
243
235
 
@@ -269,7 +261,7 @@ __asm__(
269
261
  );
270
262
 
271
263
  static VALUE
272
- custom_trampoline(caddr_t args, Closure* handle)
264
+ custom_trampoline(void *args, Closure* handle)
273
265
  {
274
266
  FunctionType* fnInfo = (FunctionType *) handle->info;
275
267
  return (*fnInfo->invoke)(*(int *) args, *(VALUE **) (args + 4), handle->function, fnInfo);
@@ -286,10 +278,10 @@ static long trampoline_ctx_offset, trampoline_func_offset;
286
278
  static long
287
279
  trampoline_offset(int off, const long value)
288
280
  {
289
- caddr_t ptr;
290
- for (ptr = (caddr_t) &ffi_trampoline + off; ptr < (caddr_t) &ffi_trampoline_end; ++ptr) {
281
+ char *ptr;
282
+ for (ptr = (char *) &ffi_trampoline + off; ptr < (char *) &ffi_trampoline_end; ++ptr) {
291
283
  if (*(long *) ptr == value) {
292
- return ptr - (caddr_t) &ffi_trampoline;
284
+ return ptr - (char *) &ffi_trampoline;
293
285
  }
294
286
  }
295
287
 
@@ -315,12 +307,10 @@ trampoline_offsets(long* ctxOffset, long* fnOffset)
315
307
  static bool
316
308
  prep_trampoline(void* ctx, void* code, Closure* closure, char* errmsg, size_t errmsgsize)
317
309
  {
318
- caddr_t ptr = (caddr_t) code;
319
-
320
- memcpy(ptr, &ffi_trampoline, trampoline_size());
310
+ memcpy(code, (void*) &ffi_trampoline, trampoline_size());
321
311
  /* Patch the context and function addresses into the stub code */
322
- *(intptr_t *)(ptr + trampoline_ctx_offset) = (intptr_t) closure;
323
- *(intptr_t *)(ptr + trampoline_func_offset) = (intptr_t) custom_trampoline;
312
+ *(intptr_t *)((char*)code + trampoline_ctx_offset) = (intptr_t) closure;
313
+ *(intptr_t *)((char*)code + trampoline_func_offset) = (intptr_t) custom_trampoline;
324
314
 
325
315
  return true;
326
316
  }
@@ -328,7 +318,7 @@ prep_trampoline(void* ctx, void* code, Closure* closure, char* errmsg, size_t er
328
318
  static long
329
319
  trampoline_size(void)
330
320
  {
331
- return (caddr_t) &ffi_trampoline_end - (caddr_t) &ffi_trampoline;
321
+ return (char *) &ffi_trampoline_end - (char *) &ffi_trampoline;
332
322
  }
333
323
 
334
324
  #endif /* CUSTOM_TRAMPOLINE */
@@ -348,6 +338,10 @@ rbffi_MethodHandle_Init(VALUE module)
348
338
  rb_raise(rb_eFatal, "Could not locate offsets in trampoline code");
349
339
  }
350
340
  #else
341
+ methodHandleParamTypes[0] = &ffi_type_sint;
342
+ methodHandleParamTypes[1] = &ffi_type_pointer;
343
+ methodHandleParamTypes[2] = &ffi_type_ulong;
344
+
351
345
  ffiStatus = ffi_prep_cif(&mh_cif, FFI_DEFAULT_ABI, 3, &ffi_type_ulong,
352
346
  methodHandleParamTypes);
353
347
  if (ffiStatus != FFI_OK) {
@@ -37,14 +37,15 @@ extern "C" {
37
37
  #include <ruby.h>
38
38
  #include "Function.h"
39
39
 
40
-
40
+
41
41
  typedef struct MethodHandlePool MethodHandlePool;
42
42
  typedef struct MethodHandle MethodHandle;
43
+ typedef VALUE (*rbffi_function_anyargs)(int argc, VALUE* argv, VALUE self);
43
44
 
44
45
 
45
46
  MethodHandle* rbffi_MethodHandle_Alloc(FunctionType* fnInfo, void* function);
46
47
  void rbffi_MethodHandle_Free(MethodHandle* handle);
47
- void* rbffi_MethodHandle_CodeAddress(MethodHandle* handle);
48
+ rbffi_function_anyargs rbffi_MethodHandle_CodeAddress(MethodHandle* handle);
48
49
  void rbffi_MethodHandle_Init(VALUE module);
49
50
 
50
51
  #ifdef __cplusplus
@@ -64,6 +64,7 @@ export_primitive_types(VALUE module)
64
64
  S(LONG, long);
65
65
  S(FLOAT, float);
66
66
  S(DOUBLE, double);
67
+ S(LONG_DOUBLE, long double);
67
68
  S(ADDRESS, void*);
68
69
  #undef S
69
70
  }
@@ -183,7 +183,7 @@ ptr_initialize_copy(VALUE self, VALUE other)
183
183
 
184
184
  dst->allocated = true;
185
185
  dst->autorelease = true;
186
- dst->memory.address = (void *) (((uintptr_t) dst->storage + 0x7) & (uintptr_t) ~0x7UL);
186
+ dst->memory.address = (void *) (((uintptr_t) dst->storage + 0x7) & (uintptr_t) ~0x7ULL);
187
187
  dst->memory.size = src->size;
188
188
  dst->memory.typeSize = src->typeSize;
189
189
 
@@ -350,8 +350,13 @@ array_field_put(VALUE self, VALUE pointer, VALUE value)
350
350
  argv[0] = INT2FIX(f->offset);
351
351
  argv[1] = value;
352
352
 
353
- rb_funcall2(pointer, rb_intern("put_string"), 2, argv);
354
-
353
+ if (RSTRING_LEN(value) < array->length) {
354
+ rb_funcall2(pointer, rb_intern("put_string"), 2, argv);
355
+ } else if (RSTRING_LEN(value) == array->length) {
356
+ rb_funcall2(pointer, rb_intern("put_bytes"), 2, argv);
357
+ } else {
358
+ rb_raise(rb_eIndexError, "String is longer (%ld bytes) than the char array (%d bytes)", RSTRING_LEN(value), array->length);
359
+ }
355
360
  } else {
356
361
  #ifdef notyet
357
362
  MemoryOp* op;
@@ -74,9 +74,6 @@ void
74
74
  rbffi_frame_push(rbffi_frame_t* frame)
75
75
  {
76
76
  memset(frame, 0, sizeof(*frame));
77
- #ifndef HAVE_RUBY_THREAD_HAS_GVL_P
78
- frame->has_gvl = true;
79
- #endif
80
77
  frame->exc = Qnil;
81
78
 
82
79
  #ifdef _WIN32
@@ -66,9 +66,6 @@ typedef struct rbffi_frame {
66
66
  struct thread_data* td;
67
67
  #endif
68
68
  struct rbffi_frame* prev;
69
- #ifndef HAVE_RUBY_THREAD_HAS_GVL_P
70
- bool has_gvl;
71
- #endif
72
69
  VALUE exc;
73
70
  } rbffi_frame_t;
74
71
 
@@ -64,6 +64,10 @@
64
64
  # define unlikely(x) (x)
65
65
  #endif
66
66
 
67
+ #ifdef _MSC_VER
68
+ #define ffi_type_longdouble ffi_type_double
69
+ #endif
70
+
67
71
  #ifndef MAX
68
72
  # define MAX(a, b) ((a) < (b) ? (b) : (a))
69
73
  #endif
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- if !defined?(RUBY_ENGINE) || RUBY_ENGINE == 'ruby' || RUBY_ENGINE == 'rbx'
3
+ if RUBY_ENGINE == 'ruby' || RUBY_ENGINE == 'rbx'
4
4
  require 'mkmf'
5
5
  require 'rbconfig'
6
6
 
@@ -8,14 +8,22 @@ if !defined?(RUBY_ENGINE) || RUBY_ENGINE == 'ruby' || RUBY_ENGINE == 'rbx'
8
8
  # We need pkg_config or ffi.h
9
9
  libffi_ok = pkg_config("libffi") ||
10
10
  have_header("ffi.h") ||
11
- find_header("ffi.h", "/usr/local/include", "/usr/include/ffi")
11
+ find_header("ffi.h", "/usr/local/include", "/usr/include/ffi",
12
+ "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/ffi",
13
+ "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/ffi") ||
14
+ (find_header("ffi.h", `xcrun --sdk macosx --show-sdk-path`.strip + "/usr/include/ffi") rescue false)
12
15
 
13
- # Ensure we can link to ffi_call
14
- libffi_ok &&= have_library("ffi", "ffi_call", [ "ffi.h" ]) ||
15
- have_library("libffi", "ffi_call", [ "ffi.h" ])
16
+ # Ensure we can link to ffi_prep_closure_loc
17
+ libffi_ok &&= have_library("ffi", "ffi_prep_closure_loc", [ "ffi.h" ]) ||
18
+ have_library("libffi", "ffi_prep_closure_loc", [ "ffi.h" ]) ||
19
+ have_library("libffi-8", "ffi_prep_closure_loc", [ "ffi.h" ])
16
20
 
17
- # And we need a libffi version recent enough to provide ffi_closure_alloc
18
- libffi_ok &&= have_func("ffi_closure_alloc")
21
+ if RbConfig::CONFIG['host_os'] =~ /mswin/
22
+ have_library('libffi_convenience')
23
+ have_library('shlwapi')
24
+ end
25
+
26
+ libffi_ok
19
27
  end
20
28
 
21
29
  dir_config("ffi_c")
@@ -36,14 +44,6 @@ if !defined?(RUBY_ENGINE) || RUBY_ENGINE == 'ruby' || RUBY_ENGINE == 'rbx'
36
44
  abort "system libffi is not usable" unless system_libffi_usable?
37
45
  end
38
46
 
39
- have_header('shlwapi.h')
40
- have_func('rb_thread_call_without_gvl') || abort("Ruby C-API function `rb_thread_call_without_gvl` is missing")
41
- have_func('ruby_native_thread_p')
42
- if RUBY_VERSION >= "2.3.0"
43
- # On OSX and Linux ruby_thread_has_gvl_p() is detected but fails at runtime for ruby < 2.3.0
44
- have_func('ruby_thread_has_gvl_p')
45
- end
46
-
47
47
  if system_libffi
48
48
  have_func('ffi_prep_cif_var')
49
49
  $defs << "-DHAVE_RAW_API" if have_func("ffi_raw_call") && have_func("ffi_prep_raw_closure")
@@ -53,13 +53,10 @@ if !defined?(RUBY_ENGINE) || RUBY_ENGINE == 'ruby' || RUBY_ENGINE == 'rbx'
53
53
  end
54
54
 
55
55
  $defs << "-DHAVE_EXTCONF_H" if $defs.empty? # needed so create_header works
56
- $defs << "-DFFI_BUILDING" if RbConfig::CONFIG['host_os'] =~ /mswin/ # for compatibility with newer libffi
57
56
 
58
57
  create_header
59
-
60
- $LOCAL_LIBS << " ./libffi/.libs/libffi_convenience.lib" if !system_libffi && RbConfig::CONFIG['host_os'] =~ /mswin/
61
-
62
58
  create_makefile("ffi_c")
59
+
63
60
  unless system_libffi
64
61
  File.open("Makefile", "a") do |mf|
65
62
  mf.puts "LIBFFI_HOST=--host=#{RbConfig::CONFIG['host_alias']}" if RbConfig::CONFIG.has_key?("host_alias")
@@ -39,6 +39,10 @@ matrix:
39
39
  - os: linux
40
40
  arch: arm64
41
41
  env: HOST=aarch64-linux-gnu
42
+ - os: linux
43
+ arch: arm64
44
+ env: HOST=aarch64-linux-gnu
45
+ compiler: clang
42
46
  - os: linux
43
47
  env: HOST=arm32v7-linux-gnu LIBFFI_TEST_OPTIMIZATION="-O0"
44
48
  - os: linux
@@ -2,6 +2,10 @@
2
2
 
3
3
  set -x
4
4
 
5
+ # This is a policy bound API key. It can only be used with
6
+ # https://github.com/libffi/rlgl-policy.git.
7
+ RLGL_KEY=0LIBFFI-0LIBFFI-0LIBFFI-0LIBFFI
8
+
5
9
  if [ -z ${QEMU_CPU+x} ]; then
6
10
  export SET_QEMU_CPU=
7
11
  else
@@ -144,7 +144,8 @@ endif
144
144
  libffi_version_info = -version-info `grep -v '^\#' $(srcdir)/libtool-version`
145
145
 
146
146
  libffi.map: $(top_srcdir)/libffi.map.in
147
- $(COMPILE) -D$(TARGET) -E -x assembler-with-cpp -o $@ $<
147
+ $(COMPILE) -D$(TARGET) -DGENERATE_LIBFFI_MAP \
148
+ -E -x assembler-with-cpp -o $@ $<
148
149
 
149
150
  libffi_la_LDFLAGS = -no-undefined $(libffi_version_info) $(libffi_version_script) $(LTLDFLAGS) $(AM_LTLDFLAGS)
150
151
  libffi_la_DEPENDENCIES = $(libffi_la_LIBADD) $(libffi_version_dep)
@@ -4,7 +4,7 @@ Status
4
4
  [![Build Status](https://travis-ci.org/libffi/libffi.svg?branch=master)](https://travis-ci.org/libffi/libffi)
5
5
  [![Build status](https://ci.appveyor.com/api/projects/status/8lko9vagbx4w2kxq?svg=true)](https://ci.appveyor.com/project/atgreen/libffi)
6
6
 
7
- libffi-3.3 was released on November 23, 2019. Check the libffi web
7
+ libffi-3.4 was released on TBD. Check the libffi web
8
8
  page for updates: <URL:http://sourceware.org/libffi/>.
9
9
 
10
10
 
@@ -196,6 +196,12 @@ History
196
196
 
197
197
  See the git log for details at http://github.com/libffi/libffi.
198
198
 
199
+ 3.4 TBD
200
+ Add support for Intel Control-flow Enforcement Technology (CET).
201
+ Add support for ARM Pointer Authentication (PA).
202
+ Fix 32-bit PPC regression.
203
+ Fix MIPS soft-float problem.
204
+
199
205
  3.3 Nov-23-19
200
206
  Add RISC-V support.
201
207
  New API in support of GO closures.