Commit a00b100c authored by Ronald Oussoren's avatar Ronald Oussoren

Fix issue 13370: Ensure that ctypes works on Mac OS X when Python is compiled...

Fix issue 13370: Ensure that ctypes works on Mac OS X when Python is compiled using the clang compiler
parent 3196529f
...@@ -95,6 +95,9 @@ Core and Builtins ...@@ -95,6 +95,9 @@ Core and Builtins
Library 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 #15544: Fix Decimal.__float__ to work with payload-carrying NaNs.
- Issue #15199: Fix JavaScript's default MIME type to application/javascript. - Issue #15199: Fix JavaScript's default MIME type to application/javascript.
......
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
_ffi_call_unix64: _ffi_call_unix64:
LUW0: LUW0:
movq (%rsp), %r10 /* Load return address. */ movq (%rsp), %r10 /* Load return address. */
movq %rdi, %r12 /* Save a copy of the register area. */
leaq (%rdi, %rsi), %rax /* Find local stack base. */ leaq (%rdi, %rsi), %rax /* Find local stack base. */
movq %rdx, (%rax) /* Save flags. */ movq %rdx, (%rax) /* Save flags. */
movq %rcx, 8(%rax) /* Save raddr. */ movq %rcx, 8(%rax) /* Save raddr. */
...@@ -52,7 +53,8 @@ LUW0: ...@@ -52,7 +53,8 @@ LUW0:
movq %r10, 24(%rax) /* Relocate return address. */ movq %r10, 24(%rax) /* Relocate return address. */
movq %rax, %rbp /* Finalize local stack frame. */ movq %rax, %rbp /* Finalize local stack frame. */
LUW1: 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. */ movq %r8, %r11 /* Save a copy of the target fn. */
movl %r9d, %eax /* Set number of SSE registers. */ movl %r9d, %eax /* Set number of SSE registers. */
...@@ -255,7 +257,7 @@ Lld_void: ...@@ -255,7 +257,7 @@ Lld_void:
ret ret
.align 3 .align 3
Lld_int8: Lld_int8:
movzbl -24(%rsp), %eax movzbl -24(%rsp), %eax
ret ret
.align 3 .align 3
Lld_int16: Lld_int16:
......
...@@ -198,8 +198,12 @@ LCFI7: ...@@ -198,8 +198,12 @@ LCFI7:
je Lcls_retldouble je Lcls_retldouble
cmpl $FFI_TYPE_SINT64, %eax cmpl $FFI_TYPE_SINT64, %eax
je Lcls_retllong je Lcls_retllong
cmpl $FFI_TYPE_UINT8, %eax
je Lcls_retstruct1
cmpl $FFI_TYPE_SINT8, %eax cmpl $FFI_TYPE_SINT8, %eax
je Lcls_retstruct1 je Lcls_retstruct1
cmpl $FFI_TYPE_UINT16, %eax
je Lcls_retstruct2
cmpl $FFI_TYPE_SINT16, %eax cmpl $FFI_TYPE_SINT16, %eax
je Lcls_retstruct2 je Lcls_retstruct2
cmpl $FFI_TYPE_STRUCT, %eax cmpl $FFI_TYPE_STRUCT, %eax
......
...@@ -152,12 +152,42 @@ classify_argument( ...@@ -152,12 +152,42 @@ classify_argument(
case FFI_TYPE_UINT64: case FFI_TYPE_UINT64:
case FFI_TYPE_SINT64: case FFI_TYPE_SINT64:
case FFI_TYPE_POINTER: case FFI_TYPE_POINTER:
#if 0
if (byte_offset + type->size <= 4) if (byte_offset + type->size <= 4)
classes[0] = X86_64_INTEGERSI_CLASS; classes[0] = X86_64_INTEGERSI_CLASS;
else else
classes[0] = X86_64_INTEGER_CLASS; classes[0] = X86_64_INTEGER_CLASS;
return 1; 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: case FFI_TYPE_FLOAT:
if (byte_offset == 0) if (byte_offset == 0)
...@@ -213,6 +243,21 @@ classify_argument( ...@@ -213,6 +243,21 @@ classify_argument(
byte_offset += (*ptr)->size; 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. */ /* Final merger cleanup. */
for (i = 0; i < words; i++) for (i = 0; i < words; i++)
{ {
...@@ -224,13 +269,20 @@ classify_argument( ...@@ -224,13 +269,20 @@ classify_argument(
/* The X86_64_SSEUP_CLASS should be always preceded by /* The X86_64_SSEUP_CLASS should be always preceded by
X86_64_SSE_CLASS. */ X86_64_SSE_CLASS. */
if (classes[i] == X86_64_SSEUP_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; classes[i] = X86_64_SSE_CLASS;
}
/* X86_64_X87UP_CLASS should be preceded by X86_64_X87_CLASS. */ /* X86_64_X87UP_CLASS should be preceded by X86_64_X87_CLASS. */
if (classes[i] == X86_64_X87UP_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; classes[i] = X86_64_SSE_CLASS;
}
} }
return words; return words;
...@@ -369,6 +421,7 @@ ffi_prep_cif_machdep( ...@@ -369,6 +421,7 @@ ffi_prep_cif_machdep(
cif->flags = flags; cif->flags = flags;
cif->bytes = bytes; cif->bytes = bytes;
cif->bytes = ALIGN(bytes,8);
return FFI_OK; return FFI_OK;
} }
...@@ -449,7 +502,61 @@ ffi_call( ...@@ -449,7 +502,61 @@ ffi_call(
case X86_64_INTEGER_CLASS: case X86_64_INTEGER_CLASS:
case X86_64_INTEGERSI_CLASS: case X86_64_INTEGERSI_CLASS:
reg_args->gpr[gprcount] = 0; 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++; gprcount++;
break; break;
...@@ -505,12 +612,15 @@ ffi_prep_closure( ...@@ -505,12 +612,15 @@ ffi_prep_closure(
return FFI_OK; return FFI_OK;
} }
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmissing-prototypes"
int int
ffi_closure_unix64_inner( ffi_closure_unix64_inner(
ffi_closure* closure, ffi_closure* closure,
void* rvalue, void* rvalue,
RegisterArgs* reg_args, RegisterArgs* reg_args,
char* argp) char* argp)
#pragma clang diagnostic pop
{ {
ffi_cif* cif = closure->cif; ffi_cif* cif = closure->cif;
void** avalue = alloca(cif->nargs * sizeof(void *)); void** avalue = alloca(cif->nargs * sizeof(void *));
...@@ -621,4 +731,4 @@ ffi_closure_unix64_inner( ...@@ -621,4 +731,4 @@ ffi_closure_unix64_inner(
return ret; return ret;
} }
#endif /* __x86_64__ */ #endif /* __x86_64__ */
\ No newline at end of file
...@@ -35,6 +35,8 @@ ...@@ -35,6 +35,8 @@
/* ffi_prep_args is called by the assembly routine once stack space /* ffi_prep_args is called by the assembly routine once stack space
has been allocated for the function's arguments */ 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) void ffi_prep_args(char *stack, extended_cif *ecif)
{ {
register unsigned int i; register unsigned int i;
...@@ -433,4 +435,4 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(), void *rvalue, ffi_raw *fake_avalue) ...@@ -433,4 +435,4 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(), void *rvalue, ffi_raw *fake_avalue)
} }
#endif #endif
#endif // __i386__ #endif // __i386__
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment