ffi 1.11.1 → 1.11.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/{appveyor.yml → .appveyor.yml} +1 -1
  3. data/.gitmodules +2 -2
  4. data/CHANGELOG.md +16 -0
  5. data/Rakefile +1 -0
  6. data/ext/ffi_c/Call.c +3 -3
  7. data/ext/ffi_c/Call.h +2 -2
  8. data/ext/ffi_c/Function.c +4 -4
  9. data/ext/ffi_c/LongDouble.c +7 -7
  10. data/ext/ffi_c/libffi.darwin.mk +1 -1
  11. data/ext/ffi_c/libffi/.appveyor.yml +29 -13
  12. data/ext/ffi_c/libffi/.gitattributes +4 -0
  13. data/ext/ffi_c/libffi/.travis.yml +31 -2
  14. data/ext/ffi_c/libffi/.travis/build-in-container.sh +22 -0
  15. data/ext/ffi_c/libffi/.travis/build.sh +83 -7
  16. data/ext/ffi_c/libffi/.travis/install.sh +32 -11
  17. data/ext/ffi_c/libffi/LICENSE +1 -1
  18. data/ext/ffi_c/libffi/LICENSE-BUILDTOOLS +5 -4
  19. data/ext/ffi_c/libffi/Makefile.am +30 -38
  20. data/ext/ffi_c/libffi/README.md +15 -6
  21. data/ext/ffi_c/libffi/configure.ac +1 -1
  22. data/ext/ffi_c/libffi/configure.host +21 -7
  23. data/ext/ffi_c/libffi/include/ffi.h.in +4 -0
  24. data/ext/ffi_c/libffi/include/ffi_common.h +4 -0
  25. data/ext/ffi_c/libffi/m4/asmcfi.m4 +1 -1
  26. data/ext/ffi_c/libffi/make_sunver.pl +333 -0
  27. data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.sln +33 -0
  28. data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.vcxproj +130 -0
  29. data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.vcxproj.filters +57 -0
  30. data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.vcxproj.user +4 -0
  31. data/ext/ffi_c/libffi/msvc_build/aarch64/aarch64_include/ffi.h +511 -0
  32. data/ext/ffi_c/libffi/msvcc.sh +27 -2
  33. data/ext/ffi_c/libffi/src/aarch64/ffi.c +124 -56
  34. data/ext/ffi_c/libffi/src/aarch64/ffitarget.h +13 -2
  35. data/ext/ffi_c/libffi/src/aarch64/sysv.S +8 -6
  36. data/ext/ffi_c/libffi/src/aarch64/win64_armasm.S +506 -0
  37. data/ext/ffi_c/libffi/src/arm/ffi.c +40 -5
  38. data/ext/ffi_c/libffi/src/arm/ffitarget.h +8 -1
  39. data/ext/ffi_c/libffi/src/arm/sysv.S +2 -0
  40. data/ext/ffi_c/libffi/src/arm/sysv_msvc_arm32.S +311 -0
  41. data/ext/ffi_c/libffi/src/closures.c +32 -8
  42. data/ext/ffi_c/libffi/src/pa/linux.S +23 -2
  43. data/ext/ffi_c/libffi/src/powerpc/ffi.c +3 -2
  44. data/ext/ffi_c/libffi/src/powerpc/ffi_linux64.c +58 -25
  45. data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +1 -1
  46. data/ext/ffi_c/libffi/src/prep_cif.c +4 -2
  47. data/ext/ffi_c/libffi/src/x86/ffi.c +13 -6
  48. data/ext/ffi_c/libffi/src/x86/ffi64.c +5 -3
  49. data/ext/ffi_c/libffi/src/x86/ffiw64.c +6 -3
  50. data/ext/ffi_c/libffi/src/x86/sysv.S +2 -2
  51. data/ext/ffi_c/libffi/src/x86/sysv_intel.S +995 -0
  52. data/ext/ffi_c/libffi/src/x86/win64.S +5 -0
  53. data/ext/ffi_c/libffi/testsuite/Makefile.am +111 -109
  54. data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +26 -5
  55. data/ext/ffi_c/libffi/testsuite/libffi.call/float2.c +9 -8
  56. data/ext/ffi_c/libffi/testsuite/libffi.call/va_1.c +1 -1
  57. data/ffi.gemspec +1 -1
  58. data/lib/ffi/library.rb +5 -5
  59. data/lib/ffi/platform.rb +4 -1
  60. data/lib/ffi/platform/aarch64-freebsd/types.conf +89 -89
  61. data/lib/ffi/platform/aarch64-freebsd12/types.conf +89 -89
  62. data/lib/ffi/platform/aarch64-linux/types.conf +81 -81
  63. data/lib/ffi/platform/arm-freebsd/types.conf +87 -87
  64. data/lib/ffi/platform/arm-freebsd12/types.conf +87 -87
  65. data/lib/ffi/platform/arm-linux/types.conf +79 -79
  66. data/lib/ffi/platform/i386-cygwin/types.conf +1 -1
  67. data/lib/ffi/platform/i386-darwin/types.conf +63 -63
  68. data/lib/ffi/platform/i386-freebsd/types.conf +87 -87
  69. data/lib/ffi/platform/i386-freebsd12/types.conf +87 -87
  70. data/lib/ffi/platform/i386-gnu/types.conf +84 -84
  71. data/lib/ffi/platform/i386-linux/types.conf +77 -77
  72. data/lib/ffi/platform/i386-netbsd/types.conf +87 -87
  73. data/lib/ffi/platform/i386-openbsd/types.conf +89 -89
  74. data/lib/ffi/platform/i386-solaris/types.conf +96 -96
  75. data/lib/ffi/platform/i386-windows/types.conf +84 -84
  76. data/lib/ffi/platform/ia64-linux/types.conf +79 -79
  77. data/lib/ffi/platform/mips-linux/types.conf +79 -79
  78. data/lib/ffi/platform/mips64-linux/types.conf +81 -81
  79. data/lib/ffi/platform/mips64el-linux/types.conf +81 -81
  80. data/lib/ffi/platform/mipsel-linux/types.conf +79 -79
  81. data/lib/ffi/platform/mipsisa32r6-linux/types.conf +79 -79
  82. data/lib/ffi/platform/mipsisa32r6el-linux/types.conf +79 -79
  83. data/lib/ffi/platform/mipsisa64r6-linux/types.conf +81 -81
  84. data/lib/ffi/platform/mipsisa64r6el-linux/types.conf +81 -81
  85. data/lib/ffi/platform/powerpc-aix/types.conf +155 -155
  86. data/lib/ffi/platform/powerpc-darwin/types.conf +63 -63
  87. data/lib/ffi/platform/powerpc-linux/types.conf +77 -77
  88. data/lib/ffi/platform/powerpc64-linux/types.conf +81 -81
  89. data/lib/ffi/platform/s390-linux/types.conf +79 -79
  90. data/lib/ffi/platform/s390x-linux/types.conf +79 -79
  91. data/lib/ffi/platform/sparc-linux/types.conf +79 -79
  92. data/lib/ffi/platform/sparc-solaris/types.conf +103 -103
  93. data/lib/ffi/platform/sparc64-linux/types.conf +79 -79
  94. data/lib/ffi/platform/sparcv9-solaris/types.conf +103 -103
  95. data/lib/ffi/platform/x86_64-cygwin/types.conf +1 -1
  96. data/lib/ffi/platform/x86_64-darwin/types.conf +84 -84
  97. data/lib/ffi/platform/x86_64-dragonflybsd/types.conf +148 -0
  98. data/lib/ffi/platform/x86_64-freebsd/types.conf +89 -89
  99. data/lib/ffi/platform/x86_64-freebsd12/types.conf +139 -109
  100. data/lib/ffi/platform/x86_64-linux/types.conf +86 -77
  101. data/lib/ffi/platform/x86_64-netbsd/types.conf +89 -89
  102. data/lib/ffi/platform/x86_64-openbsd/types.conf +86 -86
  103. data/lib/ffi/platform/x86_64-solaris/types.conf +96 -96
  104. data/lib/ffi/platform/x86_64-windows/types.conf +99 -99
  105. data/lib/ffi/tools/types_generator.rb +5 -4
  106. data/lib/ffi/version.rb +1 -1
  107. metadata +19 -5
@@ -122,7 +122,7 @@ ffi_closure_free (void *ptr)
122
122
  # define FFI_MMAP_EXEC_WRIT 1
123
123
  # define HAVE_MNTENT 1
124
124
  # endif
125
- # if defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)
125
+ # if defined(X86_WIN32) || defined(X86_WIN64) || defined(_M_ARM64) || defined(__OS2__)
126
126
  /* Windows systems may have Data Execution Protection (DEP) enabled,
127
127
  which requires the use of VirtualMalloc/VirtualFree to alloc/free
128
128
  executable memory. */
@@ -172,7 +172,7 @@ struct ffi_trampoline_table
172
172
 
173
173
  struct ffi_trampoline_table_entry
174
174
  {
175
- void *(*trampoline) ();
175
+ void *(*trampoline) (void);
176
176
  ffi_trampoline_table_entry *next;
177
177
  };
178
178
 
@@ -385,7 +385,7 @@ ffi_closure_free (void *ptr)
385
385
  #endif
386
386
  #include <string.h>
387
387
  #include <stdio.h>
388
- #if !defined(X86_WIN32) && !defined(X86_WIN64)
388
+ #if !defined(X86_WIN32) && !defined(X86_WIN64) && !defined(_M_ARM64)
389
389
  #ifdef HAVE_MNTENT
390
390
  #include <mntent.h>
391
391
  #endif /* HAVE_MNTENT */
@@ -511,7 +511,7 @@ static int dlmalloc_trim(size_t) MAYBE_UNUSED;
511
511
  static size_t dlmalloc_usable_size(void*) MAYBE_UNUSED;
512
512
  static void dlmalloc_stats(void) MAYBE_UNUSED;
513
513
 
514
- #if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
514
+ #if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(_M_ARM64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
515
515
  /* Use these for mmap and munmap within dlmalloc.c. */
516
516
  static void *dlmmap(void *, size_t, int, int, int, off_t);
517
517
  static int dlmunmap(void *, size_t);
@@ -525,7 +525,7 @@ static int dlmunmap(void *, size_t);
525
525
  #undef mmap
526
526
  #undef munmap
527
527
 
528
- #if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
528
+ #if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(_M_ARM64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
529
529
 
530
530
  /* A mutex used to synchronize access to *exec* variables in this file. */
531
531
  static pthread_mutex_t open_temp_exec_file_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -789,7 +789,13 @@ dlmmap_locked (void *start, size_t length, int prot, int flags, off_t offset)
789
789
  close (execfd);
790
790
  goto retry_open;
791
791
  }
792
- ftruncate (execfd, offset);
792
+ if (ftruncate (execfd, offset) != 0)
793
+ {
794
+ /* Fixme : Error logs can be added here. Returning an error for
795
+ * ftruncte() will not add any advantage as it is being
796
+ * validating in the error case. */
797
+ }
798
+
793
799
  return MFAIL;
794
800
  }
795
801
  else if (!offset
@@ -801,7 +807,12 @@ dlmmap_locked (void *start, size_t length, int prot, int flags, off_t offset)
801
807
  if (start == MFAIL)
802
808
  {
803
809
  munmap (ptr, length);
804
- ftruncate (execfd, offset);
810
+ if (ftruncate (execfd, offset) != 0)
811
+ {
812
+ /* Fixme : Error logs can be added here. Returning an error for
813
+ * ftruncte() will not add any advantage as it is being
814
+ * validating in the error case. */
815
+ }
805
816
  return start;
806
817
  }
807
818
 
@@ -896,7 +907,7 @@ segment_holding_code (mstate m, char* addr)
896
907
  }
897
908
  #endif
898
909
 
899
- #endif /* !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */
910
+ #endif /* !(defined(X86_WIN32) || defined(X86_WIN64) || defined(_M_ARM64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */
900
911
 
901
912
  /* Allocate a chunk of memory with the given size. Returns a pointer
902
913
  to the writable address, and sets *CODE to the executable
@@ -921,6 +932,13 @@ ffi_closure_alloc (size_t size, void **code)
921
932
  return ptr;
922
933
  }
923
934
 
935
+ void *
936
+ ffi_data_to_code_pointer (void *data)
937
+ {
938
+ msegmentptr seg = segment_holding (gm, data);
939
+ return add_segment_exec_offset (data, seg);
940
+ }
941
+
924
942
  /* Release a chunk of memory allocated with ffi_closure_alloc. If
925
943
  FFI_CLOSURE_FREE_CODE is nonzero, the given address can be the
926
944
  writable or the executable address given. Otherwise, only the
@@ -960,6 +978,12 @@ ffi_closure_free (void *ptr)
960
978
  free (ptr);
961
979
  }
962
980
 
981
+ void *
982
+ ffi_data_to_code_pointer (void *data)
983
+ {
984
+ return data;
985
+ }
986
+
963
987
  # endif /* ! FFI_MMAP_EXEC_WRIT */
964
988
  #endif /* FFI_CLOSURES */
965
989
 
@@ -297,10 +297,18 @@ ffi_closure_pa32:
297
297
  .LSCIE1:
298
298
  .word 0x0 ;# CIE Identifier Tag
299
299
  .byte 0x1 ;# CIE Version
300
+ #ifdef __PIC__
301
+ .ascii "zR\0" ;# CIE Augmentation: 'z' - data, 'R' - DW_EH_PE_... data
302
+ #else
300
303
  .ascii "\0" ;# CIE Augmentation
304
+ #endif
301
305
  .uleb128 0x1 ;# CIE Code Alignment Factor
302
306
  .sleb128 4 ;# CIE Data Alignment Factor
303
307
  .byte 0x2 ;# CIE RA Column
308
+ #ifdef __PIC__
309
+ .uleb128 0x1 ;# Augmentation size
310
+ .byte 0x1b ;# FDE Encoding (DW_EH_PE_pcrel|DW_EH_PE_sdata4)
311
+ #endif
304
312
  .byte 0xc ;# DW_CFA_def_cfa
305
313
  .uleb128 0x1e
306
314
  .uleb128 0x0
@@ -310,9 +318,15 @@ ffi_closure_pa32:
310
318
  .word .LEFDE1-.LASFDE1 ;# FDE Length
311
319
  .LASFDE1:
312
320
  .word .LASFDE1-.Lframe1 ;# FDE CIE offset
313
- .word .LFB1 ;# FDE initial location
321
+ #ifdef __PIC__
322
+ .word .LFB1-. ;# FDE initial location
323
+ #else
324
+ .word .LFB1 ;# FDE initial location
325
+ #endif
314
326
  .word .LFE1-.LFB1 ;# FDE address range
315
-
327
+ #ifdef __PIC__
328
+ .uleb128 0x0 ;# Augmentation size: no data
329
+ #endif
316
330
  .byte 0x4 ;# DW_CFA_advance_loc4
317
331
  .word .LCFI11-.LFB1
318
332
  .byte 0x83 ;# DW_CFA_offset, column 0x3
@@ -338,8 +352,15 @@ ffi_closure_pa32:
338
352
  .word .LEFDE2-.LASFDE2 ;# FDE Length
339
353
  .LASFDE2:
340
354
  .word .LASFDE2-.Lframe1 ;# FDE CIE offset
355
+ #ifdef __PIC__
356
+ .word .LFB2-. ;# FDE initial location
357
+ #else
341
358
  .word .LFB2 ;# FDE initial location
359
+ #endif
342
360
  .word .LFE2-.LFB2 ;# FDE address range
361
+ #ifdef __PIC__
362
+ .uleb128 0x0 ;# Augmentation size: no data
363
+ #endif
343
364
  .byte 0x4 ;# DW_CFA_advance_loc4
344
365
  .word .LCFI21-.LFB2
345
366
  .byte 0x83 ;# DW_CFA_offset, column 0x3
@@ -121,8 +121,9 @@ ffi_call_int (ffi_cif *cif,
121
121
  # endif
122
122
  /* The SYSV ABI returns a structure of up to 8 bytes in size
123
123
  left-padded in r3/r4, and the ELFv2 ABI similarly returns a
124
- structure of up to 8 bytes in size left-padded in r3. */
125
- if (rsize <= 8)
124
+ structure of up to 8 bytes in size left-padded in r3. But
125
+ note that a structure of a single float is not paddded. */
126
+ if (rsize <= 8 && (cif->flags & FLAG_RETURNS_FP) == 0)
126
127
  memcpy (rvalue, (char *) smst_buffer + 8 - rsize, rsize);
127
128
  else
128
129
  #endif
@@ -63,10 +63,30 @@ ffi_prep_types_linux64 (ffi_abi abi)
63
63
 
64
64
 
65
65
  static unsigned int
66
- discover_homogeneous_aggregate (const ffi_type *t, unsigned int *elnum)
66
+ discover_homogeneous_aggregate (ffi_abi abi,
67
+ const ffi_type *t,
68
+ unsigned int *elnum)
67
69
  {
68
70
  switch (t->type)
69
71
  {
72
+ #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
73
+ case FFI_TYPE_LONGDOUBLE:
74
+ /* 64-bit long doubles are equivalent to doubles. */
75
+ if ((abi & FFI_LINUX_LONG_DOUBLE_128) == 0)
76
+ {
77
+ *elnum = 1;
78
+ return FFI_TYPE_DOUBLE;
79
+ }
80
+ /* IBM extended precision values use unaligned pairs
81
+ of FPRs, but according to the ABI must be considered
82
+ distinct from doubles. They are also limited to a
83
+ maximum of four members in a homogeneous aggregate. */
84
+ else
85
+ {
86
+ *elnum = 2;
87
+ return FFI_TYPE_LONGDOUBLE;
88
+ }
89
+ #endif
70
90
  case FFI_TYPE_FLOAT:
71
91
  case FFI_TYPE_DOUBLE:
72
92
  *elnum = 1;
@@ -79,7 +99,7 @@ discover_homogeneous_aggregate (const ffi_type *t, unsigned int *elnum)
79
99
  while (*el)
80
100
  {
81
101
  unsigned int el_elt, el_elnum = 0;
82
- el_elt = discover_homogeneous_aggregate (*el, &el_elnum);
102
+ el_elt = discover_homogeneous_aggregate (abi, *el, &el_elnum);
83
103
  if (el_elt == 0
84
104
  || (base_elt && base_elt != el_elt))
85
105
  return 0;
@@ -112,7 +132,7 @@ ffi_prep_cif_linux64_core (ffi_cif *cif)
112
132
  unsigned bytes;
113
133
  unsigned i, fparg_count = 0, intarg_count = 0;
114
134
  unsigned flags = cif->flags;
115
- unsigned int elt, elnum;
135
+ unsigned elt, elnum, rtype;
116
136
 
117
137
  #if FFI_TYPE_LONGDOUBLE == FFI_TYPE_DOUBLE
118
138
  /* If compiled without long double support.. */
@@ -138,7 +158,11 @@ ffi_prep_cif_linux64_core (ffi_cif *cif)
138
158
  #endif
139
159
 
140
160
  /* Return value handling. */
141
- switch (cif->rtype->type)
161
+ rtype = cif->rtype->type;
162
+ #if _CALL_ELF == 2
163
+ homogeneous:
164
+ #endif
165
+ switch (rtype)
142
166
  {
143
167
  #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
144
168
  case FFI_TYPE_LONGDOUBLE:
@@ -164,19 +188,18 @@ ffi_prep_cif_linux64_core (ffi_cif *cif)
164
188
 
165
189
  case FFI_TYPE_STRUCT:
166
190
  #if _CALL_ELF == 2
167
- elt = discover_homogeneous_aggregate (cif->rtype, &elnum);
191
+ elt = discover_homogeneous_aggregate (cif->abi, cif->rtype, &elnum);
168
192
  if (elt)
169
- {
170
- if (elt == FFI_TYPE_DOUBLE)
171
- flags |= FLAG_RETURNS_64BITS;
172
- flags |= FLAG_RETURNS_FP | FLAG_RETURNS_SMST;
173
- break;
174
- }
193
+ {
194
+ flags |= FLAG_RETURNS_SMST;
195
+ rtype = elt;
196
+ goto homogeneous;
197
+ }
175
198
  if (cif->rtype->size <= 16)
176
- {
177
- flags |= FLAG_RETURNS_SMST;
178
- break;
179
- }
199
+ {
200
+ flags |= FLAG_RETURNS_SMST;
201
+ break;
202
+ }
180
203
  #endif
181
204
  intarg_count++;
182
205
  flags |= FLAG_RETVAL_REFERENCE;
@@ -224,7 +247,7 @@ ffi_prep_cif_linux64_core (ffi_cif *cif)
224
247
  intarg_count = FFI_ALIGN (intarg_count, align);
225
248
  }
226
249
  intarg_count += ((*ptr)->size + 7) / 8;
227
- elt = discover_homogeneous_aggregate (*ptr, &elnum);
250
+ elt = discover_homogeneous_aggregate (cif->abi, *ptr, &elnum);
228
251
  if (elt)
229
252
  {
230
253
  fparg_count += elnum;
@@ -391,7 +414,7 @@ ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack)
391
414
  valp rest;
392
415
  valp next_arg;
393
416
 
394
- /* 'fpr_base' points at the space for fpr3, and grows upwards as
417
+ /* 'fpr_base' points at the space for f1, and grows upwards as
395
418
  we use FPR registers. */
396
419
  valp fpr_base;
397
420
  unsigned int fparg_count;
@@ -492,7 +515,9 @@ ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack)
492
515
  /* Fall through. */
493
516
  #endif
494
517
  case FFI_TYPE_DOUBLE:
518
+ #if _CALL_ELF != 2
495
519
  do_double:
520
+ #endif
496
521
  double_tmp = **p_argv.d;
497
522
  if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)
498
523
  {
@@ -511,7 +536,9 @@ ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack)
511
536
  break;
512
537
 
513
538
  case FFI_TYPE_FLOAT:
539
+ #if _CALL_ELF != 2
514
540
  do_float:
541
+ #endif
515
542
  double_tmp = **p_argv.f;
516
543
  if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)
517
544
  {
@@ -548,9 +575,13 @@ ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack)
548
575
  if (align > 16)
549
576
  align = 16;
550
577
  if (align > 1)
551
- next_arg.p = FFI_ALIGN (next_arg.p, align);
578
+ {
579
+ next_arg.p = FFI_ALIGN (next_arg.p, align);
580
+ if (next_arg.ul == gpr_end.ul)
581
+ next_arg.ul = rest.ul;
582
+ }
552
583
  }
553
- elt = discover_homogeneous_aggregate (*ptr, &elnum);
584
+ elt = discover_homogeneous_aggregate (ecif->cif->abi, *ptr, &elnum);
554
585
  if (elt)
555
586
  {
556
587
  #if _CALL_ELF == 2
@@ -576,11 +607,9 @@ ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack)
576
607
  fparg_count++;
577
608
  }
578
609
  while (--elnum != 0);
579
- if ((next_arg.p & 3) != 0)
580
- {
581
- if (++next_arg.f == gpr_end.f)
582
- next_arg.f = rest.f;
583
- }
610
+ if ((next_arg.p & 7) != 0)
611
+ if (++next_arg.f == gpr_end.f)
612
+ next_arg.f = rest.f;
584
613
  }
585
614
  else
586
615
  do
@@ -813,7 +842,7 @@ ffi_closure_helper_LINUX64 (ffi_cif *cif,
813
842
  if (align > 1)
814
843
  pst = (unsigned long *) FFI_ALIGN ((size_t) pst, align);
815
844
  }
816
- elt = discover_homogeneous_aggregate (arg_types[i], &elnum);
845
+ elt = discover_homogeneous_aggregate (cif->abi, arg_types[i], &elnum);
817
846
  if (elt)
818
847
  {
819
848
  #if _CALL_ELF == 2
@@ -915,7 +944,9 @@ ffi_closure_helper_LINUX64 (ffi_cif *cif,
915
944
  /* Fall through. */
916
945
  #endif
917
946
  case FFI_TYPE_DOUBLE:
947
+ #if _CALL_ELF != 2
918
948
  do_double:
949
+ #endif
919
950
  /* On the outgoing stack all values are aligned to 8 */
920
951
  /* there are 13 64bit floating point registers */
921
952
 
@@ -930,7 +961,9 @@ ffi_closure_helper_LINUX64 (ffi_cif *cif,
930
961
  break;
931
962
 
932
963
  case FFI_TYPE_FLOAT:
964
+ #if _CALL_ELF != 2
933
965
  do_float:
966
+ #endif
934
967
  if (pfr < end_pfr && i < nfixedargs)
935
968
  {
936
969
  /* Float values are stored as doubles in the
@@ -143,7 +143,7 @@ ffi_closure_LINUX64:
143
143
  stfd %f12, -104+(11*8)(%r1)
144
144
  stfd %f13, -104+(12*8)(%r1)
145
145
 
146
- # load up the pointer to the saved fpr registers */
146
+ # load up the pointer to the saved fpr registers
147
147
  addi %r8, %r1, -104
148
148
 
149
149
  # load up the pointer to the result storage
@@ -129,7 +129,9 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi,
129
129
  cif->rtype = rtype;
130
130
 
131
131
  cif->flags = 0;
132
-
132
+ #ifdef _M_ARM64
133
+ cif->is_variadic = isvariadic;
134
+ #endif
133
135
  #if HAVE_LONG_DOUBLE_VARIANT
134
136
  ffi_prep_types (abi);
135
137
  #endif
@@ -199,7 +201,7 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi,
199
201
  bytes = 6*4;
200
202
  #endif
201
203
 
202
- bytes += STACK_ARG_SIZE((*ptr)->size);
204
+ bytes += (unsigned int)STACK_ARG_SIZE((*ptr)->size);
203
205
  }
204
206
  #endif
205
207
  }
@@ -29,7 +29,7 @@
29
29
  DEALINGS IN THE SOFTWARE.
30
30
  ----------------------------------------------------------------------- */
31
31
 
32
- #ifndef __x86_64__
32
+ #if defined(__i386__) || defined(_M_IX86)
33
33
  #include <ffi.h>
34
34
  #include <ffi_common.h>
35
35
  #include <stdint.h>
@@ -51,6 +51,13 @@
51
51
  # define __declspec(x) __attribute__((x))
52
52
  #endif
53
53
 
54
+ #if defined(_MSC_VER) && defined(_M_IX86)
55
+ /* Stack is not 16-byte aligned on Windows. */
56
+ #define STACK_ALIGN(bytes) (bytes)
57
+ #else
58
+ #define STACK_ALIGN(bytes) FFI_ALIGN (bytes, 16)
59
+ #endif
60
+
54
61
  /* Perform machine dependent cif processing. */
55
62
  ffi_status FFI_HIDDEN
56
63
  ffi_prep_cif_machdep(ffi_cif *cif)
@@ -177,7 +184,7 @@ ffi_prep_cif_machdep(ffi_cif *cif)
177
184
  bytes = FFI_ALIGN (bytes, t->alignment);
178
185
  bytes += FFI_ALIGN (t->size, FFI_SIZEOF_ARG);
179
186
  }
180
- cif->bytes = FFI_ALIGN (bytes, FFI_SIZEOF_ARG);
187
+ cif->bytes = bytes;
181
188
 
182
189
  return FFI_OK;
183
190
  }
@@ -285,7 +292,7 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
285
292
  }
286
293
  }
287
294
 
288
- bytes = cif->bytes;
295
+ bytes = STACK_ALIGN (cif->bytes);
289
296
  stack = alloca(bytes + sizeof(*frame) + rsize);
290
297
  argp = (dir < 0 ? stack + bytes : stack);
291
298
  frame = (struct call_frame *)(stack + bytes);
@@ -429,7 +436,7 @@ ffi_closure_inner (struct closure_frame *frame, char *stack)
429
436
  rvalue = frame->rettemp;
430
437
  pabi = &abi_params[cabi];
431
438
  dir = pabi->dir;
432
- argp = (dir < 0 ? stack + cif->bytes : stack);
439
+ argp = (dir < 0 ? stack + STACK_ALIGN (cif->bytes) : stack);
433
440
 
434
441
  switch (flags)
435
442
  {
@@ -693,7 +700,7 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *avalue)
693
700
  }
694
701
  }
695
702
 
696
- bytes = cif->bytes;
703
+ bytes = STACK_ALIGN (cif->bytes);
697
704
  argp = stack =
698
705
  (void *)((uintptr_t)alloca(bytes + sizeof(*frame) + rsize + 15) & ~16);
699
706
  frame = (struct call_frame *)(stack + bytes);
@@ -751,4 +758,4 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *avalue)
751
758
  ffi_call_i386 (frame, stack);
752
759
  }
753
760
  #endif /* !FFI_NO_RAW_API */
754
- #endif /* !__x86_64__ */
761
+ #endif /* __i386__ */
@@ -282,7 +282,7 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[],
282
282
 
283
283
  /* The X86_64_SSEUP_CLASS should be always preceded by
284
284
  X86_64_SSE_CLASS or X86_64_SSEUP_CLASS. */
285
- if (classes[i] == X86_64_SSEUP_CLASS
285
+ if (i > 1 && classes[i] == X86_64_SSEUP_CLASS
286
286
  && classes[i - 1] != X86_64_SSE_CLASS
287
287
  && classes[i - 1] != X86_64_SSEUP_CLASS)
288
288
  {
@@ -293,7 +293,7 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[],
293
293
 
294
294
  /* If X86_64_X87UP_CLASS isn't preceded by X86_64_X87_CLASS,
295
295
  everything should be passed in memory. */
296
- if (classes[i] == X86_64_X87UP_CLASS
296
+ if (i > 1 && classes[i] == X86_64_X87UP_CLASS
297
297
  && (classes[i - 1] != X86_64_X87_CLASS))
298
298
  {
299
299
  /* The first one should never be X86_64_X87UP_CLASS. */
@@ -394,7 +394,7 @@ extern ffi_status
394
394
  ffi_prep_cif_machdep_efi64(ffi_cif *cif);
395
395
  #endif
396
396
 
397
- ffi_status
397
+ ffi_status FFI_HIDDEN
398
398
  ffi_prep_cif_machdep (ffi_cif *cif)
399
399
  {
400
400
  int gprcount, ssecount, i, avn, ngpr, nsse;
@@ -451,9 +451,11 @@ ffi_prep_cif_machdep (ffi_cif *cif)
451
451
  case FFI_TYPE_DOUBLE:
452
452
  flags = UNIX64_RET_XMM64;
453
453
  break;
454
+ #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
454
455
  case FFI_TYPE_LONGDOUBLE:
455
456
  flags = UNIX64_RET_X87;
456
457
  break;
458
+ #endif
457
459
  case FFI_TYPE_STRUCT:
458
460
  n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse);
459
461
  if (n == 0)