ffi 1.17.1 → 1.17.3

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.
Files changed (136) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +33 -0
  4. data/Gemfile +8 -3
  5. data/README.md +1 -0
  6. data/Rakefile +7 -4
  7. data/Steepfile +8 -0
  8. data/ext/ffi_c/DynamicLibrary.c +1 -1
  9. data/ext/ffi_c/Function.c +2 -0
  10. data/ext/ffi_c/MethodHandle.c +4 -2
  11. data/ext/ffi_c/libffi/.ci/Containerfile.ppc64le +12 -0
  12. data/ext/ffi_c/libffi/.ci/build.sh +38 -33
  13. data/ext/ffi_c/libffi/.ci/install.sh +46 -50
  14. data/ext/ffi_c/libffi/.ci/site.exp +6 -0
  15. data/ext/ffi_c/libffi/.gail-labels +44 -0
  16. data/ext/ffi_c/libffi/.github/workflows/build.yml +212 -333
  17. data/ext/ffi_c/libffi/.github/workflows/emscripten.yml +101 -58
  18. data/ext/ffi_c/libffi/.github/workflows/label-new-issue.yaml +15 -0
  19. data/ext/ffi_c/libffi/.github/workflows/tarball.yml +55 -0
  20. data/ext/ffi_c/libffi/LICENSE +1 -1
  21. data/ext/ffi_c/libffi/Makefile.am +20 -15
  22. data/ext/ffi_c/libffi/Makefile.in +41 -54
  23. data/ext/ffi_c/libffi/README.md +40 -4
  24. data/ext/ffi_c/libffi/acinclude.m4 +6 -0
  25. data/ext/ffi_c/libffi/config.guess +80 -22
  26. data/ext/ffi_c/libffi/config.sub +161 -80
  27. data/ext/ffi_c/libffi/configure +1058 -1372
  28. data/ext/ffi_c/libffi/configure.ac +28 -14
  29. data/ext/ffi_c/libffi/configure.host +6 -6
  30. data/ext/ffi_c/libffi/doc/Makefile.in +4 -0
  31. data/ext/ffi_c/libffi/doc/libffi.texi +27 -4
  32. data/ext/ffi_c/libffi/doc/version.texi +4 -4
  33. data/ext/ffi_c/libffi/fficonfig.h.in +9 -9
  34. data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +1 -28
  35. data/ext/ffi_c/libffi/include/Makefile.in +4 -0
  36. data/ext/ffi_c/libffi/include/ffi.h.in +19 -1
  37. data/ext/ffi_c/libffi/include/ffi_cfi.h +2 -0
  38. data/ext/ffi_c/libffi/include/ffi_common.h +17 -0
  39. data/ext/ffi_c/libffi/libffi.map.in +13 -1
  40. data/ext/ffi_c/libffi/libtool-version +1 -1
  41. data/ext/ffi_c/libffi/m4/asmcfi.m4 +28 -11
  42. data/ext/ffi_c/libffi/m4/ax_check_compile_flag.m4 +13 -3
  43. data/ext/ffi_c/libffi/man/Makefile.in +4 -0
  44. data/ext/ffi_c/libffi/src/aarch64/ffi.c +7 -4
  45. data/ext/ffi_c/libffi/src/aarch64/ffitarget.h +2 -2
  46. data/ext/ffi_c/libffi/src/aarch64/internal.h +63 -17
  47. data/ext/ffi_c/libffi/src/aarch64/sysv.S +22 -12
  48. data/ext/ffi_c/libffi/src/arc/arcompact.S +2 -2
  49. data/ext/ffi_c/libffi/src/arc/ffi.c +6 -2
  50. data/ext/ffi_c/libffi/src/arm/sysv.S +1 -1
  51. data/ext/ffi_c/libffi/src/closures.c +3 -3
  52. data/ext/ffi_c/libffi/src/dlmalloc.c +1 -0
  53. data/ext/ffi_c/libffi/src/mips/ffitarget.h +2 -4
  54. data/ext/ffi_c/libffi/src/mips/n32.S +4 -0
  55. data/ext/ffi_c/libffi/src/mips/o32.S +4 -0
  56. data/ext/ffi_c/libffi/src/or1k/ffi.c +2 -2
  57. data/ext/ffi_c/libffi/src/pa/linux.S +4 -0
  58. data/ext/ffi_c/libffi/src/powerpc/ffi.c +19 -0
  59. data/ext/ffi_c/libffi/src/powerpc/ffi_linux64.c +26 -19
  60. data/ext/ffi_c/libffi/src/powerpc/ffi_sysv.c +26 -16
  61. data/ext/ffi_c/libffi/src/powerpc/internal.h +10 -0
  62. data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +47 -0
  63. data/ext/ffi_c/libffi/src/powerpc/ppc_closure.S +24 -0
  64. data/ext/ffi_c/libffi/src/prep_cif.c +1 -4
  65. data/ext/ffi_c/libffi/src/riscv/ffi.c +39 -16
  66. data/ext/ffi_c/libffi/src/riscv/internal.h +7 -0
  67. data/ext/ffi_c/libffi/src/riscv/sysv.S +24 -0
  68. data/ext/ffi_c/libffi/src/s390/ffi.c +28 -1
  69. data/ext/ffi_c/libffi/src/s390/internal.h +11 -0
  70. data/ext/ffi_c/libffi/src/s390/sysv.S +38 -0
  71. data/ext/ffi_c/libffi/src/sparc/ffi.c +16 -0
  72. data/ext/ffi_c/libffi/src/tramp.c +6 -1
  73. data/ext/ffi_c/libffi/src/types.c +23 -1
  74. data/ext/ffi_c/libffi/src/{wasm32 → wasm}/ffi.c +166 -315
  75. data/ext/ffi_c/libffi/src/{wasm32 → wasm}/ffitarget.h +17 -0
  76. data/ext/ffi_c/libffi/src/x86/ffi.c +4 -1
  77. data/ext/ffi_c/libffi/src/x86/ffi64.c +4 -1
  78. data/ext/ffi_c/libffi/src/x86/ffitarget.h +0 -3
  79. data/ext/ffi_c/libffi/src/x86/sysv.S +1 -3
  80. data/ext/ffi_c/libffi/src/x86/sysv_intel.S +1 -3
  81. data/ext/ffi_c/libffi/testsuite/Makefile.am +6 -4
  82. data/ext/ffi_c/libffi/testsuite/Makefile.in +10 -4
  83. data/ext/ffi_c/libffi/testsuite/emscripten/build-tests.sh +4 -24
  84. data/ext/ffi_c/libffi/testsuite/emscripten/build.sh +10 -27
  85. data/ext/ffi_c/libffi/testsuite/emscripten/node-tests.sh +6 -31
  86. data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +269 -256
  87. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/testcases.c +1 -1
  88. data/ext/ffi_c/libffi/testsuite/libffi.call/callback.c +2 -2
  89. data/ext/ffi_c/libffi/testsuite/libffi.call/callback2.c +2 -2
  90. data/ext/ffi_c/libffi/testsuite/libffi.call/callback3.c +2 -2
  91. data/ext/ffi_c/libffi/testsuite/libffi.call/callback4.c +2 -2
  92. data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +3 -0
  93. data/ext/ffi_c/libffi/testsuite/libffi.call/longjmp.c +60 -0
  94. data/ext/ffi_c/libffi/testsuite/libffi.call/overread.c +54 -0
  95. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_int_float.c +88 -0
  96. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct2.c +1 -0
  97. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct3.c +1 -0
  98. data/ext/ffi_c/libffi/testsuite/libffi.call/x32.c +31 -0
  99. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_dbls_struct.c +1 -1
  100. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_multi_sshortchar.c +1 -1
  101. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_multi_ushortchar.c +1 -1
  102. data/ext/ffi_c/libffi/testsuite/libffi.closures/huge_struct.c +1 -2
  103. data/ext/ffi_c/libffi/testsuite/libffi.closures/unwindtest.cc +2 -0
  104. data/ext/ffi_c/libffi/testsuite/libffi.closures/unwindtest_ffi_call.cc +2 -0
  105. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_int.c +1 -1
  106. data/ext/ffi_c/libffi/testsuite/libffi.threads/ffitest.h +1 -0
  107. data/ext/ffi_c/libffi/testsuite/libffi.threads/threads.exp +50 -0
  108. data/ext/ffi_c/libffi/testsuite/libffi.threads/tsan.c +74 -0
  109. data/ext/ffi_c/libffi.mk +5 -0
  110. data/ffi.gemspec +4 -5
  111. data/lib/ffi/autopointer.rb +6 -0
  112. data/lib/ffi/compat.rb +11 -0
  113. data/lib/ffi/function.rb +23 -0
  114. data/lib/ffi/library.rb +19 -3
  115. data/lib/ffi/struct_by_reference.rb +1 -1
  116. data/lib/ffi/version.rb +1 -1
  117. data/samples/hello_ractor.rb +9 -1
  118. data/samples/qsort_ractor.rb +9 -1
  119. data/sig/ffi/auto_pointer.rbs +1 -1
  120. data/sig/ffi/errno.rbs +8 -0
  121. data/sig/ffi/platform.rbs +49 -0
  122. data/sig/ffi/struct.rbs +2 -2
  123. data/sig/ffi/struct_by_reference.rbs +1 -1
  124. data/sig/ffi.rbs +4 -1
  125. data.tar.gz.sig +0 -0
  126. metadata +37 -83
  127. metadata.gz.sig +0 -0
  128. data/ext/ffi_c/libffi/.appveyor/site.exp +0 -16
  129. data/ext/ffi_c/libffi/.appveyor.yml +0 -84
  130. data/ext/ffi_c/libffi/.circleci/config.yml +0 -156
  131. data/ext/ffi_c/libffi/src/nios2/ffi.c +0 -304
  132. data/ext/ffi_c/libffi/src/nios2/ffitarget.h +0 -52
  133. data/ext/ffi_c/libffi/src/nios2/sysv.S +0 -136
  134. data/lib/ffi/tools/types_generator.rb +0 -137
  135. data/rakelib/ffi_gem_helper.rb +0 -65
  136. /data/ext/ffi_c/libffi/{.appveyor → .ci}/unix-noexec.exp +0 -0
@@ -29,6 +29,8 @@
29
29
 
30
30
  #include <ffi.h>
31
31
  #include <ffi_common.h>
32
+ #include "internal.h"
33
+ #include <tramp.h>
32
34
 
33
35
  #include <stdlib.h>
34
36
  #include <stdint.h>
@@ -424,34 +426,44 @@ extern void ffi_closure_asm(void) FFI_HIDDEN;
424
426
 
425
427
  ffi_status ffi_prep_closure_loc(ffi_closure *closure, ffi_cif *cif, void (*fun)(ffi_cif*,void*,void**,void*), void *user_data, void *codeloc)
426
428
  {
427
- uint32_t *tramp = (uint32_t *) &closure->tramp[0];
428
- uint64_t fn = (uint64_t) (uintptr_t) ffi_closure_asm;
429
-
430
429
  if (cif->abi <= FFI_FIRST_ABI || cif->abi >= FFI_LAST_ABI)
431
430
  return FFI_BAD_ABI;
432
431
 
433
- /* we will call ffi_closure_inner with codeloc, not closure, but as long
434
- as the memory is readable it should work */
432
+ #ifdef FFI_EXEC_STATIC_TRAMP
433
+ if (ffi_tramp_is_present (closure))
434
+ {
435
+ /* Initialize the static trampoline's parameters. */
436
+ void (*dest)(void) = ffi_closure_asm;
437
+ ffi_tramp_set_parms (closure->ftramp, dest, closure);
438
+ }
439
+ else
440
+ #endif
441
+ {
442
+ uint32_t *tramp = (uint32_t *) &closure->tramp[0];
443
+ uint64_t fn = (uint64_t) (uintptr_t) ffi_closure_asm;
444
+
445
+ /* we will call ffi_closure_inner with codeloc, not closure, but as long
446
+ as the memory is readable it should work */
435
447
 
436
- tramp[0] = 0x00000317; /* auipc t1, 0 (i.e. t0 <- codeloc) */
448
+ tramp[0] = 0x00000317; /* auipc t1, 0 (i.e. t0 <- codeloc) */
437
449
  #if __SIZEOF_POINTER__ == 8
438
- tramp[1] = 0x01033383; /* ld t2, 16(t1) */
450
+ tramp[1] = 0x01033383; /* ld t2, 16(t1) */
439
451
  #else
440
- tramp[1] = 0x01032383; /* lw t2, 16(t1) */
452
+ tramp[1] = 0x01032383; /* lw t2, 16(t1) */
441
453
  #endif
442
- tramp[2] = 0x00038067; /* jr t2 */
443
- tramp[3] = 0x00000013; /* nop */
444
- tramp[4] = fn;
445
- tramp[5] = fn >> 32;
454
+ tramp[2] = 0x00038067; /* jr t2 */
455
+ tramp[3] = 0x00000013; /* nop */
456
+ tramp[4] = fn;
457
+ tramp[5] = fn >> 32;
458
+ #if !defined(__FreeBSD__)
459
+ __builtin___clear_cache(codeloc, codeloc + FFI_TRAMPOLINE_SIZE);
460
+ #endif
461
+ }
446
462
 
447
463
  closure->cif = cif;
448
464
  closure->fun = fun;
449
465
  closure->user_data = user_data;
450
466
 
451
- #if !defined(__FreeBSD__)
452
- __builtin___clear_cache(codeloc, codeloc + FFI_TRAMPOLINE_SIZE);
453
- #endif
454
-
455
467
  return FFI_OK;
456
468
  }
457
469
 
@@ -512,3 +524,14 @@ ffi_closure_inner (ffi_cif *cif,
512
524
  marshal(&cb, cif->rtype, 0, rvalue);
513
525
  }
514
526
  }
527
+
528
+ #ifdef FFI_EXEC_STATIC_TRAMP
529
+ void *
530
+ ffi_tramp_arch (size_t *tramp_size, size_t *map_size)
531
+ {
532
+ extern void *trampoline_code_table;
533
+ *tramp_size = RISCV_TRAMP_SIZE;
534
+ *map_size = RISCV_TRAMP_MAP_SIZE;
535
+ return &trampoline_code_table;
536
+ }
537
+ #endif
@@ -0,0 +1,7 @@
1
+ #ifdef FFI_EXEC_STATIC_TRAMP
2
+ /* For the trampoline table mapping, a mapping size of 4K (base page size)
3
+ is chosen. */
4
+ #define RISCV_TRAMP_MAP_SHIFT 12
5
+ #define RISCV_TRAMP_MAP_SIZE (1 << RISCV_TRAMP_MAP_SHIFT)
6
+ #define RISCV_TRAMP_SIZE 16
7
+ #endif /* FFI_EXEC_STATIC_TRAMP */
@@ -29,6 +29,7 @@
29
29
  #define LIBFFI_ASM
30
30
  #include <fficonfig.h>
31
31
  #include <ffi.h>
32
+ #include "internal.h"
32
33
 
33
34
  /* Define aliases so that we can handle all ABIs uniformly */
34
35
 
@@ -291,3 +292,26 @@ ffi_go_closure_asm:
291
292
  ret
292
293
  .cfi_endproc
293
294
  .size ffi_go_closure_asm, .-ffi_go_closure_asm
295
+
296
+ #ifdef FFI_EXEC_STATIC_TRAMP
297
+ /*
298
+ trampoline_code_table.
299
+ */
300
+ .globl trampoline_code_table
301
+ .hidden trampoline_code_table
302
+ .type trampoline_code_table, @function
303
+ .align RISCV_TRAMP_MAP_SHIFT
304
+ trampoline_code_table:
305
+ .option push
306
+ # Do not allow the jr insn to be encoded as c.jr for alignment purposes
307
+ .option norvc
308
+ .rept RISCV_TRAMP_MAP_SIZE / RISCV_TRAMP_SIZE
309
+ auipc t2, RISCV_TRAMP_MAP_SIZE >> 12
310
+ LARG t1, 0(t2)
311
+ LARG t2, PTRS(t2)
312
+ jr t2
313
+ .endr
314
+ .option pop
315
+ .size trampoline_code_table,.-trampoline_code_table
316
+ .align RISCV_TRAMP_MAP_SHIFT
317
+ #endif /* FFI_EXEC_STATIC_TRAMP */
@@ -32,6 +32,7 @@
32
32
  #include <ffi_common.h>
33
33
  #include <stdint.h>
34
34
  #include "internal.h"
35
+ #include <tramp.h>
35
36
 
36
37
  /*====================== End of Includes =============================*/
37
38
 
@@ -720,16 +721,30 @@ ffi_prep_closure_loc (ffi_closure *closure,
720
721
  #endif
721
722
  0x07f1 /* br %r1 */
722
723
  };
723
-
724
+ void (*dest)(void);
724
725
  unsigned long *tramp = (unsigned long *)&closure->tramp;
725
726
 
726
727
  if (cif->abi != FFI_SYSV)
727
728
  return FFI_BAD_ABI;
728
729
 
730
+
731
+ #if defined(FFI_EXEC_STATIC_TRAMP)
732
+ if (ffi_tramp_is_present(closure))
733
+ {
734
+ /* Initialize the static trampoline's parameters. */
735
+ dest = ffi_closure_SYSV;
736
+ ffi_tramp_set_parms (closure->ftramp, dest, closure);
737
+ goto out;
738
+ }
739
+ #endif
740
+
729
741
  memcpy (tramp, template, sizeof(template));
730
742
  tramp[2] = (unsigned long)codeloc;
731
743
  tramp[3] = (unsigned long)&ffi_closure_SYSV;
732
744
 
745
+ #if defined(FFI_EXEC_STATIC_TRAMP)
746
+ out:
747
+ #endif
733
748
  closure->cif = cif;
734
749
  closure->fun = fun;
735
750
  closure->user_data = user_data;
@@ -754,3 +769,15 @@ ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif *cif,
754
769
 
755
770
  return FFI_OK;
756
771
  }
772
+
773
+ #if defined(FFI_EXEC_STATIC_TRAMP)
774
+ void *
775
+ ffi_tramp_arch (size_t *tramp_size, size_t *map_size)
776
+ {
777
+ extern void *trampoline_code_table;
778
+
779
+ *tramp_size = FFI390_TRAMP_SIZE;
780
+ *map_size = FFI390_TRAMP_MAP_SIZE;
781
+ return &trampoline_code_table;
782
+ }
783
+ #endif
@@ -9,3 +9,14 @@
9
9
  #define FFI390_RET_IN_MEM 8
10
10
 
11
11
  #define FFI390_RET_STRUCT (FFI390_RET_VOID | FFI390_RET_IN_MEM)
12
+
13
+
14
+ #if defined(FFI_EXEC_STATIC_TRAMP)
15
+ /*
16
+ * For the trampoline code table mapping, a mapping size of 4K is chosen.
17
+ */
18
+ #define FFI390_TRAMP_MAP_SHIFT 12
19
+ #define FFI390_TRAMP_MAP_SIZE (1 << FFI390_TRAMP_MAP_SHIFT)
20
+ #define FFI390_TRAMP_SIZE 16
21
+
22
+ #endif
@@ -28,6 +28,7 @@
28
28
  #define LIBFFI_ASM
29
29
  #include <fficonfig.h>
30
30
  #include <ffi.h>
31
+ #include "internal.h"
31
32
 
32
33
  .text
33
34
 
@@ -318,6 +319,43 @@ ffi_closure_SYSV:
318
319
  br %r14
319
320
  .cfi_endproc
320
321
  .size ffi_closure_SYSV,.-ffi_closure_SYSV
322
+
323
+
324
+ #if defined(FFI_EXEC_STATIC_TRAMP)
325
+ /*
326
+ * Below is the definition of the trampoline code table. Each element in
327
+ * the code table is a trampoline.
328
+ */
329
+ /*
330
+ * The trampoline uses the volatile register r0 and r1. As the registers are
331
+ * marked volatile in the ABI, the original values are not saved.
332
+ *
333
+ * The trampoline has two parameters - target code to jump to and data for
334
+ * the target code. The trampoline extracts the parameters from its parameter
335
+ * block (see tramp_table_map()). The trampoline saves the data address in r0.
336
+ * Finally, it jumps to the target code.
337
+ */
338
+
339
+ .align FFI390_TRAMP_MAP_SIZE
340
+ trampoline_code_table:
341
+ .rept FFI390_TRAMP_MAP_SIZE / FFI390_TRAMP_SIZE
342
+ basr %r1,0 # load next instruction address to r1
343
+ lmg %r0,%r1,4094(%r1) # load parameter block
344
+ # r0 -> data
345
+ # r1 -> code
346
+ br %r1 # jump to r1/code
347
+ .balign 8
348
+ .endr
349
+
350
+ .globl trampoline_code_table
351
+ FFI_HIDDEN(trampoline_code_table)
352
+ #ifdef __ELF__
353
+ .type trampoline_code_table, @function
354
+ .size trampoline_code_table,.- trampoline_code_table
355
+ #endif
356
+ .align FFI390_TRAMP_MAP_SIZE
357
+ #endif /* FFI_EXEC_STATIC_TRAMP */
358
+
321
359
  #endif /* !s390x */
322
360
 
323
361
  #if defined __ELF__ && defined __linux__
@@ -286,6 +286,8 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
286
286
  void **avalue, void *closure)
287
287
  {
288
288
  size_t bytes = cif->bytes;
289
+ size_t i, nargs = cif->nargs;
290
+ ffi_type **arg_types = cif->arg_types;
289
291
 
290
292
  FFI_ASSERT (cif->abi == FFI_V8);
291
293
 
@@ -295,6 +297,20 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
295
297
  && (cif->flags & SPARC_FLAG_RET_MASK) == SPARC_RET_STRUCT)
296
298
  bytes += FFI_ALIGN (cif->rtype->size, 8);
297
299
 
300
+ /* If we have any structure arguments, make a copy so we are passing
301
+ by value. */
302
+ for (i = 0; i < nargs; i++)
303
+ {
304
+ ffi_type *at = arg_types[i];
305
+ int size = at->size;
306
+ if (at->type == FFI_TYPE_STRUCT)
307
+ {
308
+ char *argcopy = alloca (size);
309
+ memcpy (argcopy, avalue[i], size);
310
+ avalue[i] = argcopy;
311
+ }
312
+ }
313
+
298
314
  ffi_call_v8(cif, fn, rvalue, avalue, -bytes, closure);
299
315
  }
300
316
 
@@ -209,6 +209,11 @@ ffi_tramp_get_libffi (void)
209
209
  unsigned long start, end, offset, inode;
210
210
  uintptr_t addr = (uintptr_t) tramp_globals.text;
211
211
  int nfields, found;
212
+ int open_flags = O_RDONLY;
213
+
214
+ #ifdef O_CLOEXEC
215
+ open_flags |= O_CLOEXEC;
216
+ #endif
212
217
 
213
218
  snprintf (file, PATH_MAX, "/proc/%d/maps", getpid());
214
219
  fp = fopen (file, "r");
@@ -236,7 +241,7 @@ ffi_tramp_get_libffi (void)
236
241
  if (!found)
237
242
  return 0;
238
243
 
239
- tramp_globals.fd = open (file, O_RDONLY);
244
+ tramp_globals.fd = open (file, open_flags);
240
245
  if (tramp_globals.fd == -1)
241
246
  return 0;
242
247
 
@@ -1,5 +1,5 @@
1
1
  /* -----------------------------------------------------------------------
2
- types.c - Copyright (c) 1996, 1998, 2024 Red Hat, Inc.
2
+ types.c - Copyright (c) 1996, 1998, 2024, 2025 Red Hat, Inc.
3
3
 
4
4
  Predefined ffi_types needed by libffi.
5
5
 
@@ -31,6 +31,28 @@
31
31
  #include <ffi.h>
32
32
  #include <ffi_common.h>
33
33
 
34
+ /* Return a version string. */
35
+ const char *ffi_get_version (void)
36
+ {
37
+ return FFI_VERSION_STRING;
38
+ }
39
+
40
+ /* Return the version as an unsigned long value: (x * 10000 + y * 100 + z) */
41
+ unsigned long ffi_get_version_number (void)
42
+ {
43
+ return FFI_VERSION_NUMBER;
44
+ }
45
+
46
+ unsigned int ffi_get_default_abi (void)
47
+ {
48
+ return FFI_DEFAULT_ABI;
49
+ }
50
+
51
+ size_t ffi_get_closure_size (void)
52
+ {
53
+ return sizeof(ffi_closure);
54
+ }
55
+
34
56
  /* Type definitions */
35
57
 
36
58
  #define FFI_TYPEDEF(name, type, id, maybe_const)\