diff options
author | Ronald Oussoren <ronaldoussoren@mac.com> | 2012-08-25 09:19:14 (GMT) |
---|---|---|
committer | Ronald Oussoren <ronaldoussoren@mac.com> | 2012-08-25 09:19:14 (GMT) |
commit | 25437565f9f456a1e88f209706ced0353bbdeb14 (patch) | |
tree | 74c7b952dbd62081c23f2a15d2ae25577baf0ba2 | |
parent | c8076dfa9dfafbb5455c127719e3ac5b325986b1 (diff) | |
download | cpython-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/NEWS | 3 | ||||
-rw-r--r-- | Modules/_ctypes/libffi_osx/x86/darwin64.S | 6 | ||||
-rw-r--r-- | Modules/_ctypes/libffi_osx/x86/x86-darwin.S | 4 | ||||
-rw-r--r-- | Modules/_ctypes/libffi_osx/x86/x86-ffi64.c | 118 | ||||
-rw-r--r-- | Modules/_ctypes/libffi_osx/x86/x86-ffi_darwin.c | 4 |
5 files changed, 128 insertions, 7 deletions
@@ -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 (®_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 (®_args->gpr[gprcount], &actval, 8);*/ + break; + } + + case FFI_TYPE_SINT16: + { + int16_t shortval = *(int16_t*)a; + int64_t actval = (int64_t)shortval; + memcpy (®_args->gpr[gprcount], &actval, 8); + break; + } + + case FFI_TYPE_SINT32: + { + int32_t shortval = *(int32_t*)a; + int64_t actval = (int64_t)shortval; + memcpy (®_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 (®_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 (®_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 (®_args->gpr[gprcount], &actval, 8); + break; + } + + default: + //memcpy (®_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__ |