summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRonald Oussoren <ronaldoussoren@mac.com>2012-08-25 09:19:14 (GMT)
committerRonald Oussoren <ronaldoussoren@mac.com>2012-08-25 09:19:14 (GMT)
commit25437565f9f456a1e88f209706ced0353bbdeb14 (patch)
tree74c7b952dbd62081c23f2a15d2ae25577baf0ba2
parentc8076dfa9dfafbb5455c127719e3ac5b325986b1 (diff)
downloadcpython-25437565f9f456a1e88f209706ced0353bbdeb14.zip
cpython-25437565f9f456a1e88f209706ced0353bbdeb14.tar.gz
cpython-25437565f9f456a1e88f209706ced0353bbdeb14.tar.bz2
Fix issue 13370: Ensure that ctypes works on Mac OS X when Python is compiled using the clang compiler
-rw-r--r--Misc/NEWS3
-rw-r--r--Modules/_ctypes/libffi_osx/x86/darwin64.S6
-rw-r--r--Modules/_ctypes/libffi_osx/x86/x86-darwin.S4
-rw-r--r--Modules/_ctypes/libffi_osx/x86/x86-ffi64.c118
-rw-r--r--Modules/_ctypes/libffi_osx/x86/x86-ffi_darwin.c4
5 files changed, 128 insertions, 7 deletions
diff --git a/Misc/NEWS b/Misc/NEWS
index 508a832..bcf2921 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -109,6 +109,9 @@ Core and Builtins
Library
-------
+- Issue #13370: Ensure that ctypes works on Mac OS X when Python is
+ compiled using the clang compiler
+
- Issue #15544: Fix Decimal.__float__ to work with payload-carrying NaNs.
- Issue #15249: BytesGenerator now correctly mangles From lines (when
diff --git a/Modules/_ctypes/libffi_osx/x86/darwin64.S b/Modules/_ctypes/libffi_osx/x86/darwin64.S
index eba451e..165d469 100644
--- a/Modules/_ctypes/libffi_osx/x86/darwin64.S
+++ b/Modules/_ctypes/libffi_osx/x86/darwin64.S
@@ -45,6 +45,7 @@
_ffi_call_unix64:
LUW0:
movq (%rsp), %r10 /* Load return address. */
+ movq %rdi, %r12 /* Save a copy of the register area. */
leaq (%rdi, %rsi), %rax /* Find local stack base. */
movq %rdx, (%rax) /* Save flags. */
movq %rcx, 8(%rax) /* Save raddr. */
@@ -52,7 +53,8 @@ LUW0:
movq %r10, 24(%rax) /* Relocate return address. */
movq %rax, %rbp /* Finalize local stack frame. */
LUW1:
- movq %rdi, %r10 /* Save a copy of the register area. */
+ /* movq %rdi, %r10 // Save a copy of the register area. */
+ movq %r12, %r10
movq %r8, %r11 /* Save a copy of the target fn. */
movl %r9d, %eax /* Set number of SSE registers. */
@@ -255,7 +257,7 @@ Lld_void:
ret
.align 3
Lld_int8:
- movzbl -24(%rsp), %eax
+ movzbl -24(%rsp), %eax
ret
.align 3
Lld_int16:
diff --git a/Modules/_ctypes/libffi_osx/x86/x86-darwin.S b/Modules/_ctypes/libffi_osx/x86/x86-darwin.S
index 6c85ea6..925a841 100644
--- a/Modules/_ctypes/libffi_osx/x86/x86-darwin.S
+++ b/Modules/_ctypes/libffi_osx/x86/x86-darwin.S
@@ -198,8 +198,12 @@ LCFI7:
je Lcls_retldouble
cmpl $FFI_TYPE_SINT64, %eax
je Lcls_retllong
+ cmpl $FFI_TYPE_UINT8, %eax
+ je Lcls_retstruct1
cmpl $FFI_TYPE_SINT8, %eax
je Lcls_retstruct1
+ cmpl $FFI_TYPE_UINT16, %eax
+ je Lcls_retstruct2
cmpl $FFI_TYPE_SINT16, %eax
je Lcls_retstruct2
cmpl $FFI_TYPE_STRUCT, %eax
diff --git a/Modules/_ctypes/libffi_osx/x86/x86-ffi64.c b/Modules/_ctypes/libffi_osx/x86/x86-ffi64.c
index d4a5cc1..06feaf2 100644
--- a/Modules/_ctypes/libffi_osx/x86/x86-ffi64.c
+++ b/Modules/_ctypes/libffi_osx/x86/x86-ffi64.c
@@ -152,12 +152,42 @@ classify_argument(
case FFI_TYPE_UINT64:
case FFI_TYPE_SINT64:
case FFI_TYPE_POINTER:
+#if 0
if (byte_offset + type->size <= 4)
classes[0] = X86_64_INTEGERSI_CLASS;
else
classes[0] = X86_64_INTEGER_CLASS;
return 1;
+#else
+ {
+ int size = byte_offset + type->size;
+
+ if (size <= 4)
+ {
+ classes[0] = X86_64_INTEGERSI_CLASS;
+ return 1;
+ }
+ else if (size <= 8)
+ {
+ classes[0] = X86_64_INTEGER_CLASS;
+ return 1;
+ }
+ else if (size <= 12)
+ {
+ classes[0] = X86_64_INTEGER_CLASS;
+ classes[1] = X86_64_INTEGERSI_CLASS;
+ return 2;
+ }
+ else if (size <= 16)
+ {
+ classes[0] = classes[1] = X86_64_INTEGERSI_CLASS;
+ return 2;
+ }
+ else
+ FFI_ASSERT (0);
+ }
+#endif
case FFI_TYPE_FLOAT:
if (byte_offset == 0)
@@ -213,6 +243,21 @@ classify_argument(
byte_offset += (*ptr)->size;
}
+ if (words > 2)
+ {
+ /* When size > 16 bytes, if the first one isn't
+ X86_64_SSE_CLASS or any other ones aren't
+ X86_64_SSEUP_CLASS, everything should be passed in
+ memory. */
+ if (classes[0] != X86_64_SSE_CLASS)
+ return 0;
+
+ for (i = 1; i < words; i++)
+ if (classes[i] != X86_64_SSEUP_CLASS)
+ return 0;
+ }
+
+
/* Final merger cleanup. */
for (i = 0; i < words; i++)
{
@@ -224,13 +269,20 @@ classify_argument(
/* The X86_64_SSEUP_CLASS should be always preceded by
X86_64_SSE_CLASS. */
if (classes[i] == X86_64_SSEUP_CLASS
- && (i == 0 || classes[i - 1] != X86_64_SSE_CLASS))
+ && classes[i - 1] != X86_64_SSE_CLASS
+ && classes[i - 1] != X86_64_SSEUP_CLASS)
+ {
+ FFI_ASSERT(i != 0);
classes[i] = X86_64_SSE_CLASS;
+ }
/* X86_64_X87UP_CLASS should be preceded by X86_64_X87_CLASS. */
if (classes[i] == X86_64_X87UP_CLASS
- && (i == 0 || classes[i - 1] != X86_64_X87_CLASS))
+ && classes[i - 1] != X86_64_X87_CLASS)
+ {
+ FFI_ASSERT(i != 0);
classes[i] = X86_64_SSE_CLASS;
+ }
}
return words;
@@ -369,6 +421,7 @@ ffi_prep_cif_machdep(
cif->flags = flags;
cif->bytes = bytes;
+ cif->bytes = ALIGN(bytes,8);
return FFI_OK;
}
@@ -449,7 +502,61 @@ ffi_call(
case X86_64_INTEGER_CLASS:
case X86_64_INTEGERSI_CLASS:
reg_args->gpr[gprcount] = 0;
- memcpy (&reg_args->gpr[gprcount], a, size < 8 ? size : 8);
+ switch (arg_types[i]->type) {
+ case FFI_TYPE_SINT8:
+ {
+ int8_t shortval = *(int8_t*)a;
+ int64_t actval = (int64_t)shortval;
+ reg_args->gpr[gprcount] = actval;
+ /*memcpy (&reg_args->gpr[gprcount], &actval, 8);*/
+ break;
+ }
+
+ case FFI_TYPE_SINT16:
+ {
+ int16_t shortval = *(int16_t*)a;
+ int64_t actval = (int64_t)shortval;
+ memcpy (&reg_args->gpr[gprcount], &actval, 8);
+ break;
+ }
+
+ case FFI_TYPE_SINT32:
+ {
+ int32_t shortval = *(int32_t*)a;
+ int64_t actval = (int64_t)shortval;
+ memcpy (&reg_args->gpr[gprcount], &actval, 8);
+ break;
+ }
+
+ case FFI_TYPE_UINT8:
+ {
+ u_int8_t shortval = *(u_int8_t*)a;
+ u_int64_t actval = (u_int64_t)shortval;
+ /*memcpy (&reg_args->gpr[gprcount], &actval, 8);*/
+ reg_args->gpr[gprcount] = actval;
+ break;
+ }
+
+ case FFI_TYPE_UINT16:
+ {
+ u_int16_t shortval = *(u_int16_t*)a;
+ u_int64_t actval = (u_int64_t)shortval;
+ memcpy (&reg_args->gpr[gprcount], &actval, 8);
+ break;
+ }
+
+ case FFI_TYPE_UINT32:
+ {
+ u_int32_t shortval = *(u_int32_t*)a;
+ u_int64_t actval = (u_int64_t)shortval;
+ memcpy (&reg_args->gpr[gprcount], &actval, 8);
+ break;
+ }
+
+ default:
+ //memcpy (&reg_args->gpr[gprcount], a, size < 8 ? size : 8);
+ reg_args->gpr[gprcount] = *(int64_t*)a;
+ }
gprcount++;
break;
@@ -505,12 +612,15 @@ ffi_prep_closure(
return FFI_OK;
}
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wmissing-prototypes"
int
ffi_closure_unix64_inner(
ffi_closure* closure,
void* rvalue,
RegisterArgs* reg_args,
char* argp)
+#pragma clang diagnostic pop
{
ffi_cif* cif = closure->cif;
void** avalue = alloca(cif->nargs * sizeof(void *));
@@ -621,4 +731,4 @@ ffi_closure_unix64_inner(
return ret;
}
-#endif /* __x86_64__ */ \ No newline at end of file
+#endif /* __x86_64__ */
diff --git a/Modules/_ctypes/libffi_osx/x86/x86-ffi_darwin.c b/Modules/_ctypes/libffi_osx/x86/x86-ffi_darwin.c
index c9a306e..706ea0f 100644
--- a/Modules/_ctypes/libffi_osx/x86/x86-ffi_darwin.c
+++ b/Modules/_ctypes/libffi_osx/x86/x86-ffi_darwin.c
@@ -35,6 +35,8 @@
/* ffi_prep_args is called by the assembly routine once stack space
has been allocated for the function's arguments */
+void ffi_prep_args(char *stack, extended_cif *ecif);
+
void ffi_prep_args(char *stack, extended_cif *ecif)
{
register unsigned int i;
@@ -433,4 +435,4 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(), void *rvalue, ffi_raw *fake_avalue)
}
#endif
-#endif // __i386__ \ No newline at end of file
+#endif // __i386__