]> granicus.if.org Git - python/commitdiff
Fix issue 13370: Ensure that ctypes works on Mac OS X when Python is compiled using...
authorRonald Oussoren <ronaldoussoren@mac.com>
Sat, 25 Aug 2012 09:18:48 +0000 (11:18 +0200)
committerRonald Oussoren <ronaldoussoren@mac.com>
Sat, 25 Aug 2012 09:18:48 +0000 (11:18 +0200)
Misc/NEWS
Modules/_ctypes/libffi_osx/x86/darwin64.S
Modules/_ctypes/libffi_osx/x86/x86-darwin.S
Modules/_ctypes/libffi_osx/x86/x86-ffi64.c
Modules/_ctypes/libffi_osx/x86/x86-ffi_darwin.c

index 5365d7e1d260fc9a552c8286840ade9b789b0c7c..b97655bac63d058e672c4d4cb346f2ecb5957926 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -95,6 +95,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 #15199: Fix JavaScript's default MIME type to application/javascript.
index eba451e9d2f11a04edc59265d98e7bb007274f86..165d4693a49ab0f87b63294715e64e3688cbbce7 100644 (file)
@@ -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:
index 6c85ea61d6249d6752bf9e201e20b9da5ec156c3..925a84131661e92f75e1e40a395f66ef8fc28b4d 100644 (file)
@@ -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
index d4a5cc14dee7c30fa25bd4c022d39ea78ea624eb..06feaf23da0b83333aba0e837176dd5e218ca579 100644 (file)
@@ -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__ */
index c9a306e51dcae5824ecfefc555e0197596ca8c06..706ea0f51206dc61724d3031102cd9bc13bface6 100644 (file)
@@ -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__