[Python-checkins] r47224 - python/trunk/Modules/_ctypes/libffi/src/x86/darwin.S python/trunk/Modules/_ctypes/libffi/src/x86/ffi_darwin.c
ronald.oussoren
python-checkins at python.org
Tue Jul 4 14:30:24 CEST 2006
Author: ronald.oussoren
Date: Tue Jul 4 14:30:22 2006
New Revision: 47224
Modified:
python/trunk/Modules/_ctypes/libffi/src/x86/darwin.S
python/trunk/Modules/_ctypes/libffi/src/x86/ffi_darwin.c
Log:
Sync the darwin/x86 port libffi with the copy in PyObjC. This fixes a number
of bugs in that port. The most annoying ones were due to some subtle differences
between the document ABI and the actual implementation :-(
(there are no python unittests that fail without this patch, but without it
some of libffi's unittests fail).
Modified: python/trunk/Modules/_ctypes/libffi/src/x86/darwin.S
==============================================================================
--- python/trunk/Modules/_ctypes/libffi/src/x86/darwin.S (original)
+++ python/trunk/Modules/_ctypes/libffi/src/x86/darwin.S Tue Jul 4 14:30:22 2006
@@ -35,6 +35,13 @@
#include <fficonfig.h>
#include <ffi.h>
+#ifdef PyObjC_STRICT_DEBUGGING
+ /* XXX: Debugging of stack alignment, to be removed */
+#define ASSERT_STACK_ALIGNED movdqa -16(%esp), %xmm0
+#else
+#define ASSERT_STACK_ALIGNED
+#endif
+
.text
.globl _ffi_prep_args
@@ -47,30 +54,41 @@
pushl %ebp
.LCFI0:
movl %esp,%ebp
+ subl $8,%esp
+ ASSERT_STACK_ALIGNED
.LCFI1:
/* Make room for all of the new args. */
movl 16(%ebp),%ecx
subl %ecx,%esp
+ ASSERT_STACK_ALIGNED
+
movl %esp,%eax
/* Place all of the ffi_prep_args in position */
+ subl $8,%esp
pushl 12(%ebp)
pushl %eax
call *8(%ebp)
+ ASSERT_STACK_ALIGNED
+
/* Return stack to previous state and call the function */
- addl $8,%esp
+ addl $16,%esp
- call *28(%ebp)
+ ASSERT_STACK_ALIGNED
- /* Remove the space we pushed for the args */
+ call *28(%ebp)
+
+ /* XXX: return returns return with 'ret $4', that upsets the stack! */
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
@@ -117,17 +135,47 @@
retint64:
cmpl $FFI_TYPE_SINT64,%ecx
- jne retstruct
+ jne retstruct1b
/* Load %ecx with the pointer to storage for the return value */
movl 24(%ebp),%ecx
movl %eax,0(%ecx)
movl %edx,4(%ecx)
+ jmp epilogue
+
+retstruct1b:
+ cmpl $FFI_TYPE_SINT8,%ecx
+ jne retstruct2b
+ movl 24(%ebp),%ecx
+ movb %al,0(%ecx)
+ jmp epilogue
+
+retstruct2b:
+ cmpl $FFI_TYPE_SINT16,%ecx
+ jne retstruct
+ movl 24(%ebp),%ecx
+ movw %ax,0(%ecx)
+ jmp epilogue
retstruct:
+ cmpl $FFI_TYPE_STRUCT,%ecx
+ jne noretval
/* Nothing to do! */
+ subl $4,%esp
+
+ ASSERT_STACK_ALIGNED
+
+ addl $8,%esp
+ movl %ebp, %esp
+ popl %ebp
+ ret
+
noretval:
epilogue:
+ ASSERT_STACK_ALIGNED
+ addl $8, %esp
+
+
movl %ebp,%esp
popl %ebp
ret
Modified: python/trunk/Modules/_ctypes/libffi/src/x86/ffi_darwin.c
==============================================================================
--- python/trunk/Modules/_ctypes/libffi/src/x86/ffi_darwin.c (original)
+++ python/trunk/Modules/_ctypes/libffi/src/x86/ffi_darwin.c Tue Jul 4 14:30:22 2006
@@ -140,7 +140,7 @@
switch (cif->rtype->type)
{
case FFI_TYPE_VOID:
-#if !defined(X86_WIN32)
+#if !defined(X86_WIN32) && !defined(X86_DARWIN)
case FFI_TYPE_STRUCT:
#endif
case FFI_TYPE_SINT64:
@@ -154,7 +154,7 @@
cif->flags = FFI_TYPE_SINT64;
break;
-#if defined X86_WIN32
+#if defined(X86_WIN32) || defined(X86_DARWIN)
case FFI_TYPE_STRUCT:
if (cif->rtype->size == 1)
@@ -186,10 +186,11 @@
}
/* Darwin: The stack needs to be aligned to a multiple of 16 bytes */
-#if 0
+#if 1
cif->bytes = (cif->bytes + 15) & ~0xF;
#endif
+
return FFI_OK;
}
@@ -221,7 +222,6 @@
/*@dependent@*/ void **avalue)
{
extended_cif ecif;
- int flags;
ecif.cif = cif;
ecif.avalue = avalue;
@@ -238,20 +238,6 @@
else
ecif.rvalue = rvalue;
- flags = cif->flags;
- if (flags == FFI_TYPE_STRUCT) {
- if (cif->rtype->size == 8) {
- flags = FFI_TYPE_SINT64;
- } else if (cif->rtype->size == 4) {
- flags = FFI_TYPE_INT;
- } else if (cif->rtype->size == 2) {
- flags = FFI_TYPE_INT;
- } else if (cif->rtype->size == 1) {
- flags = FFI_TYPE_INT;
- }
- }
-
-
switch (cif->abi)
{
case FFI_SYSV:
@@ -260,8 +246,8 @@
* block is a multiple of 16. Then add 8 to compensate for local variables
* in ffi_call_SYSV.
*/
- ffi_call_SYSV(ffi_prep_args, &ecif, ALIGN(cif->bytes, 16) +8,
- flags, ecif.rvalue, fn);
+ ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
/*@=usedef@*/
break;
#ifdef X86_WIN32
@@ -281,8 +267,6 @@
/** private members **/
-static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
- void** args, ffi_cif* cif);
static void ffi_closure_SYSV (ffi_closure *)
__attribute__ ((regparm(1)));
#if !FFI_NO_RAW_API
@@ -290,6 +274,48 @@
__attribute__ ((regparm(1)));
#endif
+/*@-exportheader@*/
+static inline void
+ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
+ void **avalue, ffi_cif *cif)
+/*@=exportheader@*/
+{
+ register unsigned int i;
+ register void **p_argv;
+ register char *argp;
+ register ffi_type **p_arg;
+
+ argp = stack;
+
+ if (retval_on_stack(cif->rtype)) {
+ *rvalue = *(void **) argp;
+ argp += 4;
+ }
+
+ p_argv = avalue;
+
+ for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
+ {
+ size_t z;
+
+ /* Align if necessary */
+ if ((sizeof(int) - 1) & (unsigned) argp) {
+ argp = (char *) ALIGN(argp, sizeof(int));
+ }
+
+ z = (*p_arg)->size;
+
+ /* because we're little endian, this is what it turns into. */
+
+ *p_argv = (void*) argp;
+
+ p_argv++;
+ argp += z;
+ }
+
+ return;
+}
+
/* This function is jumped to by the trampoline */
static void
@@ -302,10 +328,10 @@
// our various things...
ffi_cif *cif;
void **arg_area;
- unsigned short rtype;
void *resp = (void*)&res;
void *args = __builtin_dwarf_cfa ();
+
cif = closure->cif;
arg_area = (void**) alloca (cif->nargs * sizeof (void*));
@@ -319,94 +345,52 @@
(closure->fun) (cif, resp, arg_area, closure->user_data);
- rtype = cif->flags;
-
- if (!retval_on_stack(cif->rtype) && cif->flags == FFI_TYPE_STRUCT) {
- if (cif->rtype->size == 8) {
- rtype = FFI_TYPE_SINT64;
- } else {
- rtype = FFI_TYPE_INT;
- }
- }
-
/* now, do a generic return based on the value of rtype */
- if (rtype == FFI_TYPE_INT)
+ if (cif->flags == FFI_TYPE_INT)
{
asm ("movl (%0),%%eax" : : "r" (resp) : "eax");
}
- else if (rtype == FFI_TYPE_FLOAT)
+ else if (cif->flags == FFI_TYPE_FLOAT)
{
asm ("flds (%0)" : : "r" (resp) : "st" );
}
- else if (rtype == FFI_TYPE_DOUBLE)
+ else if (cif->flags == FFI_TYPE_DOUBLE)
{
asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" );
}
- else if (rtype == FFI_TYPE_LONGDOUBLE)
+ else if (cif->flags == FFI_TYPE_LONGDOUBLE)
{
asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" );
}
- else if (rtype == FFI_TYPE_SINT64)
+ else if (cif->flags == FFI_TYPE_SINT64)
{
asm ("movl 0(%0),%%eax;"
"movl 4(%0),%%edx"
: : "r"(resp)
: "eax", "edx");
}
-#ifdef X86_WIN32
- else if (rtype == FFI_TYPE_SINT8) /* 1-byte struct */
+#if defined(X86_WIN32) || defined(X86_DARWIN)
+ else if (cif->flags == FFI_TYPE_SINT8) /* 1-byte struct */
{
asm ("movsbl (%0),%%eax" : : "r" (resp) : "eax");
}
- else if (rtype == FFI_TYPE_SINT16) /* 2-bytes struct */
+ else if (cif->flags == FFI_TYPE_SINT16) /* 2-bytes struct */
{
asm ("movswl (%0),%%eax" : : "r" (resp) : "eax");
}
#endif
-}
-/*@-exportheader@*/
-static void
-ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
- void **avalue, ffi_cif *cif)
-/*@=exportheader@*/
-{
- register unsigned int i;
- register void **p_argv;
- register char *argp;
- register ffi_type **p_arg;
-
- argp = stack;
-
- if (retval_on_stack(cif->rtype)) {
- *rvalue = *(void **) argp;
- argp += 4;
- }
-
- p_argv = avalue;
-
- for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
+ else if (cif->flags == FFI_TYPE_STRUCT)
{
- size_t z;
-
- /* Align if necessary */
- if ((sizeof(int) - 1) & (unsigned) argp) {
- argp = (char *) ALIGN(argp, sizeof(int));
- }
-
- z = (*p_arg)->size;
-
- /* because we're little endian, this is what it turns into. */
-
- *p_argv = (void*) argp;
-
- p_argv++;
- argp += z;
+ asm ("lea -8(%ebp),%esp;"
+ "pop %esi;"
+ "pop %edi;"
+ "pop %ebp;"
+ "ret $4");
}
-
- return;
}
+
/* How to make a trampoline. Derived from gcc/config/i386/i386.c. */
#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
More information about the Python-checkins
mailing list