ffi 0.5.4 → 0.6.0

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 (203) hide show
  1. data/LICENSE +1 -27
  2. data/Rakefile +2 -11
  3. data/ext/ffi_c/AbstractMemory.c +6 -8
  4. data/ext/ffi_c/AbstractMemory.h +23 -21
  5. data/ext/ffi_c/AutoPointer.c +0 -1
  6. data/ext/ffi_c/Buffer.c +23 -8
  7. data/ext/ffi_c/Call.c +28 -0
  8. data/ext/ffi_c/Call.h +5 -1
  9. data/ext/ffi_c/DynamicLibrary.c +0 -1
  10. data/ext/ffi_c/Function.c +19 -2
  11. data/ext/ffi_c/MemoryPointer.c +2 -3
  12. data/ext/ffi_c/Pointer.c +23 -9
  13. data/ext/ffi_c/Struct.c +142 -69
  14. data/ext/ffi_c/Struct.h +16 -7
  15. data/ext/ffi_c/StructLayout.c +92 -55
  16. data/ext/ffi_c/Type.c +5 -22
  17. data/ext/ffi_c/Type.h +1 -1
  18. data/ext/ffi_c/Types.c +8 -2
  19. data/ext/ffi_c/Types.h +2 -0
  20. data/ext/ffi_c/extconf.rb +11 -7
  21. data/ext/ffi_c/libffi/ChangeLog +900 -84
  22. data/ext/ffi_c/libffi/ChangeLog.libffi +311 -0
  23. data/ext/ffi_c/libffi/LICENSE +1 -1
  24. data/ext/ffi_c/libffi/Makefile.am +14 -4
  25. data/ext/ffi_c/libffi/Makefile.in +362 -211
  26. data/ext/ffi_c/libffi/README +70 -92
  27. data/ext/ffi_c/libffi/aclocal.m4 +6068 -4586
  28. data/ext/ffi_c/libffi/config.guess +125 -143
  29. data/ext/ffi_c/libffi/config.sub +103 -27
  30. data/ext/ffi_c/libffi/configure +11364 -18497
  31. data/ext/ffi_c/libffi/configure.ac +43 -4
  32. data/ext/ffi_c/libffi/doc/libffi.info +15 -15
  33. data/ext/ffi_c/libffi/doc/libffi.texi +1 -1
  34. data/ext/ffi_c/libffi/doc/stamp-vti +4 -4
  35. data/ext/ffi_c/libffi/doc/version.texi +4 -4
  36. data/ext/ffi_c/libffi/fficonfig.h.in +24 -3
  37. data/ext/ffi_c/libffi/include/Makefile.am +1 -1
  38. data/ext/ffi_c/libffi/include/Makefile.in +97 -50
  39. data/ext/ffi_c/libffi/include/ffi.h.in +8 -2
  40. data/ext/ffi_c/libffi/include/ffi_common.h +24 -0
  41. data/ext/ffi_c/libffi/libtool-version +1 -1
  42. data/ext/ffi_c/libffi/ltmain.sh +7346 -5870
  43. data/ext/ffi_c/libffi/m4/libtool.m4 +7360 -0
  44. data/ext/ffi_c/libffi/m4/ltoptions.m4 +368 -0
  45. data/ext/ffi_c/libffi/m4/ltsugar.m4 +123 -0
  46. data/ext/ffi_c/libffi/m4/ltversion.m4 +23 -0
  47. data/ext/ffi_c/libffi/m4/lt~obsolete.m4 +92 -0
  48. data/ext/ffi_c/libffi/man/Makefile.in +115 -62
  49. data/ext/ffi_c/libffi/man/ffi_call.3 +3 -3
  50. data/ext/ffi_c/libffi/missing +15 -8
  51. data/ext/ffi_c/libffi/src/arm/sysv.S +15 -8
  52. data/ext/ffi_c/libffi/src/avr32/ffi.c +421 -0
  53. data/ext/ffi_c/libffi/src/avr32/ffitarget.h +50 -0
  54. data/ext/ffi_c/libffi/src/avr32/sysv.S +208 -0
  55. data/ext/ffi_c/libffi/src/closures.c +47 -10
  56. data/ext/ffi_c/libffi/src/frv/ffi.c +1 -1
  57. data/ext/ffi_c/libffi/src/java_raw_api.c +0 -3
  58. data/ext/ffi_c/libffi/src/mips/ffi.c +135 -32
  59. data/ext/ffi_c/libffi/src/mips/ffitarget.h +37 -4
  60. data/ext/ffi_c/libffi/src/mips/n32.S +67 -10
  61. data/ext/ffi_c/libffi/src/mips/o32.S +8 -8
  62. data/ext/ffi_c/libffi/src/pa/ffi.c +7 -0
  63. data/ext/ffi_c/libffi/src/powerpc/aix.S +163 -64
  64. data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +308 -112
  65. data/ext/ffi_c/libffi/src/powerpc/ffi.c +20 -7
  66. data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +208 -80
  67. data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +11 -3
  68. data/ext/ffi_c/libffi/src/powerpc/sysv.S +12 -23
  69. data/ext/ffi_c/libffi/src/s390/sysv.S +1 -1
  70. data/ext/ffi_c/libffi/src/sh/sysv.S +9 -9
  71. data/ext/ffi_c/libffi/src/sh64/ffi.c +37 -22
  72. data/ext/ffi_c/libffi/src/sh64/sysv.S +23 -14
  73. data/ext/ffi_c/libffi/src/sparc/ffi.c +21 -6
  74. data/ext/ffi_c/libffi/src/sparc/v8.S +55 -14
  75. data/ext/ffi_c/libffi/src/x86/darwin.S +10 -9
  76. data/ext/ffi_c/libffi/src/x86/ffi.c +293 -86
  77. data/ext/ffi_c/libffi/src/x86/ffi64.c +73 -19
  78. data/ext/ffi_c/libffi/src/x86/ffitarget.h +30 -0
  79. data/ext/ffi_c/libffi/src/x86/sysv.S +21 -4
  80. data/ext/ffi_c/libffi/src/x86/unix64.S +8 -4
  81. data/ext/ffi_c/libffi/src/x86/win32.S +633 -147
  82. data/ext/ffi_c/libffi/src/x86/win64.S +460 -0
  83. data/ext/ffi_c/libffi/testsuite/Makefile.am +63 -54
  84. data/ext/ffi_c/libffi/testsuite/Makefile.in +112 -77
  85. data/ext/ffi_c/libffi/testsuite/lib/libffi-dg.exp +12 -1
  86. data/ext/ffi_c/libffi/testsuite/libffi.call/call.exp +4 -4
  87. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn0.c +7 -15
  88. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn1.c +7 -15
  89. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn2.c +7 -15
  90. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn3.c +7 -15
  91. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn4.c +7 -15
  92. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn5.c +7 -14
  93. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn6.c +7 -15
  94. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_loc_fn0.c +95 -0
  95. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_stdcall.c +6 -14
  96. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_12byte.c +4 -12
  97. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_16byte.c +4 -12
  98. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_18byte.c +4 -12
  99. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_19byte.c +4 -12
  100. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_1_1byte.c +4 -12
  101. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte.c +4 -12
  102. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte1.c +4 -12
  103. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_24byte.c +4 -12
  104. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_2byte.c +4 -12
  105. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3_1byte.c +4 -12
  106. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte1.c +4 -12
  107. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte2.c +4 -12
  108. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4_1byte.c +4 -12
  109. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4byte.c +4 -12
  110. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5_1_byte.c +4 -12
  111. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5byte.c +4 -12
  112. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_64byte.c +4 -12
  113. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6_1_byte.c +4 -12
  114. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6byte.c +4 -12
  115. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7_1_byte.c +4 -12
  116. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7byte.c +4 -12
  117. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_8byte.c +4 -12
  118. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte1.c +4 -12
  119. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte2.c +4 -12
  120. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_double.c +4 -12
  121. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_float.c +4 -12
  122. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble.c +4 -12
  123. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split.c +134 -0
  124. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c +117 -0
  125. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_pointer.c +11 -17
  126. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint16.c +4 -12
  127. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint32.c +4 -12
  128. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint64.c +7 -15
  129. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint16.c +4 -12
  130. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint32.c +4 -12
  131. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint64.c +7 -15
  132. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_dbls_struct.c +66 -0
  133. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_double.c +4 -12
  134. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_double_va.c +57 -0
  135. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_float.c +4 -13
  136. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble.c +105 -0
  137. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble_va.c +57 -0
  138. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_schar.c +4 -12
  139. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_sshort.c +4 -12
  140. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_sshortchar.c +4 -12
  141. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_uchar.c +4 -12
  142. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_ushort.c +4 -12
  143. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_ushortchar.c +4 -12
  144. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer.c +74 -0
  145. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer_stack.c +140 -0
  146. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_schar.c +4 -12
  147. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_sint.c +4 -12
  148. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_sshort.c +4 -12
  149. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uchar.c +4 -12
  150. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uint.c +4 -12
  151. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ulonglong.c +8 -16
  152. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ushort.c +4 -12
  153. data/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_abi.c +37 -0
  154. data/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_typedef.c +25 -0
  155. data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +31 -0
  156. data/ext/ffi_c/libffi/testsuite/libffi.call/float2.c +2 -1
  157. data/ext/ffi_c/libffi/testsuite/libffi.call/huge_struct.c +342 -0
  158. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct.c +4 -12
  159. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct1.c +4 -12
  160. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct10.c +4 -12
  161. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct2.c +4 -12
  162. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct3.c +4 -12
  163. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct4.c +4 -12
  164. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct5.c +4 -12
  165. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct6.c +4 -12
  166. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct7.c +4 -12
  167. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct8.c +4 -12
  168. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct9.c +4 -12
  169. data/ext/ffi_c/libffi/testsuite/libffi.call/problem1.c +4 -12
  170. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ldl.c +1 -1
  171. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll1.c +1 -1
  172. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_large.c +145 -0
  173. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_large2.c +148 -0
  174. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium.c +124 -0
  175. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium2.c +124 -0
  176. data/ext/ffi_c/libffi/testsuite/libffi.call/testclosure.c +70 -0
  177. data/ext/ffi_c/libffi/testsuite/libffi.special/ffitestcxx.h +10 -0
  178. data/ext/ffi_c/libffi/testsuite/libffi.special/special.exp +4 -5
  179. data/ext/ffi_c/libffi/testsuite/libffi.special/unwindtest.cc +17 -16
  180. data/ext/ffi_c/libffi/texinfo.tex +155 -427
  181. data/lib/ffi/autopointer.rb +79 -20
  182. data/lib/ffi/callback.rb +4 -10
  183. data/lib/ffi/enum.rb +28 -0
  184. data/lib/ffi/io.rb +28 -0
  185. data/lib/ffi/library.rb +237 -182
  186. data/lib/ffi/memorypointer.rb +28 -62
  187. data/lib/ffi/platform.rb +27 -0
  188. data/lib/ffi/pointer.rb +28 -0
  189. data/lib/ffi/struct.rb +55 -1
  190. data/lib/ffi/types.rb +29 -0
  191. data/lib/ffi/variadic.rb +29 -0
  192. data/spec/ffi/library_spec.rb +31 -5
  193. data/spec/ffi/rbx/attach_function_spec.rb +2 -1
  194. data/spec/ffi/rbx/memory_pointer_spec.rb +2 -1
  195. data/spec/ffi/spec_helper.rb +5 -1
  196. data/spec/ffi/struct_spec.rb +64 -0
  197. metadata +28 -8
  198. data/ext/ffi_c/libffi/TODO +0 -1
  199. data/ext/ffi_c/libffi/ltcf-c.sh +0 -861
  200. data/ext/ffi_c/libffi/ltcf-cxx.sh +0 -1069
  201. data/ext/ffi_c/libffi/ltcf-gcj.sh +0 -700
  202. data/ext/ffi_c/libffi/ltconfig +0 -2862
  203. data/ext/ffi_c/libffi/mkinstalldirs +0 -158
@@ -15,15 +15,16 @@
15
15
  The above copyright notice and this permission notice shall be included
16
16
  in all copies or substantial portions of the Software.
17
17
 
18
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
19
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
22
- ANY CLAIM, DAMAGES OR
23
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25
- OTHER DEALINGS IN THE SOFTWARE.
26
- ----------------------------------------------------------------------- */
18
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
19
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25
+ DEALINGS IN THE SOFTWARE.
26
+ -----------------------------------------------------------------------
27
+ */
27
28
 
28
29
  #ifndef __x86_64__
29
30
 
@@ -3,7 +3,7 @@
3
3
  Copyright (c) 2002 Ranjit Mathew
4
4
  Copyright (c) 2002 Bo Thorsen
5
5
  Copyright (c) 2002 Roger Sayle
6
- Copyright (C) 2008 Free Software Foundation, Inc.
6
+ Copyright (C) 2008 Free Software Foundation, Inc.
7
7
 
8
8
  x86 Foreign Function Interface
9
9
 
@@ -28,7 +28,11 @@
28
28
  DEALINGS IN THE SOFTWARE.
29
29
  ----------------------------------------------------------------------- */
30
30
 
31
- #ifndef __x86_64__
31
+ #if !defined(__x86_64__) || defined(_WIN64)
32
+
33
+ #ifdef _WIN64
34
+ #include <windows.h>
35
+ #endif
32
36
 
33
37
  #include <ffi.h>
34
38
  #include <ffi_common.h>
@@ -47,10 +51,15 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
47
51
 
48
52
  argp = stack;
49
53
 
50
- if (ecif->cif->flags == FFI_TYPE_STRUCT)
54
+ if (ecif->cif->flags == FFI_TYPE_STRUCT
55
+ #ifdef X86_WIN64
56
+ && (ecif->cif->rtype->size != 1 && ecif->cif->rtype->size != 2
57
+ && ecif->cif->rtype->size != 4 && ecif->cif->rtype->size != 8)
58
+ #endif
59
+ )
51
60
  {
52
61
  *(void **) argp = ecif->rvalue;
53
- argp += 4;
62
+ argp += sizeof(void*);
54
63
  }
55
64
 
56
65
  p_argv = ecif->avalue;
@@ -62,53 +71,75 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
62
71
  size_t z;
63
72
 
64
73
  /* Align if necessary */
65
- if ((sizeof(int) - 1) & (unsigned) argp)
66
- argp = (char *) ALIGN(argp, sizeof(int));
74
+ if ((sizeof(void*) - 1) & (size_t) argp)
75
+ argp = (char *) ALIGN(argp, sizeof(void*));
67
76
 
68
77
  z = (*p_arg)->size;
69
- if (z < sizeof(int))
70
- {
71
- z = sizeof(int);
72
- switch ((*p_arg)->type)
73
- {
74
- case FFI_TYPE_SINT8:
75
- *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
76
- break;
77
-
78
- case FFI_TYPE_UINT8:
79
- *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
80
- break;
81
-
82
- case FFI_TYPE_SINT16:
83
- *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
84
- break;
85
-
86
- case FFI_TYPE_UINT16:
87
- *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
88
- break;
89
-
90
- case FFI_TYPE_SINT32:
91
- *(signed int *) argp = (signed int)*(SINT32 *)(* p_argv);
92
- break;
93
-
94
- case FFI_TYPE_UINT32:
95
- *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
96
- break;
97
-
98
- case FFI_TYPE_STRUCT:
99
- *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
100
- break;
101
-
102
- default:
103
- FFI_ASSERT(0);
104
- }
105
- }
78
+ #ifdef X86_WIN64
79
+ if (z > sizeof(ffi_arg)
80
+ || ((*p_arg)->type == FFI_TYPE_STRUCT
81
+ && (z != 1 && z != 2 && z != 4 && z != 8))
82
+ #if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
83
+ || ((*p_arg)->type == FFI_TYPE_LONGDOUBLE)
84
+ #endif
85
+ )
86
+ {
87
+ z = sizeof(ffi_arg);
88
+ *(void **)argp = *p_argv;
89
+ }
90
+ else if ((*p_arg)->type == FFI_TYPE_FLOAT)
91
+ {
92
+ memcpy(argp, *p_argv, z);
93
+ }
106
94
  else
107
- {
108
- memcpy(argp, *p_argv, z);
109
- }
95
+ #endif
96
+ if (z < sizeof(ffi_arg))
97
+ {
98
+ z = sizeof(ffi_arg);
99
+ switch ((*p_arg)->type)
100
+ {
101
+ case FFI_TYPE_SINT8:
102
+ *(ffi_sarg *) argp = (ffi_sarg)*(SINT8 *)(* p_argv);
103
+ break;
104
+
105
+ case FFI_TYPE_UINT8:
106
+ *(ffi_arg *) argp = (ffi_arg)*(UINT8 *)(* p_argv);
107
+ break;
108
+
109
+ case FFI_TYPE_SINT16:
110
+ *(ffi_sarg *) argp = (ffi_sarg)*(SINT16 *)(* p_argv);
111
+ break;
112
+
113
+ case FFI_TYPE_UINT16:
114
+ *(ffi_arg *) argp = (ffi_arg)*(UINT16 *)(* p_argv);
115
+ break;
116
+
117
+ case FFI_TYPE_SINT32:
118
+ *(ffi_sarg *) argp = (ffi_sarg)*(SINT32 *)(* p_argv);
119
+ break;
120
+
121
+ case FFI_TYPE_UINT32:
122
+ *(ffi_arg *) argp = (ffi_arg)*(UINT32 *)(* p_argv);
123
+ break;
124
+
125
+ case FFI_TYPE_STRUCT:
126
+ *(ffi_arg *) argp = *(ffi_arg *)(* p_argv);
127
+ break;
128
+
129
+ default:
130
+ FFI_ASSERT(0);
131
+ }
132
+ }
133
+ else
134
+ {
135
+ memcpy(argp, *p_argv, z);
136
+ }
110
137
  p_argv++;
138
+ #ifdef X86_WIN64
139
+ argp += (z + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
140
+ #else
111
141
  argp += z;
142
+ #endif
112
143
  }
113
144
 
114
145
  return;
@@ -124,21 +155,32 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
124
155
  #ifdef X86
125
156
  case FFI_TYPE_STRUCT:
126
157
  #endif
127
- #if defined(X86) || defined(X86_DARWIN)
158
+ #if defined(X86) || defined (X86_WIN32) || defined(X86_FREEBSD) || defined(X86_DARWIN) || defined(X86_WIN64)
128
159
  case FFI_TYPE_UINT8:
129
160
  case FFI_TYPE_UINT16:
130
161
  case FFI_TYPE_SINT8:
131
162
  case FFI_TYPE_SINT16:
132
163
  #endif
164
+ #ifdef X86_WIN64
165
+ case FFI_TYPE_UINT32:
166
+ case FFI_TYPE_SINT32:
167
+ #endif
133
168
 
134
169
  case FFI_TYPE_SINT64:
135
170
  case FFI_TYPE_FLOAT:
136
171
  case FFI_TYPE_DOUBLE:
172
+ #ifndef X86_WIN64
173
+ #if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
137
174
  case FFI_TYPE_LONGDOUBLE:
175
+ #endif
176
+ #endif
138
177
  cif->flags = (unsigned) cif->rtype->type;
139
178
  break;
140
179
 
141
180
  case FFI_TYPE_UINT64:
181
+ #ifdef X86_WIN64
182
+ case FFI_TYPE_POINTER:
183
+ #endif
142
184
  cif->flags = FFI_TYPE_SINT64;
143
185
  break;
144
186
 
@@ -154,7 +196,11 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
154
196
  }
155
197
  else if (cif->rtype->size == 4)
156
198
  {
199
+ #ifdef X86_WIN64
200
+ cif->flags = FFI_TYPE_SMALL_STRUCT_4B;
201
+ #else
157
202
  cif->flags = FFI_TYPE_INT; /* same as int type */
203
+ #endif
158
204
  }
159
205
  else if (cif->rtype->size == 8)
160
206
  {
@@ -163,12 +209,23 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
163
209
  else
164
210
  {
165
211
  cif->flags = FFI_TYPE_STRUCT;
212
+ #ifdef X86_WIN64
213
+ // allocate space for return value pointer
214
+ cif->bytes += ALIGN(sizeof(void*), FFI_SIZEOF_ARG);
215
+ #endif
166
216
  }
167
217
  break;
168
218
  #endif
169
219
 
170
220
  default:
221
+ #ifdef X86_WIN64
222
+ cif->flags = FFI_TYPE_SINT64;
223
+ break;
224
+ case FFI_TYPE_INT:
225
+ cif->flags = FFI_TYPE_SINT32;
226
+ #else
171
227
  cif->flags = FFI_TYPE_INT;
228
+ #endif
172
229
  break;
173
230
  }
174
231
 
@@ -176,17 +233,38 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
176
233
  cif->bytes = (cif->bytes + 15) & ~0xF;
177
234
  #endif
178
235
 
236
+ #ifdef X86_WIN64
237
+ {
238
+ unsigned int i;
239
+ ffi_type **ptr;
240
+
241
+ for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
242
+ {
243
+ if (((*ptr)->alignment - 1) & cif->bytes)
244
+ cif->bytes = ALIGN(cif->bytes, (*ptr)->alignment);
245
+ cif->bytes += ALIGN((*ptr)->size, FFI_SIZEOF_ARG);
246
+ }
247
+ }
248
+ // ensure space for storing four registers
249
+ cif->bytes += 4 * sizeof(ffi_arg);
250
+ #endif
251
+
179
252
  return FFI_OK;
180
253
  }
181
254
 
182
255
  extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
183
- unsigned, unsigned, unsigned *, void (*fn)(void));
256
+ unsigned, unsigned, unsigned *, void (*fn)(void));
184
257
 
185
258
  #ifdef X86_WIN32
186
259
  extern void ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *,
187
- unsigned, unsigned, unsigned *, void (*fn)(void));
260
+ unsigned, unsigned, unsigned *, void (*fn)(void));
188
261
 
189
262
  #endif /* X86_WIN32 */
263
+ #ifdef X86_WIN64
264
+ extern int
265
+ ffi_call_win64(void (*)(char *, extended_cif *), extended_cif *,
266
+ unsigned, unsigned, unsigned *, void (*fn)(void));
267
+ #endif
190
268
 
191
269
  void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
192
270
  {
@@ -195,30 +273,66 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
195
273
  ecif.cif = cif;
196
274
  ecif.avalue = avalue;
197
275
 
198
- /* If the return value is a struct and we don't have a return */
199
- /* value address then we need to make one */
200
-
201
- if ((rvalue == NULL) &&
202
- (cif->flags == FFI_TYPE_STRUCT))
276
+ /* If the return value is a struct and we don't have a return */
277
+ /* value address then we need to make one */
278
+
279
+ #ifdef X86_WIN64
280
+ if (rvalue == NULL
281
+ && cif->flags == FFI_TYPE_STRUCT
282
+ && cif->rtype->size != 1 && cif->rtype->size != 2
283
+ && cif->rtype->size != 4 && cif->rtype->size != 8)
284
+ {
285
+ ecif.rvalue = alloca((cif->rtype->size + 0xF) & ~0xF);
286
+ }
287
+ #else
288
+ if (rvalue == NULL
289
+ && cif->flags == FFI_TYPE_STRUCT)
203
290
  {
204
291
  ecif.rvalue = alloca(cif->rtype->size);
205
292
  }
293
+ #endif
206
294
  else
207
295
  ecif.rvalue = rvalue;
208
296
 
209
297
 
210
298
  switch (cif->abi)
211
299
  {
300
+ #ifdef X86_WIN64
301
+ case FFI_WIN64:
302
+ {
303
+ // Make copies of all struct arguments
304
+ // NOTE: not sure if responsibility should be here or in caller
305
+ unsigned int i;
306
+ for (i=0; i < cif->nargs;i++) {
307
+ size_t size = cif->arg_types[i]->size;
308
+ if ((cif->arg_types[i]->type == FFI_TYPE_STRUCT
309
+ && (size != 1 && size != 2 && size != 4 && size != 8))
310
+ #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
311
+ || cif->arg_types[i]->type == FFI_TYPE_LONGDOUBLE
312
+ #endif
313
+ )
314
+ {
315
+ void *local = alloca(size);
316
+ memcpy(local, avalue[i], size);
317
+ avalue[i] = local;
318
+ }
319
+ }
320
+ ffi_call_win64(ffi_prep_args, &ecif, cif->bytes,
321
+ cif->flags, ecif.rvalue, fn);
322
+ }
323
+ break;
324
+ #else
212
325
  case FFI_SYSV:
213
326
  ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
214
- fn);
327
+ fn);
215
328
  break;
216
329
  #ifdef X86_WIN32
217
330
  case FFI_STDCALL:
218
331
  ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes, cif->flags,
219
- ecif.rvalue, fn);
332
+ ecif.rvalue, fn);
220
333
  break;
221
334
  #endif /* X86_WIN32 */
335
+ #endif /* X86_WIN64 */
222
336
  default:
223
337
  FFI_ASSERT(0);
224
338
  break;
@@ -229,7 +343,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
229
343
  /** private members **/
230
344
 
231
345
  static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
232
- void** args, ffi_cif* cif);
346
+ void** args, ffi_cif* cif);
233
347
  void FFI_HIDDEN ffi_closure_SYSV (ffi_closure *)
234
348
  __attribute__ ((regparm(1)));
235
349
  unsigned int FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *, void **, void *)
@@ -240,9 +354,42 @@ void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *)
240
354
  void FFI_HIDDEN ffi_closure_STDCALL (ffi_closure *)
241
355
  __attribute__ ((regparm(1)));
242
356
  #endif
357
+ #ifdef X86_WIN64
358
+ void FFI_HIDDEN ffi_closure_win64 (ffi_closure *);
359
+ #endif
243
360
 
244
361
  /* This function is jumped to by the trampoline */
245
362
 
363
+ #ifdef X86_WIN64
364
+ void * FFI_HIDDEN
365
+ ffi_closure_win64_inner (ffi_closure *closure, void *args) {
366
+ ffi_cif *cif;
367
+ void **arg_area;
368
+ void *result;
369
+ void *resp = &result;
370
+
371
+ cif = closure->cif;
372
+ arg_area = (void**) alloca (cif->nargs * sizeof (void*));
373
+
374
+ /* this call will initialize ARG_AREA, such that each
375
+ * element in that array points to the corresponding
376
+ * value on the stack; and if the function returns
377
+ * a structure, it will change RESP to point to the
378
+ * structure return address. */
379
+
380
+ ffi_prep_incoming_args_SYSV(args, &resp, arg_area, cif);
381
+
382
+ (closure->fun) (cif, resp, arg_area, closure->user_data);
383
+
384
+ /* The result is returned in rax. This does the right thing for
385
+ result types except for floats; we have to 'mov xmm0, rax' in the
386
+ caller to correct this.
387
+ TODO: structure sizes of 3 5 6 7 are returned by reference, too!!!
388
+ */
389
+ return cif->rtype->size > sizeof(void *) ? resp : *(void **)resp;
390
+ }
391
+
392
+ #else
246
393
  unsigned int FFI_HIDDEN
247
394
  ffi_closure_SYSV_inner (closure, respp, args)
248
395
  ffi_closure *closure;
@@ -259,7 +406,7 @@ ffi_closure_SYSV_inner (closure, respp, args)
259
406
  /* this call will initialize ARG_AREA, such that each
260
407
  * element in that array points to the corresponding
261
408
  * value on the stack; and if the function returns
262
- * a structure, it will re-set RESP to point to the
409
+ * a structure, it will change RESP to point to the
263
410
  * structure return address. */
264
411
 
265
412
  ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif);
@@ -268,10 +415,11 @@ ffi_closure_SYSV_inner (closure, respp, args)
268
415
 
269
416
  return cif->flags;
270
417
  }
418
+ #endif /* !X86_WIN64 */
271
419
 
272
420
  static void
273
421
  ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
274
- ffi_cif *cif)
422
+ ffi_cif *cif)
275
423
  {
276
424
  register unsigned int i;
277
425
  register void **p_argv;
@@ -280,10 +428,20 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
280
428
 
281
429
  argp = stack;
282
430
 
431
+ #ifdef X86_WIN64
432
+ if (cif->rtype->size > sizeof(ffi_arg)
433
+ || (cif->flags == FFI_TYPE_STRUCT
434
+ && (cif->rtype->size != 1 && cif->rtype->size != 2
435
+ && cif->rtype->size != 4 && cif->rtype->size != 8))) {
436
+ *rvalue = *(void **) argp;
437
+ argp += sizeof(void *);
438
+ }
439
+ #else
283
440
  if ( cif->flags == FFI_TYPE_STRUCT ) {
284
441
  *rvalue = *(void **) argp;
285
- argp += 4;
442
+ argp += sizeof(void *);
286
443
  }
444
+ #endif
287
445
 
288
446
  p_argv = avalue;
289
447
 
@@ -292,30 +450,65 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
292
450
  size_t z;
293
451
 
294
452
  /* Align if necessary */
295
- if ((sizeof(int) - 1) & (unsigned) argp) {
296
- argp = (char *) ALIGN(argp, sizeof(int));
453
+ if ((sizeof(void*) - 1) & (size_t) argp) {
454
+ argp = (char *) ALIGN(argp, sizeof(void*));
297
455
  }
298
456
 
299
- z = (*p_arg)->size;
300
-
301
- /* because we're little endian, this is what it turns into. */
302
-
303
- *p_argv = (void*) argp;
304
-
457
+ #ifdef X86_WIN64
458
+ if ((*p_arg)->size > sizeof(ffi_arg)
459
+ || ((*p_arg)->type == FFI_TYPE_STRUCT
460
+ && ((*p_arg)->size != 1 && (*p_arg)->size != 2
461
+ && (*p_arg)->size != 4 && (*p_arg)->size != 8)))
462
+ {
463
+ z = sizeof(void *);
464
+ *p_argv = *(void **)argp;
465
+ }
466
+ else
467
+ #endif
468
+ {
469
+ z = (*p_arg)->size;
470
+
471
+ /* because we're little endian, this is what it turns into. */
472
+
473
+ *p_argv = (void*) argp;
474
+ }
475
+
305
476
  p_argv++;
477
+ #ifdef X86_WIN64
478
+ argp += (z + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
479
+ #else
306
480
  argp += z;
481
+ #endif
307
482
  }
308
483
 
309
484
  return;
310
485
  }
311
486
 
487
+ #define FFI_INIT_TRAMPOLINE_WIN64(TRAMP,FUN,CTX,MASK) \
488
+ { unsigned char *__tramp = (unsigned char*)(TRAMP); \
489
+ void* __fun = (void*)(FUN); \
490
+ void* __ctx = (void*)(CTX); \
491
+ *(unsigned char*) &__tramp[0] = 0x41; \
492
+ *(unsigned char*) &__tramp[1] = 0xbb; \
493
+ *(unsigned int*) &__tramp[2] = MASK; /* mov $mask, %r11 */ \
494
+ *(unsigned char*) &__tramp[6] = 0x48; \
495
+ *(unsigned char*) &__tramp[7] = 0xb8; \
496
+ *(void**) &__tramp[8] = __ctx; /* mov __ctx, %rax */ \
497
+ *(unsigned char *) &__tramp[16] = 0x49; \
498
+ *(unsigned char *) &__tramp[17] = 0xba; \
499
+ *(void**) &__tramp[18] = __fun; /* mov __fun, %r10 */ \
500
+ *(unsigned char *) &__tramp[26] = 0x41; \
501
+ *(unsigned char *) &__tramp[27] = 0xff; \
502
+ *(unsigned char *) &__tramp[28] = 0xe2; /* jmp %r10 */ \
503
+ }
504
+
312
505
  /* How to make a trampoline. Derived from gcc/config/i386/i386.c. */
313
506
 
314
507
  #define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
315
508
  ({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
316
509
  unsigned int __fun = (unsigned int)(FUN); \
317
510
  unsigned int __ctx = (unsigned int)(CTX); \
318
- unsigned int __dis = __fun - (__ctx + 10); \
511
+ unsigned int __dis = __fun - (__ctx + 10); \
319
512
  *(unsigned char*) &__tramp[0] = 0xb8; \
320
513
  *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
321
514
  *(unsigned char *) &__tramp[5] = 0xe9; \
@@ -340,11 +533,23 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
340
533
 
341
534
  ffi_status
342
535
  ffi_prep_closure_loc (ffi_closure* closure,
343
- ffi_cif* cif,
344
- void (*fun)(ffi_cif*,void*,void**,void*),
345
- void *user_data,
346
- void *codeloc)
536
+ ffi_cif* cif,
537
+ void (*fun)(ffi_cif*,void*,void**,void*),
538
+ void *user_data,
539
+ void *codeloc)
347
540
  {
541
+ #ifdef X86_WIN64
542
+ #define ISFLOAT(IDX) (cif->arg_types[IDX]->type == FFI_TYPE_FLOAT || cif->arg_types[IDX]->type == FFI_TYPE_DOUBLE)
543
+ #define FLAG(IDX) (cif->nargs>(IDX)&&ISFLOAT(IDX)?(1<<(IDX)):0)
544
+ if (cif->abi == FFI_WIN64)
545
+ {
546
+ int mask = FLAG(0)|FLAG(1)|FLAG(2)|FLAG(3);
547
+ FFI_INIT_TRAMPOLINE_WIN64 (&closure->tramp[0],
548
+ &ffi_closure_win64,
549
+ codeloc, mask);
550
+ /* make sure we can execute here */
551
+ }
552
+ #else
348
553
  if (cif->abi == FFI_SYSV)
349
554
  {
350
555
  FFI_INIT_TRAMPOLINE (&closure->tramp[0],
@@ -358,7 +563,8 @@ ffi_prep_closure_loc (ffi_closure* closure,
358
563
  &ffi_closure_STDCALL,
359
564
  (void*)codeloc, cif->bytes);
360
565
  }
361
- #endif
566
+ #endif /* X86_WIN32 */
567
+ #endif /* !X86_WIN64 */
362
568
  else
363
569
  {
364
570
  return FFI_BAD_ABI;
@@ -377,10 +583,10 @@ ffi_prep_closure_loc (ffi_closure* closure,
377
583
 
378
584
  ffi_status
379
585
  ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
380
- ffi_cif* cif,
381
- void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
382
- void *user_data,
383
- void *codeloc)
586
+ ffi_cif* cif,
587
+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
588
+ void *user_data,
589
+ void *codeloc)
384
590
  {
385
591
  int i;
386
592
 
@@ -401,7 +607,7 @@ ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
401
607
 
402
608
 
403
609
  FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV,
404
- codeloc);
610
+ codeloc);
405
611
 
406
612
  closure->cif = cif;
407
613
  closure->user_data = user_data;
@@ -423,12 +629,12 @@ ffi_prep_args_raw(char *stack, extended_cif *ecif)
423
629
 
424
630
  extern void
425
631
  ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, unsigned,
426
- unsigned, unsigned *, void (*fn)(void));
632
+ unsigned, unsigned *, void (*fn)(void));
427
633
 
428
634
  #ifdef X86_WIN32
429
635
  extern void
430
636
  ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *, unsigned,
431
- unsigned, unsigned *, void (*fn)(void));
637
+ unsigned, unsigned *, void (*fn)(void));
432
638
  #endif /* X86_WIN32 */
433
639
 
434
640
  void
@@ -440,8 +646,8 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
440
646
  ecif.cif = cif;
441
647
  ecif.avalue = avalue;
442
648
 
443
- /* If the return value is a struct and we don't have a return */
444
- /* value address then we need to make one */
649
+ /* If the return value is a struct and we don't have a return */
650
+ /* value address then we need to make one */
445
651
 
446
652
  if ((rvalue == NULL) &&
447
653
  (cif->rtype->type == FFI_TYPE_STRUCT))
@@ -456,12 +662,12 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
456
662
  {
457
663
  case FFI_SYSV:
458
664
  ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
459
- ecif.rvalue, fn);
665
+ ecif.rvalue, fn);
460
666
  break;
461
667
  #ifdef X86_WIN32
462
668
  case FFI_STDCALL:
463
669
  ffi_call_STDCALL(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
464
- ecif.rvalue, fn);
670
+ ecif.rvalue, fn);
465
671
  break;
466
672
  #endif /* X86_WIN32 */
467
673
  default:
@@ -472,4 +678,5 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
472
678
 
473
679
  #endif
474
680
 
475
- #endif /* __x86_64__ */
681
+ #endif /* !__x86_64__ || X86_WIN64 */
682
+