Restore execute permissions
[platform/upstream/libffi.git] / patches / msvc
1 Index: libffi/ChangeLog.libffi
2 ===================================================================
3 --- libffi.orig/ChangeLog.libffi
4 +++ libffi/ChangeLog.libffi
5 @@ -1,3 +1,26 @@
6 +2010-01-15  Anthony Green  <green@redhat.com>
7 +
8 +       * README: Add notes on building with Microsoft Visual C++.
9 +
10 +2010-01-15  Daniel Witte  <dwitte@mozilla.com>
11 +
12 +       * msvcc.sh: New file.
13 +
14 +       * src/x86/win32.S: Port assembly routines to MSVC and #ifdef.
15 +       * src/x86/ffi.c: Tweak function declaration and remove excess
16 +       parens.
17 +       * include/ffi.h.in: Add __declspec(align(8)) to typedef struct
18 +       ffi_closure.
19 +
20 +       * src/x86/ffi.c: Merge ffi_call_SYSV and ffi_call_STDCALL into new
21 +       function ffi_call_win32 on X86_WIN32.
22 +       * src/x86/win32.S (ffi_call_SYSV): Rename to ffi_call_win32.
23 +       (ffi_call_STDCALL): Remove.
24 +
25 +       * src/prep_cif.c (ffi_prep_cif): Move stack space allocation code
26 +       to ffi_prep_cif_machdep for x86.
27 +       * src/x86/ffi.c (ffi_prep_cif_machdep): To here.
28 +
29  2010-01-15  Oliver Kiddle  <okiddle@yahoo.co.uk>
30  
31         * src/x86/ffitarget.h (ffi_abi): Check for __i386 and __amd64 for
32 Index: libffi/include/ffi.h.in
33 ===================================================================
34 --- libffi.orig/include/ffi.h.in
35 +++ libffi/include/ffi.h.in
36 @@ -251,6 +251,9 @@ size_t ffi_java_raw_size (ffi_cif *cif);
37  
38  #if FFI_CLOSURES
39  
40 +#ifdef _MSC_VER
41 +__declspec(align(8))
42 +#endif
43  typedef struct {
44    char tramp[FFI_TRAMPOLINE_SIZE];
45    ffi_cif   *cif;
46 Index: libffi/src/prep_cif.c
47 ===================================================================
48 --- libffi.orig/src/prep_cif.c
49 +++ libffi/src/prep_cif.c
50 @@ -109,16 +109,13 @@ ffi_status ffi_prep_cif(ffi_cif *cif, ff
51    /* Perform a sanity check on the return type */
52    FFI_ASSERT_VALID_TYPE(cif->rtype);
53  
54 -  /* x86-64 and s390 stack space allocation is handled in prep_machdep.  */
55 -#if !defined M68K && !defined __x86_64__ && !defined S390 && !defined PA
56 +  /* x86, x86-64 and s390 stack space allocation is handled in prep_machdep. */
57 +#if !defined M68K && !defined __i386__ && !defined __x86_64__ && !defined S390 && !defined PA
58    /* Make space for the return structure pointer */
59    if (cif->rtype->type == FFI_TYPE_STRUCT
60  #ifdef SPARC
61        && (cif->abi != FFI_V9 || cif->rtype->size > 32)
62  #endif
63 -#ifdef X86_DARWIN
64 -      && (cif->rtype->size > 8)
65 -#endif
66       )
67      bytes = STACK_ARG_SIZE(sizeof(void*));
68  #endif
69 @@ -134,7 +131,7 @@ ffi_status ffi_prep_cif(ffi_cif *cif, ff
70          check after the initialization.  */
71        FFI_ASSERT_VALID_TYPE(*ptr);
72  
73 -#if !defined __x86_64__ && !defined S390 && !defined PA
74 +#if !defined __i386__ && !defined __x86_64__ && !defined S390 && !defined PA
75  #ifdef SPARC
76        if (((*ptr)->type == FFI_TYPE_STRUCT
77            && ((*ptr)->size > 16 || cif->abi != FFI_V9))
78 Index: libffi/src/x86/ffi.c
79 ===================================================================
80 --- libffi.orig/src/x86/ffi.c
81 +++ libffi/src/x86/ffi.c
82 @@ -148,13 +148,13 @@ void ffi_prep_args(char *stack, extended
83  /* Perform machine dependent cif processing */
84  ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
85  {
86 +  unsigned int i;
87 +  ffi_type **ptr;
88 +
89    /* Set the return type flag */
90    switch (cif->rtype->type)
91      {
92      case FFI_TYPE_VOID:
93 -#ifdef X86
94 -    case FFI_TYPE_STRUCT:
95 -#endif
96  #if defined(X86) || defined (X86_WIN32) || defined(X86_FREEBSD) || defined(X86_DARWIN) || defined(X86_WIN64)
97      case FFI_TYPE_UINT8:
98      case FFI_TYPE_UINT16:
99 @@ -165,7 +165,6 @@ ffi_status ffi_prep_cif_machdep(ffi_cif 
100      case FFI_TYPE_UINT32:
101      case FFI_TYPE_SINT32:
102  #endif
103 -
104      case FFI_TYPE_SINT64:
105      case FFI_TYPE_FLOAT:
106      case FFI_TYPE_DOUBLE:
107 @@ -184,8 +183,8 @@ ffi_status ffi_prep_cif_machdep(ffi_cif 
108        cif->flags = FFI_TYPE_SINT64;
109        break;
110  
111 -#ifndef X86
112      case FFI_TYPE_STRUCT:
113 +#ifndef X86
114        if (cif->rtype->size == 1)
115          {
116            cif->flags = FFI_TYPE_SMALL_STRUCT_1B; /* same as char size */
117 @@ -207,15 +206,13 @@ ffi_status ffi_prep_cif_machdep(ffi_cif 
118            cif->flags = FFI_TYPE_SINT64; /* same as int64 type */
119          }
120        else
121 +#endif
122          {
123            cif->flags = FFI_TYPE_STRUCT;
124 -#ifdef X86_WIN64
125            // allocate space for return value pointer
126            cif->bytes += ALIGN(sizeof(void*), FFI_SIZEOF_ARG);
127 -#endif
128          }
129        break;
130 -#endif
131  
132      default:
133  #ifdef X86_WIN64
134 @@ -229,41 +226,36 @@ ffi_status ffi_prep_cif_machdep(ffi_cif 
135        break;
136      }
137  
138 -#ifdef X86_DARWIN
139 -  cif->bytes = (cif->bytes + 15) & ~0xF;
140 -#endif
141 +  for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
142 +    {
143 +      if (((*ptr)->alignment - 1) & cif->bytes)
144 +        cif->bytes = ALIGN(cif->bytes, (*ptr)->alignment);
145 +      cif->bytes += ALIGN((*ptr)->size, FFI_SIZEOF_ARG);
146 +    }
147  
148  #ifdef X86_WIN64
149 -  {
150 -    unsigned int i;
151 -    ffi_type **ptr;
152 -
153 -    for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
154 -      {
155 -        if (((*ptr)->alignment - 1) & cif->bytes)
156 -          cif->bytes = ALIGN(cif->bytes, (*ptr)->alignment);
157 -        cif->bytes += ALIGN((*ptr)->size, FFI_SIZEOF_ARG);
158 -      }
159 -  }
160    // ensure space for storing four registers
161    cif->bytes += 4 * sizeof(ffi_arg);
162  #endif
163  
164 +#ifdef X86_DARWIN
165 +  cif->bytes = (cif->bytes + 15) & ~0xF;
166 +#endif
167 +
168    return FFI_OK;
169  }
170  
171 -extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
172 -                          unsigned, unsigned, unsigned *, void (*fn)(void));
173 -
174 -#ifdef X86_WIN32
175 -extern void ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *,
176 -                          unsigned, unsigned, unsigned *, void (*fn)(void));
177 -
178 -#endif /* X86_WIN32 */
179  #ifdef X86_WIN64
180  extern int
181  ffi_call_win64(void (*)(char *, extended_cif *), extended_cif *,
182                 unsigned, unsigned, unsigned *, void (*fn)(void));
183 +#elif defined(X86_WIN32)
184 +extern void
185 +ffi_call_win32(void (*)(char *, extended_cif *), extended_cif *,
186 +               unsigned, unsigned, unsigned *, void (*fn)(void));
187 +#else
188 +extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
189 +                          unsigned, unsigned, unsigned *, void (*fn)(void));
190  #endif
191  
192  void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
193 @@ -321,18 +313,18 @@ void ffi_call(ffi_cif *cif, void (*fn)(v
194                         cif->flags, ecif.rvalue, fn);
195        }
196        break;
197 +#elif defined(X86_WIN32)
198 +    case FFI_SYSV:
199 +    case FFI_STDCALL:
200 +      ffi_call_win32(ffi_prep_args, &ecif, cif->bytes, cif->flags,
201 +                     ecif.rvalue, fn);
202 +      break;
203  #else
204      case FFI_SYSV:
205        ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
206                      fn);
207        break;
208 -#ifdef X86_WIN32
209 -    case FFI_STDCALL:
210 -      ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes, cif->flags,
211 -                       ecif.rvalue, fn);
212 -      break;
213 -#endif /* X86_WIN32 */
214 -#endif /* X86_WIN64 */
215 +#endif
216      default:
217        FFI_ASSERT(0);
218        break;
219 @@ -342,6 +334,8 @@ void ffi_call(ffi_cif *cif, void (*fn)(v
220  
221  /** private members **/
222  
223 +/* The following __attribute__((regparm(1))) decorations will have no effect
224 +   on MSVC - standard cdecl convention applies. */
225  static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
226                                           void** args, ffi_cif* cif);
227  void FFI_HIDDEN ffi_closure_SYSV (ffi_closure *)
228 @@ -390,11 +384,8 @@ ffi_closure_win64_inner (ffi_closure *cl
229  }
230  
231  #else
232 -unsigned int FFI_HIDDEN
233 -ffi_closure_SYSV_inner (closure, respp, args)
234 -     ffi_closure *closure;
235 -     void **respp;
236 -     void *args;
237 +unsigned int FFI_HIDDEN __attribute__ ((regparm(1)))
238 +ffi_closure_SYSV_inner (ffi_closure *closure, void **respp, void *args)
239  {
240    /* our various things...  */
241    ffi_cif       *cif;
242 @@ -505,7 +496,7 @@ ffi_prep_incoming_args_SYSV(char *stack,
243  /* How to make a trampoline.  Derived from gcc/config/i386/i386.c. */
244  
245  #define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
246 -({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
247 +{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
248     unsigned int  __fun = (unsigned int)(FUN); \
249     unsigned int  __ctx = (unsigned int)(CTX); \
250     unsigned int  __dis = __fun - (__ctx + 10);  \
251 @@ -513,10 +504,10 @@ ffi_prep_incoming_args_SYSV(char *stack,
252     *(unsigned int*)  &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
253     *(unsigned char *)  &__tramp[5] = 0xe9; \
254     *(unsigned int*)  &__tramp[6] = __dis; /* jmp __fun  */ \
255 - })
256 + }
257  
258  #define FFI_INIT_TRAMPOLINE_STDCALL(TRAMP,FUN,CTX,SIZE)  \
259 -({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
260 +{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
261     unsigned int  __fun = (unsigned int)(FUN); \
262     unsigned int  __ctx = (unsigned int)(CTX); \
263     unsigned int  __dis = __fun - (__ctx + 10); \
264 @@ -527,7 +518,7 @@ ffi_prep_incoming_args_SYSV(char *stack,
265     *(unsigned int*)  &__tramp[6] = __dis; /* call __fun  */ \
266     *(unsigned char *)  &__tramp[10] = 0xc2; \
267     *(unsigned short*)  &__tramp[11] = __size; /* ret __size  */ \
268 - })
269 + }
270  
271  /* the cif must already be prep'ed */
272  
273 @@ -627,16 +618,6 @@ ffi_prep_args_raw(char *stack, extended_
274   * libffi-1.20, this is not the case.)
275   */
276  
277 -extern void
278 -ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, unsigned, 
279 -              unsigned, unsigned *, void (*fn)(void));
280 -
281 -#ifdef X86_WIN32
282 -extern void
283 -ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *, unsigned,
284 -                 unsigned, unsigned *, void (*fn)(void));
285 -#endif /* X86_WIN32 */
286 -
287  void
288  ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
289  {
290 @@ -660,16 +641,18 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(vo
291    
292    switch (cif->abi) 
293      {
294 +#ifdef X86_WIN32
295 +    case FFI_SYSV:
296 +    case FFI_STDCALL:
297 +      ffi_call_win32(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
298 +                     ecif.rvalue, fn);
299 +      break;
300 +#else
301      case FFI_SYSV:
302        ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
303                      ecif.rvalue, fn);
304        break;
305 -#ifdef X86_WIN32
306 -    case FFI_STDCALL:
307 -      ffi_call_STDCALL(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
308 -                       ecif.rvalue, fn);
309 -      break;
310 -#endif /* X86_WIN32 */
311 +#endif
312      default:
313        FFI_ASSERT(0);
314        break;
315 Index: libffi/src/x86/win32.S
316 ===================================================================
317 --- libffi.orig/src/x86/win32.S
318 +++ libffi/src/x86/win32.S
319 @@ -2,6 +2,7 @@
320     win32.S - Copyright (c) 1996, 1998, 2001, 2002, 2009  Red Hat, Inc.
321              Copyright (c) 2001  John Beniton
322              Copyright (c) 2002  Ranjit Mathew
323 +            Copyright (c) 2009  Daniel Witte
324                         
325   
326     X86 Foreign Function Interface
327 @@ -31,14 +32,371 @@
328  #define LIBFFI_ASM
329  #include <fficonfig.h>
330  #include <ffi.h>
331
332 +
333 +#ifdef _MSC_VER
334 +
335 +.386
336 +.MODEL FLAT, C
337 +
338 +EXTRN ffi_closure_SYSV_inner:NEAR
339 +
340 +_TEXT SEGMENT
341 +
342 +ffi_call_win32 PROC NEAR,
343 +    ffi_prep_args : NEAR PTR DWORD,
344 +    ecif          : NEAR PTR DWORD,
345 +    cif_bytes     : DWORD,
346 +    cif_flags     : DWORD,
347 +    rvalue        : NEAR PTR DWORD,
348 +    fn            : NEAR PTR DWORD
349 +
350 +        ;; Make room for all of the new args.
351 +        mov  ecx, cif_bytes
352 +        sub  esp, ecx
353 +
354 +        mov  eax, esp
355 +
356 +        ;; Place all of the ffi_prep_args in position
357 +        push ecif
358 +        push eax
359 +        call ffi_prep_args
360 +
361 +        ;; Return stack to previous state and call the function
362 +        add  esp, 8
363 +
364 +        call fn
365 +
366 +        ;; cdecl:   we restore esp in the epilogue, so there's no need to
367 +        ;;          remove the space we pushed for the args.
368 +        ;; stdcall: the callee has already cleaned the stack.
369 +
370 +        ;; Load ecx with the return type code
371 +        mov  ecx, cif_flags
372 +
373 +        ;; If the return value pointer is NULL, assume no return value.
374 +        cmp  rvalue, 0
375 +        jne  ca_jumptable
376 +
377 +        ;; Even if there is no space for the return value, we are
378 +        ;; obliged to handle floating-point values.
379 +        cmp  ecx, FFI_TYPE_FLOAT
380 +        jne  ca_epilogue
381 +        fstp st(0)
382 +
383 +        jmp  ca_epilogue
384 +
385 +ca_jumptable:
386 +        jmp  [ca_jumpdata + 4 * ecx]
387 +ca_jumpdata:
388 +        ;; Do not insert anything here between label and jump table.
389 +        dd offset ca_epilogue       ;; FFI_TYPE_VOID
390 +        dd offset ca_retint         ;; FFI_TYPE_INT
391 +        dd offset ca_retfloat       ;; FFI_TYPE_FLOAT
392 +        dd offset ca_retdouble      ;; FFI_TYPE_DOUBLE
393 +        dd offset ca_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
394 +        dd offset ca_retint8        ;; FFI_TYPE_UINT8
395 +        dd offset ca_retint8        ;; FFI_TYPE_SINT8
396 +        dd offset ca_retint16       ;; FFI_TYPE_UINT16
397 +        dd offset ca_retint16       ;; FFI_TYPE_SINT16
398 +        dd offset ca_retint         ;; FFI_TYPE_UINT32
399 +        dd offset ca_retint         ;; FFI_TYPE_SINT32
400 +        dd offset ca_retint64       ;; FFI_TYPE_UINT64
401 +        dd offset ca_retint64       ;; FFI_TYPE_SINT64
402 +        dd offset ca_epilogue       ;; FFI_TYPE_STRUCT
403 +        dd offset ca_retint         ;; FFI_TYPE_POINTER
404 +        dd offset ca_retint8        ;; FFI_TYPE_SMALL_STRUCT_1B
405 +        dd offset ca_retint16       ;; FFI_TYPE_SMALL_STRUCT_2B
406 +        dd offset ca_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
407 +
408 +ca_retint8:
409 +        ;; Load %ecx with the pointer to storage for the return value
410 +        mov   ecx, rvalue
411 +        mov   [ecx + 0], al
412 +        jmp   ca_epilogue
413 +
414 +ca_retint16:
415 +        ;; Load %ecx with the pointer to storage for the return value
416 +        mov   ecx, rvalue
417 +        mov   [ecx + 0], ax
418 +        jmp   ca_epilogue
419 +
420 +ca_retint:
421 +        ;; Load %ecx with the pointer to storage for the return value
422 +        mov   ecx, rvalue
423 +        mov   [ecx + 0], eax
424 +        jmp   ca_epilogue
425 +
426 +ca_retint64:
427 +        ;; Load %ecx with the pointer to storage for the return value
428 +        mov   ecx, rvalue
429 +        mov   [ecx + 0], eax
430 +        mov   [ecx + 4], edx
431 +        jmp   ca_epilogue
432 +
433 +ca_retfloat:
434 +        ;; Load %ecx with the pointer to storage for the return value
435 +        mov   ecx, rvalue
436 +        fstp  DWORD PTR [ecx]
437 +        jmp   ca_epilogue
438 +
439 +ca_retdouble:
440 +        ;; Load %ecx with the pointer to storage for the return value
441 +        mov   ecx, rvalue
442 +        fstp  QWORD PTR [ecx]
443 +        jmp   ca_epilogue
444 +
445 +ca_retlongdouble:
446 +        ;; Load %ecx with the pointer to storage for the return value
447 +        mov   ecx, rvalue
448 +        fstp  TBYTE PTR [ecx]
449 +        jmp   ca_epilogue
450 +
451 +ca_epilogue:
452 +        ;; Epilogue code is autogenerated.
453 +        ret
454 +ffi_call_win32 ENDP
455 +
456 +ffi_closure_SYSV PROC NEAR FORCEFRAME
457 +    ;; the ffi_closure ctx is passed in eax by the trampoline.
458 +
459 +        sub  esp, 40
460 +        lea  edx, [ebp - 24]
461 +        mov  [ebp - 12], edx         ;; resp
462 +        lea  edx, [ebp + 8]
463 +        mov  [esp + 8], edx          ;; args
464 +        lea  edx, [ebp - 12]
465 +        mov  [esp + 4], edx          ;; &resp
466 +        mov  [esp], eax              ;; closure
467 +        call ffi_closure_SYSV_inner
468 +        mov  ecx, [ebp - 12]
469 +
470 +cs_jumptable:
471 +        jmp  [cs_jumpdata + 4 * eax]
472 +cs_jumpdata:
473 +        ;; Do not insert anything here between the label and jump table.
474 +        dd offset cs_epilogue       ;; FFI_TYPE_VOID
475 +        dd offset cs_retint         ;; FFI_TYPE_INT
476 +        dd offset cs_retfloat       ;; FFI_TYPE_FLOAT
477 +        dd offset cs_retdouble      ;; FFI_TYPE_DOUBLE
478 +        dd offset cs_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
479 +        dd offset cs_retint8        ;; FFI_TYPE_UINT8
480 +        dd offset cs_retint8        ;; FFI_TYPE_SINT8
481 +        dd offset cs_retint16       ;; FFI_TYPE_UINT16
482 +        dd offset cs_retint16       ;; FFI_TYPE_SINT16
483 +        dd offset cs_retint         ;; FFI_TYPE_UINT32
484 +        dd offset cs_retint         ;; FFI_TYPE_SINT32
485 +        dd offset cs_retint64       ;; FFI_TYPE_UINT64
486 +        dd offset cs_retint64       ;; FFI_TYPE_SINT64
487 +        dd offset cs_retstruct      ;; FFI_TYPE_STRUCT
488 +        dd offset cs_retint         ;; FFI_TYPE_POINTER
489 +        dd offset cs_retint8        ;; FFI_TYPE_SMALL_STRUCT_1B
490 +        dd offset cs_retint16       ;; FFI_TYPE_SMALL_STRUCT_2B
491 +        dd offset cs_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
492 +
493 +cs_retint8:
494 +        mov   al, [ecx]
495 +        jmp   cs_epilogue
496 +
497 +cs_retint16:
498 +        mov   ax, [ecx]
499 +        jmp   cs_epilogue
500 +
501 +cs_retint:
502 +        mov   eax, [ecx]
503 +        jmp   cs_epilogue
504 +
505 +cs_retint64:
506 +        mov   eax, [ecx + 0]
507 +        mov   edx, [ecx + 4]
508 +        jmp   cs_epilogue
509 +
510 +cs_retfloat:
511 +        fld   DWORD PTR [ecx]
512 +        jmp   cs_epilogue
513 +
514 +cs_retdouble:
515 +        fld   QWORD PTR [ecx]
516 +        jmp   cs_epilogue
517 +
518 +cs_retlongdouble:
519 +        fld   TBYTE PTR [ecx]
520 +        jmp   cs_epilogue
521 +
522 +cs_retstruct:
523 +        ;; Caller expects us to pop struct return value pointer hidden arg.
524 +        ;; Epilogue code is autogenerated.
525 +        ret    4
526 +
527 +cs_epilogue:
528 +        ;; Epilogue code is autogenerated.
529 +        ret
530 +ffi_closure_SYSV ENDP
531 +
532 +#if !FFI_NO_RAW_API
533 +
534 +#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) AND NOT 3)
535 +#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
536 +#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
537 +#define CIF_FLAGS_OFFSET 20
538 +
539 +ffi_closure_raw_SYSV PROC NEAR USES esi
540 +    ;; the ffi_closure ctx is passed in eax by the trampoline.
541 +
542 +        sub  esp, 40
543 +        mov  esi, [eax + RAW_CLOSURE_CIF_OFFSET]        ;; closure->cif
544 +        mov  edx, [eax + RAW_CLOSURE_USER_DATA_OFFSET]  ;; closure->user_data
545 +        mov  [esp + 12], edx                            ;; user_data
546 +        lea  edx, [ebp + 8]
547 +        mov  [esp + 8], edx                             ;; raw_args
548 +        lea  edx, [ebp - 24]
549 +        mov  [esp + 4], edx                             ;; &res
550 +        mov  [esp], esi                                 ;; cif
551 +        call DWORD PTR [eax + RAW_CLOSURE_FUN_OFFSET]   ;; closure->fun
552 +        mov  eax, [esi + CIF_FLAGS_OFFSET]              ;; cif->flags
553 +        lea  ecx, [ebp - 24]
554 +
555 +cr_jumptable:
556 +        jmp  [cr_jumpdata + 4 * eax]
557 +cr_jumpdata:
558 +        ;; Do not insert anything here between the label and jump table.
559 +        dd offset cr_epilogue       ;; FFI_TYPE_VOID
560 +        dd offset cr_retint         ;; FFI_TYPE_INT
561 +        dd offset cr_retfloat       ;; FFI_TYPE_FLOAT
562 +        dd offset cr_retdouble      ;; FFI_TYPE_DOUBLE
563 +        dd offset cr_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
564 +        dd offset cr_retint8        ;; FFI_TYPE_UINT8
565 +        dd offset cr_retint8        ;; FFI_TYPE_SINT8
566 +        dd offset cr_retint16       ;; FFI_TYPE_UINT16
567 +        dd offset cr_retint16       ;; FFI_TYPE_SINT16
568 +        dd offset cr_retint         ;; FFI_TYPE_UINT32
569 +        dd offset cr_retint         ;; FFI_TYPE_SINT32
570 +        dd offset cr_retint64       ;; FFI_TYPE_UINT64
571 +        dd offset cr_retint64       ;; FFI_TYPE_SINT64
572 +        dd offset cr_epilogue       ;; FFI_TYPE_STRUCT
573 +        dd offset cr_retint         ;; FFI_TYPE_POINTER
574 +        dd offset cr_retint8        ;; FFI_TYPE_SMALL_STRUCT_1B
575 +        dd offset cr_retint16       ;; FFI_TYPE_SMALL_STRUCT_2B
576 +        dd offset cr_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
577 +
578 +cr_retint8:
579 +        mov   al, [ecx]
580 +        jmp   cr_epilogue
581 +
582 +cr_retint16:
583 +        mov   ax, [ecx]
584 +        jmp   cr_epilogue
585 +
586 +cr_retint:
587 +        mov   eax, [ecx]
588 +        jmp   cr_epilogue
589 +
590 +cr_retint64:
591 +        mov   eax, [ecx + 0]
592 +        mov   edx, [ecx + 4]
593 +        jmp   cr_epilogue
594 +
595 +cr_retfloat:
596 +        fld   DWORD PTR [ecx]
597 +        jmp   cr_epilogue
598 +
599 +cr_retdouble:
600 +        fld   QWORD PTR [ecx]
601 +        jmp   cr_epilogue
602 +
603 +cr_retlongdouble:
604 +        fld   TBYTE PTR [ecx]
605 +        jmp   cr_epilogue
606 +
607 +cr_epilogue:
608 +        ;; Epilogue code is autogenerated.
609 +        ret
610 +ffi_closure_raw_SYSV ENDP
611 +
612 +#endif /* !FFI_NO_RAW_API */
613 +
614 +ffi_closure_STDCALL PROC NEAR FORCEFRAME
615 +    ;; the ffi_closure ctx is passed in eax by the trampoline.
616 +
617 +        sub  esp, 40
618 +        lea  edx, [ebp - 24]
619 +        mov  [ebp - 12], edx         ;; resp
620 +        lea  edx, [ebp + 12]         ;; account for stub return address on stack
621 +        mov  [esp + 8], edx          ;; args
622 +        lea  edx, [ebp - 12]
623 +        mov  [esp + 4], edx          ;; &resp
624 +        mov  [esp], eax              ;; closure
625 +        call ffi_closure_SYSV_inner
626 +        mov  ecx, [ebp - 12]
627 +
628 +cd_jumptable:
629 +        jmp  [cd_jumpdata + 4 * eax]
630 +cd_jumpdata:
631 +        ;; Do not insert anything here between the label and jump table.
632 +        dd offset cd_epilogue       ;; FFI_TYPE_VOID
633 +        dd offset cd_retint         ;; FFI_TYPE_INT
634 +        dd offset cd_retfloat       ;; FFI_TYPE_FLOAT
635 +        dd offset cd_retdouble      ;; FFI_TYPE_DOUBLE
636 +        dd offset cd_retlongdouble  ;; FFI_TYPE_LONGDOUBLE
637 +        dd offset cd_retint8        ;; FFI_TYPE_UINT8
638 +        dd offset cd_retint8        ;; FFI_TYPE_SINT8
639 +        dd offset cd_retint16       ;; FFI_TYPE_UINT16
640 +        dd offset cd_retint16       ;; FFI_TYPE_SINT16
641 +        dd offset cd_retint         ;; FFI_TYPE_UINT32
642 +        dd offset cd_retint         ;; FFI_TYPE_SINT32
643 +        dd offset cd_retint64       ;; FFI_TYPE_UINT64
644 +        dd offset cd_retint64       ;; FFI_TYPE_SINT64
645 +        dd offset cd_epilogue       ;; FFI_TYPE_STRUCT
646 +        dd offset cd_retint         ;; FFI_TYPE_POINTER
647 +        dd offset cd_retint8        ;; FFI_TYPE_SMALL_STRUCT_1B
648 +        dd offset cd_retint16       ;; FFI_TYPE_SMALL_STRUCT_2B
649 +        dd offset cd_retint         ;; FFI_TYPE_SMALL_STRUCT_4B
650 +
651 +cd_retint8:
652 +        mov   al, [ecx]
653 +        jmp   cd_epilogue
654 +
655 +cd_retint16:
656 +        mov   ax, [ecx]
657 +        jmp   cd_epilogue
658 +
659 +cd_retint:
660 +        mov   eax, [ecx]
661 +        jmp   cd_epilogue
662 +
663 +cd_retint64:
664 +        mov   eax, [ecx + 0]
665 +        mov   edx, [ecx + 4]
666 +        jmp   cd_epilogue
667 +
668 +cd_retfloat:
669 +        fld   DWORD PTR [ecx]
670 +        jmp   cd_epilogue
671 +
672 +cd_retdouble:
673 +        fld   QWORD PTR [ecx]
674 +        jmp   cd_epilogue
675 +
676 +cd_retlongdouble:
677 +        fld   TBYTE PTR [ecx]
678 +        jmp   cd_epilogue
679 +
680 +cd_epilogue:
681 +        ;; Epilogue code is autogenerated.
682 +        ret
683 +ffi_closure_STDCALL ENDP
684 +
685 +_TEXT ENDS
686 +END
687 +
688 +#else
689 +
690         .text
691   
692          # This assumes we are using gas.
693          .balign 16
694 -       .globl  _ffi_call_SYSV
695 -       .def    _ffi_call_SYSV; .scl    2;      .type   32;     .endef
696 -_ffi_call_SYSV:
697 +       .globl  _ffi_call_win32
698 +       .def    _ffi_call_win32;        .scl    2;      .type   32;     .endef
699 +_ffi_call_win32:
700  .LFB1:
701          pushl %ebp
702  .LCFI0:
703 @@ -61,8 +419,10 @@ _ffi_call_SYSV:
704          # FIXME: Align the stack to a 128-bit boundary to avoid
705          # potential performance hits.
706  
707 -       call  *28(%ebp)
708 +        call  *28(%ebp)
709   
710 +        # stdcall functions pop arguments off the stack themselves
711 +
712          # Load %ecx with the return type code
713          movl  20(%ebp),%ecx
714   
715 @@ -181,164 +541,11 @@ _ffi_call_SYSV:
716          movl %ebp,%esp
717          popl %ebp
718          ret
719 -.ffi_call_SYSV_end:
720 +.ffi_call_win32_end:
721  .LFE1:
722  
723          # This assumes we are using gas.
724          .balign 16
725 -       .globl  _ffi_call_STDCALL
726 -       .def    _ffi_call_STDCALL;      .scl    2;      .type   32;     .endef
727 -_ffi_call_STDCALL:
728 -.LFB2:
729 -        pushl %ebp
730 -.LCFI2:
731 -        movl  %esp,%ebp
732 -.LCFI3:
733 -        # Make room for all of the new args.
734 -        movl  16(%ebp),%ecx 
735 -        subl  %ecx,%esp
736 -
737 -        movl  %esp,%eax
738 -
739 -        # Place all of the ffi_prep_args in position
740 -        pushl 12(%ebp)
741 -        pushl %eax
742 -        call  *8(%ebp)
743 -
744 -        # Return stack to previous state and call the function
745 -        addl  $8,%esp
746 -
747 -        # FIXME: Align the stack to a 128-bit boundary to avoid
748 -        # potential performance hits.
749 -
750 -        call  *28(%ebp)
751 -
752 -        # stdcall functions pop arguments off the stack themselves
753 -
754 -        # Load %ecx with the return type code
755 -        movl  20(%ebp),%ecx
756 -
757 -        # If the return value pointer is NULL, assume no return value.
758 -        cmpl  $0,24(%ebp)
759 -        jne   0f
760 -
761 -        # Even if there is no space for the return value, we are
762 -        # obliged to handle floating-point values.
763 -        cmpl  $FFI_TYPE_FLOAT,%ecx
764 -        jne   .Lsc_noretval
765 -        fstp  %st(0)
766 -
767 -        jmp   .Lsc_epilogue
768 -
769 -0:
770 -       call    1f
771 -       # Do not insert anything here between the call and the jump table.
772 -.Lsc_store_table:
773 -       .long   .Lsc_noretval           /* FFI_TYPE_VOID */
774 -       .long   .Lsc_retint             /* FFI_TYPE_INT */
775 -       .long   .Lsc_retfloat           /* FFI_TYPE_FLOAT */
776 -       .long   .Lsc_retdouble          /* FFI_TYPE_DOUBLE */
777 -       .long   .Lsc_retlongdouble      /* FFI_TYPE_LONGDOUBLE */
778 -       .long   .Lsc_retuint8           /* FFI_TYPE_UINT8 */
779 -       .long   .Lsc_retsint8           /* FFI_TYPE_SINT8 */
780 -       .long   .Lsc_retuint16          /* FFI_TYPE_UINT16 */
781 -       .long   .Lsc_retsint16          /* FFI_TYPE_SINT16 */
782 -       .long   .Lsc_retint             /* FFI_TYPE_UINT32 */
783 -       .long   .Lsc_retint             /* FFI_TYPE_SINT32 */
784 -       .long   .Lsc_retint64           /* FFI_TYPE_UINT64 */
785 -       .long   .Lsc_retint64           /* FFI_TYPE_SINT64 */
786 -       .long   .Lsc_retstruct          /* FFI_TYPE_STRUCT */
787 -       .long   .Lsc_retint             /* FFI_TYPE_POINTER */
788 -       .long   .Lsc_retstruct1b        /* FFI_TYPE_SMALL_STRUCT_1B */
789 -       .long   .Lsc_retstruct2b        /* FFI_TYPE_SMALL_STRUCT_2B */
790 -       .long   .Lsc_retstruct4b        /* FFI_TYPE_SMALL_STRUCT_4B */
791 -
792 -1:
793 -       add     %ecx, %ecx
794 -       add     %ecx, %ecx
795 -       add     (%esp),%ecx
796 -       add     $4, %esp
797 -       jmp     *(%ecx)
798 -
799 -       /* Sign/zero extend as appropriate.  */
800 -.Lsc_retsint8:
801 -       movsbl  %al, %eax
802 -       jmp     .Lsc_retint
803 -
804 -.Lsc_retsint16:
805 -       movswl  %ax, %eax
806 -       jmp     .Lsc_retint
807 -
808 -.Lsc_retuint8:
809 -       movzbl  %al, %eax
810 -       jmp     .Lsc_retint
811 -
812 -.Lsc_retuint16:
813 -       movzwl  %ax, %eax
814 -       jmp     .Lsc_retint
815 -
816 -.Lsc_retint:
817 -        # Load %ecx with the pointer to storage for the return value
818 -        movl  24(%ebp),%ecx
819 -        movl  %eax,0(%ecx)
820 -        jmp   .Lsc_epilogue
821 -
822 -.Lsc_retfloat:
823 -         # Load %ecx with the pointer to storage for the return value
824 -        movl  24(%ebp),%ecx
825 -        fstps (%ecx)
826 -        jmp   .Lsc_epilogue
827 -
828 -.Lsc_retdouble:
829 -        # Load %ecx with the pointer to storage for the return value
830 -        movl  24(%ebp),%ecx
831 -        fstpl (%ecx)
832 -        jmp   .Lsc_epilogue
833 -
834 -.Lsc_retlongdouble:
835 -        # Load %ecx with the pointer to storage for the return value
836 -        movl  24(%ebp),%ecx
837 -        fstpt (%ecx)
838 -        jmp   .Lsc_epilogue
839 -
840 -.Lsc_retint64:
841 -        # Load %ecx with the pointer to storage for the return value
842 -        movl  24(%ebp),%ecx
843 -        movl  %eax,0(%ecx)
844 -        movl  %edx,4(%ecx)
845 -       jmp   .Lsc_epilogue
846 -
847 -.Lsc_retstruct1b:
848 -        # Load %ecx with the pointer to storage for the return value
849 -        movl  24(%ebp),%ecx
850 -        movb  %al,0(%ecx)
851 -        jmp   .Lsc_epilogue
852 -
853 -.Lsc_retstruct2b:
854 -        # Load %ecx with the pointer to storage for the return value
855 -        movl  24(%ebp),%ecx
856 -        movw  %ax,0(%ecx)
857 -        jmp   .Lsc_epilogue
858 -
859 -.Lsc_retstruct4b:
860 -        # Load %ecx with the pointer to storage for the return value
861 -        movl  24(%ebp),%ecx
862 -        movl  %eax,0(%ecx)
863 -        jmp   .Lsc_epilogue
864 -
865 -.Lsc_retstruct:
866 -        # Nothing to do!
867 -
868 -.Lsc_noretval:
869 -.Lsc_epilogue:
870 -        movl %ebp,%esp
871 -        popl %ebp
872 -        ret
873 -.ffi_call_STDCALL_end:
874 -.LFE2:
875 -
876 -        # This assumes we are using gas.
877 -        .balign 16
878         .globl  _ffi_closure_SYSV
879         .def    _ffi_closure_SYSV;      .scl    2;      .type   32;     .endef
880  _ffi_closure_SYSV:
881 @@ -742,38 +949,6 @@ _ffi_closure_STDCALL:
882  .LEFDE1:
883  
884  
885 -.LSFDE2:
886 -       .long   .LEFDE2-.LASFDE2        /* FDE Length */
887 -.LASFDE2:
888 -       .long   .LASFDE2-.Lframe1       /* FDE CIE offset */
889 -#if defined __PIC__ && defined HAVE_AS_X86_PCREL
890 -       .long   .LFB2-. /* FDE initial location */
891 -#else
892 -       .long   .LFB2
893 -#endif
894 -       .long   .LFE2-.LFB2     /* FDE address range */
895 -#ifdef __PIC__
896 -       .byte   0x0     /* .uleb128 0x0; Augmentation size */
897 -#endif
898 -       /* DW_CFA_xxx CFI instructions go here.  */
899 -
900 -       .byte   0x4     /* DW_CFA_advance_loc4 */
901 -       .long   .LCFI2-.LFB2
902 -       .byte   0xe     /* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
903 -       .byte   0x8     /* .uleb128 0x8 */
904 -       .byte   0x85    /* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
905 -       .byte   0x2     /* .uleb128 0x2 */
906 -
907 -       .byte   0x4     /* DW_CFA_advance_loc4 */
908 -       .long   .LCFI3-.LCFI2
909 -       .byte   0xd     /* DW_CFA_def_cfa_register CFA = r5 = %ebp */
910 -       .byte   0x5     /* .uleb128 0x5 */
911 -
912 -       /* End of DW_CFA_xxx CFI instructions.  */
913 -       .align 4
914 -.LEFDE2:
915 -
916 -
917  .LSFDE3:
918         .long   .LEFDE3-.LASFDE3        /* FDE Length */
919  .LASFDE3:
920 @@ -875,3 +1050,6 @@ _ffi_closure_STDCALL:
921         /* End of DW_CFA_xxx CFI instructions.  */
922         .align 4
923  .LEFDE5:
924 +
925 +#endif /* !_MSC_VER */
926 +
927 Index: libffi/README
928 ===================================================================
929 --- libffi.orig/README
930 +++ libffi/README
931 @@ -109,6 +109,14 @@ will add some extra code which will supp
932  are using Purify with libffi. Only use this switch when using 
933  Purify, as it will slow down the library.
934  
935 +It's also possible to build libffi on Windows platforms with
936 +Microsoft's Visual C++ compiler.  In this case, use the msvcc.sh
937 +wrapper script during configuration like so:
938 +
939 +path/to/configure --enable-shared --enable-static \
940 +       CC=path/to/msvcc.sh LD=link \
941 +       CPP=\"cl -nologo -EP\"
942 +
943  Configure has many other options. Use "configure --help" to see them all.
944  
945  Once configure has finished, type "make". Note that you must be using
946 @@ -128,6 +136,8 @@ See the ChangeLog files for details.
947  3.0.10 ???-??-??
948          Fix the N64 build on mips-sgi-irix6.5.
949         Testsuite fixes for Tru64 Unix.
950 +       Enable builds with Microsoft's compiler.
951 +       Enable x86 builds with Sun's compiler.
952  
953  3.0.9 Dec-31-09
954          Add AVR32 and win64 ports.  Add ARM softfp support.