This is the mail archive of the libffi-discuss@sourceware.org mailing list for the libffi project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] port libffi to x86/msvc


Hi all,

I've finished my port of libffi to x86/msvc. There are three patches attached, against 3.0.9. Anthony, if these look okay to you, could you please apply?

Details:
These avoid hacks to the build system by using Timothy Wall's idea of a wrapper script, 'cc.sh', which acts like gcc but translates commandline args and calls cl/ml appropriately. (I've attached it in case anyone wants to test; I don't think it should be merged, but if we can get it to be generic enough then perhaps it could be.) Patches are built and tested on i686-pc-linux-gnu, i686-pc-mingw32 (with MSVC), and i386-apple-darwin9.2.0, using Mozilla's testsuite. This tests ffi_call extensively and ffi_closure_SYSV somewhat, but does not test the raw API. (Any assistance in doing this would be greatly appreciated.)

For MSVC, libffi was configured with
configure --enable-shared --enable-static CC=path/to/cc.sh LD=link CPP=\"cl -nologo -EP\"

Patch descriptions are below. The first patch consolidates the stack space allocation code; it's currently fragmented between ffi_prep_cif and ffi_prep_cif_machdep depending on X86, X86_DARWIN, or X86_WIN64, which made it somewhat hard to read. The second merges ffi_call_SYSV and ffi_call_STDCALL since they're identical. The third fixes a few MSVC syntax errors and adds the assembly routines.

The assembly for MSVC is a direct translation of existing win32 assembly, with the exception of sint8/uint8/sint16/uint16 return type handling. Zero- or sign-extending these into a 4-byte register or memory location is unnecessary, and in the case of ffi_call, wrong - it means we're writing 4 bytes into a memory slot that may only hold 1 or 2 bytes. MSVC does not extend when compiling a C function that returns 1 or 2 bytes. (I can write a followup patch to change the other x86 platforms, as appropriate.)

[libffi-part1-x86-stack-alloc-machdep-1]
    2010-01-12  Daniel Witte  <dwitte@mozilla.com>
      * src/prep_cif.c (ffi_prep_cif): Move stack space allocation code to
      ffi_prep_cif_machdep for x86.
      * src/x86/ffi.c (ffi_prep_cif_machdep): To here.

[libffi-part2-ffi_call_win32-1]
    2010-01-12  Daniel Witte  <dwitte@mozilla.com>
      * src/x86/ffi.c: Merge ffi_call_SYSV and ffi_call_STDCALL into new
      function ffi_call_win32 on X86_WIN32.
      * src/x86/win32.S (ffi_call_SYSV): Rename to ffi_call_win32.
      (ffi_call_STDCALL): Remove.

[libffi-part3-msvc-port-1]
    2010-01-12  Daniel Witte  <dwitte@mozilla.com>
      * src/x86/win32.S: Port assembly routines to MSVC and #ifdef.
      * src/x86/ffi.c: Tweak function declaration and remove excess parens.
      * include/ffi.h.in: Add __declspec(align(8)) to typedef struct ffi_closure.
2010-01-12  Daniel Witte  <dwitte@mozilla.com>
  * src/x86/ffi.c: Merge ffi_call_SYSV and ffi_call_STDCALL into new
  function ffi_call_win32 on X86_WIN32.
  * src/x86/win32.S (ffi_call_SYSV): Rename to ffi_call_win32.
  (ffi_call_STDCALL): Remove.

diff --git a/libffi/ChangeLog b/libffi/ChangeLog
--- a/libffi/ChangeLog
+++ b/libffi/ChangeLog
@@ -1,8 +1,14 @@
+2010-01-12  Daniel Witte  <dwitte@mozilla.com>
+  * src/x86/ffi.c: Merge ffi_call_SYSV and ffi_call_STDCALL into new
+  function ffi_call_win32 on X86_WIN32.
+  * src/x86/win32.S (ffi_call_SYSV): Rename to ffi_call_win32.
+  (ffi_call_STDCALL): Remove.
+
 2010-01-12  Daniel Witte  <dwitte@mozilla.com>
   * src/prep_cif.c (ffi_prep_cif): Move stack space allocation code to
   ffi_prep_cif_machdep for x86.
   * src/x86/ffi.c (ffi_prep_cif_machdep): To here.
 
 2009-12-28  David Edelsohn  <edelsohn@gnu.org>
 
 	* src/powerpc/ffi_darwin.c (ffi_prep_args): Copy abi and nargs to
diff --git a/libffi/src/x86/ffi.c b/libffi/src/x86/ffi.c
--- a/libffi/src/x86/ffi.c
+++ b/libffi/src/x86/ffi.c
@@ -240,28 +240,27 @@ ffi_status ffi_prep_cif_machdep(ffi_cif 
 
 #ifdef X86_DARWIN
   cif->bytes = (cif->bytes + 15) & ~0xF;
 #endif
 
   return FFI_OK;
 }
 
-extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
-                          unsigned, unsigned, unsigned *, void (*fn)(void));
-
-#ifdef X86_WIN32
-extern void ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *,
-                          unsigned, unsigned, unsigned *, void (*fn)(void));
-
-#endif /* X86_WIN32 */
 #ifdef X86_WIN64
 extern int
 ffi_call_win64(void (*)(char *, extended_cif *), extended_cif *,
                unsigned, unsigned, unsigned *, void (*fn)(void));
+#elif defined(X86_WIN32)
+extern void
+ffi_call_win32(void (*)(char *, extended_cif *), extended_cif *,
+               unsigned, unsigned, unsigned *, void (*fn)(void));
+#else
+extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
+                          unsigned, unsigned, unsigned *, void (*fn)(void));
 #endif
 
 void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
 {
   extended_cif ecif;
 
   ecif.cif = cif;
   ecif.avalue = avalue;
@@ -309,28 +308,28 @@ void ffi_call(ffi_cif *cif, void (*fn)(v
               memcpy(local, avalue[i], size);
               avalue[i] = local;
             }
         }
         ffi_call_win64(ffi_prep_args, &ecif, cif->bytes,
                        cif->flags, ecif.rvalue, fn);
       }
       break;
+#elif defined(X86_WIN32)
+    case FFI_SYSV:
+    case FFI_STDCALL:
+      ffi_call_win32(ffi_prep_args, &ecif, cif->bytes, cif->flags,
+                     ecif.rvalue, fn);
+      break;
 #else
     case FFI_SYSV:
       ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
                     fn);
       break;
-#ifdef X86_WIN32
-    case FFI_STDCALL:
-      ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes, cif->flags,
-                       ecif.rvalue, fn);
-      break;
-#endif /* X86_WIN32 */
-#endif /* X86_WIN64 */
+#endif
     default:
       FFI_ASSERT(0);
       break;
     }
 }
 
 
 /** private members **/
@@ -615,26 +614,16 @@ ffi_prep_args_raw(char *stack, extended_
   memcpy (stack, ecif->avalue, ecif->cif->bytes);
 }
 
 /* we borrow this routine from libffi (it must be changed, though, to
  * actually call the function passed in the first argument.  as of
  * libffi-1.20, this is not the case.)
  */
 
-extern void
-ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, unsigned, 
-              unsigned, unsigned *, void (*fn)(void));
-
-#ifdef X86_WIN32
-extern void
-ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *, unsigned,
-                 unsigned, unsigned *, void (*fn)(void));
-#endif /* X86_WIN32 */
-
 void
 ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
 {
   extended_cif ecif;
   void **avalue = (void **)fake_avalue;
 
   ecif.cif = cif;
   ecif.avalue = avalue;
@@ -648,26 +637,28 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(vo
       ecif.rvalue = alloca(cif->rtype->size);
     }
   else
     ecif.rvalue = rvalue;
     
   
   switch (cif->abi) 
     {
+#ifdef X86_WIN32
+    case FFI_SYSV:
+    case FFI_STDCALL:
+      ffi_call_win32(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
+                     ecif.rvalue, fn);
+      break;
+#else
     case FFI_SYSV:
       ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
                     ecif.rvalue, fn);
       break;
-#ifdef X86_WIN32
-    case FFI_STDCALL:
-      ffi_call_STDCALL(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
-                       ecif.rvalue, fn);
-      break;
-#endif /* X86_WIN32 */
+#endif
     default:
       FFI_ASSERT(0);
       break;
     }
 }
 
 #endif
 
diff --git a/libffi/src/x86/win32.S b/libffi/src/x86/win32.S
--- a/libffi/src/x86/win32.S
+++ b/libffi/src/x86/win32.S
@@ -31,19 +31,19 @@
 #define LIBFFI_ASM
 #include <fficonfig.h>
 #include <ffi.h>
  
 	.text
  
         # This assumes we are using gas.
         .balign 16
-	.globl	_ffi_call_SYSV
-	.def	_ffi_call_SYSV;	.scl	2;	.type	32;	.endef
-_ffi_call_SYSV:
+	.globl	_ffi_call_win32
+	.def	_ffi_call_win32;	.scl	2;	.type	32;	.endef
+_ffi_call_win32:
 .LFB1:
         pushl %ebp
 .LCFI0:
         movl  %esp,%ebp
 .LCFI1:
         # Make room for all of the new args.
         movl  16(%ebp),%ecx                                                     
         subl  %ecx,%esp
@@ -56,18 +56,20 @@ _ffi_call_SYSV:
         call  *8(%ebp)
  
         # Return stack to previous state and call the function
         addl  $8,%esp
  
         # FIXME: Align the stack to a 128-bit boundary to avoid
         # potential performance hits.
 
-	call  *28(%ebp)
+        call  *28(%ebp)
  
+        # stdcall functions pop arguments off the stack themselves
+
         # Load %ecx with the return type code
         movl  20(%ebp),%ecx
  
         # If the return value pointer is NULL, assume no return value.
         cmpl  $0,24(%ebp)
         jne   0f
  
         # Even if there is no space for the return value, we are
@@ -176,174 +178,21 @@ 1:
 .Lretstruct:
         # Nothing to do!
  
 .Lnoretval:
 .Lepilogue:
         movl %ebp,%esp
         popl %ebp
         ret
-.ffi_call_SYSV_end:
+.ffi_call_win32_end:
 .LFE1:
 
         # This assumes we are using gas.
         .balign 16
-	.globl	_ffi_call_STDCALL
-	.def	_ffi_call_STDCALL;	.scl	2;	.type	32;	.endef
-_ffi_call_STDCALL:
-.LFB2:
-        pushl %ebp
-.LCFI2:
-        movl  %esp,%ebp
-.LCFI3:
-        # Make room for all of the new args.
-        movl  16(%ebp),%ecx 
-        subl  %ecx,%esp
-
-        movl  %esp,%eax
-
-        # Place all of the ffi_prep_args in position
-        pushl 12(%ebp)
-        pushl %eax
-        call  *8(%ebp)
-
-        # Return stack to previous state and call the function
-        addl  $8,%esp
-
-        # FIXME: Align the stack to a 128-bit boundary to avoid
-        # potential performance hits.
-
-        call  *28(%ebp)
-
-        # stdcall functions pop arguments off the stack themselves
-
-        # Load %ecx with the return type code
-        movl  20(%ebp),%ecx
-
-        # If the return value pointer is NULL, assume no return value.
-        cmpl  $0,24(%ebp)
-        jne   0f
-
-        # Even if there is no space for the return value, we are
-        # obliged to handle floating-point values.
-        cmpl  $FFI_TYPE_FLOAT,%ecx
-        jne   .Lsc_noretval
-        fstp  %st(0)
-
-        jmp   .Lsc_epilogue
-
-0:
-	call	1f
-	# Do not insert anything here between the call and the jump table.
-.Lsc_store_table:
-	.long	.Lsc_noretval		/* FFI_TYPE_VOID */
-	.long	.Lsc_retint		/* FFI_TYPE_INT */
-	.long	.Lsc_retfloat		/* FFI_TYPE_FLOAT */
-	.long	.Lsc_retdouble		/* FFI_TYPE_DOUBLE */
-	.long	.Lsc_retlongdouble	/* FFI_TYPE_LONGDOUBLE */
-	.long	.Lsc_retuint8		/* FFI_TYPE_UINT8 */
-	.long	.Lsc_retsint8		/* FFI_TYPE_SINT8 */
-	.long	.Lsc_retuint16		/* FFI_TYPE_UINT16 */
-	.long	.Lsc_retsint16		/* FFI_TYPE_SINT16 */
-	.long	.Lsc_retint		/* FFI_TYPE_UINT32 */
-	.long	.Lsc_retint		/* FFI_TYPE_SINT32 */
-	.long	.Lsc_retint64		/* FFI_TYPE_UINT64 */
-	.long	.Lsc_retint64		/* FFI_TYPE_SINT64 */
-	.long	.Lsc_retstruct		/* FFI_TYPE_STRUCT */
-	.long	.Lsc_retint		/* FFI_TYPE_POINTER */
-	.long	.Lsc_retstruct1b	/* FFI_TYPE_SMALL_STRUCT_1B */
-	.long	.Lsc_retstruct2b	/* FFI_TYPE_SMALL_STRUCT_2B */
-	.long	.Lsc_retstruct4b	/* FFI_TYPE_SMALL_STRUCT_4B */
-
-1:
-	add	%ecx, %ecx
-	add	%ecx, %ecx
-	add	(%esp),%ecx
-	add	$4, %esp
-	jmp	*(%ecx)
-
-	/* Sign/zero extend as appropriate.  */
-.Lsc_retsint8:
-	movsbl	%al, %eax
-	jmp	.Lsc_retint
-
-.Lsc_retsint16:
-	movswl	%ax, %eax
-	jmp	.Lsc_retint
-
-.Lsc_retuint8:
-	movzbl	%al, %eax
-	jmp	.Lsc_retint
-
-.Lsc_retuint16:
-	movzwl	%ax, %eax
-	jmp	.Lsc_retint
-
-.Lsc_retint:
-        # Load %ecx with the pointer to storage for the return value
-        movl  24(%ebp),%ecx
-        movl  %eax,0(%ecx)
-        jmp   .Lsc_epilogue
-
-.Lsc_retfloat:
-         # Load %ecx with the pointer to storage for the return value
-        movl  24(%ebp),%ecx
-        fstps (%ecx)
-        jmp   .Lsc_epilogue
-
-.Lsc_retdouble:
-        # Load %ecx with the pointer to storage for the return value
-        movl  24(%ebp),%ecx
-        fstpl (%ecx)
-        jmp   .Lsc_epilogue
-
-.Lsc_retlongdouble:
-        # Load %ecx with the pointer to storage for the return value
-        movl  24(%ebp),%ecx
-        fstpt (%ecx)
-        jmp   .Lsc_epilogue
-
-.Lsc_retint64:
-        # Load %ecx with the pointer to storage for the return value
-        movl  24(%ebp),%ecx
-        movl  %eax,0(%ecx)
-        movl  %edx,4(%ecx)
-	jmp   .Lsc_epilogue
-
-.Lsc_retstruct1b:
-        # Load %ecx with the pointer to storage for the return value
-        movl  24(%ebp),%ecx
-        movb  %al,0(%ecx)
-        jmp   .Lsc_epilogue
-
-.Lsc_retstruct2b:
-        # Load %ecx with the pointer to storage for the return value
-        movl  24(%ebp),%ecx
-        movw  %ax,0(%ecx)
-        jmp   .Lsc_epilogue
-
-.Lsc_retstruct4b:
-        # Load %ecx with the pointer to storage for the return value
-        movl  24(%ebp),%ecx
-        movl  %eax,0(%ecx)
-        jmp   .Lsc_epilogue
-
-.Lsc_retstruct:
-        # Nothing to do!
-
-.Lsc_noretval:
-.Lsc_epilogue:
-        movl %ebp,%esp
-        popl %ebp
-        ret
-.ffi_call_STDCALL_end:
-.LFE2:
-
-        # This assumes we are using gas.
-        .balign 16
 	.globl	_ffi_closure_SYSV
 	.def	_ffi_closure_SYSV;	.scl	2;	.type	32;	.endef
 _ffi_closure_SYSV:
 .LFB3:
 	pushl	%ebp
 .LCFI4:
 	movl	%esp, %ebp
 .LCFI5:
@@ -737,48 +586,16 @@ 1:
 	.byte	0xd	/* DW_CFA_def_cfa_register CFA = r5 = %ebp */
 	.byte	0x5	/* .uleb128 0x5 */
 
 	/* End of DW_CFA_xxx CFI instructions.  */
 	.align 4
 .LEFDE1:
 
 
-.LSFDE2:
-	.long	.LEFDE2-.LASFDE2	/* FDE Length */
-.LASFDE2:
-	.long	.LASFDE2-.Lframe1	/* FDE CIE offset */
-#if defined __PIC__ && defined HAVE_AS_X86_PCREL
-	.long	.LFB2-.	/* FDE initial location */
-#else
-	.long	.LFB2
-#endif
-	.long	.LFE2-.LFB2	/* FDE address range */
-#ifdef __PIC__
-	.byte	0x0	/* .uleb128 0x0; Augmentation size */
-#endif
-	/* DW_CFA_xxx CFI instructions go here.  */
-
-	.byte	0x4	/* DW_CFA_advance_loc4 */
-	.long	.LCFI2-.LFB2
-	.byte	0xe	/* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
-	.byte	0x8	/* .uleb128 0x8 */
-	.byte	0x85	/* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
-	.byte	0x2	/* .uleb128 0x2 */
-
-	.byte	0x4	/* DW_CFA_advance_loc4 */
-	.long	.LCFI3-.LCFI2
-	.byte	0xd	/* DW_CFA_def_cfa_register CFA = r5 = %ebp */
-	.byte	0x5	/* .uleb128 0x5 */
-
-	/* End of DW_CFA_xxx CFI instructions.  */
-	.align 4
-.LEFDE2:
-
-
 .LSFDE3:
 	.long	.LEFDE3-.LASFDE3	/* FDE Length */
 .LASFDE3:
 	.long	.LASFDE3-.Lframe1	/* FDE CIE offset */
 #if defined __PIC__ && defined HAVE_AS_X86_PCREL
 	.long	.LFB3-.	/* FDE initial location */
 #else
 	.long	.LFB3
2010-01-12  Daniel Witte  <dwitte@mozilla.com>
  * src/x86/win32.S: Port assembly routines to MSVC and #ifdef.
  * src/x86/ffi.c: Tweak function declaration and remove excess parens.
  * include/ffi.h.in: Add __declspec(align(8)) to typedef struct ffi_closure.

diff --git a/libffi/ChangeLog b/libffi/ChangeLog
--- a/libffi/ChangeLog
+++ b/libffi/ChangeLog
@@ -1,8 +1,13 @@
+2010-01-12  Daniel Witte  <dwitte@mozilla.com>
+  * src/x86/win32.S: Port assembly routines to MSVC and #ifdef.
+  * src/x86/ffi.c: Tweak function declaration and remove excess parens.
+  * include/ffi.h.in: Add __declspec(align(8)) to typedef struct ffi_closure.
+
 2010-01-12  Daniel Witte  <dwitte@mozilla.com>
   * src/x86/ffi.c: Merge ffi_call_SYSV and ffi_call_STDCALL into new
   function ffi_call_win32 on X86_WIN32.
   * src/x86/win32.S (ffi_call_SYSV): Rename to ffi_call_win32.
   (ffi_call_STDCALL): Remove.
 
 2010-01-12  Daniel Witte  <dwitte@mozilla.com>
   * src/prep_cif.c (ffi_prep_cif): Move stack space allocation code to
diff --git a/libffi/include/ffi.h.in b/libffi/include/ffi.h.in
--- a/libffi/include/ffi.h.in
+++ b/libffi/include/ffi.h.in
@@ -246,16 +246,19 @@ void ffi_java_raw_call (ffi_cif *cif,
 void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw);
 void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args);
 size_t ffi_java_raw_size (ffi_cif *cif);
 
 /* ---- Definitions for closures ----------------------------------------- */
 
 #if FFI_CLOSURES
 
+#ifdef _MSC_VER
+__declspec(align(8))
+#endif
 typedef struct {
   char tramp[FFI_TRAMPOLINE_SIZE];
   ffi_cif   *cif;
   void     (*fun)(ffi_cif*,void*,void**,void*);
   void      *user_data;
 #ifdef __GNUC__
 } ffi_closure __attribute__((aligned (8)));
 #else
diff --git a/libffi/src/x86/ffi.c b/libffi/src/x86/ffi.c
--- a/libffi/src/x86/ffi.c
+++ b/libffi/src/x86/ffi.c
@@ -329,16 +329,18 @@ void ffi_call(ffi_cif *cif, void (*fn)(v
       FFI_ASSERT(0);
       break;
     }
 }
 
 
 /** private members **/
 
+/* The following __attribute__((regparm(1))) decorations will have no effect
+   on MSVC - standard cdecl convention applies. */
 static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
                                          void** args, ffi_cif* cif);
 void FFI_HIDDEN ffi_closure_SYSV (ffi_closure *)
      __attribute__ ((regparm(1)));
 unsigned int FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *, void **, void *)
      __attribute__ ((regparm(1)));
 void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *)
      __attribute__ ((regparm(1)));
@@ -377,21 +379,18 @@ ffi_closure_win64_inner (ffi_closure *cl
      result types except for floats; we have to 'mov xmm0, rax' in the
      caller to correct this.
      TODO: structure sizes of 3 5 6 7 are returned by reference, too!!!
   */
   return cif->rtype->size > sizeof(void *) ? resp : *(void **)resp;
 }
 
 #else
-unsigned int FFI_HIDDEN
-ffi_closure_SYSV_inner (closure, respp, args)
-     ffi_closure *closure;
-     void **respp;
-     void *args;
+unsigned int FFI_HIDDEN __attribute__ ((regparm(1)))
+ffi_closure_SYSV_inner (ffi_closure *closure, void **respp, void *args)
 {
   /* our various things...  */
   ffi_cif       *cif;
   void         **arg_area;
 
   cif         = closure->cif;
   arg_area    = (void**) alloca (cif->nargs * sizeof (void*));  
 
@@ -492,39 +491,39 @@ ffi_prep_incoming_args_SYSV(char *stack,
    *(unsigned char *)  &__tramp[26] = 0x41; \
    *(unsigned char *)  &__tramp[27] = 0xff; \
    *(unsigned char *)  &__tramp[28] = 0xe2; /* jmp %r10 */ \
  }
 
 /* How to make a trampoline.  Derived from gcc/config/i386/i386.c. */
 
 #define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
-({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
+{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
    unsigned int  __fun = (unsigned int)(FUN); \
    unsigned int  __ctx = (unsigned int)(CTX); \
    unsigned int  __dis = __fun - (__ctx + 10);  \
    *(unsigned char*) &__tramp[0] = 0xb8; \
    *(unsigned int*)  &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
    *(unsigned char *)  &__tramp[5] = 0xe9; \
    *(unsigned int*)  &__tramp[6] = __dis; /* jmp __fun  */ \
- })
+ }
 
 #define FFI_INIT_TRAMPOLINE_STDCALL(TRAMP,FUN,CTX,SIZE)  \
-({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
+{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
    unsigned int  __fun = (unsigned int)(FUN); \
    unsigned int  __ctx = (unsigned int)(CTX); \
    unsigned int  __dis = __fun - (__ctx + 10); \
    unsigned short __size = (unsigned short)(SIZE); \
    *(unsigned char*) &__tramp[0] = 0xb8; \
    *(unsigned int*)  &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
    *(unsigned char *)  &__tramp[5] = 0xe8; \
    *(unsigned int*)  &__tramp[6] = __dis; /* call __fun  */ \
    *(unsigned char *)  &__tramp[10] = 0xc2; \
    *(unsigned short*)  &__tramp[11] = __size; /* ret __size  */ \
- })
+ }
 
 /* the cif must already be prep'ed */
 
 ffi_status
 ffi_prep_closure_loc (ffi_closure* closure,
                       ffi_cif* cif,
                       void (*fun)(ffi_cif*,void*,void**,void*),
                       void *user_data,
diff --git a/libffi/src/x86/win32.S b/libffi/src/x86/win32.S
--- a/libffi/src/x86/win32.S
+++ b/libffi/src/x86/win32.S
@@ -1,12 +1,13 @@
 /* -----------------------------------------------------------------------
    win32.S - Copyright (c) 1996, 1998, 2001, 2002, 2009  Red Hat, Inc.
 	     Copyright (c) 2001  John Beniton
 	     Copyright (c) 2002  Ranjit Mathew
+	     Copyright (c) 2009  Daniel Witte
 			
  
    X86 Foreign Function Interface
  
    Permission is hereby granted, free of charge, to any person obtaining
    a copy of this software and associated documentation files (the
    ``Software''), to deal in the Software without restriction, including
    without limitation the rights to use, copy, modify, merge, publish,
@@ -26,17 +27,374 @@
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    DEALINGS IN THE SOFTWARE.
    -----------------------------------------------------------------------
    */
  
 #define LIBFFI_ASM
 #include <fficonfig.h>
 #include <ffi.h>
- 
+
+#ifdef _MSC_VER
+
+.386
+.MODEL FLAT, C
+
+EXTRN ffi_closure_SYSV_inner:NEAR
+
+_TEXT SEGMENT
+
+ffi_call_win32 PROC NEAR,
+    ffi_prep_args : NEAR PTR DWORD,
+    ecif          : NEAR PTR DWORD,
+    cif_bytes     : DWORD,
+    cif_flags     : DWORD,
+    rvalue        : NEAR PTR DWORD,
+    fn            : NEAR PTR DWORD
+
+        ;; Make room for all of the new args.
+        mov  ecx, cif_bytes
+        sub  esp, ecx
+
+        mov  eax, esp
+
+        ;; Place all of the ffi_prep_args in position
+        push ecif
+        push eax
+        call ffi_prep_args
+
+        ;; Return stack to previous state and call the function
+        add  esp, 8
+
+        call fn
+
+        ;; cdecl:   we restore esp in the epilogue, so there's no need to
+        ;;          remove the space we pushed for the args.
+        ;; stdcall: the callee has already cleaned the stack.
+
+        ;; Load ecx with the return type code
+        mov  ecx, cif_flags
+
+        ;; If the return value pointer is NULL, assume no return value.
+        cmp  rvalue, 0
+        jne  ca_jumptable
+
+        ;; Even if there is no space for the return value, we are
+        ;; obliged to handle floating-point values.
+        cmp  ecx, FFI_TYPE_FLOAT
+        jne  ca_epilogue
+        fstp st(0)
+
+        jmp  ca_epilogue
+
+ca_jumptable:
+        jmp  [ca_jumpdata + 4 * ecx]
+ca_jumpdata:
+        ;; Do not insert anything here between label and jump table.
+        dd offset ca_epilogue       ;; FFI_TYPE_VOID
+        dd offset ca_retint         ;; FFI_TYPE_INT
+        dd offset ca_retfloat       ;; FFI_TYPE_FLOAT
+        dd offset ca_retdouble      ;; FFI_TYPE_DOUBLE
+        dd offset ca_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
+        dd offset ca_retint8        ;; FFI_TYPE_UINT8
+        dd offset ca_retint8        ;; FFI_TYPE_SINT8
+        dd offset ca_retint16       ;; FFI_TYPE_UINT16
+        dd offset ca_retint16       ;; FFI_TYPE_SINT16
+        dd offset ca_retint         ;; FFI_TYPE_UINT32
+        dd offset ca_retint         ;; FFI_TYPE_SINT32
+        dd offset ca_retint64       ;; FFI_TYPE_UINT64
+        dd offset ca_retint64       ;; FFI_TYPE_SINT64
+        dd offset ca_epilogue       ;; FFI_TYPE_STRUCT
+        dd offset ca_retint         ;; FFI_TYPE_POINTER
+        dd offset ca_retint8        ;; FFI_TYPE_SMALL_STRUCT_1B
+        dd offset ca_retint16       ;; FFI_TYPE_SMALL_STRUCT_2B
+        dd offset ca_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
+
+ca_retint8:
+        ;; Load %ecx with the pointer to storage for the return value
+        mov   ecx, rvalue
+        mov   [ecx + 0], al
+        jmp   ca_epilogue
+
+ca_retint16:
+        ;; Load %ecx with the pointer to storage for the return value
+        mov   ecx, rvalue
+        mov   [ecx + 0], ax
+        jmp   ca_epilogue
+
+ca_retint:
+        ;; Load %ecx with the pointer to storage for the return value
+        mov   ecx, rvalue
+        mov   [ecx + 0], eax
+        jmp   ca_epilogue
+
+ca_retint64:
+        ;; Load %ecx with the pointer to storage for the return value
+        mov   ecx, rvalue
+        mov   [ecx + 0], eax
+        mov   [ecx + 4], edx
+        jmp   ca_epilogue
+
+ca_retfloat:
+        ;; Load %ecx with the pointer to storage for the return value
+        mov   ecx, rvalue
+        fstp  DWORD PTR [ecx]
+        jmp   ca_epilogue
+
+ca_retdouble:
+        ;; Load %ecx with the pointer to storage for the return value
+        mov   ecx, rvalue
+        fstp  QWORD PTR [ecx]
+        jmp   ca_epilogue
+
+ca_retlongdouble:
+        ;; Load %ecx with the pointer to storage for the return value
+        mov   ecx, rvalue
+        fstp  TBYTE PTR [ecx]
+        jmp   ca_epilogue
+
+ca_epilogue:
+        ;; Epilogue code is autogenerated.
+        ret
+ffi_call_win32 ENDP
+
+ffi_closure_SYSV PROC NEAR FORCEFRAME
+    ;; the ffi_closure ctx is passed in eax by the trampoline.
+
+        sub  esp, 40
+        lea  edx, [ebp - 24]
+        mov  [ebp - 12], edx         ;; resp
+        lea  edx, [ebp + 8]
+        mov  [esp + 8], edx          ;; args
+        lea  edx, [ebp - 12]
+        mov  [esp + 4], edx          ;; &resp
+        mov  [esp], eax              ;; closure
+        call ffi_closure_SYSV_inner
+        mov  ecx, [ebp - 12]
+
+cs_jumptable:
+        jmp  [cs_jumpdata + 4 * eax]
+cs_jumpdata:
+        ;; Do not insert anything here between the label and jump table.
+        dd offset cs_epilogue       ;; FFI_TYPE_VOID
+        dd offset cs_retint         ;; FFI_TYPE_INT
+        dd offset cs_retfloat       ;; FFI_TYPE_FLOAT
+        dd offset cs_retdouble      ;; FFI_TYPE_DOUBLE
+        dd offset cs_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
+        dd offset cs_retint8        ;; FFI_TYPE_UINT8
+        dd offset cs_retint8        ;; FFI_TYPE_SINT8
+        dd offset cs_retint16       ;; FFI_TYPE_UINT16
+        dd offset cs_retint16       ;; FFI_TYPE_SINT16
+        dd offset cs_retint         ;; FFI_TYPE_UINT32
+        dd offset cs_retint         ;; FFI_TYPE_SINT32
+        dd offset cs_retint64       ;; FFI_TYPE_UINT64
+        dd offset cs_retint64       ;; FFI_TYPE_SINT64
+        dd offset cs_retstruct      ;; FFI_TYPE_STRUCT
+        dd offset cs_retint         ;; FFI_TYPE_POINTER
+        dd offset cs_retint8        ;; FFI_TYPE_SMALL_STRUCT_1B
+        dd offset cs_retint16       ;; FFI_TYPE_SMALL_STRUCT_2B
+        dd offset cs_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
+
+cs_retint8:
+        mov   al, [ecx]
+        jmp   cs_epilogue
+
+cs_retint16:
+        mov   ax, [ecx]
+        jmp   cs_epilogue
+
+cs_retint:
+        mov   eax, [ecx]
+        jmp   cs_epilogue
+
+cs_retint64:
+        mov   eax, [ecx + 0]
+        mov   edx, [ecx + 4]
+        jmp   cs_epilogue
+
+cs_retfloat:
+        fld   DWORD PTR [ecx]
+        jmp   cs_epilogue
+
+cs_retdouble:
+        fld   QWORD PTR [ecx]
+        jmp   cs_epilogue
+
+cs_retlongdouble:
+        fld   TBYTE PTR [ecx]
+        jmp   cs_epilogue
+
+cs_retstruct:
+        ;; Caller expects us to pop struct return value pointer hidden arg.
+        ;; Epilogue code is autogenerated.
+        ret	4
+
+cs_epilogue:
+        ;; Epilogue code is autogenerated.
+        ret
+ffi_closure_SYSV ENDP
+
+#if !FFI_NO_RAW_API
+
+#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) AND NOT 3)
+#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
+#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
+#define CIF_FLAGS_OFFSET 20
+
+ffi_closure_raw_SYSV PROC NEAR USES esi
+    ;; the ffi_closure ctx is passed in eax by the trampoline.
+
+        sub  esp, 40
+        mov  esi, [eax + RAW_CLOSURE_CIF_OFFSET]        ;; closure->cif
+        mov  edx, [eax + RAW_CLOSURE_USER_DATA_OFFSET]  ;; closure->user_data
+        mov  [esp + 12], edx                            ;; user_data
+        lea  edx, [ebp + 8]
+        mov  [esp + 8], edx                             ;; raw_args
+        lea  edx, [ebp - 24]
+        mov  [esp + 4], edx                             ;; &res
+        mov  [esp], esi                                 ;; cif
+        call DWORD PTR [eax + RAW_CLOSURE_FUN_OFFSET]   ;; closure->fun
+        mov  eax, [esi + CIF_FLAGS_OFFSET]              ;; cif->flags
+        lea  ecx, [ebp - 24]
+
+cr_jumptable:
+        jmp  [cr_jumpdata + 4 * eax]
+cr_jumpdata:
+        ;; Do not insert anything here between the label and jump table.
+        dd offset cr_epilogue       ;; FFI_TYPE_VOID
+        dd offset cr_retint         ;; FFI_TYPE_INT
+        dd offset cr_retfloat       ;; FFI_TYPE_FLOAT
+        dd offset cr_retdouble      ;; FFI_TYPE_DOUBLE
+        dd offset cr_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
+        dd offset cr_retint8        ;; FFI_TYPE_UINT8
+        dd offset cr_retint8        ;; FFI_TYPE_SINT8
+        dd offset cr_retint16       ;; FFI_TYPE_UINT16
+        dd offset cr_retint16       ;; FFI_TYPE_SINT16
+        dd offset cr_retint         ;; FFI_TYPE_UINT32
+        dd offset cr_retint         ;; FFI_TYPE_SINT32
+        dd offset cr_retint64       ;; FFI_TYPE_UINT64
+        dd offset cr_retint64       ;; FFI_TYPE_SINT64
+        dd offset cr_epilogue       ;; FFI_TYPE_STRUCT
+        dd offset cr_retint         ;; FFI_TYPE_POINTER
+        dd offset cr_retint8        ;; FFI_TYPE_SMALL_STRUCT_1B
+        dd offset cr_retint16       ;; FFI_TYPE_SMALL_STRUCT_2B
+        dd offset cr_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
+
+cr_retint8:
+        mov   al, [ecx]
+        jmp   cr_epilogue
+
+cr_retint16:
+        mov   ax, [ecx]
+        jmp   cr_epilogue
+
+cr_retint:
+        mov   eax, [ecx]
+        jmp   cr_epilogue
+
+cr_retint64:
+        mov   eax, [ecx + 0]
+        mov   edx, [ecx + 4]
+        jmp   cr_epilogue
+
+cr_retfloat:
+        fld   DWORD PTR [ecx]
+        jmp   cr_epilogue
+
+cr_retdouble:
+        fld   QWORD PTR [ecx]
+        jmp   cr_epilogue
+
+cr_retlongdouble:
+        fld   TBYTE PTR [ecx]
+        jmp   cr_epilogue
+
+cr_epilogue:
+        ;; Epilogue code is autogenerated.
+        ret
+ffi_closure_raw_SYSV ENDP
+
+#endif /* !FFI_NO_RAW_API */
+
+ffi_closure_STDCALL PROC NEAR FORCEFRAME
+    ;; the ffi_closure ctx is passed in eax by the trampoline.
+
+        sub  esp, 40
+        lea  edx, [ebp - 24]
+        mov  [ebp - 12], edx         ;; resp
+        lea  edx, [ebp + 12]         ;; account for stub return address on stack
+        mov  [esp + 8], edx          ;; args
+        lea  edx, [ebp - 12]
+        mov  [esp + 4], edx          ;; &resp
+        mov  [esp], eax              ;; closure
+        call ffi_closure_SYSV_inner
+        mov  ecx, [ebp - 12]
+
+cd_jumptable:
+        jmp  [cd_jumpdata + 4 * eax]
+cd_jumpdata:
+        ;; Do not insert anything here between the label and jump table.
+        dd offset cd_epilogue       ;; FFI_TYPE_VOID
+        dd offset cd_retint         ;; FFI_TYPE_INT
+        dd offset cd_retfloat       ;; FFI_TYPE_FLOAT
+        dd offset cd_retdouble      ;; FFI_TYPE_DOUBLE
+        dd offset cd_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
+        dd offset cd_retint8        ;; FFI_TYPE_UINT8
+        dd offset cd_retint8        ;; FFI_TYPE_SINT8
+        dd offset cd_retint16       ;; FFI_TYPE_UINT16
+        dd offset cd_retint16       ;; FFI_TYPE_SINT16
+        dd offset cd_retint         ;; FFI_TYPE_UINT32
+        dd offset cd_retint         ;; FFI_TYPE_SINT32
+        dd offset cd_retint64       ;; FFI_TYPE_UINT64
+        dd offset cd_retint64       ;; FFI_TYPE_SINT64
+        dd offset cd_epilogue       ;; FFI_TYPE_STRUCT
+        dd offset cd_retint         ;; FFI_TYPE_POINTER
+        dd offset cd_retint8        ;; FFI_TYPE_SMALL_STRUCT_1B
+        dd offset cd_retint16       ;; FFI_TYPE_SMALL_STRUCT_2B
+        dd offset cd_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
+
+cd_retint8:
+        mov   al, [ecx]
+        jmp   cd_epilogue
+
+cd_retint16:
+        mov   ax, [ecx]
+        jmp   cd_epilogue
+
+cd_retint:
+        mov   eax, [ecx]
+        jmp   cd_epilogue
+
+cd_retint64:
+        mov   eax, [ecx + 0]
+        mov   edx, [ecx + 4]
+        jmp   cd_epilogue
+
+cd_retfloat:
+        fld   DWORD PTR [ecx]
+        jmp   cd_epilogue
+
+cd_retdouble:
+        fld   QWORD PTR [ecx]
+        jmp   cd_epilogue
+
+cd_retlongdouble:
+        fld   TBYTE PTR [ecx]
+        jmp   cd_epilogue
+
+cd_epilogue:
+        ;; Epilogue code is autogenerated.
+        ret
+ffi_closure_STDCALL ENDP
+
+_TEXT ENDS
+END
+
+#else
+
 	.text
  
         # This assumes we are using gas.
         .balign 16
 	.globl	_ffi_call_win32
 	.def	_ffi_call_win32;	.scl	2;	.type	32;	.endef
 _ffi_call_win32:
 .LFB1:
@@ -687,8 +1045,11 @@ 1:
 	.byte	0x4	/* DW_CFA_advance_loc4 */
 	.long	.LCFI10-.LCFI9
 	.byte	0xd	/* DW_CFA_def_cfa_register CFA = r5 = %ebp */
 	.byte	0x5	/* .uleb128 0x5 */
 
 	/* End of DW_CFA_xxx CFI instructions.  */
 	.align 4
 .LEFDE5:
+
+#endif /* !_MSC_VER */
+

Attachment: cc.sh
Description: application/shellscript

2010-01-12  Daniel Witte  <dwitte@mozilla.com>
  * src/prep_cif.c (ffi_prep_cif): Move stack space allocation code to
  ffi_prep_cif_machdep for x86.
  * src/x86/ffi.c (ffi_prep_cif_machdep): To here.

diff --git a/libffi/ChangeLog b/libffi/ChangeLog
--- a/libffi/ChangeLog
+++ b/libffi/ChangeLog
@@ -1,8 +1,13 @@
+2010-01-12  Daniel Witte  <dwitte@mozilla.com>
+  * src/prep_cif.c (ffi_prep_cif): Move stack space allocation code to
+  ffi_prep_cif_machdep for x86.
+  * src/x86/ffi.c (ffi_prep_cif_machdep): To here.
+
 2009-12-28  David Edelsohn  <edelsohn@gnu.org>
 
 	* src/powerpc/ffi_darwin.c (ffi_prep_args): Copy abi and nargs to
 	local variables.
 	(aix_adjust_aggregate_sizes): New function.
 	(ffi_prep_cif_machdep): Call it.
 
 2009-12-26  Andreas Tobler  <a.tobler@schweiz.org>
diff --git a/libffi/src/prep_cif.c b/libffi/src/prep_cif.c
--- a/libffi/src/prep_cif.c
+++ b/libffi/src/prep_cif.c
@@ -104,42 +104,39 @@ ffi_status ffi_prep_cif(ffi_cif *cif, ff
 
   /* Initialize the return type if necessary */
   if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK))
     return FFI_BAD_TYPEDEF;
 
   /* Perform a sanity check on the return type */
   FFI_ASSERT_VALID_TYPE(cif->rtype);
 
-  /* x86-64 and s390 stack space allocation is handled in prep_machdep.  */
-#if !defined M68K && !defined __x86_64__ && !defined S390 && !defined PA
+  /* x86, x86-64 and s390 stack space allocation is handled in prep_machdep. */
+#if !defined M68K && !defined __i386__ && !defined __x86_64__ && !defined S390 && !defined PA
   /* Make space for the return structure pointer */
   if (cif->rtype->type == FFI_TYPE_STRUCT
 #ifdef SPARC
       && (cif->abi != FFI_V9 || cif->rtype->size > 32)
 #endif
-#ifdef X86_DARWIN
-      && (cif->rtype->size > 8)
-#endif
      )
     bytes = STACK_ARG_SIZE(sizeof(void*));
 #endif
 
   for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
     {
 
       /* Initialize any uninitialized aggregate type definitions */
       if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
 	return FFI_BAD_TYPEDEF;
 
       /* Perform a sanity check on the argument type, do this
 	 check after the initialization.  */
       FFI_ASSERT_VALID_TYPE(*ptr);
 
-#if !defined __x86_64__ && !defined S390 && !defined PA
+#if !defined __i386__ && !defined __x86_64__ && !defined S390 && !defined PA
 #ifdef SPARC
       if (((*ptr)->type == FFI_TYPE_STRUCT
 	   && ((*ptr)->size > 16 || cif->abi != FFI_V9))
 	  || ((*ptr)->type == FFI_TYPE_LONGDOUBLE
 	      && cif->abi != FFI_V9))
 	bytes += sizeof(void*);
       else
 #endif
diff --git a/libffi/src/x86/ffi.c b/libffi/src/x86/ffi.c
--- a/libffi/src/x86/ffi.c
+++ b/libffi/src/x86/ffi.c
@@ -143,34 +143,33 @@ void ffi_prep_args(char *stack, extended
     }
   
   return;
 }
 
 /* Perform machine dependent cif processing */
 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
 {
+  unsigned int i;
+  ffi_type **ptr;
+
   /* Set the return type flag */
   switch (cif->rtype->type)
     {
     case FFI_TYPE_VOID:
-#ifdef X86
-    case FFI_TYPE_STRUCT:
-#endif
 #if defined(X86) || defined (X86_WIN32) || defined(X86_FREEBSD) || defined(X86_DARWIN) || defined(X86_WIN64)
     case FFI_TYPE_UINT8:
     case FFI_TYPE_UINT16:
     case FFI_TYPE_SINT8:
     case FFI_TYPE_SINT16:
 #endif
 #ifdef X86_WIN64
     case FFI_TYPE_UINT32:
     case FFI_TYPE_SINT32:
 #endif
-
     case FFI_TYPE_SINT64:
     case FFI_TYPE_FLOAT:
     case FFI_TYPE_DOUBLE:
 #ifndef X86_WIN64
 #if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
     case FFI_TYPE_LONGDOUBLE:
 #endif
 #endif
@@ -179,18 +178,18 @@ ffi_status ffi_prep_cif_machdep(ffi_cif 
 
     case FFI_TYPE_UINT64:
 #ifdef X86_WIN64
     case FFI_TYPE_POINTER:
 #endif
       cif->flags = FFI_TYPE_SINT64;
       break;
 
+    case FFI_TYPE_STRUCT:
 #ifndef X86
-    case FFI_TYPE_STRUCT:
       if (cif->rtype->size == 1)
         {
           cif->flags = FFI_TYPE_SMALL_STRUCT_1B; /* same as char size */
         }
       else if (cif->rtype->size == 2)
         {
           cif->flags = FFI_TYPE_SMALL_STRUCT_2B; /* same as short size */
         }
@@ -202,58 +201,52 @@ ffi_status ffi_prep_cif_machdep(ffi_cif 
           cif->flags = FFI_TYPE_INT; /* same as int type */
 #endif
         }
       else if (cif->rtype->size == 8)
         {
           cif->flags = FFI_TYPE_SINT64; /* same as int64 type */
         }
       else
+#endif
         {
           cif->flags = FFI_TYPE_STRUCT;
-#ifdef X86_WIN64
           // allocate space for return value pointer
           cif->bytes += ALIGN(sizeof(void*), FFI_SIZEOF_ARG);
-#endif
         }
       break;
-#endif
 
     default:
 #ifdef X86_WIN64
       cif->flags = FFI_TYPE_SINT64;
       break;
     case FFI_TYPE_INT:
       cif->flags = FFI_TYPE_SINT32;
 #else
       cif->flags = FFI_TYPE_INT;
 #endif
       break;
     }
 
+  for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+    {
+      if (((*ptr)->alignment - 1) & cif->bytes)
+        cif->bytes = ALIGN(cif->bytes, (*ptr)->alignment);
+      cif->bytes += ALIGN((*ptr)->size, FFI_SIZEOF_ARG);
+    }
+
+#ifdef X86_WIN64
+  // ensure space for storing four registers
+  cif->bytes += 4 * sizeof(ffi_arg);
+#endif
+
 #ifdef X86_DARWIN
   cif->bytes = (cif->bytes + 15) & ~0xF;
 #endif
 
-#ifdef X86_WIN64
-  {
-    unsigned int i;
-    ffi_type **ptr;
-
-    for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
-      {
-        if (((*ptr)->alignment - 1) & cif->bytes)
-          cif->bytes = ALIGN(cif->bytes, (*ptr)->alignment);
-        cif->bytes += ALIGN((*ptr)->size, FFI_SIZEOF_ARG);
-      }
-  }
-  // ensure space for storing four registers
-  cif->bytes += 4 * sizeof(ffi_arg);
-#endif
-
   return FFI_OK;
 }
 
 extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
                           unsigned, unsigned, unsigned *, void (*fn)(void));
 
 #ifdef X86_WIN32
 extern void ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *,

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]