ffi 1.0.11 → 1.0.12.pre

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 (159) hide show
  1. data/Rakefile +1 -1
  2. data/ext/ffi_c/AbstractMemory.c +9 -0
  3. data/ext/ffi_c/AbstractMemory.h +4 -0
  4. data/ext/ffi_c/Buffer.c +8 -0
  5. data/ext/ffi_c/Call.c +8 -0
  6. data/ext/ffi_c/ClosurePool.c +12 -0
  7. data/ext/ffi_c/DynamicLibrary.c +7 -1
  8. data/ext/ffi_c/Function.c +11 -1
  9. data/ext/ffi_c/Function.h +6 -0
  10. data/ext/ffi_c/FunctionInfo.c +8 -0
  11. data/ext/ffi_c/LastError.c +8 -0
  12. data/ext/ffi_c/MemoryPointer.c +8 -0
  13. data/ext/ffi_c/MemoryPointer.h +6 -0
  14. data/ext/ffi_c/MethodHandle.c +8 -0
  15. data/ext/ffi_c/Platform.c +8 -0
  16. data/ext/ffi_c/Pointer.c +8 -0
  17. data/ext/ffi_c/Pointer.h +6 -0
  18. data/ext/ffi_c/Struct.c +6 -0
  19. data/ext/ffi_c/StructByReference.c +8 -0
  20. data/ext/ffi_c/StructByValue.c +8 -0
  21. data/ext/ffi_c/StructLayout.c +6 -0
  22. data/ext/ffi_c/Thread.c +7 -0
  23. data/ext/ffi_c/Thread.h +6 -0
  24. data/ext/ffi_c/Type.c +3 -0
  25. data/ext/ffi_c/Types.h +4 -0
  26. data/ext/ffi_c/Variadic.c +8 -0
  27. data/ext/ffi_c/endian.h +3 -0
  28. data/ext/ffi_c/extconf.rb +6 -1
  29. data/ext/ffi_c/libffi.vc.mk +26 -0
  30. data/ext/ffi_c/libffi.vc64.mk +26 -0
  31. data/ext/ffi_c/libffi/ChangeLog +541 -0
  32. data/ext/ffi_c/libffi/ChangeLog.libffi +13 -87
  33. data/ext/ffi_c/libffi/LICENSE +3 -3
  34. data/ext/ffi_c/libffi/Makefile.am +41 -32
  35. data/ext/ffi_c/libffi/Makefile.in +95 -66
  36. data/ext/ffi_c/libffi/Makefile.vc +141 -0
  37. data/ext/ffi_c/libffi/Makefile.vc64 +141 -0
  38. data/ext/ffi_c/libffi/README +40 -4
  39. data/ext/ffi_c/libffi/aclocal.m4 +729 -7854
  40. data/ext/ffi_c/libffi/build-ios.sh +67 -0
  41. data/ext/ffi_c/libffi/compile +11 -10
  42. data/ext/ffi_c/libffi/config.guess +4 -1
  43. data/ext/ffi_c/libffi/config.sub +6 -3
  44. data/ext/ffi_c/libffi/configure +6264 -6354
  45. data/ext/ffi_c/libffi/configure.ac +155 -63
  46. data/ext/ffi_c/libffi/depcomp +81 -35
  47. data/ext/ffi_c/libffi/doc/libffi.info +78 -18
  48. data/ext/ffi_c/libffi/doc/libffi.texi +64 -5
  49. data/ext/ffi_c/libffi/doc/stamp-vti +4 -4
  50. data/ext/ffi_c/libffi/doc/version.texi +4 -4
  51. data/ext/ffi_c/libffi/fficonfig.h.in +18 -0
  52. data/ext/ffi_c/libffi/fficonfig.hw +57 -0
  53. data/ext/ffi_c/libffi/include/Makefile.in +21 -3
  54. data/ext/ffi_c/libffi/include/ffi.h.in +42 -14
  55. data/ext/ffi_c/libffi/include/ffi.h.vc +427 -0
  56. data/ext/ffi_c/libffi/include/ffi.h.vc64 +427 -0
  57. data/ext/ffi_c/libffi/include/ffi_common.h +9 -5
  58. data/ext/ffi_c/libffi/install-sh +364 -167
  59. data/ext/ffi_c/libffi/ltmain.sh +2599 -1369
  60. data/ext/ffi_c/libffi/m4/ax_cc_maxopt.m4 +176 -0
  61. data/ext/ffi_c/libffi/m4/ax_cflags_warn_all.m4 +195 -0
  62. data/ext/ffi_c/libffi/m4/ax_check_compiler_flags.m4 +76 -0
  63. data/ext/ffi_c/libffi/m4/ax_compiler_vendor.m4 +63 -0
  64. data/ext/ffi_c/libffi/m4/ax_configure_args.m4 +70 -0
  65. data/ext/ffi_c/libffi/m4/ax_enable_builddir.m4 +300 -0
  66. data/ext/ffi_c/libffi/m4/ax_gcc_archflag.m4 +215 -0
  67. data/ext/ffi_c/libffi/m4/ax_gcc_x86_cpuid.m4 +79 -0
  68. data/ext/ffi_c/libffi/m4/libtool.m4 +1239 -768
  69. data/ext/ffi_c/libffi/m4/ltoptions.m4 +7 -6
  70. data/ext/ffi_c/libffi/m4/ltversion.m4 +6 -6
  71. data/ext/ffi_c/libffi/m4/lt~obsolete.m4 +9 -3
  72. data/ext/ffi_c/libffi/man/Makefile.in +21 -3
  73. data/ext/ffi_c/libffi/mdate-sh +0 -0
  74. data/ext/ffi_c/libffi/missing +60 -44
  75. data/ext/ffi_c/libffi/msvcc.sh +197 -0
  76. data/ext/ffi_c/libffi/src/alpha/osf.S +39 -18
  77. data/ext/ffi_c/libffi/src/arm/ffi.c +443 -24
  78. data/ext/ffi_c/libffi/src/arm/ffitarget.h +17 -1
  79. data/ext/ffi_c/libffi/src/arm/gentramp.sh +118 -0
  80. data/ext/ffi_c/libffi/src/arm/sysv.S +206 -15
  81. data/ext/ffi_c/libffi/src/arm/trampoline.S +4450 -0
  82. data/ext/ffi_c/libffi/src/avr32/ffi.c +4 -2
  83. data/ext/ffi_c/libffi/src/avr32/ffitarget.h +2 -2
  84. data/ext/ffi_c/libffi/src/closures.c +17 -35
  85. data/ext/ffi_c/libffi/src/cris/ffi.c +1 -1
  86. data/ext/ffi_c/libffi/src/cris/ffitarget.h +2 -2
  87. data/ext/ffi_c/libffi/src/dlmalloc.c +66 -4
  88. data/ext/ffi_c/libffi/src/frv/ffitarget.h +2 -6
  89. data/ext/ffi_c/libffi/src/ia64/ffi.c +7 -5
  90. data/ext/ffi_c/libffi/src/ia64/ffitarget.h +2 -2
  91. data/ext/ffi_c/libffi/src/java_raw_api.c +1 -1
  92. data/ext/ffi_c/libffi/src/m32r/ffitarget.h +2 -2
  93. data/ext/ffi_c/libffi/src/m68k/ffi.c +10 -0
  94. data/ext/ffi_c/libffi/src/m68k/ffitarget.h +2 -2
  95. data/ext/ffi_c/libffi/src/m68k/sysv.S +36 -0
  96. data/ext/ffi_c/libffi/src/mips/ffi.c +12 -5
  97. data/ext/ffi_c/libffi/src/mips/ffitarget.h +18 -11
  98. data/ext/ffi_c/libffi/src/mips/n32.S +4 -4
  99. data/ext/ffi_c/libffi/src/moxie/eabi.S +128 -0
  100. data/ext/ffi_c/libffi/src/moxie/ffi.c +276 -0
  101. data/ext/ffi_c/libffi/src/pa/ffi.c +7 -4
  102. data/ext/ffi_c/libffi/src/pa/ffitarget.h +6 -5
  103. data/ext/ffi_c/libffi/src/powerpc/aix.S +5 -1
  104. data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +2 -0
  105. data/ext/ffi_c/libffi/src/powerpc/asm.h +1 -1
  106. data/ext/ffi_c/libffi/src/powerpc/darwin.S +215 -77
  107. data/ext/ffi_c/libffi/src/powerpc/darwin_closure.S +358 -100
  108. data/ext/ffi_c/libffi/src/powerpc/ffi.c +11 -5
  109. data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +603 -172
  110. data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +17 -4
  111. data/ext/ffi_c/libffi/src/prep_cif.c +16 -13
  112. data/ext/ffi_c/libffi/src/s390/ffitarget.h +4 -2
  113. data/ext/ffi_c/libffi/src/sh/ffitarget.h +2 -2
  114. data/ext/ffi_c/libffi/src/sh64/ffitarget.h +2 -2
  115. data/ext/ffi_c/libffi/src/sparc/ffi.c +55 -11
  116. data/ext/ffi_c/libffi/src/sparc/ffitarget.h +5 -3
  117. data/ext/ffi_c/libffi/src/x86/ffi.c +54 -92
  118. data/ext/ffi_c/libffi/src/x86/ffi64.c +17 -8
  119. data/ext/ffi_c/libffi/src/x86/ffitarget.h +15 -14
  120. data/ext/ffi_c/libffi/src/x86/sysv.S +40 -26
  121. data/ext/ffi_c/libffi/src/x86/unix64.S +4 -0
  122. data/ext/ffi_c/libffi/src/x86/win32.S +379 -191
  123. data/ext/ffi_c/libffi/src/x86/win64.S +15 -7
  124. data/ext/ffi_c/libffi/testsuite/Makefile.am +1 -1
  125. data/ext/ffi_c/libffi/testsuite/Makefile.in +22 -4
  126. data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +350 -0
  127. data/ext/ffi_c/libffi/testsuite/libffi.call/call.exp +1 -5
  128. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split.c +1 -1
  129. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c +1 -1
  130. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint64.c +1 -0
  131. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint64.c +1 -0
  132. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_double_va.c +3 -0
  133. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble.c +2 -2
  134. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble_va.c +3 -0
  135. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer.c +1 -1
  136. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer_stack.c +1 -1
  137. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ulonglong.c +1 -0
  138. data/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_abi.c +2 -3
  139. data/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_typedef.c +2 -1
  140. data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +36 -0
  141. data/ext/ffi_c/libffi/testsuite/libffi.call/huge_struct.c +17 -17
  142. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll1.c +1 -0
  143. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium2.c +1 -0
  144. data/ext/ffi_c/libffi/testsuite/libffi.special/ffitestcxx.h +1 -1
  145. data/ext/ffi_c/libffi/testsuite/libffi.special/special.exp +1 -3
  146. data/ext/ffi_c/win32/stdint.h +199 -0
  147. data/gen/Rakefile +18 -2
  148. data/lib/ffi/platform/arm-linux/types.conf +102 -0
  149. data/lib/ffi/platform/i486-gnu/types.conf +107 -0
  150. data/lib/ffi/platform/ia64-linux/types.conf +102 -0
  151. data/lib/ffi/platform/mips-linux/types.conf +102 -0
  152. data/lib/ffi/platform/mipsel-linux/types.conf +102 -0
  153. data/lib/ffi/platform/powerpc-linux/types.conf +100 -0
  154. data/lib/ffi/platform/s390-linux/types.conf +102 -0
  155. data/lib/ffi/platform/s390x-linux/types.conf +102 -0
  156. data/lib/ffi/platform/sparc-linux/types.conf +102 -0
  157. data/lib/ffi/tools/types_generator.rb +8 -1
  158. data/lib/ffi_c.bundle +0 -0
  159. metadata +72 -42
@@ -1,6 +1,6 @@
1
1
  /* -----------------------------------------------------------------*-C-*-
2
2
  ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
3
- Copyright (C) 2007, 2008 Free Software Foundation, Inc
3
+ Copyright (C) 2007, 2008, 2010 Free Software Foundation, Inc
4
4
  Target configuration macros for PowerPC.
5
5
 
6
6
  Permission is hereby granted, free of charge, to any person obtaining
@@ -31,12 +31,21 @@
31
31
  /* ---- System specific configurations ----------------------------------- */
32
32
 
33
33
  #if defined (POWERPC) && defined (__powerpc64__) /* linux64 */
34
+ #ifndef POWERPC64
34
35
  #define POWERPC64
35
- #elif defined (POWERPC_DARWIN) && defined (__ppc64__) /* Darwin */
36
+ #endif
37
+ #elif defined (POWERPC_DARWIN) && defined (__ppc64__) /* Darwin64 */
38
+ #ifndef POWERPC64
36
39
  #define POWERPC64
40
+ #endif
41
+ #ifndef POWERPC_DARWIN64
42
+ #define POWERPC_DARWIN64
43
+ #endif
37
44
  #elif defined (POWERPC_AIX) && defined (__64BIT__) /* AIX64 */
45
+ #ifndef POWERPC64
38
46
  #define POWERPC64
39
47
  #endif
48
+ #endif
40
49
 
41
50
  #ifndef LIBFFI_ASM
42
51
  typedef unsigned long ffi_arg;
@@ -108,9 +117,13 @@ typedef enum ffi_abi {
108
117
  #define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_TYPE_LAST + 2)
109
118
 
110
119
  #if defined(POWERPC64) || defined(POWERPC_AIX)
111
- #define FFI_TRAMPOLINE_SIZE 24
120
+ # if defined(POWERPC_DARWIN64)
121
+ # define FFI_TRAMPOLINE_SIZE 48
122
+ # else
123
+ # define FFI_TRAMPOLINE_SIZE 24
124
+ # endif
112
125
  #else /* POWERPC || POWERPC_AIX */
113
- #define FFI_TRAMPOLINE_SIZE 40
126
+ # define FFI_TRAMPOLINE_SIZE 40
114
127
  #endif
115
128
 
116
129
  #ifndef LIBFFI_ASM
@@ -1,5 +1,6 @@
1
1
  /* -----------------------------------------------------------------------
2
- prep_cif.c - Copyright (c) 1996, 1998, 2007 Red Hat, Inc.
2
+ prep_cif.c - Copyright (c) 2011 Anthony Green
3
+ Copyright (c) 1996, 1998, 2007 Red Hat, Inc.
3
4
 
4
5
  Permission is hereby granted, free of charge, to any person obtaining
5
6
  a copy of this software and associated documentation files (the
@@ -37,17 +38,21 @@ static ffi_status initialize_aggregate(ffi_type *arg)
37
38
  {
38
39
  ffi_type **ptr;
39
40
 
40
- FFI_ASSERT(arg != NULL);
41
+ if (UNLIKELY(arg == NULL || arg->elements == NULL))
42
+ return FFI_BAD_TYPEDEF;
41
43
 
42
- FFI_ASSERT(arg->elements != NULL);
43
- FFI_ASSERT(arg->size == 0);
44
- FFI_ASSERT(arg->alignment == 0);
44
+ arg->size = 0;
45
+ arg->alignment = 0;
45
46
 
46
47
  ptr = &(arg->elements[0]);
47
48
 
49
+ if (UNLIKELY(ptr == 0))
50
+ return FFI_BAD_TYPEDEF;
51
+
48
52
  while ((*ptr) != NULL)
49
53
  {
50
- if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
54
+ if (UNLIKELY(((*ptr)->size == 0)
55
+ && (initialize_aggregate((*ptr)) != FFI_OK)))
51
56
  return FFI_BAD_TYPEDEF;
52
57
 
53
58
  /* Perform a sanity check on the argument type */
@@ -93,7 +98,8 @@ ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,
93
98
  ffi_type **ptr;
94
99
 
95
100
  FFI_ASSERT(cif != NULL);
96
- FFI_ASSERT((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI));
101
+ if (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI))
102
+ return FFI_BAD_ABI;
97
103
 
98
104
  cif->abi = abi;
99
105
  cif->arg_types = atypes;
@@ -109,15 +115,12 @@ ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,
109
115
  /* Perform a sanity check on the return type */
110
116
  FFI_ASSERT_VALID_TYPE(cif->rtype);
111
117
 
112
- /* x86-64 and s390 stack space allocation is handled in prep_machdep. */
113
- #if !defined M68K && !defined __x86_64__ && !defined S390 && !defined PA
118
+ /* x86, x86-64 and s390 stack space allocation is handled in prep_machdep. */
119
+ #if !defined M68K && !defined X86_ANY && !defined S390 && !defined PA
114
120
  /* Make space for the return structure pointer */
115
121
  if (cif->rtype->type == FFI_TYPE_STRUCT
116
122
  #ifdef SPARC
117
123
  && (cif->abi != FFI_V9 || cif->rtype->size > 32)
118
- #endif
119
- #ifdef X86_DARWIN
120
- && (cif->rtype->size > 8)
121
124
  #endif
122
125
  )
123
126
  bytes = STACK_ARG_SIZE(sizeof(void*));
@@ -134,7 +137,7 @@ ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,
134
137
  check after the initialization. */
135
138
  FFI_ASSERT_VALID_TYPE(*ptr);
136
139
 
137
- #if !defined __x86_64__ && !defined S390 && !defined PA
140
+ #if !defined X86_ANY && !defined S390 && !defined PA
138
141
  #ifdef SPARC
139
142
  if (((*ptr)->type == FFI_TYPE_STRUCT
140
143
  && ((*ptr)->size > 16 || cif->abi != FFI_V9))
@@ -28,8 +28,10 @@
28
28
  #define LIBFFI_TARGET_H
29
29
 
30
30
  #if defined (__s390x__)
31
+ #ifndef S390X
31
32
  #define S390X
32
33
  #endif
34
+ #endif
33
35
 
34
36
  /* ---- System specific configurations ----------------------------------- */
35
37
 
@@ -40,8 +42,8 @@ typedef signed long ffi_sarg;
40
42
  typedef enum ffi_abi {
41
43
  FFI_FIRST_ABI = 0,
42
44
  FFI_SYSV,
43
- FFI_DEFAULT_ABI = FFI_SYSV,
44
- FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
45
+ FFI_LAST_ABI,
46
+ FFI_DEFAULT_ABI = FFI_SYSV
45
47
  } ffi_abi;
46
48
  #endif
47
49
 
@@ -36,8 +36,8 @@ typedef signed long ffi_sarg;
36
36
  typedef enum ffi_abi {
37
37
  FFI_FIRST_ABI = 0,
38
38
  FFI_SYSV,
39
- FFI_DEFAULT_ABI = FFI_SYSV,
40
- FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
39
+ FFI_LAST_ABI,
40
+ FFI_DEFAULT_ABI = FFI_SYSV
41
41
  } ffi_abi;
42
42
  #endif
43
43
 
@@ -36,8 +36,8 @@ typedef signed long ffi_sarg;
36
36
  typedef enum ffi_abi {
37
37
  FFI_FIRST_ABI = 0,
38
38
  FFI_SYSV,
39
- FFI_DEFAULT_ABI = FFI_SYSV,
40
- FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
39
+ FFI_LAST_ABI,
40
+ FFI_DEFAULT_ABI = FFI_SYSV
41
41
  } ffi_abi;
42
42
 
43
43
  #define FFI_EXTRA_CIF_FIELDS long long flags2
@@ -1,5 +1,6 @@
1
1
  /* -----------------------------------------------------------------------
2
- ffi.c - Copyright (c) 1996, 2003, 2004, 2007, 2008 Red Hat, Inc.
2
+ ffi.c - Copyright (c) 2011 Anthony Green
3
+ Copyright (c) 1996, 2003-2004, 2007-2008 Red Hat, Inc.
3
4
 
4
5
  SPARC Foreign Function Interface
5
6
 
@@ -406,8 +407,50 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
406
407
  /* We don't yet support calling 32bit code from 64bit */
407
408
  FFI_ASSERT(0);
408
409
  #else
409
- ffi_call_v8(ffi_prep_args_v8, &ecif, cif->bytes,
410
- cif->flags, rvalue, fn);
410
+ if (rvalue && (cif->rtype->type == FFI_TYPE_STRUCT
411
+ #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
412
+ || cif->flags == FFI_TYPE_LONGDOUBLE
413
+ #endif
414
+ ))
415
+ {
416
+ /* For v8, we need an "unimp" with size of returning struct */
417
+ /* behind "call", so we alloc some executable space for it. */
418
+ /* l7 is used, we need to make sure v8.S doesn't use %l7. */
419
+ unsigned int *call_struct = NULL;
420
+ ffi_closure_alloc(32, &call_struct);
421
+ if (call_struct)
422
+ {
423
+ unsigned long f = (unsigned long)fn;
424
+ call_struct[0] = 0xae10001f; /* mov %i7, %l7 */
425
+ call_struct[1] = 0xbe10000f; /* mov %o7, %i7 */
426
+ call_struct[2] = 0x03000000 | f >> 10; /* sethi %hi(fn), %g1 */
427
+ call_struct[3] = 0x9fc06000 | (f & 0x3ff); /* jmp %g1+%lo(fn), %o7 */
428
+ call_struct[4] = 0x01000000; /* nop */
429
+ if (cif->rtype->size < 0x7f)
430
+ call_struct[5] = cif->rtype->size; /* unimp */
431
+ else
432
+ call_struct[5] = 0x01000000; /* nop */
433
+ call_struct[6] = 0x81c7e008; /* ret */
434
+ call_struct[7] = 0xbe100017; /* mov %l7, %i7 */
435
+ asm volatile ("iflush %0; iflush %0+8; iflush %0+16; iflush %0+24" : :
436
+ "r" (call_struct) : "memory");
437
+ /* SPARC v8 requires 5 instructions for flush to be visible */
438
+ asm volatile ("nop; nop; nop; nop; nop");
439
+ ffi_call_v8(ffi_prep_args_v8, &ecif, cif->bytes,
440
+ cif->flags, rvalue, call_struct);
441
+ ffi_closure_free(call_struct);
442
+ }
443
+ else
444
+ {
445
+ ffi_call_v8(ffi_prep_args_v8, &ecif, cif->bytes,
446
+ cif->flags, rvalue, fn);
447
+ }
448
+ }
449
+ else
450
+ {
451
+ ffi_call_v8(ffi_prep_args_v8, &ecif, cif->bytes,
452
+ cif->flags, rvalue, fn);
453
+ }
411
454
  #endif
412
455
  break;
413
456
  case FFI_V9:
@@ -425,7 +468,6 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
425
468
  FFI_ASSERT(0);
426
469
  break;
427
470
  }
428
-
429
471
  }
430
472
 
431
473
 
@@ -447,7 +489,8 @@ ffi_prep_closure_loc (ffi_closure* closure,
447
489
  #ifdef SPARC64
448
490
  /* Trampoline address is equal to the closure address. We take advantage
449
491
  of that to reduce the trampoline size by 8 bytes. */
450
- FFI_ASSERT (cif->abi == FFI_V9);
492
+ if (cif->abi != FFI_V9)
493
+ return FFI_BAD_ABI;
451
494
  fn = (unsigned long) ffi_closure_v9;
452
495
  tramp[0] = 0x83414000; /* rd %pc, %g1 */
453
496
  tramp[1] = 0xca586010; /* ldx [%g1+16], %g5 */
@@ -456,7 +499,8 @@ ffi_prep_closure_loc (ffi_closure* closure,
456
499
  *((unsigned long *) &tramp[4]) = fn;
457
500
  #else
458
501
  unsigned long ctx = (unsigned long) codeloc;
459
- FFI_ASSERT (cif->abi == FFI_V8);
502
+ if (cif->abi != FFI_V8)
503
+ return FFI_BAD_ABI;
460
504
  fn = (unsigned long) ffi_closure_v8;
461
505
  tramp[0] = 0x03000000 | fn >> 10; /* sethi %hi(fn), %g1 */
462
506
  tramp[1] = 0x05000000 | ctx >> 10; /* sethi %hi(ctx), %g2 */
@@ -468,13 +512,13 @@ ffi_prep_closure_loc (ffi_closure* closure,
468
512
  closure->fun = fun;
469
513
  closure->user_data = user_data;
470
514
 
471
- /* Flush the Icache. FIXME: alignment isn't certain, assume 8 bytes */
515
+ /* Flush the Icache. closure is 8 bytes aligned. */
472
516
  #ifdef SPARC64
473
- asm volatile ("flush %0" : : "r" (closure) : "memory");
474
- asm volatile ("flush %0" : : "r" (((char *) closure) + 8) : "memory");
517
+ asm volatile ("flush %0; flush %0+8" : : "r" (closure) : "memory");
475
518
  #else
476
- asm volatile ("iflush %0" : : "r" (closure) : "memory");
477
- asm volatile ("iflush %0" : : "r" (((char *) closure) + 8) : "memory");
519
+ asm volatile ("iflush %0; iflush %0+8" : : "r" (closure) : "memory");
520
+ /* SPARC v8 requires 5 instructions for flush to be visible */
521
+ asm volatile ("nop; nop; nop; nop; nop");
478
522
  #endif
479
523
 
480
524
  return FFI_OK;
@@ -30,8 +30,10 @@
30
30
  /* ---- System specific configurations ----------------------------------- */
31
31
 
32
32
  #if defined(__arch64__) || defined(__sparcv9)
33
+ #ifndef SPARC64
33
34
  #define SPARC64
34
35
  #endif
36
+ #endif
35
37
 
36
38
  #ifndef LIBFFI_ASM
37
39
  typedef unsigned long ffi_arg;
@@ -42,12 +44,12 @@ typedef enum ffi_abi {
42
44
  FFI_V8,
43
45
  FFI_V8PLUS,
44
46
  FFI_V9,
47
+ FFI_LAST_ABI,
45
48
  #ifdef SPARC64
46
- FFI_DEFAULT_ABI = FFI_V9,
49
+ FFI_DEFAULT_ABI = FFI_V9
47
50
  #else
48
- FFI_DEFAULT_ABI = FFI_V8,
51
+ FFI_DEFAULT_ABI = FFI_V8
49
52
  #endif
50
- FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
51
53
  } ffi_abi;
52
54
  #endif
53
55
 
@@ -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, 2010 Free Software Foundation, Inc.
7
7
 
8
8
  x86 Foreign Function Interface
9
9
 
@@ -148,24 +148,21 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
148
148
  /* Perform machine dependent cif processing */
149
149
  ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
150
150
  {
151
+ unsigned int i;
152
+ ffi_type **ptr;
153
+
151
154
  /* Set the return type flag */
152
155
  switch (cif->rtype->type)
153
156
  {
154
157
  case FFI_TYPE_VOID:
155
- #ifdef X86
156
- case FFI_TYPE_STRUCT:
157
- #endif
158
- #if defined(X86) || defined (X86_WIN32) || defined(X86_FREEBSD) || defined(X86_DARWIN) || defined(X86_WIN64)
159
158
  case FFI_TYPE_UINT8:
160
159
  case FFI_TYPE_UINT16:
161
160
  case FFI_TYPE_SINT8:
162
161
  case FFI_TYPE_SINT16:
163
- #endif
164
162
  #ifdef X86_WIN64
165
163
  case FFI_TYPE_UINT32:
166
164
  case FFI_TYPE_SINT32:
167
165
  #endif
168
-
169
166
  case FFI_TYPE_SINT64:
170
167
  case FFI_TYPE_FLOAT:
171
168
  case FFI_TYPE_DOUBLE:
@@ -184,8 +181,8 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
184
181
  cif->flags = FFI_TYPE_SINT64;
185
182
  break;
186
183
 
187
- #ifndef X86
188
184
  case FFI_TYPE_STRUCT:
185
+ #ifndef X86
189
186
  if (cif->rtype->size == 1)
190
187
  {
191
188
  cif->flags = FFI_TYPE_SMALL_STRUCT_1B; /* same as char size */
@@ -207,15 +204,13 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
207
204
  cif->flags = FFI_TYPE_SINT64; /* same as int64 type */
208
205
  }
209
206
  else
207
+ #endif
210
208
  {
211
209
  cif->flags = FFI_TYPE_STRUCT;
212
- #ifdef X86_WIN64
213
- // allocate space for return value pointer
210
+ /* allocate space for return value pointer */
214
211
  cif->bytes += ALIGN(sizeof(void*), FFI_SIZEOF_ARG);
215
- #endif
216
212
  }
217
213
  break;
218
- #endif
219
214
 
220
215
  default:
221
216
  #ifdef X86_WIN64
@@ -229,41 +224,36 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
229
224
  break;
230
225
  }
231
226
 
232
- #ifdef X86_DARWIN
233
- cif->bytes = (cif->bytes + 15) & ~0xF;
234
- #endif
227
+ for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
228
+ {
229
+ if (((*ptr)->alignment - 1) & cif->bytes)
230
+ cif->bytes = ALIGN(cif->bytes, (*ptr)->alignment);
231
+ cif->bytes += ALIGN((*ptr)->size, FFI_SIZEOF_ARG);
232
+ }
235
233
 
236
234
  #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
235
+ /* ensure space for storing four registers */
249
236
  cif->bytes += 4 * sizeof(ffi_arg);
250
237
  #endif
251
238
 
239
+ #ifdef X86_DARWIN
240
+ cif->bytes = (cif->bytes + 15) & ~0xF;
241
+ #endif
242
+
252
243
  return FFI_OK;
253
244
  }
254
245
 
255
- extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
256
- unsigned, unsigned, unsigned *, void (*fn)(void));
257
-
258
- #ifdef X86_WIN32
259
- extern void ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *,
260
- unsigned, unsigned, unsigned *, void (*fn)(void));
261
-
262
- #endif /* X86_WIN32 */
263
246
  #ifdef X86_WIN64
264
247
  extern int
265
248
  ffi_call_win64(void (*)(char *, extended_cif *), extended_cif *,
266
249
  unsigned, unsigned, unsigned *, void (*fn)(void));
250
+ #elif defined(X86_WIN32)
251
+ extern void
252
+ ffi_call_win32(void (*)(char *, extended_cif *), extended_cif *,
253
+ unsigned, unsigned, unsigned *, void (*fn)(void));
254
+ #else
255
+ extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
256
+ unsigned, unsigned, unsigned *, void (*fn)(void));
267
257
  #endif
268
258
 
269
259
  void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
@@ -299,40 +289,21 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
299
289
  {
300
290
  #ifdef X86_WIN64
301
291
  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
- }
292
+ ffi_call_win64(ffi_prep_args, &ecif, cif->bytes,
293
+ cif->flags, ecif.rvalue, fn);
294
+ break;
295
+ #elif defined(X86_WIN32)
296
+ case FFI_SYSV:
297
+ case FFI_STDCALL:
298
+ ffi_call_win32(ffi_prep_args, &ecif, cif->bytes, cif->flags,
299
+ ecif.rvalue, fn);
323
300
  break;
324
301
  #else
325
302
  case FFI_SYSV:
326
303
  ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
327
304
  fn);
328
305
  break;
329
- #ifdef X86_WIN32
330
- case FFI_STDCALL:
331
- ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes, cif->flags,
332
- ecif.rvalue, fn);
333
- break;
334
- #endif /* X86_WIN32 */
335
- #endif /* X86_WIN64 */
306
+ #endif
336
307
  default:
337
308
  FFI_ASSERT(0);
338
309
  break;
@@ -342,6 +313,8 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
342
313
 
343
314
  /** private members **/
344
315
 
316
+ /* The following __attribute__((regparm(1))) decorations will have no effect
317
+ on MSVC - standard cdecl convention applies. */
345
318
  static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
346
319
  void** args, ffi_cif* cif);
347
320
  void FFI_HIDDEN ffi_closure_SYSV (ffi_closure *)
@@ -390,11 +363,8 @@ ffi_closure_win64_inner (ffi_closure *closure, void *args) {
390
363
  }
391
364
 
392
365
  #else
393
- unsigned int FFI_HIDDEN
394
- ffi_closure_SYSV_inner (closure, respp, args)
395
- ffi_closure *closure;
396
- void **respp;
397
- void *args;
366
+ unsigned int FFI_HIDDEN __attribute__ ((regparm(1)))
367
+ ffi_closure_SYSV_inner (ffi_closure *closure, void **respp, void *args)
398
368
  {
399
369
  /* our various things... */
400
370
  ffi_cif *cif;
@@ -505,7 +475,7 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
505
475
  /* How to make a trampoline. Derived from gcc/config/i386/i386.c. */
506
476
 
507
477
  #define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
508
- ({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
478
+ { unsigned char *__tramp = (unsigned char*)(TRAMP); \
509
479
  unsigned int __fun = (unsigned int)(FUN); \
510
480
  unsigned int __ctx = (unsigned int)(CTX); \
511
481
  unsigned int __dis = __fun - (__ctx + 10); \
@@ -513,10 +483,10 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
513
483
  *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
514
484
  *(unsigned char *) &__tramp[5] = 0xe9; \
515
485
  *(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \
516
- })
486
+ }
517
487
 
518
488
  #define FFI_INIT_TRAMPOLINE_STDCALL(TRAMP,FUN,CTX,SIZE) \
519
- ({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
489
+ { unsigned char *__tramp = (unsigned char*)(TRAMP); \
520
490
  unsigned int __fun = (unsigned int)(FUN); \
521
491
  unsigned int __ctx = (unsigned int)(CTX); \
522
492
  unsigned int __dis = __fun - (__ctx + 10); \
@@ -527,7 +497,7 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
527
497
  *(unsigned int*) &__tramp[6] = __dis; /* call __fun */ \
528
498
  *(unsigned char *) &__tramp[10] = 0xc2; \
529
499
  *(unsigned short*) &__tramp[11] = __size; /* ret __size */ \
530
- })
500
+ }
531
501
 
532
502
  /* the cif must already be prep'ed */
533
503
 
@@ -594,10 +564,10 @@ ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
594
564
  return FFI_BAD_ABI;
595
565
  }
596
566
 
597
- // we currently don't support certain kinds of arguments for raw
598
- // closures. This should be implemented by a separate assembly language
599
- // routine, since it would require argument processing, something we
600
- // don't do now for performance.
567
+ /* we currently don't support certain kinds of arguments for raw
568
+ closures. This should be implemented by a separate assembly
569
+ language routine, since it would require argument processing,
570
+ something we don't do now for performance. */
601
571
 
602
572
  for (i = cif->nargs-1; i >= 0; i--)
603
573
  {
@@ -627,16 +597,6 @@ ffi_prep_args_raw(char *stack, extended_cif *ecif)
627
597
  * libffi-1.20, this is not the case.)
628
598
  */
629
599
 
630
- extern void
631
- ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, unsigned,
632
- unsigned, unsigned *, void (*fn)(void));
633
-
634
- #ifdef X86_WIN32
635
- extern void
636
- ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *, unsigned,
637
- unsigned, unsigned *, void (*fn)(void));
638
- #endif /* X86_WIN32 */
639
-
640
600
  void
641
601
  ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
642
602
  {
@@ -660,16 +620,18 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
660
620
 
661
621
  switch (cif->abi)
662
622
  {
623
+ #ifdef X86_WIN32
624
+ case FFI_SYSV:
625
+ case FFI_STDCALL:
626
+ ffi_call_win32(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
627
+ ecif.rvalue, fn);
628
+ break;
629
+ #else
663
630
  case FFI_SYSV:
664
631
  ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
665
632
  ecif.rvalue, fn);
666
633
  break;
667
- #ifdef X86_WIN32
668
- case FFI_STDCALL:
669
- ffi_call_STDCALL(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
670
- ecif.rvalue, fn);
671
- break;
672
- #endif /* X86_WIN32 */
634
+ #endif
673
635
  default:
674
636
  FFI_ASSERT(0);
675
637
  break;