Eryk Sun added the comment:

The 24-byte struct gets passed on the stack, as it should be. In this case 
ffi_call doesn't abort() because examine_argument returns 0, which is due to 
the following code in classify_argument:

    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;
    }

It looks like X86_64_SSEUP_CLASS is never actually assigned by 
classify_argument(), in which case libffi never uses registers to pass structs 
that are larger than 16 bytes. 

Regarding floating-point values, we get a similar abort for passing a struct 
containing an array of two doubles because ctypes passes one ffi_type_pointer 
element instead of two ffi_type_double elements. 

Also, a struct with an array of one double (weird but should be supported) 
doesn't abort, but instead gets passed incorrectly like a pointer, i.e. as an 
integer in register rdi, instead of in the expected xmm0 register. The call 
thus uses whatever garbage value is currently in xmm0. You have to use a test 
lib to reproduce this. It's not apparent with a ctypes callback because 
ffi_closure_unix64 (unix64.S) and ffi_closure_unix64_inner (ffi64.c) use the 
same incorrect classification before calling ctypes closure_fcn and 
_CallPythonObject.

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue22273>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to