__attribute__ ((regparm(1)));
void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *)
__attribute__ ((regparm(1)));
-#ifndef X86_WIN64
+#ifdef X86_WIN32
void FFI_HIDDEN ffi_closure_raw_THISCALL (ffi_raw_closure *)
__attribute__ ((regparm(1)));
+#endif
+#ifndef X86_WIN64
void FFI_HIDDEN ffi_closure_STDCALL (ffi_closure *)
__attribute__ ((regparm(1)));
void FFI_HIDDEN ffi_closure_THISCALL (ffi_closure *)
*(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \
}
-#define FFI_INIT_TRAMPOLINE_THISCALL(TRAMP,FUN,CTX,SIZE) \
+#define FFI_INIT_TRAMPOLINE_RAW_THISCALL(TRAMP,FUN,CTX,SIZE) \
{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
unsigned int __fun = (unsigned int)(FUN); \
unsigned int __ctx = (unsigned int)(CTX); \
*(unsigned short*) &__tramp[50] = (__size + 8); /* ret (__size + 8) */ \
}
-#define FFI_INIT_TRAMPOLINE_STDCALL(TRAMP,FUN,CTX,SIZE) \
+#define FFI_INIT_TRAMPOLINE_STDCALL(TRAMP,FUN,CTX) \
{ 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 */
}
else if (cif->abi == FFI_THISCALL)
{
- FFI_INIT_TRAMPOLINE_THISCALL (&closure->tramp[0],
- &ffi_closure_THISCALL,
- (void*)codeloc,
- cif->bytes);
+ FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0],
+ &ffi_closure_THISCALL,
+ (void*)codeloc);
}
else if (cif->abi == FFI_STDCALL)
{
FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0],
&ffi_closure_STDCALL,
- (void*)codeloc, cif->bytes);
+ (void*)codeloc);
}
#ifdef X86_WIN32
else if (cif->abi == FFI_MS_CDECL)
int i;
if (cif->abi != FFI_SYSV
-#ifndef X86_WIN64
+#ifdef X86_WIN32
&& cif->abi != FFI_THISCALL
#endif
)
FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE);
}
-#ifndef X86_WIN64
+#ifdef X86_WIN32
if (cif->abi == FFI_SYSV)
{
#endif
FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV,
codeloc);
-#ifndef X86_WIN64
+#ifdef X86_WIN32
}
else if (cif->abi == FFI_THISCALL)
{
- FFI_INIT_TRAMPOLINE_THISCALL (&closure->tramp[0], &ffi_closure_raw_THISCALL,
- codeloc, cif->bytes);
+ FFI_INIT_TRAMPOLINE_RAW_THISCALL (&closure->tramp[0], &ffi_closure_raw_THISCALL, codeloc);
}
#endif
closure->cif = cif;
#if defined (X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
#define FFI_TRAMPOLINE_SIZE 24
#define FFI_NATIVE_RAW_API 0
-#elif defined(X86_WIN64)
+#else
+#ifdef X86_WIN32
+#define FFI_TRAMPOLINE_SIZE 52
+#else
+#ifdef X86_WIN64
#define FFI_TRAMPOLINE_SIZE 29
#define FFI_NATIVE_RAW_API 0
#define FFI_NO_RAW_API 1
#else
-#define FFI_TRAMPOLINE_SIZE 52
+#define FFI_TRAMPOLINE_SIZE 10
+#endif
+#endif
+#ifndef X86_WIN64
#define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */
#endif
+#endif
#endif
#include <fficonfig.h>
#include <ffi.h>
+#define CIF_ABI_OFFSET 0
+#define CIF_BYTES_OFFSET 16
+
#ifdef _MSC_VER
+#define CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) AND NOT 3)
+
.386
.MODEL FLAT, C
ret
ffi_call_win32 ENDP
-ffi_closure_THISCALL PROC NEAR FORCEFRAME
- sub esp, 40
- lea edx, [ebp -24]
- mov [ebp - 12], edx /* resp */
- lea edx, [ebp + 12] /* account for stub return address on stack */
- jmp stub
+ffi_closure_THISCALL PROC NEAR
+ ;; Insert the register argument on the stack as the first argument
+ xchg DWORD PTR [esp+4], ecx
+ xchg DWORD PTR [esp], ecx
+ push ecx
+ jmp ffi_closure_STDCALL
ffi_closure_THISCALL ENDP
ffi_closure_SYSV PROC NEAR FORCEFRAME
jmp cd_epilogue
cd_epilogue:
- ;; Epilogue code is autogenerated.
- ret
+ mov esp, ebp
+ pop ebp
+ pop ecx
+ mov ecx, DWORD PTR [ecx + (CLOSURE_CIF_OFFSET-10)]
+ cmp DWORD PTR [ecx + CIF_ABI_OFFSET], 3
+ mov ecx, DWORD PTR [ecx + CIF_BYTES_OFFSET]
+ jne cd_not_thiscall
+ add ecx, 4
+cd_not_thiscall:
+ pop edx
+ add esp, ecx
+ jmp edx
ffi_closure_STDCALL ENDP
_TEXT ENDS
#else
+#define CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
+
#if defined(SYMBOL_UNDERSCORE)
#define USCORE_SYMBOL(x) _##x
#else
.def _ffi_closure_THISCALL; .scl 2; .type 32; .endef
#endif
USCORE_SYMBOL(ffi_closure_THISCALL):
- 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 */
- jmp .stub
+ /* Insert the register argument on the stack as the first argument */
+ xchg %ecx, 4(%esp)
+ xchg %ecx, (%esp)
+ push %ecx
+ jmp .ffi_closure_STDCALL_internal
.LFE1:
# This assumes we are using gas.
leal -24(%ebp), %edx
movl %edx, -12(%ebp) /* resp */
leal 8(%ebp), %edx
-.stub:
movl %edx, 4(%esp) /* args = __builtin_dwarf_cfa () */
leal -12(%ebp), %edx
movl %edx, (%esp) /* &resp */
#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
+
+#ifdef X86_WIN32
.balign 16
FFI_HIDDEN(ffi_closure_raw_THISCALL)
.globl USCORE_SYMBOL(ffi_closure_raw_THISCALL)
movl %edx, 12(%esp) /* user_data */
leal 12(%ebp), %edx /* __builtin_dwarf_cfa () */
jmp .stubraw
+#endif /* X86_WIN32 */
+
# This assumes we are using gas.
.balign 16
#if defined(X86_WIN32)
.def _ffi_closure_STDCALL; .scl 2; .type 32; .endef
#endif
USCORE_SYMBOL(ffi_closure_STDCALL):
+.ffi_closure_STDCALL_internal:
.LFB5:
pushl %ebp
.LCFI9:
.Lscls_epilogue:
movl %ebp, %esp
popl %ebp
- ret
+ popl %ecx
+ movl (CLOSURE_CIF_OFFSET-10)(%ecx), %ecx
+ cmpl $3, CIF_ABI_OFFSET(%ecx) /* FFI_THISCALL */
+ movl CIF_BYTES_OFFSET(%ecx), %ecx
+ jne 1f
+ addl $4, %ecx
+1: popl %edx
+ addl %ecx, %esp
+ jmp *%edx
.ffi_closure_STDCALL_end:
.LFE5: