mirror of
https://github.com/python/cpython.git
synced 2025-10-03 05:35:59 +00:00
Update to newer version of ffi. Fixes crashes and test failures of longdouble
This commit is contained in:
parent
e9057ff1a9
commit
b3c8243c47
2 changed files with 48 additions and 16 deletions
|
@ -25,11 +25,22 @@
|
||||||
|
|
||||||
#include <ffi.h>
|
#include <ffi.h>
|
||||||
#include <ffi_common.h>
|
#include <ffi_common.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
extern void ffi_call_osf(void *, unsigned long, unsigned, void *, void (*)(void));
|
/* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE;
|
||||||
extern void ffi_closure_osf(void);
|
all further uses in this file will refer to the 128-bit type. */
|
||||||
|
#if defined(__LONG_DOUBLE_128__)
|
||||||
|
# if FFI_TYPE_LONGDOUBLE != 4
|
||||||
|
# error FFI_TYPE_LONGDOUBLE out of date
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# undef FFI_TYPE_LONGDOUBLE
|
||||||
|
# define FFI_TYPE_LONGDOUBLE 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern void ffi_call_osf(void *, unsigned long, unsigned, void *, void (*)(void))
|
||||||
|
FFI_HIDDEN;
|
||||||
|
extern void ffi_closure_osf(void) FFI_HIDDEN;
|
||||||
|
|
||||||
|
|
||||||
ffi_status
|
ffi_status
|
||||||
|
@ -49,6 +60,11 @@ ffi_prep_cif_machdep(ffi_cif *cif)
|
||||||
cif->flags = cif->rtype->type;
|
cif->flags = cif->rtype->type;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FFI_TYPE_LONGDOUBLE:
|
||||||
|
/* 128-bit long double is returned in memory, like a struct. */
|
||||||
|
cif->flags = FFI_TYPE_STRUCT;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
cif->flags = FFI_TYPE_INT;
|
cif->flags = FFI_TYPE_INT;
|
||||||
break;
|
break;
|
||||||
|
@ -57,6 +73,7 @@ ffi_prep_cif_machdep(ffi_cif *cif)
|
||||||
return FFI_OK;
|
return FFI_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||||
{
|
{
|
||||||
|
@ -64,8 +81,6 @@ ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||||
long i, avn;
|
long i, avn;
|
||||||
ffi_type **arg_types;
|
ffi_type **arg_types;
|
||||||
|
|
||||||
FFI_ASSERT (cif->abi == FFI_OSF);
|
|
||||||
|
|
||||||
/* If the return value is a struct and we don't have a return
|
/* If the return value is a struct and we don't have a return
|
||||||
value address then we need to make one. */
|
value address then we need to make one. */
|
||||||
if (rvalue == NULL && cif->flags == FFI_TYPE_STRUCT)
|
if (rvalue == NULL && cif->flags == FFI_TYPE_STRUCT)
|
||||||
|
@ -84,6 +99,8 @@ ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||||
|
|
||||||
while (i < avn)
|
while (i < avn)
|
||||||
{
|
{
|
||||||
|
size_t size = (*arg_types)->size;
|
||||||
|
|
||||||
switch ((*arg_types)->type)
|
switch ((*arg_types)->type)
|
||||||
{
|
{
|
||||||
case FFI_TYPE_SINT8:
|
case FFI_TYPE_SINT8:
|
||||||
|
@ -129,6 +146,12 @@ ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||||
*(double *) argp = *(double *)(* avalue);
|
*(double *) argp = *(double *)(* avalue);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FFI_TYPE_LONGDOUBLE:
|
||||||
|
/* 128-bit long double is passed by reference. */
|
||||||
|
*(long double **) argp = (long double *)(* avalue);
|
||||||
|
size = sizeof (long double *);
|
||||||
|
break;
|
||||||
|
|
||||||
case FFI_TYPE_STRUCT:
|
case FFI_TYPE_STRUCT:
|
||||||
memcpy(argp, *avalue, (*arg_types)->size);
|
memcpy(argp, *avalue, (*arg_types)->size);
|
||||||
break;
|
break;
|
||||||
|
@ -137,7 +160,7 @@ ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||||
FFI_ASSERT(0);
|
FFI_ASSERT(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
argp += ALIGN((*arg_types)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
|
argp += ALIGN(size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
|
||||||
i++, arg_types++, avalue++;
|
i++, arg_types++, avalue++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,8 +176,6 @@ ffi_prep_closure (ffi_closure* closure,
|
||||||
{
|
{
|
||||||
unsigned int *tramp;
|
unsigned int *tramp;
|
||||||
|
|
||||||
FFI_ASSERT (cif->abi == FFI_OSF);
|
|
||||||
|
|
||||||
tramp = (unsigned int *) &closure->tramp[0];
|
tramp = (unsigned int *) &closure->tramp[0];
|
||||||
tramp[0] = 0x47fb0401; /* mov $27,$1 */
|
tramp[0] = 0x47fb0401; /* mov $27,$1 */
|
||||||
tramp[1] = 0xa77b0010; /* ldq $27,16($27) */
|
tramp[1] = 0xa77b0010; /* ldq $27,16($27) */
|
||||||
|
@ -177,7 +198,8 @@ ffi_prep_closure (ffi_closure* closure,
|
||||||
return FFI_OK;
|
return FFI_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
|
long FFI_HIDDEN
|
||||||
ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp)
|
ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp)
|
||||||
{
|
{
|
||||||
ffi_cif *cif;
|
ffi_cif *cif;
|
||||||
|
@ -205,6 +227,8 @@ ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp)
|
||||||
/* Grab the addresses of the arguments from the stack frame. */
|
/* Grab the addresses of the arguments from the stack frame. */
|
||||||
while (i < avn)
|
while (i < avn)
|
||||||
{
|
{
|
||||||
|
size_t size = arg_types[i]->size;
|
||||||
|
|
||||||
switch (arg_types[i]->type)
|
switch (arg_types[i]->type)
|
||||||
{
|
{
|
||||||
case FFI_TYPE_SINT8:
|
case FFI_TYPE_SINT8:
|
||||||
|
@ -236,16 +260,22 @@ ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp)
|
||||||
avalue[i] = &argp[argn - (argn < 6 ? 6 : 0)];
|
avalue[i] = &argp[argn - (argn < 6 ? 6 : 0)];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FFI_TYPE_LONGDOUBLE:
|
||||||
|
/* 128-bit long double is passed by reference. */
|
||||||
|
avalue[i] = (long double *) argp[argn];
|
||||||
|
size = sizeof (long double *);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
FFI_ASSERT(0);
|
abort ();
|
||||||
}
|
}
|
||||||
|
|
||||||
argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
|
argn += ALIGN(size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Invoke the closure. */
|
/* Invoke the closure. */
|
||||||
(closure->fun) (cif, rvalue, avalue, closure->user_data);
|
closure->fun (cif, rvalue, avalue, closure->user_data);
|
||||||
|
|
||||||
/* Tell ffi_closure_osf how to perform return type promotions. */
|
/* Tell ffi_closure_osf how to perform return type promotions. */
|
||||||
return cif->rtype->type;
|
return cif->rtype->type;
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
/* -----------------------------------------------------------------------
|
/* -----------------------------------------------------------------------
|
||||||
osf.S - Copyright (c) 1998, 2001 Red Hat
|
osf.S - Copyright (c) 1998, 2001, 2007 Red Hat
|
||||||
|
|
||||||
Alpha/OSF Foreign Function Interface
|
Alpha/OSF Foreign Function Interface
|
||||||
|
|
||||||
$Id: osf.S,v 1.2 2006/03/03 20:24:26 theller Exp $
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
a copy of this software and associated documentation files (the
|
a copy of this software and associated documentation files (the
|
||||||
``Software''), to deal in the Software without restriction, including
|
``Software''), to deal in the Software without restriction, including
|
||||||
|
@ -42,6 +40,8 @@
|
||||||
.align 3
|
.align 3
|
||||||
.globl ffi_call_osf
|
.globl ffi_call_osf
|
||||||
.ent ffi_call_osf
|
.ent ffi_call_osf
|
||||||
|
FFI_HIDDEN(ffi_call_osf)
|
||||||
|
|
||||||
ffi_call_osf:
|
ffi_call_osf:
|
||||||
.frame $15, 32, $26, 0
|
.frame $15, 32, $26, 0
|
||||||
.mask 0x4008000, -32
|
.mask 0x4008000, -32
|
||||||
|
@ -129,6 +129,8 @@ $LFE1:
|
||||||
.align 3
|
.align 3
|
||||||
.globl ffi_closure_osf
|
.globl ffi_closure_osf
|
||||||
.ent ffi_closure_osf
|
.ent ffi_closure_osf
|
||||||
|
FFI_HIDDEN(ffi_closure_osf)
|
||||||
|
|
||||||
ffi_closure_osf:
|
ffi_closure_osf:
|
||||||
.frame $30, 16*8, $26, 0
|
.frame $30, 16*8, $26, 0
|
||||||
.mask 0x4000000, -16*8
|
.mask 0x4000000, -16*8
|
||||||
|
@ -265,7 +267,7 @@ $load_table:
|
||||||
.gprel32 $load_32 # FFI_TYPE_INT
|
.gprel32 $load_32 # FFI_TYPE_INT
|
||||||
.gprel32 $load_float # FFI_TYPE_FLOAT
|
.gprel32 $load_float # FFI_TYPE_FLOAT
|
||||||
.gprel32 $load_double # FFI_TYPE_DOUBLE
|
.gprel32 $load_double # FFI_TYPE_DOUBLE
|
||||||
.gprel32 $load_double # FFI_TYPE_LONGDOUBLE
|
.gprel32 $load_none # FFI_TYPE_LONGDOUBLE
|
||||||
.gprel32 $load_u8 # FFI_TYPE_UINT8
|
.gprel32 $load_u8 # FFI_TYPE_UINT8
|
||||||
.gprel32 $load_s8 # FFI_TYPE_SINT8
|
.gprel32 $load_s8 # FFI_TYPE_SINT8
|
||||||
.gprel32 $load_u16 # FFI_TYPE_UINT16
|
.gprel32 $load_u16 # FFI_TYPE_UINT16
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue