bpo-40302: Add pycore_byteswap.h header file (GH-19552)
Add a new internal pycore_byteswap.h header file with the following functions: * _Py_bswap16() * _Py_bswap32() * _Py_bswap64() Use these functions in _ctypes, sha256 and sha512 modules, and also use in the UTF-32 encoder. sha256, sha512 and _ctypes modules are now built with the internal C API.
This commit is contained in:
parent
485e715cb1
commit
1ae035b7e8
|
@ -0,0 +1,89 @@
|
|||
/* Bytes swap functions, reverse order of bytes:
|
||||
|
||||
- _Py_bswap16(uint16_t)
|
||||
- _Py_bswap32(uint32_t)
|
||||
- _Py_bswap64(uint64_t)
|
||||
*/
|
||||
|
||||
#ifndef Py_INTERNAL_BSWAP_H
|
||||
#define Py_INTERNAL_BSWAP_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
#if defined(__clang__) || \
|
||||
(defined(__GNUC__) && \
|
||||
((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)))
|
||||
/* __builtin_bswap16() is available since GCC 4.8,
|
||||
__builtin_bswap32() is available since GCC 4.3,
|
||||
__builtin_bswap64() is available since GCC 4.3. */
|
||||
# define _PY_HAVE_BUILTIN_BSWAP
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* Get _byteswap_ushort(), _byteswap_ulong(), _byteswap_uint64() */
|
||||
# include <intrin.h>
|
||||
#endif
|
||||
|
||||
static inline uint16_t
|
||||
_Py_bswap16(uint16_t word)
|
||||
{
|
||||
#ifdef _PY_HAVE_BUILTIN_BSWAP
|
||||
return __builtin_bswap16(word);
|
||||
#elif defined(_MSC_VER)
|
||||
Py_BUILD_ASSERT(sizeof(word) == sizeof(unsigned short));
|
||||
return _byteswap_ushort(word);
|
||||
#else
|
||||
// Portable implementation which doesn't rely on circular bit shift
|
||||
return ( ((word & UINT16_C(0x00FF)) << 8)
|
||||
| ((word & UINT16_C(0xFF00)) >> 8));
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
_Py_bswap32(uint32_t word)
|
||||
{
|
||||
#ifdef _PY_HAVE_BUILTIN_BSWAP
|
||||
return __builtin_bswap32(word);
|
||||
#elif defined(_MSC_VER)
|
||||
Py_BUILD_ASSERT(sizeof(word) == sizeof(unsigned long));
|
||||
return _byteswap_ulong(word);
|
||||
#else
|
||||
// Portable implementation which doesn't rely on circular bit shift
|
||||
return ( ((word & UINT32_C(0x000000FF)) << 24)
|
||||
| ((word & UINT32_C(0x0000FF00)) << 8)
|
||||
| ((word & UINT32_C(0x00FF0000)) >> 8)
|
||||
| ((word & UINT32_C(0xFF000000)) >> 24));
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
_Py_bswap64(uint64_t word)
|
||||
{
|
||||
#ifdef _PY_HAVE_BUILTIN_BSWAP
|
||||
return __builtin_bswap64(word);
|
||||
#elif defined(_MSC_VER)
|
||||
return _byteswap_uint64(word);
|
||||
#else
|
||||
// Portable implementation which doesn't rely on circular bit shift
|
||||
return ( ((word & UINT64_C(0x00000000000000FF)) << 56)
|
||||
| ((word & UINT64_C(0x000000000000FF00)) << 40)
|
||||
| ((word & UINT64_C(0x0000000000FF0000)) << 24)
|
||||
| ((word & UINT64_C(0x00000000FF000000)) << 8)
|
||||
| ((word & UINT64_C(0x000000FF00000000)) >> 8)
|
||||
| ((word & UINT64_C(0x0000FF0000000000)) >> 24)
|
||||
| ((word & UINT64_C(0x00FF000000000000)) >> 40)
|
||||
| ((word & UINT64_C(0xFF00000000000000)) >> 56));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_INTERNAL_BSWAP_H */
|
||||
|
|
@ -24,6 +24,8 @@ except ImportError:
|
|||
# Skip this test if the _testcapi module isn't available.
|
||||
_testcapi = support.import_module('_testcapi')
|
||||
|
||||
import _testinternalcapi
|
||||
|
||||
# Were we compiled --with-pydebug or with #define Py_DEBUG?
|
||||
Py_DEBUG = hasattr(sys, 'gettotalrefcount')
|
||||
|
||||
|
@ -658,6 +660,12 @@ class Test_testcapi(unittest.TestCase):
|
|||
if name.startswith('test_') and not name.endswith('_code'))
|
||||
|
||||
|
||||
class Test_testinternalcapi(unittest.TestCase):
|
||||
locals().update((name, getattr(_testinternalcapi, name))
|
||||
for name in dir(_testinternalcapi)
|
||||
if name.startswith('test_'))
|
||||
|
||||
|
||||
class PyMemDebugTests(unittest.TestCase):
|
||||
PYTHONMALLOC = 'debug'
|
||||
# '0x04c06e0' or '04C06E0'
|
||||
|
|
|
@ -1083,6 +1083,7 @@ PYTHON_HEADERS= \
|
|||
$(srcdir)/Include/internal/pycore_abstract.h \
|
||||
$(srcdir)/Include/internal/pycore_accu.h \
|
||||
$(srcdir)/Include/internal/pycore_atomic.h \
|
||||
$(srcdir)/Include/internal/pycore_byteswap.h \
|
||||
$(srcdir)/Include/internal/pycore_bytes_methods.h \
|
||||
$(srcdir)/Include/internal/pycore_call.h \
|
||||
$(srcdir)/Include/internal/pycore_ceval.h \
|
||||
|
|
|
@ -247,8 +247,8 @@ _symtable symtablemodule.c
|
|||
# The _sha module implements the SHA checksum algorithms.
|
||||
# (NIST's Secure Hash Algorithms.)
|
||||
#_sha1 sha1module.c
|
||||
#_sha256 sha256module.c
|
||||
#_sha512 sha512module.c
|
||||
#_sha256 sha256module.c -DPy_BUILD_CORE_BUILTIN
|
||||
#_sha512 sha512module.c -DPy_BUILD_CORE_BUILTIN
|
||||
#_sha3 _sha3/sha3module.c
|
||||
|
||||
# _blake module
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "Python.h"
|
||||
#include "pycore_byteswap.h" // _Py_bswap32()
|
||||
|
||||
#include <ffi.h>
|
||||
#ifdef MS_WIN32
|
||||
|
@ -448,46 +449,32 @@ get_ulonglong(PyObject *v, unsigned long long *p)
|
|||
( ( (type)x & ~(BIT_MASK(type, size) << LOW_BIT(size)) ) | ( ((type)v & BIT_MASK(type, size)) << LOW_BIT(size) ) ) \
|
||||
: (type)v)
|
||||
|
||||
/* byte swapping macros */
|
||||
#define SWAP_2(v) \
|
||||
( ( (v >> 8) & 0x00FF) | \
|
||||
( (v << 8) & 0xFF00) )
|
||||
|
||||
#define SWAP_4(v) \
|
||||
( ( (v & 0x000000FF) << 24 ) | \
|
||||
( (v & 0x0000FF00) << 8 ) | \
|
||||
( (v & 0x00FF0000) >> 8 ) | \
|
||||
( ((v >> 24) & 0xFF)) )
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define SWAP_8(v) \
|
||||
( ( (v & 0x00000000000000FFL) << 56 ) | \
|
||||
( (v & 0x000000000000FF00L) << 40 ) | \
|
||||
( (v & 0x0000000000FF0000L) << 24 ) | \
|
||||
( (v & 0x00000000FF000000L) << 8 ) | \
|
||||
( (v & 0x000000FF00000000L) >> 8 ) | \
|
||||
( (v & 0x0000FF0000000000L) >> 24 ) | \
|
||||
( (v & 0x00FF000000000000L) >> 40 ) | \
|
||||
( ((v >> 56) & 0xFF)) )
|
||||
#if SIZEOF_SHORT == 2
|
||||
# define SWAP_SHORT _Py_bswap16
|
||||
#else
|
||||
#define SWAP_8(v) \
|
||||
( ( (v & 0x00000000000000FFLL) << 56 ) | \
|
||||
( (v & 0x000000000000FF00LL) << 40 ) | \
|
||||
( (v & 0x0000000000FF0000LL) << 24 ) | \
|
||||
( (v & 0x00000000FF000000LL) << 8 ) | \
|
||||
( (v & 0x000000FF00000000LL) >> 8 ) | \
|
||||
( (v & 0x0000FF0000000000LL) >> 24 ) | \
|
||||
( (v & 0x00FF000000000000LL) >> 40 ) | \
|
||||
( ((v >> 56) & 0xFF)) )
|
||||
# error "unsupported short size"
|
||||
#endif
|
||||
|
||||
#define SWAP_INT SWAP_4
|
||||
#if SIZEOF_INT == 4
|
||||
# define SWAP_INT _Py_bswap32
|
||||
#else
|
||||
# error "unsupported int size"
|
||||
#endif
|
||||
|
||||
#if SIZEOF_LONG == 4
|
||||
# define SWAP_LONG SWAP_4
|
||||
# define SWAP_LONG _Py_bswap32
|
||||
#elif SIZEOF_LONG == 8
|
||||
# define SWAP_LONG SWAP_8
|
||||
# define SWAP_LONG _Py_bswap64
|
||||
#else
|
||||
# error "unsupported long size"
|
||||
#endif
|
||||
|
||||
#if SIZEOF_LONG_LONG == 8
|
||||
# define SWAP_LONG_LONG _Py_bswap64
|
||||
#else
|
||||
# error "unsupported long long size"
|
||||
#endif
|
||||
|
||||
/*****************************************************************
|
||||
* The setter methods return an object which must be kept alive, to keep the
|
||||
* data valid which has been stored in the memory block. The ctypes object
|
||||
|
@ -569,12 +556,13 @@ h_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
|
|||
{
|
||||
long val;
|
||||
short field;
|
||||
if (get_long(value, &val) < 0)
|
||||
if (get_long(value, &val) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
memcpy(&field, ptr, sizeof(field));
|
||||
field = SWAP_2(field);
|
||||
field = SWAP_SHORT(field);
|
||||
field = SET(short, field, val, size);
|
||||
field = SWAP_2(field);
|
||||
field = SWAP_SHORT(field);
|
||||
memcpy(ptr, &field, sizeof(field));
|
||||
_RET(value);
|
||||
}
|
||||
|
@ -593,7 +581,7 @@ h_get_sw(void *ptr, Py_ssize_t size)
|
|||
{
|
||||
short val;
|
||||
memcpy(&val, ptr, sizeof(val));
|
||||
val = SWAP_2(val);
|
||||
val = SWAP_SHORT(val);
|
||||
GET_BITFIELD(val, size);
|
||||
return PyLong_FromLong(val);
|
||||
}
|
||||
|
@ -616,12 +604,13 @@ H_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
|
|||
{
|
||||
unsigned long val;
|
||||
unsigned short field;
|
||||
if (get_ulong(value, &val) < 0)
|
||||
if (get_ulong(value, &val) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
memcpy(&field, ptr, sizeof(field));
|
||||
field = SWAP_2(field);
|
||||
field = SWAP_SHORT(field);
|
||||
field = SET(unsigned short, field, val, size);
|
||||
field = SWAP_2(field);
|
||||
field = SWAP_SHORT(field);
|
||||
memcpy(ptr, &field, sizeof(field));
|
||||
_RET(value);
|
||||
}
|
||||
|
@ -641,7 +630,7 @@ H_get_sw(void *ptr, Py_ssize_t size)
|
|||
{
|
||||
unsigned short val;
|
||||
memcpy(&val, ptr, sizeof(val));
|
||||
val = SWAP_2(val);
|
||||
val = SWAP_SHORT(val);
|
||||
GET_BITFIELD(val, size);
|
||||
return PyLong_FromLong(val);
|
||||
}
|
||||
|
@ -664,8 +653,9 @@ i_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
|
|||
{
|
||||
long val;
|
||||
int field;
|
||||
if (get_long(value, &val) < 0)
|
||||
if (get_long(value, &val) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
memcpy(&field, ptr, sizeof(field));
|
||||
field = SWAP_INT(field);
|
||||
field = SET(int, field, val, size);
|
||||
|
@ -757,8 +747,9 @@ I_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
|
|||
{
|
||||
unsigned long val;
|
||||
unsigned int field;
|
||||
if (get_ulong(value, &val) < 0)
|
||||
if (get_ulong(value, &val) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
memcpy(&field, ptr, sizeof(field));
|
||||
field = SWAP_INT(field);
|
||||
field = SET(unsigned int, field, (unsigned int)val, size);
|
||||
|
@ -805,8 +796,9 @@ l_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
|
|||
{
|
||||
long val;
|
||||
long field;
|
||||
if (get_long(value, &val) < 0)
|
||||
if (get_long(value, &val) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
memcpy(&field, ptr, sizeof(field));
|
||||
field = SWAP_LONG(field);
|
||||
field = SET(long, field, val, size);
|
||||
|
@ -853,8 +845,9 @@ L_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
|
|||
{
|
||||
unsigned long val;
|
||||
unsigned long field;
|
||||
if (get_ulong(value, &val) < 0)
|
||||
if (get_ulong(value, &val) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
memcpy(&field, ptr, sizeof(field));
|
||||
field = SWAP_LONG(field);
|
||||
field = SET(unsigned long, field, val, size);
|
||||
|
@ -901,12 +894,13 @@ q_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
|
|||
{
|
||||
long long val;
|
||||
long long field;
|
||||
if (get_longlong(value, &val) < 0)
|
||||
if (get_longlong(value, &val) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
memcpy(&field, ptr, sizeof(field));
|
||||
field = SWAP_8(field);
|
||||
field = SWAP_LONG_LONG(field);
|
||||
field = SET(long long, field, val, size);
|
||||
field = SWAP_8(field);
|
||||
field = SWAP_LONG_LONG(field);
|
||||
memcpy(ptr, &field, sizeof(field));
|
||||
_RET(value);
|
||||
}
|
||||
|
@ -925,7 +919,7 @@ q_get_sw(void *ptr, Py_ssize_t size)
|
|||
{
|
||||
long long val;
|
||||
memcpy(&val, ptr, sizeof(val));
|
||||
val = SWAP_8(val);
|
||||
val = SWAP_LONG_LONG(val);
|
||||
GET_BITFIELD(val, size);
|
||||
return PyLong_FromLongLong(val);
|
||||
}
|
||||
|
@ -948,12 +942,13 @@ Q_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
|
|||
{
|
||||
unsigned long long val;
|
||||
unsigned long long field;
|
||||
if (get_ulonglong(value, &val) < 0)
|
||||
if (get_ulonglong(value, &val) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
memcpy(&field, ptr, sizeof(field));
|
||||
field = SWAP_8(field);
|
||||
field = SWAP_LONG_LONG(field);
|
||||
field = SET(unsigned long long, field, val, size);
|
||||
field = SWAP_8(field);
|
||||
field = SWAP_LONG_LONG(field);
|
||||
memcpy(ptr, &field, sizeof(field));
|
||||
_RET(value);
|
||||
}
|
||||
|
@ -972,7 +967,7 @@ Q_get_sw(void *ptr, Py_ssize_t size)
|
|||
{
|
||||
unsigned long long val;
|
||||
memcpy(&val, ptr, sizeof(val));
|
||||
val = SWAP_8(val);
|
||||
val = SWAP_LONG_LONG(val);
|
||||
GET_BITFIELD(val, size);
|
||||
return PyLong_FromUnsignedLongLong(val);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#define PY_SSIZE_T_CLEAN
|
||||
|
||||
#include "Python.h"
|
||||
#include "pycore_byteswap.h" // _Py_bswap32()
|
||||
#include "pycore_initconfig.h" // _Py_GetConfigsAsDict()
|
||||
#include "pycore_gc.h" // PyGC_Head
|
||||
|
||||
|
@ -21,7 +22,7 @@ get_configs(PyObject *self, PyObject *Py_UNUSED(args))
|
|||
|
||||
|
||||
static PyObject*
|
||||
get_recursion_depth(PyObject *self, PyObject *args)
|
||||
get_recursion_depth(PyObject *self, PyObject *Py_UNUSED(args))
|
||||
{
|
||||
PyThreadState *tstate = PyThreadState_Get();
|
||||
|
||||
|
@ -30,9 +31,38 @@ get_recursion_depth(PyObject *self, PyObject *args)
|
|||
}
|
||||
|
||||
|
||||
static PyObject*
|
||||
test_bswap(PyObject *self, PyObject *Py_UNUSED(args))
|
||||
{
|
||||
uint16_t u16 = _Py_bswap16(UINT16_C(0x3412));
|
||||
if (u16 != UINT16_C(0x1234)) {
|
||||
PyErr_Format(PyExc_AssertionError,
|
||||
"_Py_bswap16(0x3412) returns %u", u16);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32_t u32 = _Py_bswap32(UINT32_C(0x78563412));
|
||||
if (u32 != UINT32_C(0x12345678)) {
|
||||
PyErr_Format(PyExc_AssertionError,
|
||||
"_Py_bswap32(0x78563412) returns %lu", u32);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint64_t u64 = _Py_bswap64(UINT64_C(0xEFCDAB9078563412));
|
||||
if (u64 != UINT64_C(0x1234567890ABCDEF)) {
|
||||
PyErr_Format(PyExc_AssertionError,
|
||||
"_Py_bswap64(0xEFCDAB9078563412) returns %llu", u64);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
static PyMethodDef TestMethods[] = {
|
||||
{"get_configs", get_configs, METH_NOARGS},
|
||||
{"get_recursion_depth", get_recursion_depth, METH_NOARGS},
|
||||
{"test_bswap", test_bswap, METH_NOARGS},
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
/* SHA objects */
|
||||
|
||||
#include "Python.h"
|
||||
#include "pycore_byteswap.h" // _Py_bswap32()
|
||||
#include "structmember.h" // PyMemberDef
|
||||
#include "hashlib.h"
|
||||
#include "pystrhex.h"
|
||||
|
@ -30,12 +31,7 @@ class SHA256Type "SHAobject *" "&PyType_Type"
|
|||
/* Some useful types */
|
||||
|
||||
typedef unsigned char SHA_BYTE;
|
||||
|
||||
#if SIZEOF_INT == 4
|
||||
typedef unsigned int SHA_INT32; /* 32-bit integer */
|
||||
#else
|
||||
/* not defined. compilation will die. */
|
||||
#endif
|
||||
typedef uint32_t SHA_INT32; /* 32-bit integer */
|
||||
|
||||
/* The SHA block size and message digest sizes, in bytes */
|
||||
|
||||
|
@ -61,14 +57,9 @@ typedef struct {
|
|||
#if PY_LITTLE_ENDIAN
|
||||
static void longReverse(SHA_INT32 *buffer, int byteCount)
|
||||
{
|
||||
SHA_INT32 value;
|
||||
|
||||
byteCount /= sizeof(*buffer);
|
||||
while (byteCount--) {
|
||||
value = *buffer;
|
||||
value = ( ( value & 0xFF00FF00L ) >> 8 ) | \
|
||||
( ( value & 0x00FF00FFL ) << 8 );
|
||||
*buffer++ = ( value << 16 ) | ( value >> 16 );
|
||||
for (; byteCount--; buffer++) {
|
||||
*buffer = _Py_bswap32(*buffer);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
/* SHA objects */
|
||||
|
||||
#include "Python.h"
|
||||
#include "pycore_byteswap.h" // _Py_bswap32()
|
||||
#include "structmember.h" // PyMemberDef
|
||||
#include "hashlib.h"
|
||||
#include "pystrhex.h"
|
||||
|
@ -30,13 +31,8 @@ class SHA512Type "SHAobject *" "&PyType_Type"
|
|||
/* Some useful types */
|
||||
|
||||
typedef unsigned char SHA_BYTE;
|
||||
|
||||
#if SIZEOF_INT == 4
|
||||
typedef unsigned int SHA_INT32; /* 32-bit integer */
|
||||
typedef unsigned long long SHA_INT64; /* 64-bit integer */
|
||||
#else
|
||||
/* not defined. compilation will die. */
|
||||
#endif
|
||||
typedef uint32_t SHA_INT32; /* 32-bit integer */
|
||||
typedef uint64_t SHA_INT64; /* 64-bit integer */
|
||||
|
||||
/* The SHA block size and message digest sizes, in bytes */
|
||||
|
||||
|
@ -62,22 +58,9 @@ typedef struct {
|
|||
#if PY_LITTLE_ENDIAN
|
||||
static void longReverse(SHA_INT64 *buffer, int byteCount)
|
||||
{
|
||||
SHA_INT64 value;
|
||||
|
||||
byteCount /= sizeof(*buffer);
|
||||
while (byteCount--) {
|
||||
value = *buffer;
|
||||
|
||||
((unsigned char*)buffer)[0] = (unsigned char)(value >> 56) & 0xff;
|
||||
((unsigned char*)buffer)[1] = (unsigned char)(value >> 48) & 0xff;
|
||||
((unsigned char*)buffer)[2] = (unsigned char)(value >> 40) & 0xff;
|
||||
((unsigned char*)buffer)[3] = (unsigned char)(value >> 32) & 0xff;
|
||||
((unsigned char*)buffer)[4] = (unsigned char)(value >> 24) & 0xff;
|
||||
((unsigned char*)buffer)[5] = (unsigned char)(value >> 16) & 0xff;
|
||||
((unsigned char*)buffer)[6] = (unsigned char)(value >> 8) & 0xff;
|
||||
((unsigned char*)buffer)[7] = (unsigned char)(value ) & 0xff;
|
||||
|
||||
buffer++;
|
||||
for (; byteCount--; buffer++) {
|
||||
*buffer = _Py_bswap64(*buffer);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
# error "codecs.h is specific to Unicode"
|
||||
#endif
|
||||
|
||||
#include "pycore_byteswap.h" // _Py_bswap32()
|
||||
|
||||
/* Mask to quickly check whether a C 'long' contains a
|
||||
non-ASCII, UTF8-encoded char. */
|
||||
#if (SIZEOF_LONG == 8)
|
||||
|
@ -732,24 +734,28 @@ STRINGLIB(utf16_encode)(const STRINGLIB_CHAR *in,
|
|||
#endif
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
STRINGLIB(SWAB4)(STRINGLIB_CHAR ch)
|
||||
{
|
||||
uint32_t word = ch;
|
||||
#if STRINGLIB_SIZEOF_CHAR == 1
|
||||
# define SWAB4(CH, tmp) ((CH) << 24) /* high bytes are zero */
|
||||
#elif STRINGLIB_SIZEOF_CHAR == 2
|
||||
# define SWAB4(CH, tmp) (tmp = (CH), \
|
||||
((tmp & 0x00FFu) << 24) + ((tmp & 0xFF00u) << 8))
|
||||
/* high bytes are zero */
|
||||
return (word << 24);
|
||||
#elif STRINGLIB_SIZEOF_CHAR == 2
|
||||
/* high bytes are zero */
|
||||
return ((word & 0x00FFu) << 24) + ((word & 0xFF00u) << 8);
|
||||
#else
|
||||
# define SWAB4(CH, tmp) (tmp = (CH), \
|
||||
tmp = ((tmp & 0x00FF00FFu) << 8) + ((tmp >> 8) & 0x00FF00FFu), \
|
||||
((tmp & 0x0000FFFFu) << 16) + ((tmp >> 16) & 0x0000FFFFu))
|
||||
return _Py_bswap32(word);
|
||||
#endif
|
||||
}
|
||||
|
||||
Py_LOCAL_INLINE(Py_ssize_t)
|
||||
STRINGLIB(utf32_encode)(const STRINGLIB_CHAR *in,
|
||||
Py_ssize_t len,
|
||||
PY_UINT32_T **outptr,
|
||||
uint32_t **outptr,
|
||||
int native_ordering)
|
||||
{
|
||||
PY_UINT32_T *out = *outptr;
|
||||
uint32_t *out = *outptr;
|
||||
const STRINGLIB_CHAR *end = in + len;
|
||||
if (native_ordering) {
|
||||
const STRINGLIB_CHAR *unrolled_end = in + _Py_SIZE_ROUND_DOWN(len, 4);
|
||||
|
@ -783,7 +789,6 @@ STRINGLIB(utf32_encode)(const STRINGLIB_CHAR *in,
|
|||
const STRINGLIB_CHAR *unrolled_end = in + _Py_SIZE_ROUND_DOWN(len, 4);
|
||||
while (in < unrolled_end) {
|
||||
#if STRINGLIB_SIZEOF_CHAR > 1
|
||||
Py_UCS4 ch1, ch2, ch3, ch4;
|
||||
/* check if any character is a surrogate character */
|
||||
if (((in[0] ^ 0xd800) &
|
||||
(in[1] ^ 0xd800) &
|
||||
|
@ -791,10 +796,10 @@ STRINGLIB(utf32_encode)(const STRINGLIB_CHAR *in,
|
|||
(in[3] ^ 0xd800) & 0xf800) == 0)
|
||||
break;
|
||||
#endif
|
||||
out[0] = SWAB4(in[0], ch1);
|
||||
out[1] = SWAB4(in[1], ch2);
|
||||
out[2] = SWAB4(in[2], ch3);
|
||||
out[3] = SWAB4(in[3], ch4);
|
||||
out[0] = STRINGLIB(SWAB4)(in[0]);
|
||||
out[1] = STRINGLIB(SWAB4)(in[1]);
|
||||
out[2] = STRINGLIB(SWAB4)(in[2]);
|
||||
out[3] = STRINGLIB(SWAB4)(in[3]);
|
||||
in += 4; out += 4;
|
||||
}
|
||||
while (in < end) {
|
||||
|
@ -805,7 +810,7 @@ STRINGLIB(utf32_encode)(const STRINGLIB_CHAR *in,
|
|||
goto fail;
|
||||
}
|
||||
#endif
|
||||
*out++ = SWAB4(ch, ch);
|
||||
*out++ = STRINGLIB(SWAB4)(ch);
|
||||
}
|
||||
}
|
||||
*outptr = out;
|
||||
|
@ -816,6 +821,5 @@ STRINGLIB(utf32_encode)(const STRINGLIB_CHAR *in,
|
|||
return len - (end - in + 1);
|
||||
#endif
|
||||
}
|
||||
#undef SWAB4
|
||||
|
||||
#endif
|
||||
|
|
|
@ -164,6 +164,7 @@
|
|||
<ClInclude Include="..\Include\internal\pycore_abstract.h" />
|
||||
<ClInclude Include="..\Include\internal\pycore_accu.h" />
|
||||
<ClInclude Include="..\Include\internal\pycore_atomic.h" />
|
||||
<ClInclude Include="..\Include\internal\pycore_byteswap.h" />
|
||||
<ClInclude Include="..\Include\internal\pycore_bytes_methods.h" />
|
||||
<ClInclude Include="..\Include\internal\pycore_call.h" />
|
||||
<ClInclude Include="..\Include\internal\pycore_ceval.h" />
|
||||
|
|
|
@ -195,6 +195,9 @@
|
|||
<ClInclude Include="..\Include\internal\pycore_atomic.h">
|
||||
<Filter>Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\internal\pycore_byteswap.h">
|
||||
<Filter>Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\internal\pycore_bytes_methods.h">
|
||||
<Filter>Include</Filter>
|
||||
</ClInclude>
|
||||
|
|
4
setup.py
4
setup.py
|
@ -2044,7 +2044,7 @@ class PyBuildExt(build_ext):
|
|||
# Thomas Heller's _ctypes module
|
||||
self.use_system_libffi = False
|
||||
include_dirs = []
|
||||
extra_compile_args = []
|
||||
extra_compile_args = ['-DPy_BUILD_CORE_MODULE']
|
||||
extra_link_args = []
|
||||
sources = ['_ctypes/_ctypes.c',
|
||||
'_ctypes/callbacks.c',
|
||||
|
@ -2298,8 +2298,10 @@ class PyBuildExt(build_ext):
|
|||
# It's harmless and the object code is tiny (40-50 KiB per module,
|
||||
# only loaded when actually used).
|
||||
self.add(Extension('_sha256', ['sha256module.c'],
|
||||
extra_compile_args=['-DPy_BUILD_CORE_MODULE'],
|
||||
depends=['hashlib.h']))
|
||||
self.add(Extension('_sha512', ['sha512module.c'],
|
||||
extra_compile_args=['-DPy_BUILD_CORE_MODULE'],
|
||||
depends=['hashlib.h']))
|
||||
self.add(Extension('_md5', ['md5module.c'],
|
||||
depends=['hashlib.h']))
|
||||
|
|
Loading…
Reference in New Issue