From 4b75a7c1cfb0aebd939fc17fccbcfc66ade4dea0 Mon Sep 17 00:00:00 2001 From: Thomas Heller Date: Fri, 21 Apr 2006 16:48:56 +0000 Subject: Merge in changes from ctypes 0.9.9.6 upstream version. --- Modules/_ctypes/_ctypes.c | 17 ++- Modules/_ctypes/libffi/fficonfig.py.in | 1 + Modules/_ctypes/libffi_msvc/ffi.c | 85 ++++-------- Modules/_ctypes/libffi_msvc/ffi.h | 4 - Modules/_ctypes/libffi_msvc/ffi_common.h | 19 +-- Modules/_ctypes/libffi_msvc/ffitarget.h | 20 ++- Modules/_ctypes/libffi_msvc/mingwin32.S | 228 +++++++++++++++++++++++++++++++ Modules/_ctypes/libffi_msvc/prep_cif.c | 2 +- Modules/_ctypes/libffi_msvc/win32.S | 20 ++- 9 files changed, 297 insertions(+), 99 deletions(-) create mode 100644 Modules/_ctypes/libffi_msvc/mingwin32.S diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 0108a7c..6a27833 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -1223,6 +1223,19 @@ c_void_p_from_param(PyObject *type, PyObject *value) return value; } } +/* function pointer */ + if (CFuncPtrObject_Check(value)) { + PyCArgObject *parg; + CFuncPtrObject *func; + func = (CFuncPtrObject *)value; + parg = new_CArgObject(); + parg->pffi_type = &ffi_type_pointer; + parg->tag = 'P'; + Py_INCREF(value); + parg->value.p = *(void **)func->b_ptr; + parg->obj = value; + return (PyObject *)parg; + } /* c_char_p, c_wchar_p */ stgd = PyObject_stgdict(value); if (stgd && CDataObject_Check(value) && stgd->proto && PyString_Check(stgd->proto)) { @@ -4407,6 +4420,8 @@ cast_check_pointertype(PyObject *arg) if (PointerTypeObject_Check(arg)) return 1; + if (CFuncPtrTypeObject_Check(arg)) + return 1; dict = PyType_stgdict(arg); if (dict) { if (PyString_Check(dict->proto) @@ -4566,7 +4581,7 @@ init_ctypes(void) #endif PyModule_AddObject(m, "FUNCFLAG_CDECL", PyInt_FromLong(FUNCFLAG_CDECL)); PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyInt_FromLong(FUNCFLAG_PYTHONAPI)); - PyModule_AddStringConstant(m, "__version__", "0.9.9.4"); + PyModule_AddStringConstant(m, "__version__", "0.9.9.6"); PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove)); PyModule_AddObject(m, "_memset_addr", PyLong_FromVoidPtr(memset)); diff --git a/Modules/_ctypes/libffi/fficonfig.py.in b/Modules/_ctypes/libffi/fficonfig.py.in index 2ed2347..5e53c6d 100644 --- a/Modules/_ctypes/libffi/fficonfig.py.in +++ b/Modules/_ctypes/libffi/fficonfig.py.in @@ -31,5 +31,6 @@ ffi_sources += ffi_platforms['@TARGET@'] ffi_sources = [os.path.join('@srcdir@', f) for f in ffi_sources] ffi_cflags = '@CFLAGS@' +# I think this may no longer be needed: if sys.platform == "openbsd3": ffi_cflags += " -fno-stack-protector" diff --git a/Modules/_ctypes/libffi_msvc/ffi.c b/Modules/_ctypes/libffi_msvc/ffi.c index 5c49b39..e5600b2 100644 --- a/Modules/_ctypes/libffi_msvc/ffi.c +++ b/Modules/_ctypes/libffi_msvc/ffi.c @@ -26,8 +26,6 @@ OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ -#ifndef __x86_64__ - #include #include @@ -143,11 +141,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) /*@-declundef@*/ /*@-exportheader@*/ -#ifdef _MSC_VER extern int -#else -extern void -#endif ffi_call_SYSV(void (*)(char *, extended_cif *), /*@out@*/ extended_cif *, unsigned, unsigned, @@ -156,14 +150,9 @@ ffi_call_SYSV(void (*)(char *, extended_cif *), /*@=declundef@*/ /*@=exportheader@*/ -#if defined(X86_WIN32) || defined(_MSC_VER) /*@-declundef@*/ /*@-exportheader@*/ -#ifdef _MSC_VER extern int -#else -extern void -#endif ffi_call_STDCALL(void (*)(char *, extended_cif *), /*@out@*/ extended_cif *, unsigned, unsigned, @@ -171,13 +160,8 @@ ffi_call_STDCALL(void (*)(char *, extended_cif *), void (*fn)()); /*@=declundef@*/ /*@=exportheader@*/ -#endif /* X86_WIN32 || _MSC_VER*/ -#ifdef _MSC_VER int -#else -void -#endif ffi_call(/*@dependent@*/ ffi_cif *cif, void (*fn)(), /*@out@*/ void *rvalue, @@ -206,24 +190,18 @@ ffi_call(/*@dependent@*/ ffi_cif *cif, { case FFI_SYSV: /*@-usedef@*/ -#ifdef _MSC_VER - return -#endif - ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, - cif->flags, ecif.rvalue, fn); + return ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, + cif->flags, ecif.rvalue, fn); /*@=usedef@*/ break; -#if defined(X86_WIN32) || defined(_MSC_VER) + case FFI_STDCALL: /*@-usedef@*/ -#ifdef _MSC_VER - return -#endif - ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes, - cif->flags, ecif.rvalue, fn); + return ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes, + cif->flags, ecif.rvalue, fn); /*@=usedef@*/ break; -#endif /* X86_WIN32 */ + default: FFI_ASSERT(0); break; @@ -236,23 +214,10 @@ ffi_call(/*@dependent@*/ ffi_cif *cif, static void ffi_prep_incoming_args_SYSV (char *stack, void **ret, void** args, ffi_cif* cif); -#ifndef _MSC_VER -static void ffi_closure_SYSV (ffi_closure *) - __attribute__ ((regparm(1))); -static void ffi_closure_raw_SYSV (ffi_raw_closure *) - __attribute__ ((regparm(1))); -#endif - /* This function is jumped to by the trampoline */ -#ifdef _MSC_VER static void __fastcall ffi_closure_SYSV (ffi_closure *closure, int *argp) -#else -static void -ffi_closure_SYSV (closure) - ffi_closure *closure; -#endif { // this is our return value storage long double res; @@ -262,11 +227,11 @@ ffi_closure_SYSV (closure) void **arg_area; unsigned short rtype; void *resp = (void*)&res; -#ifdef _MSC_VER +//#ifdef _MSC_VER void *args = &argp[1]; -#else - void *args = __builtin_dwarf_cfa (); -#endif +//#else +// void *args = __builtin_dwarf_cfa (); +//#endif cif = closure->cif; arg_area = (void**) alloca (cif->nargs * sizeof (void*)); @@ -390,7 +355,7 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, /* MOV EDX, ESP is 0x8b 0xd4 */ -#ifdef _MSC_VER +//#ifdef _MSC_VER #define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX,BYTES) \ { unsigned char *__tramp = (unsigned char*)(TRAMP); \ @@ -407,18 +372,18 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, *(unsigned short*) &__tramp[13] = BYTES; \ } -#else -#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX,BYTES) \ -({ 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 char*) &__tramp[0] = 0xb8; \ - *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \ - *(unsigned char *) &__tramp[5] = 0xe9; \ - *(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \ - }) -#endif +//#else +//#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX,BYTES) \ +//({ 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 char*) &__tramp[0] = 0xb8; \ +// *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \ +// *(unsigned char *) &__tramp[5] = 0xe9; \ +// *(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \ +// }) +//#endif /* the cif must already be prep'ed */ @@ -433,10 +398,8 @@ ffi_prep_closure (ffi_closure* closure, if (cif->abi == FFI_SYSV) bytes = 0; -#ifdef _MSC_VER else if (cif->abi == FFI_STDCALL) bytes = cif->bytes; -#endif else return FFI_BAD_ABI; @@ -450,5 +413,3 @@ ffi_prep_closure (ffi_closure* closure, return FFI_OK; } - -#endif /* __x86_64__ */ diff --git a/Modules/_ctypes/libffi_msvc/ffi.h b/Modules/_ctypes/libffi_msvc/ffi.h index b9d31fd..203142d 100644 --- a/Modules/_ctypes/libffi_msvc/ffi.h +++ b/Modules/_ctypes/libffi_msvc/ffi.h @@ -272,11 +272,7 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype, /*@dependent@*/ ffi_type **atypes); -#ifdef _MSC_VER int -#else -void -#endif ffi_call(/*@dependent@*/ ffi_cif *cif, void (*fn)(), /*@out@*/ void *rvalue, diff --git a/Modules/_ctypes/libffi_msvc/ffi_common.h b/Modules/_ctypes/libffi_msvc/ffi_common.h index 1b948d5..43fb83b 100644 --- a/Modules/_ctypes/libffi_msvc/ffi_common.h +++ b/Modules/_ctypes/libffi_msvc/ffi_common.h @@ -13,24 +13,7 @@ extern "C" { #endif #include - -/* Do not move this. Some versions of AIX are very picky about where - this is positioned. */ -#ifdef __GNUC__ -# define alloca __builtin_alloca -#else -# if HAVE_ALLOCA_H -# include -# else -# ifdef _AIX - #pragma alloca -# else -# ifndef alloca /* predefined by HP cc +Olibcalls */ -char *alloca (); -# endif -# endif -# endif -#endif +#include /* Check for the existence of memcpy. */ #if STDC_HEADERS diff --git a/Modules/_ctypes/libffi_msvc/ffitarget.h b/Modules/_ctypes/libffi_msvc/ffitarget.h index c9d95bc..57d275b 100644 --- a/Modules/_ctypes/libffi_msvc/ffitarget.h +++ b/Modules/_ctypes/libffi_msvc/ffitarget.h @@ -43,23 +43,21 @@ typedef enum ffi_abi { FFI_FIRST_ABI = 0, /* ---- Intel x86 Win32 ---------- */ -#if defined(X86_WIN32) || defined(_MSC_VER) FFI_SYSV, FFI_STDCALL, /* TODO: Add fastcall support for the sake of completeness */ FFI_DEFAULT_ABI = FFI_SYSV, -#endif /* ---- Intel x86 and AMD x86-64 - */ -#if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__)) - FFI_SYSV, - FFI_UNIX64, /* Unix variants all use the same ABI for x86-64 */ -#ifdef __i386__ - FFI_DEFAULT_ABI = FFI_SYSV, -#else - FFI_DEFAULT_ABI = FFI_UNIX64, -#endif -#endif +/* #if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__)) */ +/* FFI_SYSV, */ +/* FFI_UNIX64,*/ /* Unix variants all use the same ABI for x86-64 */ +/* #ifdef __i386__ */ +/* FFI_DEFAULT_ABI = FFI_SYSV, */ +/* #else */ +/* FFI_DEFAULT_ABI = FFI_UNIX64, */ +/* #endif */ +/* #endif */ FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 } ffi_abi; diff --git a/Modules/_ctypes/libffi_msvc/mingwin32.S b/Modules/_ctypes/libffi_msvc/mingwin32.S new file mode 100644 index 0000000..e71f2b2 --- /dev/null +++ b/Modules/_ctypes/libffi_msvc/mingwin32.S @@ -0,0 +1,228 @@ +/* ----------------------------------------------------------------------- + win32.S - Copyright (c) 1996, 1998, 2001, 2002 Red Hat, Inc. + Copyright (c) 2001 John Beniton + Copyright (c) 2002 Ranjit Mathew + + + 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, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#define LIBFFI_ASM +#include +#include + +.text + +.globl ffi_prep_args + + # This assumes we are using gas. + .balign 16 +.globl _ffi_call_SYSV + +_ffi_call_SYSV: + pushl %ebp + movl %esp,%ebp + + # 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) + + # Remove the space we pushed for the args + movl 16(%ebp),%ecx + addl %ecx,%esp + + # 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 retint + + # Even if there is no space for the return value, we are + # obliged to handle floating-point values. + cmpl $2,%ecx # Float_type + jne noretval + fstp %st(0) + + jmp epilogue + +retint: + cmpl $1,%ecx # Int_type + jne retfloat + # Load %ecx with the pointer to storage for the return value + movl 24(%ebp),%ecx + movl %eax,0(%ecx) + jmp epilogue + +retfloat: + cmpl $2,%ecx # Float_type + jne retdouble + # Load %ecx with the pointer to storage for the return value + movl 24(%ebp),%ecx + fstps (%ecx) + jmp epilogue + +retdouble: + cmpl $3,%ecx # Double_type + jne retlongdouble + # Load %ecx with the pointer to storage for the return value + movl 24(%ebp),%ecx + fstpl (%ecx) + jmp epilogue + +retlongdouble: + cmpl $4,%ecx # Longdouble_type + jne retint64 + # Load %ecx with the pointer to storage for the return value + movl 24(%ebp),%ecx + fstpt (%ecx) + jmp epilogue + +retint64: + cmpl $12,%ecx # SINT64_type + jne retstruct + # Load %ecx with the pointer to storage for the return value + movl 24(%ebp),%ecx + movl %eax,0(%ecx) + movl %edx,4(%ecx) + +retstruct: + # Nothing to do! + +noretval: +epilogue: + movl %ebp,%esp + popl %ebp + ret + +.ffi_call_SYSV_end: + + # This assumes we are using gas. + .balign 16 +.globl _ffi_call_STDCALL + +_ffi_call_STDCALL: + pushl %ebp + movl %esp,%ebp + + # 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 sc_retint + + # Even if there is no space for the return value, we are + # obliged to handle floating-point values. + cmpl $2,%ecx # Float_type + jne sc_noretval + fstp %st(0) + + jmp sc_epilogue + +sc_retint: + cmpl $1,%ecx # Int_type + jne sc_retfloat + # Load %ecx with the pointer to storage for the return value + movl 24(%ebp),%ecx + movl %eax,0(%ecx) + jmp sc_epilogue + +sc_retfloat: + cmpl $2,%ecx # Float_type + jne sc_retdouble + # Load %ecx with the pointer to storage for the return value + movl 24(%ebp),%ecx + fstps (%ecx) + jmp sc_epilogue + +sc_retdouble: + cmpl $2,%ecx # Double_type + jne sc_retlongdouble + # Load %ecx with the pointer to storage for the return value + movl 24(%ebp),%ecx + fstpl (%ecx) + jmp sc_epilogue + +sc_retlongdouble: + cmpl $4,%ecx # Longdouble_type + jne sc_retint64 + # Load %ecx with the pointer to storage for the return value + movl 24(%ebp),%ecx + fstpt (%ecx) + jmp sc_epilogue + +sc_retint64: + cmpl $12,%ecx # SINT64_Type + jne sc_retstruct + # Load %ecx with the pointer to storage for the return value + movl 24(%ebp),%ecx + movl %eax,0(%ecx) + movl %edx,4(%ecx) + +sc_retstruct: + # Nothing to do! + +sc_noretval: +sc_epilogue: + movl %ebp,%esp + popl %ebp + ret + +.ffi_call_STDCALL_end: + diff --git a/Modules/_ctypes/libffi_msvc/prep_cif.c b/Modules/_ctypes/libffi_msvc/prep_cif.c index 9edce2f..2650fa0 100644 --- a/Modules/_ctypes/libffi_msvc/prep_cif.c +++ b/Modules/_ctypes/libffi_msvc/prep_cif.c @@ -147,7 +147,7 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, else #endif { -#ifndef _MSC_VER +#if !defined(_MSC_VER) && !defined(__MINGW32__) /* Don't know if this is a libffi bug or not. At least on Windows with MSVC, function call parameters are *not* aligned in the same way as structure fields are, they are diff --git a/Modules/_ctypes/libffi_msvc/win32.S b/Modules/_ctypes/libffi_msvc/win32.S index 40743af..cc82ab9 100644 --- a/Modules/_ctypes/libffi_msvc/win32.S +++ b/Modules/_ctypes/libffi_msvc/win32.S @@ -41,7 +41,11 @@ _ffi_call_SYSV: pushl %ebp movl %esp,%ebp - + + #THe: save previous %esi, and store the current stack pointer in %esi + pushl %esi + movl %esp,%esi + # Make room for all of the new args. movl 16(%ebp),%ecx subl %ecx,%esp @@ -64,7 +68,9 @@ _ffi_call_SYSV: # Remove the space we pushed for the args movl 16(%ebp),%ecx addl %ecx,%esp - + + sub %esp,%esi # calculate stack pointer difference + # Load %ecx with the return type code movl 20(%ebp),%ecx @@ -125,6 +131,8 @@ retstruct: noretval: epilogue: + movl %esi,%eax # return the stack pointer detlta in %eax + popl %esi # restore previous %esi movl %ebp,%esp popl %ebp ret @@ -139,6 +147,10 @@ _ffi_call_STDCALL: pushl %ebp movl %esp,%ebp + #THe: save previous %esi, and store the current stack pointer in %esi + pushl %esi + movl %esp,%esi + # Make room for all of the new args. movl 16(%ebp),%ecx subl %ecx,%esp @@ -158,6 +170,8 @@ _ffi_call_STDCALL: call *28(%ebp) + sub %esp,%esi # difference in stack + # stdcall functions pop arguments off the stack themselves # Load %ecx with the return type code @@ -220,6 +234,8 @@ sc_retstruct: sc_noretval: sc_epilogue: + movl %esi,%eax # return the stack difference + popl %esi # restore previous %esi value movl %ebp,%esp popl %ebp ret -- cgit v0.12