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
@@ -1,9 +1,9 @@
1
1
  #! /bin/sh
2
2
  # Common stub for a few missing GNU programs while installing.
3
3
 
4
- scriptversion=2004-09-07.08
4
+ scriptversion=2005-06-08.21
5
5
 
6
- # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004
6
+ # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005
7
7
  # Free Software Foundation, Inc.
8
8
  # Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
9
9
 
@@ -19,8 +19,8 @@ scriptversion=2004-09-07.08
19
19
 
20
20
  # You should have received a copy of the GNU General Public License
21
21
  # along with this program; if not, write to the Free Software
22
- # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23
- # 02111-1307, USA.
22
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23
+ # 02110-1301, USA.
24
24
 
25
25
  # As a special exception to the GNU General Public License, if you
26
26
  # distribute this file as part of a program that contains a
@@ -87,12 +87,12 @@ Supported PROGRAM values:
87
87
  yacc create \`y.tab.[ch]', if possible, from existing .[ch]
88
88
 
89
89
  Send bug reports to <bug-automake@gnu.org>."
90
- exit 0
90
+ exit $?
91
91
  ;;
92
92
 
93
93
  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
94
94
  echo "missing $scriptversion (GNU Automake)"
95
- exit 0
95
+ exit $?
96
96
  ;;
97
97
 
98
98
  -*)
@@ -288,11 +288,18 @@ WARNING: \`$1' is $msg. You should only need it if
288
288
  call might also be the consequence of using a buggy \`make' (AIX,
289
289
  DU, IRIX). You might want to install the \`Texinfo' package or
290
290
  the \`GNU make' package. Grab either from any GNU archive site."
291
+ # The file to touch is that specified with -o ...
291
292
  file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
292
293
  if test -z "$file"; then
293
- file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
294
- file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
294
+ # ... or it is the one specified with @setfilename ...
295
+ infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
296
+ file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile`
297
+ # ... or it is derived from the source name (dir/f.texi becomes f.info)
298
+ test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
295
299
  fi
300
+ # If the file does not exist, the user really needs makeinfo;
301
+ # let's fail without touching anything.
302
+ test -f $file || exit 1
296
303
  touch $file
297
304
  ;;
298
305
 
@@ -67,11 +67,18 @@
67
67
 
68
68
  #if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
69
69
  || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
70
- || defined(__ARM_ARCH_6ZK__)
70
+ || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
71
+ || defined(__ARM_ARCH_6M__)
71
72
  # undef __ARM_ARCH__
72
73
  # define __ARM_ARCH__ 6
73
74
  #endif
74
75
 
76
+ #if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
77
+ || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__)
78
+ # undef __ARM_ARCH__
79
+ # define __ARM_ARCH__ 7
80
+ #endif
81
+
75
82
  #if __ARM_ARCH__ >= 5
76
83
  # define call_reg(x) blx x
77
84
  #elif defined (__ARM_ARCH_4T__)
@@ -189,7 +196,7 @@ ARM_FUNC_START ffi_call_SYSV
189
196
 
190
197
  @ return INT
191
198
  cmp r3, #FFI_TYPE_INT
192
- #ifdef __SOFTFP__
199
+ #if defined(__SOFTFP__) || defined(__ARM_EABI__)
193
200
  cmpne r3, #FFI_TYPE_FLOAT
194
201
  #endif
195
202
  streq r0, [r2]
@@ -197,12 +204,12 @@ ARM_FUNC_START ffi_call_SYSV
197
204
 
198
205
  @ return INT64
199
206
  cmp r3, #FFI_TYPE_SINT64
200
- #ifdef __SOFTFP__
207
+ #if defined(__SOFTFP__) || defined(__ARM_EABI__)
201
208
  cmpne r3, #FFI_TYPE_DOUBLE
202
209
  #endif
203
210
  stmeqia r2, {r0, r1}
204
211
 
205
- #ifndef __SOFTFP__
212
+ #if !defined(__SOFTFP__) && !defined(__ARM_EABI__)
206
213
  beq LSYM(Lepilogue)
207
214
 
208
215
  @ return FLOAT
@@ -245,21 +252,21 @@ ARM_FUNC_START ffi_closure_SYSV
245
252
  beq .Lretint
246
253
 
247
254
  cmp r0, #FFI_TYPE_FLOAT
248
- #ifdef __SOFTFP__
255
+ #if defined(__SOFTFP__) || defined(__ARM_EABI__)
249
256
  beq .Lretint
250
257
  #else
251
258
  beq .Lretfloat
252
259
  #endif
253
260
 
254
261
  cmp r0, #FFI_TYPE_DOUBLE
255
- #ifdef __SOFTFP__
262
+ #if defined(__SOFTFP__) || defined(__ARM_EABI__)
256
263
  beq .Lretlonglong
257
264
  #else
258
265
  beq .Lretdouble
259
266
  #endif
260
267
 
261
268
  cmp r0, #FFI_TYPE_LONGDOUBLE
262
- #ifdef __SOFTFP__
269
+ #if defined(__SOFTFP__) || defined(__ARM_EABI__)
263
270
  beq .Lretlonglong
264
271
  #else
265
272
  beq .Lretlongdouble
@@ -278,7 +285,7 @@ ARM_FUNC_START ffi_closure_SYSV
278
285
  ldr r1, [sp, #4]
279
286
  b .Lclosure_epilogue
280
287
 
281
- #ifndef __SOFTFP__
288
+ #if !defined(__SOFTFP__) && !defined(__ARM_EABI__)
282
289
  .Lretfloat:
283
290
  ldfs f0, [sp]
284
291
  b .Lclosure_epilogue
@@ -0,0 +1,421 @@
1
+ /* -----------------------------------------------------------------------
2
+ ffi.c - Copyright (c) 2009 Bradley Smith <brad@brad-smith.co.uk>
3
+
4
+ AVR32 Foreign Function Interface
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining
7
+ a copy of this software and associated documentation files (the
8
+ ``Software''), to deal in the Software without restriction, including
9
+ without limitation the rights to use, copy, modify, merge, publish,
10
+ distribute, sublicense, and/or sell copies of the Software, and to
11
+ permit persons to whom the Software is furnished to do so, subject to
12
+ the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included
15
+ in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24
+ DEALINGS IN THE SOFTWARE.
25
+ ----------------------------------------------------------------------- */
26
+
27
+ #include <ffi.h>
28
+ #include <ffi_common.h>
29
+
30
+ #include <stdlib.h>
31
+ #include <stdio.h>
32
+ #include <unistd.h>
33
+ #include <asm/unistd.h>
34
+
35
+ /* #define DEBUG */
36
+
37
+ extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
38
+ unsigned int, unsigned int, unsigned int*, unsigned int,
39
+ void (*fn)(void));
40
+ extern void ffi_closure_SYSV (ffi_closure *);
41
+
42
+ unsigned int pass_struct_on_stack(ffi_type *type)
43
+ {
44
+ if(type->type != FFI_TYPE_STRUCT)
45
+ return 0;
46
+
47
+ if(type->alignment < type->size &&
48
+ !(type->size == 4 || type->size == 8) &&
49
+ !(type->size == 8 && type->alignment >= 4))
50
+ return 1;
51
+
52
+ if(type->size == 3 || type->size == 5 || type->size == 6 ||
53
+ type->size == 7)
54
+ return 1;
55
+
56
+ return 0;
57
+ }
58
+
59
+ /* ffi_prep_args is called by the assembly routine once stack space
60
+ * has been allocated for the function's arguments
61
+ *
62
+ * This is annoyingly complex since we need to keep track of used
63
+ * registers.
64
+ */
65
+
66
+ void ffi_prep_args(char *stack, extended_cif *ecif)
67
+ {
68
+ unsigned int i;
69
+ void **p_argv;
70
+ ffi_type **p_arg;
71
+ char *reg_base = stack;
72
+ char *stack_base = stack + 20;
73
+ unsigned int stack_offset = 0;
74
+ unsigned int reg_mask = 0;
75
+
76
+ p_argv = ecif->avalue;
77
+
78
+ /* If cif->flags is struct then we know it's not passed in registers */
79
+ if(ecif->cif->flags == FFI_TYPE_STRUCT)
80
+ {
81
+ *(void**)reg_base = ecif->rvalue;
82
+ reg_mask |= 1;
83
+ }
84
+
85
+ for(i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs;
86
+ i++, p_arg++)
87
+ {
88
+ size_t z = (*p_arg)->size;
89
+ int alignment = (*p_arg)->alignment;
90
+ int type = (*p_arg)->type;
91
+ char *addr = 0;
92
+
93
+ if(z % 4 != 0)
94
+ z += (4 - z % 4);
95
+
96
+ if(reg_mask != 0x1f)
97
+ {
98
+ if(pass_struct_on_stack(*p_arg))
99
+ {
100
+ addr = stack_base + stack_offset;
101
+ stack_offset += z;
102
+ }
103
+ else if(z == sizeof(int))
104
+ {
105
+ char index = 0;
106
+
107
+ while((reg_mask >> index) & 1)
108
+ index++;
109
+
110
+ addr = reg_base + (index * 4);
111
+ reg_mask |= (1 << index);
112
+ }
113
+ else if(z == 2 * sizeof(int))
114
+ {
115
+ if(!((reg_mask >> 1) & 1))
116
+ {
117
+ addr = reg_base + 4;
118
+ reg_mask |= (3 << 1);
119
+ }
120
+ else if(!((reg_mask >> 3) & 1))
121
+ {
122
+ addr = reg_base + 12;
123
+ reg_mask |= (3 << 3);
124
+ }
125
+ }
126
+ }
127
+
128
+ if(!addr)
129
+ {
130
+ addr = stack_base + stack_offset;
131
+ stack_offset += z;
132
+ }
133
+
134
+ if(type == FFI_TYPE_STRUCT && (*p_arg)->elements[1] == NULL)
135
+ type = (*p_arg)->elements[0]->type;
136
+
137
+ switch(type)
138
+ {
139
+ case FFI_TYPE_UINT8:
140
+ *(unsigned int *)addr = (unsigned int)*(UINT8 *)(*p_argv);
141
+ break;
142
+ case FFI_TYPE_SINT8:
143
+ *(signed int *)addr = (signed int)*(SINT8 *)(*p_argv);
144
+ break;
145
+ case FFI_TYPE_UINT16:
146
+ *(unsigned int *)addr = (unsigned int)*(UINT16 *)(*p_argv);
147
+ break;
148
+ case FFI_TYPE_SINT16:
149
+ *(signed int *)addr = (signed int)*(SINT16 *)(*p_argv);
150
+ break;
151
+ default:
152
+ memcpy(addr, *p_argv, z);
153
+ }
154
+
155
+ p_argv++;
156
+ }
157
+
158
+ #ifdef DEBUG
159
+ /* Debugging */
160
+ for(i = 0; i < 5; i++)
161
+ {
162
+ if((reg_mask & (1 << i)) == 0)
163
+ printf("r%d: (unused)\n", 12 - i);
164
+ else
165
+ printf("r%d: 0x%08x\n", 12 - i, ((unsigned int*)reg_base)[i]);
166
+ }
167
+
168
+ for(i = 0; i < stack_offset / 4; i++)
169
+ {
170
+ printf("sp+%d: 0x%08x\n", i*4, ((unsigned int*)stack_base)[i]);
171
+ }
172
+ #endif
173
+ }
174
+
175
+ /* Perform machine dependent cif processing */
176
+ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
177
+ {
178
+ /* Round the stack up to a multiple of 8 bytes. This isn't needed
179
+ * everywhere, but it is on some platforms, and it doesn't harm
180
+ * anything when it isn't needed. */
181
+ cif->bytes = (cif->bytes + 7) & ~7;
182
+
183
+ /* Flag to indicate that he return value is in fact a struct */
184
+ cif->rstruct_flag = 0;
185
+
186
+ /* Set the return type flag */
187
+ switch(cif->rtype->type)
188
+ {
189
+ case FFI_TYPE_SINT8:
190
+ case FFI_TYPE_UINT8:
191
+ cif->flags = (unsigned)FFI_TYPE_UINT8;
192
+ break;
193
+ case FFI_TYPE_SINT16:
194
+ case FFI_TYPE_UINT16:
195
+ cif->flags = (unsigned)FFI_TYPE_UINT16;
196
+ break;
197
+ case FFI_TYPE_FLOAT:
198
+ case FFI_TYPE_SINT32:
199
+ case FFI_TYPE_UINT32:
200
+ case FFI_TYPE_POINTER:
201
+ cif->flags = (unsigned)FFI_TYPE_UINT32;
202
+ break;
203
+ case FFI_TYPE_DOUBLE:
204
+ case FFI_TYPE_SINT64:
205
+ case FFI_TYPE_UINT64:
206
+ cif->flags = (unsigned)FFI_TYPE_UINT64;
207
+ break;
208
+ case FFI_TYPE_STRUCT:
209
+ cif->rstruct_flag = 1;
210
+ if(!pass_struct_on_stack(cif->rtype))
211
+ {
212
+ if(cif->rtype->size <= 1)
213
+ cif->flags = (unsigned)FFI_TYPE_UINT8;
214
+ else if(cif->rtype->size <= 2)
215
+ cif->flags = (unsigned)FFI_TYPE_UINT16;
216
+ else if(cif->rtype->size <= 4)
217
+ cif->flags = (unsigned)FFI_TYPE_UINT32;
218
+ else if(cif->rtype->size <= 8)
219
+ cif->flags = (unsigned)FFI_TYPE_UINT64;
220
+ else
221
+ cif->flags = (unsigned)cif->rtype->type;
222
+ }
223
+ else
224
+ cif->flags = (unsigned)cif->rtype->type;
225
+ break;
226
+ default:
227
+ cif->flags = (unsigned)cif->rtype->type;
228
+ break;
229
+ }
230
+
231
+ return FFI_OK;
232
+ }
233
+
234
+ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
235
+ {
236
+ extended_cif ecif;
237
+
238
+ unsigned int size = 0, i = 0;
239
+ ffi_type **p_arg;
240
+
241
+ ecif.cif = cif;
242
+ ecif.avalue = avalue;
243
+
244
+ for(i = 0, p_arg = cif->arg_types; i < cif->nargs; i++, p_arg++)
245
+ size += (*p_arg)->size + (4 - (*p_arg)->size % 4);
246
+
247
+ /* If the return value is a struct and we don't have a return value
248
+ * address then we need to make one */
249
+
250
+ /* If cif->flags is struct then it's not suitable for registers */
251
+ if((rvalue == NULL) && (cif->flags == FFI_TYPE_STRUCT))
252
+ ecif.rvalue = alloca(cif->rtype->size);
253
+ else
254
+ ecif.rvalue = rvalue;
255
+
256
+ switch(cif->abi)
257
+ {
258
+ case FFI_SYSV:
259
+ ffi_call_SYSV(ffi_prep_args, &ecif, size, cif->flags,
260
+ ecif.rvalue, cif->rstruct_flag, fn);
261
+ break;
262
+ default:
263
+ FFI_ASSERT(0);
264
+ break;
265
+ }
266
+ }
267
+
268
+ static void ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
269
+ void **avalue, ffi_cif *cif)
270
+ {
271
+ register unsigned int i, reg_mask = 0;
272
+ register void **p_argv;
273
+ register ffi_type **p_arg;
274
+ register char *reg_base = stack;
275
+ register char *stack_base = stack + 20;
276
+ register unsigned int stack_offset = 0;
277
+
278
+ #ifdef DEBUG
279
+ /* Debugging */
280
+ for(i = 0; i < cif->nargs + 7; i++)
281
+ {
282
+ printf("sp+%d: 0x%08x\n", i*4, ((unsigned int*)stack)[i]);
283
+ }
284
+ #endif
285
+
286
+ /* If cif->flags is struct then we know it's not passed in registers */
287
+ if(cif->flags == FFI_TYPE_STRUCT)
288
+ {
289
+ *rvalue = *(void **)reg_base;
290
+ reg_mask |= 1;
291
+ }
292
+
293
+ p_argv = avalue;
294
+
295
+ for(i = 0, p_arg = cif->arg_types; i < cif->nargs; i++, p_arg++)
296
+ {
297
+ size_t z = (*p_arg)->size;
298
+ int alignment = (*p_arg)->alignment;
299
+
300
+ *p_argv = 0;
301
+
302
+ if(z % 4 != 0)
303
+ z += (4 - z % 4);
304
+
305
+ if(reg_mask != 0x1f)
306
+ {
307
+ if(pass_struct_on_stack(*p_arg))
308
+ {
309
+ *p_argv = (void*)stack_base + stack_offset;
310
+ stack_offset += z;
311
+ }
312
+ else if(z <= sizeof(int))
313
+ {
314
+ char index = 0;
315
+
316
+ while((reg_mask >> index) & 1)
317
+ index++;
318
+
319
+ *p_argv = (void*)reg_base + (index * 4);
320
+ reg_mask |= (1 << index);
321
+ }
322
+ else if(z == 2 * sizeof(int))
323
+ {
324
+ if(!((reg_mask >> 1) & 1))
325
+ {
326
+ *p_argv = (void*)reg_base + 4;
327
+ reg_mask |= (3 << 1);
328
+ }
329
+ else if(!((reg_mask >> 3) & 1))
330
+ {
331
+ *p_argv = (void*)reg_base + 12;
332
+ reg_mask |= (3 << 3);
333
+ }
334
+ }
335
+ }
336
+
337
+ if(!*p_argv)
338
+ {
339
+ *p_argv = (void*)stack_base + stack_offset;
340
+ stack_offset += z;
341
+ }
342
+
343
+ if((*p_arg)->type != FFI_TYPE_STRUCT ||
344
+ (*p_arg)->elements[1] == NULL)
345
+ {
346
+ if(alignment == 1)
347
+ **(unsigned int**)p_argv <<= 24;
348
+ else if(alignment == 2)
349
+ **(unsigned int**)p_argv <<= 16;
350
+ }
351
+
352
+ p_argv++;
353
+ }
354
+
355
+ #ifdef DEBUG
356
+ /* Debugging */
357
+ for(i = 0; i < cif->nargs; i++)
358
+ {
359
+ printf("sp+%d: 0x%08x\n", i*4, *(((unsigned int**)avalue)[i]));
360
+ }
361
+ #endif
362
+ }
363
+
364
+ /* This function is jumped to by the trampoline */
365
+
366
+ unsigned int ffi_closure_SYSV_inner(ffi_closure *closure, void **respp,
367
+ void *args)
368
+ {
369
+ ffi_cif *cif;
370
+ void **arg_area;
371
+ unsigned int i, size = 0;
372
+ ffi_type **p_arg;
373
+
374
+ cif = closure->cif;
375
+
376
+ for(i = 0, p_arg = cif->arg_types; i < cif->nargs; i++, p_arg++)
377
+ size += (*p_arg)->size + (4 - (*p_arg)->size % 4);
378
+
379
+ arg_area = (void **)alloca(size);
380
+
381
+ /* this call will initialize ARG_AREA, such that each element in that
382
+ * array points to the corresponding value on the stack; and if the
383
+ * function returns a structure, it will re-set RESP to point to the
384
+ * structure return address. */
385
+
386
+ ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif);
387
+
388
+ (closure->fun)(cif, *respp, arg_area, closure->user_data);
389
+
390
+ return cif->flags;
391
+ }
392
+
393
+ ffi_status ffi_prep_closure_loc(ffi_closure* closure, ffi_cif* cif,
394
+ void (*fun)(ffi_cif*, void*, void**, void*), void *user_data,
395
+ void *codeloc)
396
+ {
397
+ FFI_ASSERT(cif->abi == FFI_SYSV);
398
+
399
+ unsigned char *__tramp = (unsigned char*)(&closure->tramp[0]);
400
+ unsigned int __fun = (unsigned int)(&ffi_closure_SYSV);
401
+ unsigned int __ctx = (unsigned int)(codeloc);
402
+ unsigned int __rstruct_flag = (unsigned int)(cif->rstruct_flag);
403
+ unsigned int __inner = (unsigned int)(&ffi_closure_SYSV_inner);
404
+ *(unsigned int*) &__tramp[0] = 0xebcd1f00; /* pushm r8-r12 */
405
+ *(unsigned int*) &__tramp[4] = 0xfefc0010; /* ld.w r12, pc[16] */
406
+ *(unsigned int*) &__tramp[8] = 0xfefb0010; /* ld.w r11, pc[16] */
407
+ *(unsigned int*) &__tramp[12] = 0xfefa0010; /* ld.w r10, pc[16] */
408
+ *(unsigned int*) &__tramp[16] = 0xfeff0010; /* ld.w pc, pc[16] */
409
+ *(unsigned int*) &__tramp[20] = __ctx;
410
+ *(unsigned int*) &__tramp[24] = __rstruct_flag;
411
+ *(unsigned int*) &__tramp[28] = __inner;
412
+ *(unsigned int*) &__tramp[32] = __fun;
413
+ syscall(__NR_cacheflush, 0, (&__tramp[0]), 36);
414
+
415
+ closure->cif = cif;
416
+ closure->user_data = user_data;
417
+ closure->fun = fun;
418
+
419
+ return FFI_OK;
420
+ }
421
+