ffi 1.9.21 → 1.9.22

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of ffi might be problematic. Click here for more details.

Files changed (151) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +3 -0
  3. data.tar.gz.sig +0 -0
  4. data/.gitignore +22 -0
  5. data/.gitmodules +3 -0
  6. data/.travis.yml +52 -0
  7. data/.yardopts +5 -0
  8. data/Gemfile +15 -0
  9. data/{spec/ffi/LICENSE.SPECS → LICENSE.SPECS} +1 -1
  10. data/README.md +1 -1
  11. data/Rakefile +28 -3
  12. data/appveyor.yml +22 -0
  13. data/ext/ffi_c/Call.c +1 -22
  14. data/ext/ffi_c/Call.h +0 -9
  15. data/ext/ffi_c/Closure.c +54 -0
  16. data/ext/ffi_c/{ClosurePool.h → Closure.h} +13 -23
  17. data/ext/ffi_c/Function.c +16 -25
  18. data/ext/ffi_c/Function.h +1 -2
  19. data/ext/ffi_c/FunctionInfo.c +0 -4
  20. data/ext/ffi_c/MethodHandle.c +33 -268
  21. data/ext/ffi_c/extconf.rb +3 -3
  22. data/ext/ffi_c/ffi.c +2 -2
  23. data/ext/ffi_c/libffi.bsd.mk +3 -3
  24. data/ext/ffi_c/libffi.darwin.mk +1 -1
  25. data/ext/ffi_c/libffi.gnu.mk +1 -1
  26. data/ext/ffi_c/libffi.mk +2 -2
  27. data/ext/ffi_c/libffi.vc.mk +1 -1
  28. data/ext/ffi_c/libffi.vc64.mk +1 -1
  29. data/ext/ffi_c/libffi/.appveyor.yml +48 -0
  30. data/ext/ffi_c/libffi/.gitignore +36 -0
  31. data/ext/ffi_c/libffi/.travis.yml +30 -0
  32. data/ext/ffi_c/libffi/.travis/install.sh +14 -0
  33. data/ext/ffi_c/libffi/Makefile.am +5 -3
  34. data/ext/ffi_c/libffi/acinclude.m4 +6 -0
  35. data/ext/ffi_c/libffi/autogen.sh +1 -1
  36. data/ext/ffi_c/libffi/config.guess +1466 -0
  37. data/ext/ffi_c/libffi/config.sub +1836 -0
  38. data/ext/ffi_c/libffi/configure.ac +2 -2
  39. data/ext/ffi_c/libffi/configure.host +15 -3
  40. data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +11 -15
  41. data/ext/ffi_c/libffi/include/ffi.h.in +6 -1
  42. data/ext/ffi_c/libffi/libffi.xcodeproj/project.pbxproj +465 -59
  43. data/ext/ffi_c/libffi/src/aarch64/ffi.c +33 -10
  44. data/ext/ffi_c/libffi/src/aarch64/sysv.S +2 -2
  45. data/ext/ffi_c/libffi/src/arm/ffi.c +12 -1
  46. data/ext/ffi_c/libffi/src/arm/sysv.S +1 -1
  47. data/ext/ffi_c/libffi/src/closures.c +143 -97
  48. data/ext/ffi_c/libffi/src/ia64/unix.S +2 -0
  49. data/ext/ffi_c/libffi/src/mips/ffi.c +8 -0
  50. data/ext/ffi_c/libffi/src/mips/ffitarget.h +1 -1
  51. data/ext/ffi_c/libffi/src/mips/n32.S +2 -0
  52. data/ext/ffi_c/libffi/src/powerpc/aix.S +239 -1
  53. data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +250 -3
  54. data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +86 -5
  55. data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +3 -0
  56. data/ext/ffi_c/libffi/src/x86/ffi.c +3 -1
  57. data/ext/ffi_c/libffi/src/x86/ffi64.c +26 -5
  58. data/ext/ffi_c/libffi/src/x86/sysv.S +2 -2
  59. data/ext/ffi_c/libffi/src/x86/unix64.S +1 -1
  60. data/ext/ffi_c/libffi/src/x86/win64.S +1 -1
  61. data/ext/ffi_c/libffi/testsuite/Makefile.am +2 -1
  62. data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +2 -1
  63. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3float.c +95 -0
  64. data/ffi.gemspec +14 -1
  65. data/lib/ffi/library.rb +1 -1
  66. data/lib/ffi/version.rb +1 -1
  67. data/samples/getlogin.rb +8 -0
  68. data/samples/getpid.rb +8 -0
  69. data/samples/gettimeofday.rb +18 -0
  70. data/samples/hello.rb +7 -0
  71. data/samples/inotify.rb +60 -0
  72. data/samples/pty.rb +76 -0
  73. data/samples/qsort.rb +21 -0
  74. data/samples/sample_helper.rb +6 -0
  75. metadata +59 -81
  76. metadata.gz.sig +0 -0
  77. data/ext/ffi_c/ClosurePool.c +0 -283
  78. data/gen/Rakefile +0 -30
  79. data/libtest/Benchmark.c +0 -52
  80. data/libtest/BoolTest.c +0 -34
  81. data/libtest/BufferTest.c +0 -31
  82. data/libtest/ClosureTest.c +0 -205
  83. data/libtest/EnumTest.c +0 -51
  84. data/libtest/FunctionTest.c +0 -70
  85. data/libtest/GNUmakefile +0 -149
  86. data/libtest/GlobalVariable.c +0 -62
  87. data/libtest/LastErrorTest.c +0 -21
  88. data/libtest/NumberTest.c +0 -132
  89. data/libtest/PointerTest.c +0 -63
  90. data/libtest/ReferenceTest.c +0 -23
  91. data/libtest/StringTest.c +0 -34
  92. data/libtest/StructTest.c +0 -243
  93. data/libtest/UnionTest.c +0 -43
  94. data/libtest/VariadicTest.c +0 -99
  95. data/spec/ffi/async_callback_spec.rb +0 -35
  96. data/spec/ffi/bitmask_spec.rb +0 -575
  97. data/spec/ffi/bool_spec.rb +0 -32
  98. data/spec/ffi/buffer_spec.rb +0 -279
  99. data/spec/ffi/callback_spec.rb +0 -773
  100. data/spec/ffi/custom_param_type.rb +0 -37
  101. data/spec/ffi/custom_type_spec.rb +0 -74
  102. data/spec/ffi/dup_spec.rb +0 -52
  103. data/spec/ffi/enum_spec.rb +0 -423
  104. data/spec/ffi/errno_spec.rb +0 -20
  105. data/spec/ffi/ffi_spec.rb +0 -28
  106. data/spec/ffi/fixtures/Benchmark.c +0 -52
  107. data/spec/ffi/fixtures/BitmaskTest.c +0 -51
  108. data/spec/ffi/fixtures/BoolTest.c +0 -34
  109. data/spec/ffi/fixtures/BufferTest.c +0 -31
  110. data/spec/ffi/fixtures/ClosureTest.c +0 -205
  111. data/spec/ffi/fixtures/EnumTest.c +0 -51
  112. data/spec/ffi/fixtures/FunctionTest.c +0 -142
  113. data/spec/ffi/fixtures/GNUmakefile +0 -149
  114. data/spec/ffi/fixtures/GlobalVariable.c +0 -62
  115. data/spec/ffi/fixtures/LastErrorTest.c +0 -21
  116. data/spec/ffi/fixtures/NumberTest.c +0 -132
  117. data/spec/ffi/fixtures/PipeHelper.h +0 -21
  118. data/spec/ffi/fixtures/PipeHelperPosix.c +0 -41
  119. data/spec/ffi/fixtures/PipeHelperWindows.c +0 -72
  120. data/spec/ffi/fixtures/PointerTest.c +0 -63
  121. data/spec/ffi/fixtures/ReferenceTest.c +0 -23
  122. data/spec/ffi/fixtures/StringTest.c +0 -34
  123. data/spec/ffi/fixtures/StructTest.c +0 -243
  124. data/spec/ffi/fixtures/UnionTest.c +0 -43
  125. data/spec/ffi/fixtures/VariadicTest.c +0 -99
  126. data/spec/ffi/fixtures/classes.rb +0 -438
  127. data/spec/ffi/function_spec.rb +0 -97
  128. data/spec/ffi/io_spec.rb +0 -16
  129. data/spec/ffi/library_spec.rb +0 -286
  130. data/spec/ffi/long_double.rb +0 -30
  131. data/spec/ffi/managed_struct_spec.rb +0 -68
  132. data/spec/ffi/memorypointer_spec.rb +0 -78
  133. data/spec/ffi/number_spec.rb +0 -247
  134. data/spec/ffi/platform_spec.rb +0 -114
  135. data/spec/ffi/pointer_spec.rb +0 -285
  136. data/spec/ffi/rbx/attach_function_spec.rb +0 -34
  137. data/spec/ffi/rbx/memory_pointer_spec.rb +0 -198
  138. data/spec/ffi/rbx/spec_helper.rb +0 -6
  139. data/spec/ffi/rbx/struct_spec.rb +0 -18
  140. data/spec/ffi/spec_helper.rb +0 -93
  141. data/spec/ffi/string_spec.rb +0 -118
  142. data/spec/ffi/strptr_spec.rb +0 -50
  143. data/spec/ffi/struct_by_ref_spec.rb +0 -43
  144. data/spec/ffi/struct_callback_spec.rb +0 -69
  145. data/spec/ffi/struct_initialize_spec.rb +0 -35
  146. data/spec/ffi/struct_packed_spec.rb +0 -50
  147. data/spec/ffi/struct_spec.rb +0 -882
  148. data/spec/ffi/typedef_spec.rb +0 -91
  149. data/spec/ffi/union_spec.rb +0 -67
  150. data/spec/ffi/variadic_spec.rb +0 -132
  151. data/spec/spec.opts +0 -4
@@ -33,6 +33,7 @@
33
33
  #include <stdlib.h>
34
34
 
35
35
  extern void ffi_closure_ASM (void);
36
+ extern void ffi_go_closure_ASM (void);
36
37
 
37
38
  enum {
38
39
  /* The assembly depends on these exact flags.
@@ -908,6 +909,9 @@ ffi_prep_cif_machdep (ffi_cif *cif)
908
909
  extern void ffi_call_AIX(extended_cif *, long, unsigned, unsigned *,
909
910
  void (*fn)(void), void (*fn2)(void));
910
911
 
912
+ extern void ffi_call_go_AIX(extended_cif *, long, unsigned, unsigned *,
913
+ void (*fn)(void), void (*fn2)(void), void *closure);
914
+
911
915
  extern void ffi_call_DARWIN(extended_cif *, long, unsigned, unsigned *,
912
916
  void (*fn)(void), void (*fn2)(void), ffi_type*);
913
917
 
@@ -946,6 +950,38 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
946
950
  }
947
951
  }
948
952
 
953
+ void
954
+ ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue,
955
+ void *closure)
956
+ {
957
+ extended_cif ecif;
958
+
959
+ ecif.cif = cif;
960
+ ecif.avalue = avalue;
961
+
962
+ /* If the return value is a struct and we don't have a return
963
+ value address then we need to make one. */
964
+
965
+ if ((rvalue == NULL) &&
966
+ (cif->rtype->type == FFI_TYPE_STRUCT))
967
+ {
968
+ ecif.rvalue = alloca (cif->rtype->size);
969
+ }
970
+ else
971
+ ecif.rvalue = rvalue;
972
+
973
+ switch (cif->abi)
974
+ {
975
+ case FFI_AIX:
976
+ ffi_call_go_AIX(&ecif, -(long)cif->bytes, cif->flags, ecif.rvalue, fn,
977
+ FFI_FN(ffi_prep_args), closure);
978
+ break;
979
+ default:
980
+ FFI_ASSERT(0);
981
+ break;
982
+ }
983
+ }
984
+
949
985
  static void flush_icache(char *);
950
986
  static void flush_range(char *, int);
951
987
 
@@ -1074,6 +1110,30 @@ ffi_prep_closure_loc (ffi_closure* closure,
1074
1110
  return FFI_OK;
1075
1111
  }
1076
1112
 
1113
+ ffi_status
1114
+ ffi_prep_go_closure (ffi_go_closure* closure,
1115
+ ffi_cif* cif,
1116
+ void (*fun)(ffi_cif*, void*, void**, void*))
1117
+ {
1118
+ switch (cif->abi)
1119
+ {
1120
+ case FFI_AIX:
1121
+
1122
+ FFI_ASSERT (cif->abi == FFI_AIX);
1123
+
1124
+ closure->tramp = (void *)ffi_go_closure_ASM;
1125
+ closure->cif = cif;
1126
+ closure->fun = fun;
1127
+ return FFI_OK;
1128
+
1129
+ // For now, ffi_prep_go_closure is only implemented for AIX, not for Darwin
1130
+ default:
1131
+ return FFI_BAD_ABI;
1132
+ break;
1133
+ }
1134
+ return FFI_OK;
1135
+ }
1136
+
1077
1137
  static void
1078
1138
  flush_icache(char *addr)
1079
1139
  {
@@ -1108,6 +1168,10 @@ ffi_type *
1108
1168
  ffi_closure_helper_DARWIN (ffi_closure *, void *,
1109
1169
  unsigned long *, ffi_dblfl *);
1110
1170
 
1171
+ ffi_type *
1172
+ ffi_go_closure_helper_DARWIN (ffi_go_closure*, void *,
1173
+ unsigned long *, ffi_dblfl *);
1174
+
1111
1175
  /* Basically the trampoline invokes ffi_closure_ASM, and on
1112
1176
  entry, r11 holds the address of the closure.
1113
1177
  After storing the registers that could possibly contain
@@ -1115,8 +1179,10 @@ ffi_closure_helper_DARWIN (ffi_closure *, void *,
1115
1179
  up space for a return value, ffi_closure_ASM invokes the
1116
1180
  following helper function to do most of the work. */
1117
1181
 
1118
- ffi_type *
1119
- ffi_closure_helper_DARWIN (ffi_closure *closure, void *rvalue,
1182
+ static ffi_type *
1183
+ ffi_closure_helper_common (ffi_cif* cif,
1184
+ void (*fun)(ffi_cif*, void*, void**, void*),
1185
+ void *user_data, void *rvalue,
1120
1186
  unsigned long *pgr, ffi_dblfl *pfr)
1121
1187
  {
1122
1188
  /* rvalue is the pointer to space for return value in closure assembly
@@ -1134,14 +1200,12 @@ ffi_closure_helper_DARWIN (ffi_closure *closure, void *rvalue,
1134
1200
  void ** avalue;
1135
1201
  ffi_type ** arg_types;
1136
1202
  long i, avn;
1137
- ffi_cif * cif;
1138
1203
  ffi_dblfl * end_pfr = pfr + NUM_FPR_ARG_REGISTERS;
1139
1204
  unsigned size_al;
1140
1205
  #if defined(POWERPC_DARWIN64)
1141
1206
  unsigned fpsused = 0;
1142
1207
  #endif
1143
1208
 
1144
- cif = closure->cif;
1145
1209
  avalue = alloca (cif->nargs * sizeof(void *));
1146
1210
 
1147
1211
  if (cif->rtype->type == FFI_TYPE_STRUCT)
@@ -1352,8 +1416,25 @@ ffi_closure_helper_DARWIN (ffi_closure *closure, void *rvalue,
1352
1416
  i++;
1353
1417
  }
1354
1418
 
1355
- (closure->fun) (cif, rvalue, avalue, closure->user_data);
1419
+ (fun) (cif, rvalue, avalue, user_data);
1356
1420
 
1357
1421
  /* Tell ffi_closure_ASM to perform return type promotions. */
1358
1422
  return cif->rtype;
1359
1423
  }
1424
+
1425
+ ffi_type *
1426
+ ffi_closure_helper_DARWIN (ffi_closure *closure, void *rvalue,
1427
+ unsigned long *pgr, ffi_dblfl *pfr)
1428
+ {
1429
+ return ffi_closure_helper_common (closure->cif, closure->fun,
1430
+ closure->user_data, rvalue, pgr, pfr);
1431
+ }
1432
+
1433
+ ffi_type *
1434
+ ffi_go_closure_helper_DARWIN (ffi_go_closure *closure, void *rvalue,
1435
+ unsigned long *pgr, ffi_dblfl *pfr)
1436
+ {
1437
+ return ffi_closure_helper_common (closure->cif, closure->fun,
1438
+ closure, rvalue, pgr, pfr);
1439
+ }
1440
+
@@ -142,6 +142,9 @@ typedef enum ffi_abi {
142
142
  # define FFI_TARGET_SPECIFIC_VARIADIC 1
143
143
  # define FFI_EXTRA_CIF_FIELDS unsigned nfixedargs
144
144
  #endif
145
+ #if defined (POWERPC_AIX)
146
+ # define FFI_GO_CLOSURES 1
147
+ #endif
145
148
 
146
149
  /* ppc_closure.S and linux64_closure.S expect this. */
147
150
  #define FFI_PPC_TYPE_LAST FFI_TYPE_POINTER
@@ -32,6 +32,7 @@
32
32
  #ifndef __x86_64__
33
33
  #include <ffi.h>
34
34
  #include <ffi_common.h>
35
+ #include <stdint.h>
35
36
  #include <stdlib.h>
36
37
  #include "internal.h"
37
38
 
@@ -674,7 +675,8 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *avalue)
674
675
  }
675
676
 
676
677
  bytes = cif->bytes;
677
- argp = stack = alloca(bytes + sizeof(*frame) + rsize);
678
+ argp = stack =
679
+ (void *)((uintptr_t)alloca(bytes + sizeof(*frame) + rsize + 15) & ~16);
678
680
  frame = (struct call_frame *)(stack + bytes);
679
681
  if (rsize)
680
682
  rvalue = frame + 1;
@@ -389,19 +389,24 @@ examine_argument (ffi_type *type, enum x86_64_reg_class classes[MAX_CLASSES],
389
389
 
390
390
  /* Perform machine dependent cif processing. */
391
391
 
392
+ #ifndef __ILP32__
392
393
  extern ffi_status
393
394
  ffi_prep_cif_machdep_efi64(ffi_cif *cif);
395
+ #endif
394
396
 
395
397
  ffi_status
396
398
  ffi_prep_cif_machdep (ffi_cif *cif)
397
399
  {
398
- int gprcount, ssecount, i, avn, ngpr, nsse, flags;
400
+ int gprcount, ssecount, i, avn, ngpr, nsse;
401
+ unsigned flags;
399
402
  enum x86_64_reg_class classes[MAX_CLASSES];
400
403
  size_t bytes, n, rtype_size;
401
404
  ffi_type *rtype;
402
405
 
406
+ #ifndef __ILP32__
403
407
  if (cif->abi == FFI_EFI64)
404
408
  return ffi_prep_cif_machdep_efi64(cif);
409
+ #endif
405
410
  if (cif->abi != FFI_UNIX64)
406
411
  return FFI_BAD_ABI;
407
412
 
@@ -494,7 +499,7 @@ ffi_prep_cif_machdep (ffi_cif *cif)
494
499
  case FFI_TYPE_SINT32:
495
500
  case FFI_TYPE_UINT64:
496
501
  case FFI_TYPE_SINT64:
497
- flags = UNIX64_RET_ST_RAX_RDX | (rtype_size << UNIX64_SIZE_SHIFT);
502
+ flags = UNIX64_RET_ST_RAX_RDX | ((unsigned) rtype_size << UNIX64_SIZE_SHIFT);
498
503
  break;
499
504
  case FFI_TYPE_FLOAT:
500
505
  flags = UNIX64_RET_XMM64;
@@ -542,7 +547,7 @@ ffi_prep_cif_machdep (ffi_cif *cif)
542
547
  flags |= UNIX64_FLAG_XMM_ARGS;
543
548
 
544
549
  cif->flags = flags;
545
- cif->bytes = FFI_ALIGN (bytes, 8);
550
+ cif->bytes = (unsigned) FFI_ALIGN (bytes, 8);
546
551
 
547
552
  return FFI_OK;
548
553
  }
@@ -646,10 +651,10 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
646
651
  break;
647
652
  case X86_64_SSE_CLASS:
648
653
  case X86_64_SSEDF_CLASS:
649
- reg_args->sse[ssecount++].i64 = *(UINT64 *) a;
654
+ memcpy (&reg_args->sse[ssecount++].i64, a, sizeof(UINT64));
650
655
  break;
651
656
  case X86_64_SSESF_CLASS:
652
- reg_args->sse[ssecount++].i32 = *(UINT32 *) a;
657
+ memcpy (&reg_args->sse[ssecount++].i32, a, sizeof(UINT32));
653
658
  break;
654
659
  default:
655
660
  abort();
@@ -663,27 +668,35 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
663
668
  flags, rvalue, fn);
664
669
  }
665
670
 
671
+ #ifndef __ILP32__
666
672
  extern void
667
673
  ffi_call_efi64(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue);
674
+ #endif
668
675
 
669
676
  void
670
677
  ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
671
678
  {
679
+ #ifndef __ILP32__
672
680
  if (cif->abi == FFI_EFI64)
673
681
  return ffi_call_efi64(cif, fn, rvalue, avalue);
682
+ #endif
674
683
  ffi_call_int (cif, fn, rvalue, avalue, NULL);
675
684
  }
676
685
 
686
+ #ifndef __ILP32__
677
687
  extern void
678
688
  ffi_call_go_efi64(ffi_cif *cif, void (*fn)(void), void *rvalue,
679
689
  void **avalue, void *closure);
690
+ #endif
680
691
 
681
692
  void
682
693
  ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
683
694
  void **avalue, void *closure)
684
695
  {
696
+ #ifndef __ILP32__
685
697
  if (cif->abi == FFI_EFI64)
686
698
  ffi_call_go_efi64(cif, fn, rvalue, avalue, closure);
699
+ #endif
687
700
  ffi_call_int (cif, fn, rvalue, avalue, closure);
688
701
  }
689
702
 
@@ -691,12 +704,14 @@ ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
691
704
  extern void ffi_closure_unix64(void) FFI_HIDDEN;
692
705
  extern void ffi_closure_unix64_sse(void) FFI_HIDDEN;
693
706
 
707
+ #ifndef __ILP32__
694
708
  extern ffi_status
695
709
  ffi_prep_closure_loc_efi64(ffi_closure* closure,
696
710
  ffi_cif* cif,
697
711
  void (*fun)(ffi_cif*, void*, void**, void*),
698
712
  void *user_data,
699
713
  void *codeloc);
714
+ #endif
700
715
 
701
716
  ffi_status
702
717
  ffi_prep_closure_loc (ffi_closure* closure,
@@ -716,8 +731,10 @@ ffi_prep_closure_loc (ffi_closure* closure,
716
731
  void (*dest)(void);
717
732
  char *tramp = closure->tramp;
718
733
 
734
+ #ifndef __ILP32__
719
735
  if (cif->abi == FFI_EFI64)
720
736
  return ffi_prep_closure_loc_efi64(closure, cif, fun, user_data, codeloc);
737
+ #endif
721
738
  if (cif->abi != FFI_UNIX64)
722
739
  return FFI_BAD_ABI;
723
740
 
@@ -832,16 +849,20 @@ ffi_closure_unix64_inner(ffi_cif *cif,
832
849
  extern void ffi_go_closure_unix64(void) FFI_HIDDEN;
833
850
  extern void ffi_go_closure_unix64_sse(void) FFI_HIDDEN;
834
851
 
852
+ #ifndef __ILP32__
835
853
  extern ffi_status
836
854
  ffi_prep_go_closure_efi64(ffi_go_closure* closure, ffi_cif* cif,
837
855
  void (*fun)(ffi_cif*, void*, void**, void*));
856
+ #endif
838
857
 
839
858
  ffi_status
840
859
  ffi_prep_go_closure (ffi_go_closure* closure, ffi_cif* cif,
841
860
  void (*fun)(ffi_cif*, void*, void**, void*))
842
861
  {
862
+ #ifndef __ILP32__
843
863
  if (cif->abi == FFI_EFI64)
844
864
  return ffi_prep_go_closure_efi64(closure, cif, fun);
865
+ #endif
845
866
  if (cif->abi != FFI_UNIX64)
846
867
  return FFI_BAD_ABI;
847
868
 
@@ -274,7 +274,7 @@ L(C1(pc,N)): \
274
274
  # define FFI_CLOSURE_CALL_INNER(UWN) \
275
275
  movl %ebx, 40(%esp); /* save ebx */ \
276
276
  L(C1(UW,UWN)): \
277
- # cfi_rel_offset(%ebx, 40); \
277
+ /* cfi_rel_offset(%ebx, 40); */ \
278
278
  call C(__x86.get_pc_thunk.bx); /* load got register */ \
279
279
  addl $C(_GLOBAL_OFFSET_TABLE_), %ebx; \
280
280
  call ffi_closure_inner@PLT
@@ -284,7 +284,7 @@ L(C1(UW,UWN)): \
284
284
  leal L(C1(load_table,N))@GOTOFF(%ebx, %eax, 8), %edx; \
285
285
  movl 40(%esp), %ebx; /* restore ebx */ \
286
286
  L(C1(UW,UWN)): \
287
- # cfi_restore(%ebx); \
287
+ /* cfi_restore(%ebx); */ \
288
288
  movl closure_CF(%esp), %eax; /* optimiztic load */ \
289
289
  jmp *%edx
290
290
  # endif /* DARWIN || HIDDEN */
@@ -274,7 +274,7 @@ L(do_closure):
274
274
  leaq ffi_closure_OFS_RVALUE(%rsp), %rcx /* Load rvalue */
275
275
  movq %rsp, %r8 /* Load reg_args */
276
276
  leaq ffi_closure_FS+8(%rsp), %r9 /* Load argp */
277
- call C(ffi_closure_unix64_inner)
277
+ call PLT(C(ffi_closure_unix64_inner))
278
278
 
279
279
  /* Deallocate stack frame early; return value is now in redzone. */
280
280
  addq $ffi_closure_FS, %rsp
@@ -214,7 +214,7 @@ C(ffi_closure_win64):
214
214
  movsd %xmm3, ffi_clo_OFF_X+24(%rsp)
215
215
 
216
216
  leaq ffi_clo_OFF_R(%rsp), %r9
217
- call C(ffi_closure_win64_inner)
217
+ call PLT(C(ffi_closure_win64_inner))
218
218
 
219
219
  /* Load the result into both possible result registers. */
220
220
  movq ffi_clo_OFF_R(%rsp), %rax
@@ -82,4 +82,5 @@ libffi.call/va_1.c libffi.call/va_struct1.c libffi.call/va_struct2.c \
82
82
  libffi.call/va_struct3.c \
83
83
  libffi.call/strlen2.c \
84
84
  libffi.call/strlen3.c \
85
- libffi.call/strlen4.c
85
+ libffi.call/strlen4.c \
86
+ libffi.call/cls_3float.c
@@ -324,7 +324,8 @@ proc run-many-tests { testcases extra_flags } {
324
324
  "-DABI_NUM=FFI_THISCALL -DABI_ATTR=__THISCALL__"
325
325
  "-DABI_NUM=FFI_FASTCALL -DABI_ATTR=__FASTCALL__"
326
326
  }
327
- } elseif [istarget "x86_64-*-*"] {
327
+ } elseif { [istarget "x86_64-*-*"] \
328
+ && [libffi_feature_test "#ifndef __ILP32__"] } {
328
329
  set targetabis {
329
330
  ""
330
331
  "-DABI_NUM=FFI_WIN64 -DABI_ATTR=__MSABI__"
@@ -0,0 +1,95 @@
1
+ /* Area: ffi_call, closure_call
2
+ Purpose: Check structure passing with different structure size.
3
+ Depending on the ABI. Check overlapping.
4
+ Limitations:>none.
5
+ PR: none.
6
+ Originator: <compnerd@compnerd.org> 20171026 */
7
+
8
+ /* { dg-do run } */
9
+
10
+ #include "ffitest.h"
11
+
12
+ typedef struct cls_struct_3float {
13
+ float f;
14
+ float g;
15
+ float h;
16
+ } cls_struct_3float;
17
+
18
+ cls_struct_3float cls_struct_3float_fn(struct cls_struct_3float a1,
19
+ struct cls_struct_3float a2)
20
+ {
21
+ struct cls_struct_3float result;
22
+
23
+ result.f = a1.f + a2.f;
24
+ result.g = a1.g + a2.g;
25
+ result.h = a1.h + a2.h;
26
+
27
+ printf("%g %g %g %g %g %g: %g %g %g\n", a1.f, a1.g, a1.h,
28
+ a2.f, a2.g, a2.h, result.f, result.g, result.h);
29
+
30
+ return result;
31
+ }
32
+
33
+ static void
34
+ cls_struct_3float_gn(ffi_cif *cif __UNUSED__, void* resp, void **args,
35
+ void* userdata __UNUSED__)
36
+ {
37
+ struct cls_struct_3float a1, a2;
38
+
39
+ a1 = *(struct cls_struct_3float*)(args[0]);
40
+ a2 = *(struct cls_struct_3float*)(args[1]);
41
+
42
+ *(cls_struct_3float*)resp = cls_struct_3float_fn(a1, a2);
43
+ }
44
+
45
+ int main (void)
46
+ {
47
+ ffi_cif cif;
48
+ void *code;
49
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
50
+ void *args_dbl[3];
51
+ ffi_type* cls_struct_fields[4];
52
+ ffi_type cls_struct_type;
53
+ ffi_type* dbl_arg_types[3];
54
+
55
+ struct cls_struct_3float g_dbl = { 1.0f, 2.0f, 3.0f };
56
+ struct cls_struct_3float f_dbl = { 1.0f, 2.0f, 3.0f };
57
+ struct cls_struct_3float res_dbl;
58
+
59
+ cls_struct_fields[0] = &ffi_type_float;
60
+ cls_struct_fields[1] = &ffi_type_float;
61
+ cls_struct_fields[2] = &ffi_type_float;
62
+ cls_struct_fields[3] = NULL;
63
+
64
+ cls_struct_type.size = 0;
65
+ cls_struct_type.alignment = 0;
66
+ cls_struct_type.type = FFI_TYPE_STRUCT;
67
+ cls_struct_type.elements = cls_struct_fields;
68
+
69
+ dbl_arg_types[0] = &cls_struct_type;
70
+ dbl_arg_types[1] = &cls_struct_type;
71
+ dbl_arg_types[2] = NULL;
72
+
73
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
74
+ dbl_arg_types) == FFI_OK);
75
+
76
+ args_dbl[0] = &g_dbl;
77
+ args_dbl[1] = &f_dbl;
78
+ args_dbl[2] = NULL;
79
+
80
+ ffi_call(&cif, FFI_FN(cls_struct_3float_fn), &res_dbl, args_dbl);
81
+ /* { dg-output "1 2 3 1 2 3: 2 4 6" } */
82
+ printf("res: %g %g %g\n", res_dbl.f, res_dbl.g, res_dbl.h);
83
+ /* { dg-output "\nres: 2 4 6" } */
84
+
85
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_3float_gn, NULL, code) ==
86
+ FFI_OK);
87
+
88
+ res_dbl = ((cls_struct_3float(*)(cls_struct_3float,
89
+ cls_struct_3float))(code))(g_dbl, f_dbl);
90
+ /* { dg-output "\n1 2 3 1 2 3: 2 4 6" } */
91
+ printf("res: %g %g %g\n", res_dbl.f, res_dbl.g, res_dbl.h);
92
+ /* { dg-output "\nres: 2 4 6" } */
93
+
94
+ exit(0);
95
+ }