Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit cb460b9

Browse files
Fix issue 13370: Ensure that ctypes works on Mac OS X when Python is
compiled using the clang compiler (merge from 3.2)
2 parents cc0274b + 2543756 commit cb460b9

5 files changed

Lines changed: 128 additions & 7 deletions

File tree

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ Core and Builtins
3939
Library
4040
-------
4141

42+
- Issue #13370: Ensure that ctypes works on Mac OS X when Python is
43+
compiled using the clang compiler
44+
4245
- Issue #13072: The array module's 'u' format code is now deprecated and
4346
will be removed in Python 4.0.
4447

Modules/_ctypes/libffi_osx/x86/darwin64.S

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,16 @@
4545
_ffi_call_unix64:
4646
LUW0:
4747
movq (%rsp), %r10 /* Load return address. */
48+
movq %rdi, %r12 /* Save a copy of the register area. */
4849
leaq (%rdi, %rsi), %rax /* Find local stack base. */
4950
movq %rdx, (%rax) /* Save flags. */
5051
movq %rcx, 8(%rax) /* Save raddr. */
5152
movq %rbp, 16(%rax) /* Save old frame pointer. */
5253
movq %r10, 24(%rax) /* Relocate return address. */
5354
movq %rax, %rbp /* Finalize local stack frame. */
5455
LUW1:
55-
movq %rdi, %r10 /* Save a copy of the register area. */
56+
/* movq %rdi, %r10 // Save a copy of the register area. */
57+
movq %r12, %r10
5658
movq %r8, %r11 /* Save a copy of the target fn. */
5759
movl %r9d, %eax /* Set number of SSE registers. */
5860

@@ -255,7 +257,7 @@ Lld_void:
255257
ret
256258
.align 3
257259
Lld_int8:
258-
movzbl -24(%rsp), %eax
260+
movzbl -24(%rsp), %eax
259261
ret
260262
.align 3
261263
Lld_int16:

Modules/_ctypes/libffi_osx/x86/x86-darwin.S

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,12 @@ LCFI7:
198198
je Lcls_retldouble
199199
cmpl $FFI_TYPE_SINT64, %eax
200200
je Lcls_retllong
201+
cmpl $FFI_TYPE_UINT8, %eax
202+
je Lcls_retstruct1
201203
cmpl $FFI_TYPE_SINT8, %eax
202204
je Lcls_retstruct1
205+
cmpl $FFI_TYPE_UINT16, %eax
206+
je Lcls_retstruct2
203207
cmpl $FFI_TYPE_SINT16, %eax
204208
je Lcls_retstruct2
205209
cmpl $FFI_TYPE_STRUCT, %eax

Modules/_ctypes/libffi_osx/x86/x86-ffi64.c

Lines changed: 114 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,12 +152,42 @@ classify_argument(
152152
case FFI_TYPE_UINT64:
153153
case FFI_TYPE_SINT64:
154154
case FFI_TYPE_POINTER:
155+
#if 0
155156
if (byte_offset + type->size <= 4)
156157
classes[0] = X86_64_INTEGERSI_CLASS;
157158
else
158159
classes[0] = X86_64_INTEGER_CLASS;
159160

160161
return 1;
162+
#else
163+
{
164+
int size = byte_offset + type->size;
165+
166+
if (size <= 4)
167+
{
168+
classes[0] = X86_64_INTEGERSI_CLASS;
169+
return 1;
170+
}
171+
else if (size <= 8)
172+
{
173+
classes[0] = X86_64_INTEGER_CLASS;
174+
return 1;
175+
}
176+
else if (size <= 12)
177+
{
178+
classes[0] = X86_64_INTEGER_CLASS;
179+
classes[1] = X86_64_INTEGERSI_CLASS;
180+
return 2;
181+
}
182+
else if (size <= 16)
183+
{
184+
classes[0] = classes[1] = X86_64_INTEGERSI_CLASS;
185+
return 2;
186+
}
187+
else
188+
FFI_ASSERT (0);
189+
}
190+
#endif
161191

162192
case FFI_TYPE_FLOAT:
163193
if (byte_offset == 0)
@@ -213,6 +243,21 @@ classify_argument(
213243
byte_offset += (*ptr)->size;
214244
}
215245

246+
if (words > 2)
247+
{
248+
/* When size > 16 bytes, if the first one isn't
249+
X86_64_SSE_CLASS or any other ones aren't
250+
X86_64_SSEUP_CLASS, everything should be passed in
251+
memory. */
252+
if (classes[0] != X86_64_SSE_CLASS)
253+
return 0;
254+
255+
for (i = 1; i < words; i++)
256+
if (classes[i] != X86_64_SSEUP_CLASS)
257+
return 0;
258+
}
259+
260+
216261
/* Final merger cleanup. */
217262
for (i = 0; i < words; i++)
218263
{
@@ -224,13 +269,20 @@ classify_argument(
224269
/* The X86_64_SSEUP_CLASS should be always preceded by
225270
X86_64_SSE_CLASS. */
226271
if (classes[i] == X86_64_SSEUP_CLASS
227-
&& (i == 0 || classes[i - 1] != X86_64_SSE_CLASS))
272+
&& classes[i - 1] != X86_64_SSE_CLASS
273+
&& classes[i - 1] != X86_64_SSEUP_CLASS)
274+
{
275+
FFI_ASSERT(i != 0);
228276
classes[i] = X86_64_SSE_CLASS;
277+
}
229278

230279
/* X86_64_X87UP_CLASS should be preceded by X86_64_X87_CLASS. */
231280
if (classes[i] == X86_64_X87UP_CLASS
232-
&& (i == 0 || classes[i - 1] != X86_64_X87_CLASS))
281+
&& classes[i - 1] != X86_64_X87_CLASS)
282+
{
283+
FFI_ASSERT(i != 0);
233284
classes[i] = X86_64_SSE_CLASS;
285+
}
234286
}
235287

236288
return words;
@@ -369,6 +421,7 @@ ffi_prep_cif_machdep(
369421

370422
cif->flags = flags;
371423
cif->bytes = bytes;
424+
cif->bytes = ALIGN(bytes,8);
372425

373426
return FFI_OK;
374427
}
@@ -449,7 +502,61 @@ ffi_call(
449502
case X86_64_INTEGER_CLASS:
450503
case X86_64_INTEGERSI_CLASS:
451504
reg_args->gpr[gprcount] = 0;
452-
memcpy (&reg_args->gpr[gprcount], a, size < 8 ? size : 8);
505+
switch (arg_types[i]->type) {
506+
case FFI_TYPE_SINT8:
507+
{
508+
int8_t shortval = *(int8_t*)a;
509+
int64_t actval = (int64_t)shortval;
510+
reg_args->gpr[gprcount] = actval;
511+
/*memcpy (&reg_args->gpr[gprcount], &actval, 8);*/
512+
break;
513+
}
514+
515+
case FFI_TYPE_SINT16:
516+
{
517+
int16_t shortval = *(int16_t*)a;
518+
int64_t actval = (int64_t)shortval;
519+
memcpy (&reg_args->gpr[gprcount], &actval, 8);
520+
break;
521+
}
522+
523+
case FFI_TYPE_SINT32:
524+
{
525+
int32_t shortval = *(int32_t*)a;
526+
int64_t actval = (int64_t)shortval;
527+
memcpy (&reg_args->gpr[gprcount], &actval, 8);
528+
break;
529+
}
530+
531+
case FFI_TYPE_UINT8:
532+
{
533+
u_int8_t shortval = *(u_int8_t*)a;
534+
u_int64_t actval = (u_int64_t)shortval;
535+
/*memcpy (&reg_args->gpr[gprcount], &actval, 8);*/
536+
reg_args->gpr[gprcount] = actval;
537+
break;
538+
}
539+
540+
case FFI_TYPE_UINT16:
541+
{
542+
u_int16_t shortval = *(u_int16_t*)a;
543+
u_int64_t actval = (u_int64_t)shortval;
544+
memcpy (&reg_args->gpr[gprcount], &actval, 8);
545+
break;
546+
}
547+
548+
case FFI_TYPE_UINT32:
549+
{
550+
u_int32_t shortval = *(u_int32_t*)a;
551+
u_int64_t actval = (u_int64_t)shortval;
552+
memcpy (&reg_args->gpr[gprcount], &actval, 8);
553+
break;
554+
}
555+
556+
default:
557+
//memcpy (&reg_args->gpr[gprcount], a, size < 8 ? size : 8);
558+
reg_args->gpr[gprcount] = *(int64_t*)a;
559+
}
453560
gprcount++;
454561
break;
455562

@@ -505,12 +612,15 @@ ffi_prep_closure(
505612
return FFI_OK;
506613
}
507614

615+
#pragma clang diagnostic push
616+
#pragma clang diagnostic ignored "-Wmissing-prototypes"
508617
int
509618
ffi_closure_unix64_inner(
510619
ffi_closure* closure,
511620
void* rvalue,
512621
RegisterArgs* reg_args,
513622
char* argp)
623+
#pragma clang diagnostic pop
514624
{
515625
ffi_cif* cif = closure->cif;
516626
void** avalue = alloca(cif->nargs * sizeof(void *));
@@ -621,4 +731,4 @@ ffi_closure_unix64_inner(
621731
return ret;
622732
}
623733

624-
#endif /* __x86_64__ */
734+
#endif /* __x86_64__ */

Modules/_ctypes/libffi_osx/x86/x86-ffi_darwin.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
/* ffi_prep_args is called by the assembly routine once stack space
3636
has been allocated for the function's arguments */
3737

38+
void ffi_prep_args(char *stack, extended_cif *ecif);
39+
3840
void ffi_prep_args(char *stack, extended_cif *ecif)
3941
{
4042
register unsigned int i;
@@ -433,4 +435,4 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(), void *rvalue, ffi_raw *fake_avalue)
433435
}
434436

435437
#endif
436-
#endif // __i386__
438+
#endif // __i386__

0 commit comments

Comments
 (0)