[Python-checkins] cpython (merge 3.2 -> default): Fix issue 13370: Ensure that ctypes works on Mac OS X when Python is

ronald.oussoren python-checkins at python.org
Sat Aug 25 11:24:36 CEST 2012


http://hg.python.org/cpython/rev/bed8dd30309d
changeset:   78766:bed8dd30309d
parent:      78762:016087c46600
parent:      78765:a425f2697273
user:        Ronald Oussoren <ronaldoussoren at mac.com>
date:        Sat Aug 25 11:24:00 2012 +0200
summary:
  Fix issue 13370: Ensure that ctypes works on Mac OS X when Python is
  compiled using the clang compiler

(merge from 3.2)

files:
  Misc/NEWS                                       |    3 +
  Modules/_ctypes/libffi_osx/x86/darwin64.S       |    6 +-
  Modules/_ctypes/libffi_osx/x86/x86-darwin.S     |    4 +
  Modules/_ctypes/libffi_osx/x86/x86-ffi64.c      |  118 +++++++++-
  Modules/_ctypes/libffi_osx/x86/x86-ffi_darwin.c |    4 +-
  5 files changed, 128 insertions(+), 7 deletions(-)


diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -39,6 +39,9 @@
 Library
 -------
 
+- Issue #13370: Ensure that ctypes works on Mac OS X when Python is
+  compiled using the clang compiler
+
 - Issue #13072: The array module's 'u' format code is now deprecated and
   will be removed in Python 4.0.
 
diff --git a/Modules/_ctypes/libffi_osx/x86/darwin64.S b/Modules/_ctypes/libffi_osx/x86/darwin64.S
--- 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 @@
  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 @@
  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
--- a/Modules/_ctypes/libffi_osx/x86/x86-darwin.S
+++ b/Modules/_ctypes/libffi_osx/x86/x86-darwin.S
@@ -198,8 +198,12 @@
 	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
--- a/Modules/_ctypes/libffi_osx/x86/x86-ffi64.c
+++ b/Modules/_ctypes/libffi_osx/x86/x86-ffi64.c
@@ -152,12 +152,42 @@
 		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 @@
 				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 @@
 				/*	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 @@
 
 	cif->flags = flags;
 	cif->bytes = bytes;
+	cif->bytes = ALIGN(bytes,8);
 
 	return FFI_OK;
 }
@@ -449,7 +502,61 @@
 					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 @@
 	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 @@
 	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
--- 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 @@
 }
 
 #endif
-#endif	// __i386__
\ No newline at end of file
+#endif	// __i386__

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list