Merge in changes from ctypes 0.9.9.6 upstream version.
This commit is contained in:
parent
f9cc594096
commit
4b75a7c1cf
|
@ -1223,6 +1223,19 @@ c_void_p_from_param(PyObject *type, PyObject *value)
|
||||||
return 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 */
|
/* c_char_p, c_wchar_p */
|
||||||
stgd = PyObject_stgdict(value);
|
stgd = PyObject_stgdict(value);
|
||||||
if (stgd && CDataObject_Check(value) && stgd->proto && PyString_Check(stgd->proto)) {
|
if (stgd && CDataObject_Check(value) && stgd->proto && PyString_Check(stgd->proto)) {
|
||||||
|
@ -4407,6 +4420,8 @@ cast_check_pointertype(PyObject *arg)
|
||||||
|
|
||||||
if (PointerTypeObject_Check(arg))
|
if (PointerTypeObject_Check(arg))
|
||||||
return 1;
|
return 1;
|
||||||
|
if (CFuncPtrTypeObject_Check(arg))
|
||||||
|
return 1;
|
||||||
dict = PyType_stgdict(arg);
|
dict = PyType_stgdict(arg);
|
||||||
if (dict) {
|
if (dict) {
|
||||||
if (PyString_Check(dict->proto)
|
if (PyString_Check(dict->proto)
|
||||||
|
@ -4566,7 +4581,7 @@ init_ctypes(void)
|
||||||
#endif
|
#endif
|
||||||
PyModule_AddObject(m, "FUNCFLAG_CDECL", PyInt_FromLong(FUNCFLAG_CDECL));
|
PyModule_AddObject(m, "FUNCFLAG_CDECL", PyInt_FromLong(FUNCFLAG_CDECL));
|
||||||
PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyInt_FromLong(FUNCFLAG_PYTHONAPI));
|
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, "_memmove_addr", PyLong_FromVoidPtr(memmove));
|
||||||
PyModule_AddObject(m, "_memset_addr", PyLong_FromVoidPtr(memset));
|
PyModule_AddObject(m, "_memset_addr", PyLong_FromVoidPtr(memset));
|
||||||
|
|
|
@ -31,5 +31,6 @@ ffi_sources += ffi_platforms['@TARGET@']
|
||||||
ffi_sources = [os.path.join('@srcdir@', f) for f in ffi_sources]
|
ffi_sources = [os.path.join('@srcdir@', f) for f in ffi_sources]
|
||||||
|
|
||||||
ffi_cflags = '@CFLAGS@'
|
ffi_cflags = '@CFLAGS@'
|
||||||
|
# I think this may no longer be needed:
|
||||||
if sys.platform == "openbsd3":
|
if sys.platform == "openbsd3":
|
||||||
ffi_cflags += " -fno-stack-protector"
|
ffi_cflags += " -fno-stack-protector"
|
||||||
|
|
|
@ -26,8 +26,6 @@
|
||||||
OTHER DEALINGS IN THE SOFTWARE.
|
OTHER DEALINGS IN THE SOFTWARE.
|
||||||
----------------------------------------------------------------------- */
|
----------------------------------------------------------------------- */
|
||||||
|
|
||||||
#ifndef __x86_64__
|
|
||||||
|
|
||||||
#include <ffi.h>
|
#include <ffi.h>
|
||||||
#include <ffi_common.h>
|
#include <ffi_common.h>
|
||||||
|
|
||||||
|
@ -143,11 +141,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
|
||||||
|
|
||||||
/*@-declundef@*/
|
/*@-declundef@*/
|
||||||
/*@-exportheader@*/
|
/*@-exportheader@*/
|
||||||
#ifdef _MSC_VER
|
|
||||||
extern int
|
extern int
|
||||||
#else
|
|
||||||
extern void
|
|
||||||
#endif
|
|
||||||
ffi_call_SYSV(void (*)(char *, extended_cif *),
|
ffi_call_SYSV(void (*)(char *, extended_cif *),
|
||||||
/*@out@*/ extended_cif *,
|
/*@out@*/ extended_cif *,
|
||||||
unsigned, unsigned,
|
unsigned, unsigned,
|
||||||
|
@ -156,14 +150,9 @@ ffi_call_SYSV(void (*)(char *, extended_cif *),
|
||||||
/*@=declundef@*/
|
/*@=declundef@*/
|
||||||
/*@=exportheader@*/
|
/*@=exportheader@*/
|
||||||
|
|
||||||
#if defined(X86_WIN32) || defined(_MSC_VER)
|
|
||||||
/*@-declundef@*/
|
/*@-declundef@*/
|
||||||
/*@-exportheader@*/
|
/*@-exportheader@*/
|
||||||
#ifdef _MSC_VER
|
|
||||||
extern int
|
extern int
|
||||||
#else
|
|
||||||
extern void
|
|
||||||
#endif
|
|
||||||
ffi_call_STDCALL(void (*)(char *, extended_cif *),
|
ffi_call_STDCALL(void (*)(char *, extended_cif *),
|
||||||
/*@out@*/ extended_cif *,
|
/*@out@*/ extended_cif *,
|
||||||
unsigned, unsigned,
|
unsigned, unsigned,
|
||||||
|
@ -171,13 +160,8 @@ ffi_call_STDCALL(void (*)(char *, extended_cif *),
|
||||||
void (*fn)());
|
void (*fn)());
|
||||||
/*@=declundef@*/
|
/*@=declundef@*/
|
||||||
/*@=exportheader@*/
|
/*@=exportheader@*/
|
||||||
#endif /* X86_WIN32 || _MSC_VER*/
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
int
|
int
|
||||||
#else
|
|
||||||
void
|
|
||||||
#endif
|
|
||||||
ffi_call(/*@dependent@*/ ffi_cif *cif,
|
ffi_call(/*@dependent@*/ ffi_cif *cif,
|
||||||
void (*fn)(),
|
void (*fn)(),
|
||||||
/*@out@*/ void *rvalue,
|
/*@out@*/ void *rvalue,
|
||||||
|
@ -206,24 +190,18 @@ ffi_call(/*@dependent@*/ ffi_cif *cif,
|
||||||
{
|
{
|
||||||
case FFI_SYSV:
|
case FFI_SYSV:
|
||||||
/*@-usedef@*/
|
/*@-usedef@*/
|
||||||
#ifdef _MSC_VER
|
return ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes,
|
||||||
return
|
cif->flags, ecif.rvalue, fn);
|
||||||
#endif
|
|
||||||
ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes,
|
|
||||||
cif->flags, ecif.rvalue, fn);
|
|
||||||
/*@=usedef@*/
|
/*@=usedef@*/
|
||||||
break;
|
break;
|
||||||
#if defined(X86_WIN32) || defined(_MSC_VER)
|
|
||||||
case FFI_STDCALL:
|
case FFI_STDCALL:
|
||||||
/*@-usedef@*/
|
/*@-usedef@*/
|
||||||
#ifdef _MSC_VER
|
return ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes,
|
||||||
return
|
cif->flags, ecif.rvalue, fn);
|
||||||
#endif
|
|
||||||
ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes,
|
|
||||||
cif->flags, ecif.rvalue, fn);
|
|
||||||
/*@=usedef@*/
|
/*@=usedef@*/
|
||||||
break;
|
break;
|
||||||
#endif /* X86_WIN32 */
|
|
||||||
default:
|
default:
|
||||||
FFI_ASSERT(0);
|
FFI_ASSERT(0);
|
||||||
break;
|
break;
|
||||||
|
@ -236,23 +214,10 @@ ffi_call(/*@dependent@*/ ffi_cif *cif,
|
||||||
|
|
||||||
static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
|
static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
|
||||||
void** args, ffi_cif* cif);
|
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 */
|
/* This function is jumped to by the trampoline */
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
static void __fastcall
|
static void __fastcall
|
||||||
ffi_closure_SYSV (ffi_closure *closure, int *argp)
|
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
|
// this is our return value storage
|
||||||
long double res;
|
long double res;
|
||||||
|
@ -262,11 +227,11 @@ ffi_closure_SYSV (closure)
|
||||||
void **arg_area;
|
void **arg_area;
|
||||||
unsigned short rtype;
|
unsigned short rtype;
|
||||||
void *resp = (void*)&res;
|
void *resp = (void*)&res;
|
||||||
#ifdef _MSC_VER
|
//#ifdef _MSC_VER
|
||||||
void *args = &argp[1];
|
void *args = &argp[1];
|
||||||
#else
|
//#else
|
||||||
void *args = __builtin_dwarf_cfa ();
|
// void *args = __builtin_dwarf_cfa ();
|
||||||
#endif
|
//#endif
|
||||||
|
|
||||||
cif = closure->cif;
|
cif = closure->cif;
|
||||||
arg_area = (void**) alloca (cif->nargs * sizeof (void*));
|
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 */
|
/* MOV EDX, ESP is 0x8b 0xd4 */
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
//#ifdef _MSC_VER
|
||||||
|
|
||||||
#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX,BYTES) \
|
#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX,BYTES) \
|
||||||
{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
|
{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
|
||||||
|
@ -407,18 +372,18 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
|
||||||
*(unsigned short*) &__tramp[13] = BYTES; \
|
*(unsigned short*) &__tramp[13] = BYTES; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
//#else
|
||||||
#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX,BYTES) \
|
//#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX,BYTES) \
|
||||||
({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
|
//({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
|
||||||
unsigned int __fun = (unsigned int)(FUN); \
|
// unsigned int __fun = (unsigned int)(FUN); \
|
||||||
unsigned int __ctx = (unsigned int)(CTX); \
|
// unsigned int __ctx = (unsigned int)(CTX); \
|
||||||
unsigned int __dis = __fun - ((unsigned int) __tramp + FFI_TRAMPOLINE_SIZE); \
|
// unsigned int __dis = __fun - ((unsigned int) __tramp + FFI_TRAMPOLINE_SIZE); \
|
||||||
*(unsigned char*) &__tramp[0] = 0xb8; \
|
// *(unsigned char*) &__tramp[0] = 0xb8; \
|
||||||
*(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
|
// *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
|
||||||
*(unsigned char *) &__tramp[5] = 0xe9; \
|
// *(unsigned char *) &__tramp[5] = 0xe9; \
|
||||||
*(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \
|
// *(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \
|
||||||
})
|
// })
|
||||||
#endif
|
//#endif
|
||||||
|
|
||||||
/* the cif must already be prep'ed */
|
/* the cif must already be prep'ed */
|
||||||
|
|
||||||
|
@ -433,10 +398,8 @@ ffi_prep_closure (ffi_closure* closure,
|
||||||
|
|
||||||
if (cif->abi == FFI_SYSV)
|
if (cif->abi == FFI_SYSV)
|
||||||
bytes = 0;
|
bytes = 0;
|
||||||
#ifdef _MSC_VER
|
|
||||||
else if (cif->abi == FFI_STDCALL)
|
else if (cif->abi == FFI_STDCALL)
|
||||||
bytes = cif->bytes;
|
bytes = cif->bytes;
|
||||||
#endif
|
|
||||||
else
|
else
|
||||||
return FFI_BAD_ABI;
|
return FFI_BAD_ABI;
|
||||||
|
|
||||||
|
@ -450,5 +413,3 @@ ffi_prep_closure (ffi_closure* closure,
|
||||||
|
|
||||||
return FFI_OK;
|
return FFI_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __x86_64__ */
|
|
||||||
|
|
|
@ -272,11 +272,7 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
|
||||||
/*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype,
|
/*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype,
|
||||||
/*@dependent@*/ ffi_type **atypes);
|
/*@dependent@*/ ffi_type **atypes);
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
int
|
int
|
||||||
#else
|
|
||||||
void
|
|
||||||
#endif
|
|
||||||
ffi_call(/*@dependent@*/ ffi_cif *cif,
|
ffi_call(/*@dependent@*/ ffi_cif *cif,
|
||||||
void (*fn)(),
|
void (*fn)(),
|
||||||
/*@out@*/ void *rvalue,
|
/*@out@*/ void *rvalue,
|
||||||
|
|
|
@ -13,24 +13,7 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <fficonfig.h>
|
#include <fficonfig.h>
|
||||||
|
#include <malloc.h>
|
||||||
/* 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 <alloca.h>
|
|
||||||
# else
|
|
||||||
# ifdef _AIX
|
|
||||||
#pragma alloca
|
|
||||||
# else
|
|
||||||
# ifndef alloca /* predefined by HP cc +Olibcalls */
|
|
||||||
char *alloca ();
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Check for the existence of memcpy. */
|
/* Check for the existence of memcpy. */
|
||||||
#if STDC_HEADERS
|
#if STDC_HEADERS
|
||||||
|
|
|
@ -43,23 +43,21 @@ typedef enum ffi_abi {
|
||||||
FFI_FIRST_ABI = 0,
|
FFI_FIRST_ABI = 0,
|
||||||
|
|
||||||
/* ---- Intel x86 Win32 ---------- */
|
/* ---- Intel x86 Win32 ---------- */
|
||||||
#if defined(X86_WIN32) || defined(_MSC_VER)
|
|
||||||
FFI_SYSV,
|
FFI_SYSV,
|
||||||
FFI_STDCALL,
|
FFI_STDCALL,
|
||||||
/* TODO: Add fastcall support for the sake of completeness */
|
/* TODO: Add fastcall support for the sake of completeness */
|
||||||
FFI_DEFAULT_ABI = FFI_SYSV,
|
FFI_DEFAULT_ABI = FFI_SYSV,
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ---- Intel x86 and AMD x86-64 - */
|
/* ---- Intel x86 and AMD x86-64 - */
|
||||||
#if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__))
|
/* #if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__)) */
|
||||||
FFI_SYSV,
|
/* FFI_SYSV, */
|
||||||
FFI_UNIX64, /* Unix variants all use the same ABI for x86-64 */
|
/* FFI_UNIX64,*/ /* Unix variants all use the same ABI for x86-64 */
|
||||||
#ifdef __i386__
|
/* #ifdef __i386__ */
|
||||||
FFI_DEFAULT_ABI = FFI_SYSV,
|
/* FFI_DEFAULT_ABI = FFI_SYSV, */
|
||||||
#else
|
/* #else */
|
||||||
FFI_DEFAULT_ABI = FFI_UNIX64,
|
/* FFI_DEFAULT_ABI = FFI_UNIX64, */
|
||||||
#endif
|
/* #endif */
|
||||||
#endif
|
/* #endif */
|
||||||
|
|
||||||
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
|
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
|
||||||
} ffi_abi;
|
} ffi_abi;
|
||||||
|
|
|
@ -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 <fficonfig.h>
|
||||||
|
#include <ffi.h>
|
||||||
|
|
||||||
|
.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:
|
||||||
|
|
|
@ -147,7 +147,7 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#ifndef _MSC_VER
|
#if !defined(_MSC_VER) && !defined(__MINGW32__)
|
||||||
/* Don't know if this is a libffi bug or not. At least on
|
/* Don't know if this is a libffi bug or not. At least on
|
||||||
Windows with MSVC, function call parameters are *not*
|
Windows with MSVC, function call parameters are *not*
|
||||||
aligned in the same way as structure fields are, they are
|
aligned in the same way as structure fields are, they are
|
||||||
|
|
|
@ -41,7 +41,11 @@
|
||||||
_ffi_call_SYSV:
|
_ffi_call_SYSV:
|
||||||
pushl %ebp
|
pushl %ebp
|
||||||
movl %esp,%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.
|
# Make room for all of the new args.
|
||||||
movl 16(%ebp),%ecx
|
movl 16(%ebp),%ecx
|
||||||
subl %ecx,%esp
|
subl %ecx,%esp
|
||||||
|
@ -64,7 +68,9 @@ _ffi_call_SYSV:
|
||||||
# Remove the space we pushed for the args
|
# Remove the space we pushed for the args
|
||||||
movl 16(%ebp),%ecx
|
movl 16(%ebp),%ecx
|
||||||
addl %ecx,%esp
|
addl %ecx,%esp
|
||||||
|
|
||||||
|
sub %esp,%esi # calculate stack pointer difference
|
||||||
|
|
||||||
# Load %ecx with the return type code
|
# Load %ecx with the return type code
|
||||||
movl 20(%ebp),%ecx
|
movl 20(%ebp),%ecx
|
||||||
|
|
||||||
|
@ -125,6 +131,8 @@ retstruct:
|
||||||
|
|
||||||
noretval:
|
noretval:
|
||||||
epilogue:
|
epilogue:
|
||||||
|
movl %esi,%eax # return the stack pointer detlta in %eax
|
||||||
|
popl %esi # restore previous %esi
|
||||||
movl %ebp,%esp
|
movl %ebp,%esp
|
||||||
popl %ebp
|
popl %ebp
|
||||||
ret
|
ret
|
||||||
|
@ -139,6 +147,10 @@ _ffi_call_STDCALL:
|
||||||
pushl %ebp
|
pushl %ebp
|
||||||
movl %esp,%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.
|
# Make room for all of the new args.
|
||||||
movl 16(%ebp),%ecx
|
movl 16(%ebp),%ecx
|
||||||
subl %ecx,%esp
|
subl %ecx,%esp
|
||||||
|
@ -158,6 +170,8 @@ _ffi_call_STDCALL:
|
||||||
|
|
||||||
call *28(%ebp)
|
call *28(%ebp)
|
||||||
|
|
||||||
|
sub %esp,%esi # difference in stack
|
||||||
|
|
||||||
# stdcall functions pop arguments off the stack themselves
|
# stdcall functions pop arguments off the stack themselves
|
||||||
|
|
||||||
# Load %ecx with the return type code
|
# Load %ecx with the return type code
|
||||||
|
@ -220,6 +234,8 @@ sc_retstruct:
|
||||||
|
|
||||||
sc_noretval:
|
sc_noretval:
|
||||||
sc_epilogue:
|
sc_epilogue:
|
||||||
|
movl %esi,%eax # return the stack difference
|
||||||
|
popl %esi # restore previous %esi value
|
||||||
movl %ebp,%esp
|
movl %ebp,%esp
|
||||||
popl %ebp
|
popl %ebp
|
||||||
ret
|
ret
|
||||||
|
|
Loading…
Reference in New Issue