mirror of
https://github.com/python/cpython.git
synced 2025-11-17 01:25:57 +00:00
(Most of) SF patch 601369 (Christos Georgiou): obmalloc,structmodule:
64bit, big endian (issue 2 only). This adds a bunch of memcpy calls via a temporary variable to avoid alignment errors. That's needed for some platforms.
This commit is contained in:
parent
683c0fe414
commit
960bc5490b
1 changed files with 54 additions and 27 deletions
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
/* struct module -- pack values into and (out of) strings */
|
/* struct module -- pack values into and (out of) strings */
|
||||||
|
|
||||||
/* New version supporting byte order, alignment and size options,
|
/* New version supporting byte order, alignment and size options,
|
||||||
|
|
@ -482,6 +481,14 @@ typedef struct _formatdef {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Native mode routines. ****************************************************/
|
/* Native mode routines. ****************************************************/
|
||||||
|
/* NOTE:
|
||||||
|
In all n[up]_<type> routines handling types larger than 1 byte, there is
|
||||||
|
*no* guarantee that the p pointer is properly aligned for each type,
|
||||||
|
therefore memcpy is called. An intermediate variable is used to
|
||||||
|
compensate for big-endian architectures.
|
||||||
|
Normally both the intermediate variable and the memcpy call will be
|
||||||
|
skipped by C optimisation in little-endian architectures (gcc >= 2.91
|
||||||
|
does this). */
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
nu_char(const char *p, const formatdef *f)
|
nu_char(const char *p, const formatdef *f)
|
||||||
|
|
@ -504,38 +511,49 @@ nu_ubyte(const char *p, const formatdef *f)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
nu_short(const char *p, const formatdef *f)
|
nu_short(const char *p, const formatdef *f)
|
||||||
{
|
{
|
||||||
return PyInt_FromLong((long) *(short *)p);
|
short x;
|
||||||
|
memcpy((char *)&x, p, sizeof x);
|
||||||
|
return PyInt_FromLong((long)x);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
nu_ushort(const char *p, const formatdef *f)
|
nu_ushort(const char *p, const formatdef *f)
|
||||||
{
|
{
|
||||||
return PyInt_FromLong((long) *(unsigned short *)p);
|
unsigned short x;
|
||||||
|
memcpy((char *)&x, p, sizeof x);
|
||||||
|
return PyInt_FromLong((long)x);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
nu_int(const char *p, const formatdef *f)
|
nu_int(const char *p, const formatdef *f)
|
||||||
{
|
{
|
||||||
return PyInt_FromLong((long) *(int *)p);
|
int x;
|
||||||
|
memcpy((char *)&x, p, sizeof x);
|
||||||
|
return PyInt_FromLong((long)x);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
nu_uint(const char *p, const formatdef *f)
|
nu_uint(const char *p, const formatdef *f)
|
||||||
{
|
{
|
||||||
unsigned int x = *(unsigned int *)p;
|
unsigned int x;
|
||||||
|
memcpy((char *)&x, p, sizeof x);
|
||||||
return PyLong_FromUnsignedLong((unsigned long)x);
|
return PyLong_FromUnsignedLong((unsigned long)x);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
nu_long(const char *p, const formatdef *f)
|
nu_long(const char *p, const formatdef *f)
|
||||||
{
|
{
|
||||||
return PyInt_FromLong(*(long *)p);
|
long x;
|
||||||
|
memcpy((char *)&x, p, sizeof x);
|
||||||
|
return PyInt_FromLong(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
nu_ulong(const char *p, const formatdef *f)
|
nu_ulong(const char *p, const formatdef *f)
|
||||||
{
|
{
|
||||||
return PyLong_FromUnsignedLong(*(unsigned long *)p);
|
unsigned long x;
|
||||||
|
memcpy((char *)&x, p, sizeof x);
|
||||||
|
return PyLong_FromUnsignedLong(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Native mode doesn't support q or Q unless the platform C supports
|
/* Native mode doesn't support q or Q unless the platform C supports
|
||||||
|
|
@ -546,27 +564,26 @@ nu_ulong(const char *p, const formatdef *f)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
nu_longlong(const char *p, const formatdef *f)
|
nu_longlong(const char *p, const formatdef *f)
|
||||||
{
|
{
|
||||||
/* p may not be properly aligned */
|
|
||||||
LONG_LONG x;
|
LONG_LONG x;
|
||||||
memcpy(&x, p, sizeof(LONG_LONG));
|
memcpy((char *)&x, p, sizeof x);
|
||||||
return PyLong_FromLongLong(x);
|
return PyLong_FromLongLong(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
nu_ulonglong(const char *p, const formatdef *f)
|
nu_ulonglong(const char *p, const formatdef *f)
|
||||||
{
|
{
|
||||||
/* p may not be properly aligned */
|
|
||||||
unsigned LONG_LONG x;
|
unsigned LONG_LONG x;
|
||||||
memcpy(&x, p, sizeof(unsigned LONG_LONG));
|
memcpy((char *)&x, p, sizeof x);
|
||||||
return PyLong_FromUnsignedLongLong(x);
|
return PyLong_FromUnsignedLongLong(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
nu_float(const char *p, const formatdef *f)
|
nu_float(const char *p, const formatdef *f)
|
||||||
{
|
{
|
||||||
float x;
|
float x;
|
||||||
memcpy((char *)&x, p, sizeof(float));
|
memcpy((char *)&x, p, sizeof x);
|
||||||
return PyFloat_FromDouble((double)x);
|
return PyFloat_FromDouble((double)x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -574,14 +591,16 @@ static PyObject *
|
||||||
nu_double(const char *p, const formatdef *f)
|
nu_double(const char *p, const formatdef *f)
|
||||||
{
|
{
|
||||||
double x;
|
double x;
|
||||||
memcpy((char *)&x, p, sizeof(double));
|
memcpy((char *)&x, p, sizeof x);
|
||||||
return PyFloat_FromDouble(x);
|
return PyFloat_FromDouble(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
nu_void_p(const char *p, const formatdef *f)
|
nu_void_p(const char *p, const formatdef *f)
|
||||||
{
|
{
|
||||||
return PyLong_FromVoidPtr(*(void **)p);
|
void *x;
|
||||||
|
memcpy((char *)&x, p, sizeof x);
|
||||||
|
return PyLong_FromVoidPtr(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
@ -630,6 +649,7 @@ static int
|
||||||
np_short(char *p, PyObject *v, const formatdef *f)
|
np_short(char *p, PyObject *v, const formatdef *f)
|
||||||
{
|
{
|
||||||
long x;
|
long x;
|
||||||
|
short y;
|
||||||
if (get_long(v, &x) < 0)
|
if (get_long(v, &x) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (x < SHRT_MIN || x > SHRT_MAX){
|
if (x < SHRT_MIN || x > SHRT_MAX){
|
||||||
|
|
@ -638,7 +658,8 @@ np_short(char *p, PyObject *v, const formatdef *f)
|
||||||
"<=number<=" STRINGIFY(SHRT_MAX));
|
"<=number<=" STRINGIFY(SHRT_MAX));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
* (short *)p = (short)x;
|
y = (short)x;
|
||||||
|
memcpy(p, (char *)&y, sizeof y);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -646,6 +667,7 @@ static int
|
||||||
np_ushort(char *p, PyObject *v, const formatdef *f)
|
np_ushort(char *p, PyObject *v, const formatdef *f)
|
||||||
{
|
{
|
||||||
long x;
|
long x;
|
||||||
|
unsigned short y;
|
||||||
if (get_long(v, &x) < 0)
|
if (get_long(v, &x) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (x < 0 || x > USHRT_MAX){
|
if (x < 0 || x > USHRT_MAX){
|
||||||
|
|
@ -653,7 +675,8 @@ np_ushort(char *p, PyObject *v, const formatdef *f)
|
||||||
"short format requires 0<=number<=" STRINGIFY(USHRT_MAX));
|
"short format requires 0<=number<=" STRINGIFY(USHRT_MAX));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
* (unsigned short *)p = (unsigned short)x;
|
y = (unsigned short)x;
|
||||||
|
memcpy(p, (char *)&y, sizeof y);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -661,9 +684,11 @@ static int
|
||||||
np_int(char *p, PyObject *v, const formatdef *f)
|
np_int(char *p, PyObject *v, const formatdef *f)
|
||||||
{
|
{
|
||||||
long x;
|
long x;
|
||||||
|
int y;
|
||||||
if (get_long(v, &x) < 0)
|
if (get_long(v, &x) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
* (int *)p = x;
|
y = (int)x;
|
||||||
|
memcpy(p, (char *)&y, sizeof y);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -671,9 +696,11 @@ static int
|
||||||
np_uint(char *p, PyObject *v, const formatdef *f)
|
np_uint(char *p, PyObject *v, const formatdef *f)
|
||||||
{
|
{
|
||||||
unsigned long x;
|
unsigned long x;
|
||||||
|
unsigned int y;
|
||||||
if (get_ulong(v, &x) < 0)
|
if (get_ulong(v, &x) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
* (unsigned int *)p = x;
|
y = (unsigned int)x;
|
||||||
|
memcpy(p, (char *)&y, sizeof y);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -683,7 +710,7 @@ np_long(char *p, PyObject *v, const formatdef *f)
|
||||||
long x;
|
long x;
|
||||||
if (get_long(v, &x) < 0)
|
if (get_long(v, &x) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
* (long *)p = x;
|
memcpy(p, (char *)&x, sizeof x);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -693,7 +720,7 @@ np_ulong(char *p, PyObject *v, const formatdef *f)
|
||||||
unsigned long x;
|
unsigned long x;
|
||||||
if (get_ulong(v, &x) < 0)
|
if (get_ulong(v, &x) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
* (unsigned long *)p = x;
|
memcpy(p, (char *)&x, sizeof x);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -705,7 +732,7 @@ np_longlong(char *p, PyObject *v, const formatdef *f)
|
||||||
LONG_LONG x;
|
LONG_LONG x;
|
||||||
if (get_longlong(v, &x) < 0)
|
if (get_longlong(v, &x) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
memcpy(p, &x, sizeof(LONG_LONG));
|
memcpy(p, (char *)&x, sizeof x);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -715,7 +742,7 @@ np_ulonglong(char *p, PyObject *v, const formatdef *f)
|
||||||
unsigned LONG_LONG x;
|
unsigned LONG_LONG x;
|
||||||
if (get_ulonglong(v, &x) < 0)
|
if (get_ulonglong(v, &x) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
memcpy(p, &x, sizeof(unsigned LONG_LONG));
|
memcpy(p, (char *)&x, sizeof x);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -729,7 +756,7 @@ np_float(char *p, PyObject *v, const formatdef *f)
|
||||||
"required argument is not a float");
|
"required argument is not a float");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
memcpy(p, (char *)&x, sizeof(float));
|
memcpy(p, (char *)&x, sizeof x);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -757,7 +784,7 @@ np_void_p(char *p, PyObject *v, const formatdef *f)
|
||||||
"required argument is not an integer");
|
"required argument is not an integer");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
*(void **)p = x;
|
memcpy(p, (char *)&x, sizeof x);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue