Add Tim Wall's x86 windows patch.

This commit is contained in:
green
2008-01-31 11:58:57 +00:00
parent e332366d15
commit abc0bbf381
5 changed files with 140 additions and 6 deletions

View File

@@ -235,6 +235,10 @@ 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)));
#ifdef X86_WIN32
void FFI_HIDDEN ffi_closure_STDCALL (ffi_closure *)
__attribute__ ((regparm(1)));
#endif
/* This function is jumped to by the trampoline */
@@ -317,6 +321,19 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
*(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \
})
#define FFI_INIT_TRAMPOLINE_STDCALL(TRAMP,FUN,CTX,SIZE) \
({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
unsigned int __fun = (unsigned int)(FUN); \
unsigned int __ctx = (unsigned int)(CTX); \
unsigned int __dis = __fun - ((unsigned int) __tramp + FFI_TRAMPOLINE_SIZE); \
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 */
@@ -327,11 +344,24 @@ ffi_prep_closure_loc (ffi_closure* closure,
void *user_data,
void *codeloc)
{
FFI_ASSERT (cif->abi == FFI_SYSV);
FFI_INIT_TRAMPOLINE (&closure->tramp[0], \
&ffi_closure_SYSV, \
codeloc);
if (cif->abi == FFI_SYSV)
{
FFI_INIT_TRAMPOLINE (&closure->tramp[0],
&ffi_closure_SYSV,
(void*)closure);
}
#ifdef X86_WIN32
else if (cif->abi == FFI_STDCALL)
{
FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0],
&ffi_closure_STDCALL,
(void*)closure, cif->bytes);
}
#endif
else
{
return FFI_BAD_ABI;
}
closure->cif = cif;
closure->user_data = user_data;
@@ -353,7 +383,9 @@ ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
{
int i;
FFI_ASSERT (cif->abi == FFI_SYSV);
if (cif->abi != FFI_SYSV) {
return FFI_BAD_ABI;
}
// we currently don't support certain kinds of arguments for raw
// closures. This should be implemented by a separate assembly language

View File

@@ -77,7 +77,11 @@ typedef enum ffi_abi {
#define FFI_TRAMPOLINE_SIZE 24
#define FFI_NATIVE_RAW_API 0
#else
#ifdef X86_WIN32
#define FFI_TRAMPOLINE_SIZE 13
#else
#define FFI_TRAMPOLINE_SIZE 10
#endif
#define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */
#endif

View File

@@ -258,6 +258,22 @@ sc_epilogue:
.ffi_call_STDCALL_end:
.globl _ffi_closure_STDCALL
_ffi_closure_STDCALL:
pushl %ebp
movl %esp, %ebp
subl $40, %esp
leal -24(%ebp), %edx
movl %edx, -12(%ebp) /* resp */
leal 12(%ebp), %edx /* account for stub return address on stack */
movl %edx, 4(%esp) /* args */
leal -12(%ebp), %edx
movl %edx, (%esp) /* &resp */
call _ffi_closure_SYSV_inner
movl -12(%ebp), %ecx
jmp .Lcls_return_result
.ffi_closure_STDCALL_end:
.globl _ffi_closure_SYSV
_ffi_closure_SYSV:
pushl %ebp
@@ -271,6 +287,7 @@ _ffi_closure_SYSV:
movl %edx, (%esp) /* &resp */
call _ffi_closure_SYSV_inner
movl -12(%ebp), %ecx
.Lcls_return_result:
cmpl $FFI_TYPE_INT, %eax
je .Lcls_retint
cmpl $FFI_TYPE_FLOAT, %eax