From 1ae035b7e847064d09df01ca62b8a761e9b5aae3 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 17 Apr 2020 17:47:20 +0200 Subject: [PATCH] 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. --- Include/internal/pycore_byteswap.h | 89 +++++++++++++++++++++++++ Include/pyport.h | 8 +-- Lib/test/test_capi.py | 8 +++ Makefile.pre.in | 1 + Modules/Setup | 4 +- Modules/_ctypes/cfield.c | 101 ++++++++++++++--------------- Modules/_testinternalcapi.c | 32 ++++++++- Modules/sha256module.c | 17 ++--- Modules/sha512module.c | 27 ++------ Objects/stringlib/codecs.h | 36 +++++----- PCbuild/pythoncore.vcxproj | 1 + PCbuild/pythoncore.vcxproj.filters | 3 + setup.py | 4 +- 13 files changed, 219 insertions(+), 112 deletions(-) create mode 100644 Include/internal/pycore_byteswap.h diff --git a/Include/internal/pycore_byteswap.h b/Include/internal/pycore_byteswap.h new file mode 100644 index 00000000000..5e64704a004 --- /dev/null +++ b/Include/internal/pycore_byteswap.h @@ -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 +#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 */ + diff --git a/Include/pyport.h b/Include/pyport.h index 72e74e046a5..63d3b81de5d 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -768,11 +768,11 @@ extern char * _getpty(int *, int, mode_t, int); */ #ifdef WORDS_BIGENDIAN -#define PY_BIG_ENDIAN 1 -#define PY_LITTLE_ENDIAN 0 +# define PY_BIG_ENDIAN 1 +# define PY_LITTLE_ENDIAN 0 #else -#define PY_BIG_ENDIAN 0 -#define PY_LITTLE_ENDIAN 1 +# define PY_BIG_ENDIAN 0 +# define PY_LITTLE_ENDIAN 1 #endif #ifdef Py_BUILD_CORE diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 024343963b6..f9578d3afa8 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -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' diff --git a/Makefile.pre.in b/Makefile.pre.in index 6b265226c49..4511e607d89 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -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 \ diff --git a/Modules/Setup b/Modules/Setup index 40266a192bc..9dcca131000 100644 --- a/Modules/Setup +++ b/Modules/Setup @@ -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 diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index 2060d15a64d..a72682d7292 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -1,4 +1,5 @@ #include "Python.h" +#include "pycore_byteswap.h" // _Py_bswap32() #include #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); } diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index 8352f6e2590..9330e2625b3 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -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 */ }; diff --git a/Modules/sha256module.c b/Modules/sha256module.c index 731082655c0..e0ff9b2b3a1 100644 --- a/Modules/sha256module.c +++ b/Modules/sha256module.c @@ -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 diff --git a/Modules/sha512module.c b/Modules/sha512module.c index 38d303d369e..780f8e7f06c 100644 --- a/Modules/sha512module.c +++ b/Modules/sha512module.c @@ -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 diff --git a/Objects/stringlib/codecs.h b/Objects/stringlib/codecs.h index cd7aa699b8f..208e8fe4a48 100644 --- a/Objects/stringlib/codecs.h +++ b/Objects/stringlib/codecs.h @@ -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 */ + /* high bytes are zero */ + return (word << 24); #elif STRINGLIB_SIZEOF_CHAR == 2 -# define SWAB4(CH, tmp) (tmp = (CH), \ - ((tmp & 0x00FFu) << 24) + ((tmp & 0xFF00u) << 8)) - /* high bytes are zero */ + /* 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 diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index c35499e0eb7..862c5a821b1 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -164,6 +164,7 @@ + diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index c04df27de58..9d6d997b526 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -195,6 +195,9 @@ Include + + Include + Include diff --git a/setup.py b/setup.py index 0357a0124f8..65a1cfab078 100644 --- a/setup.py +++ b/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']))