bpo-47164: Add _PyASCIIObject_CAST() macro (GH-32191)

Add macros to cast objects to PyASCIIObject*, PyCompactUnicodeObject*
and PyUnicodeObject*: _PyASCIIObject_CAST(),
_PyCompactUnicodeObject_CAST() and _PyUnicodeObject_CAST(). Using
these new macros make the code more readable and check their argument
with: assert(PyUnicode_Check(op)).

Remove redundant assert(PyUnicode_Check(op)) in macros using directly
or indirectly these new CAST macros.

Replacing existing casts with these macros.
This commit is contained in:
Victor Stinner 2022-03-31 09:59:27 +02:00 committed by GitHub
parent db4dada510
commit c14d7e4b81
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 76 additions and 78 deletions

View file

@ -234,6 +234,15 @@ PyAPI_FUNC(int) _PyUnicode_CheckConsistency(
PyObject *op, PyObject *op,
int check_content); int check_content);
#define _PyASCIIObject_CAST(op) \
(assert(PyUnicode_Check(op)), (PyASCIIObject*)(op))
#define _PyCompactUnicodeObject_CAST(op) \
(assert(PyUnicode_Check(op)), (PyCompactUnicodeObject*)(op))
#define _PyUnicodeObject_CAST(op) \
(assert(PyUnicode_Check(op)), (PyUnicodeObject*)(op))
/* Fast access macros */ /* Fast access macros */
/* Returns the deprecated Py_UNICODE representation's size in code units /* Returns the deprecated Py_UNICODE representation's size in code units
@ -243,11 +252,10 @@ PyAPI_FUNC(int) _PyUnicode_CheckConsistency(
/* Py_DEPRECATED(3.3) */ /* Py_DEPRECATED(3.3) */
#define PyUnicode_GET_SIZE(op) \ #define PyUnicode_GET_SIZE(op) \
(assert(PyUnicode_Check(op)), \ (_PyASCIIObject_CAST(op)->wstr ? \
(((PyASCIIObject *)(op))->wstr) ? \
PyUnicode_WSTR_LENGTH(op) : \ PyUnicode_WSTR_LENGTH(op) : \
((void)PyUnicode_AsUnicode(_PyObject_CAST(op)),\ ((void)PyUnicode_AsUnicode(_PyObject_CAST(op)),\
assert(((PyASCIIObject *)(op))->wstr), \ assert(_PyASCIIObject_CAST(op)->wstr), \
PyUnicode_WSTR_LENGTH(op))) PyUnicode_WSTR_LENGTH(op)))
/* Py_DEPRECATED(3.3) */ /* Py_DEPRECATED(3.3) */
@ -261,9 +269,8 @@ PyAPI_FUNC(int) _PyUnicode_CheckConsistency(
/* Py_DEPRECATED(3.3) */ /* Py_DEPRECATED(3.3) */
#define PyUnicode_AS_UNICODE(op) \ #define PyUnicode_AS_UNICODE(op) \
(assert(PyUnicode_Check(op)), \ (_PyASCIIObject_CAST(op)->wstr ? _PyASCIIObject_CAST(op)->wstr : \
(((PyASCIIObject *)(op))->wstr) ? (((PyASCIIObject *)(op))->wstr) : \ PyUnicode_AsUnicode(_PyObject_CAST(op)))
PyUnicode_AsUnicode(_PyObject_CAST(op)))
/* Py_DEPRECATED(3.3) */ /* Py_DEPRECATED(3.3) */
#define PyUnicode_AS_DATA(op) \ #define PyUnicode_AS_DATA(op) \
@ -281,25 +288,24 @@ PyAPI_FUNC(int) _PyUnicode_CheckConsistency(
/* Use only if you know it's a string */ /* Use only if you know it's a string */
#define PyUnicode_CHECK_INTERNED(op) \ #define PyUnicode_CHECK_INTERNED(op) \
(((PyASCIIObject *)(op))->state.interned) (_PyASCIIObject_CAST(op)->state.interned)
/* Return true if the string contains only ASCII characters, or 0 if not. The /* Return true if the string contains only ASCII characters, or 0 if not. The
string may be compact (PyUnicode_IS_COMPACT_ASCII) or not, but must be string may be compact (PyUnicode_IS_COMPACT_ASCII) or not, but must be
ready. */ ready. */
#define PyUnicode_IS_ASCII(op) \ #define PyUnicode_IS_ASCII(op) \
(assert(PyUnicode_Check(op)), \ (assert(PyUnicode_IS_READY(op)), \
assert(PyUnicode_IS_READY(op)), \ _PyASCIIObject_CAST(op)->state.ascii)
((PyASCIIObject*)op)->state.ascii)
/* Return true if the string is compact or 0 if not. /* Return true if the string is compact or 0 if not.
No type checks or Ready calls are performed. */ No type checks or Ready calls are performed. */
#define PyUnicode_IS_COMPACT(op) \ #define PyUnicode_IS_COMPACT(op) \
(((PyASCIIObject*)(op))->state.compact) (_PyASCIIObject_CAST(op)->state.compact)
/* Return true if the string is a compact ASCII string (use PyASCIIObject /* Return true if the string is a compact ASCII string (use PyASCIIObject
structure), or 0 if not. No type checks or Ready calls are performed. */ structure), or 0 if not. No type checks or Ready calls are performed. */
#define PyUnicode_IS_COMPACT_ASCII(op) \ #define PyUnicode_IS_COMPACT_ASCII(op) \
(((PyASCIIObject*)op)->state.ascii && PyUnicode_IS_COMPACT(op)) (_PyASCIIObject_CAST(op)->state.ascii && PyUnicode_IS_COMPACT(op))
enum PyUnicode_Kind { enum PyUnicode_Kind {
/* String contains only wstr byte characters. This is only possible /* String contains only wstr byte characters. This is only possible
@ -323,23 +329,21 @@ enum PyUnicode_Kind {
/* Return one of the PyUnicode_*_KIND values defined above. */ /* Return one of the PyUnicode_*_KIND values defined above. */
#define PyUnicode_KIND(op) \ #define PyUnicode_KIND(op) \
(assert(PyUnicode_Check(op)), \ (assert(PyUnicode_IS_READY(op)), \
assert(PyUnicode_IS_READY(op)), \ _PyASCIIObject_CAST(op)->state.kind)
((PyASCIIObject *)(op))->state.kind)
/* Return a void pointer to the raw unicode buffer. */ /* Return a void pointer to the raw unicode buffer. */
#define _PyUnicode_COMPACT_DATA(op) \ #define _PyUnicode_COMPACT_DATA(op) \
(PyUnicode_IS_ASCII(op) ? \ (PyUnicode_IS_ASCII(op) ? \
((void*)((PyASCIIObject*)(op) + 1)) : \ ((void*)(_PyASCIIObject_CAST(op) + 1)) : \
((void*)((PyCompactUnicodeObject*)(op) + 1))) ((void*)(_PyCompactUnicodeObject_CAST(op) + 1)))
#define _PyUnicode_NONCOMPACT_DATA(op) \ #define _PyUnicode_NONCOMPACT_DATA(op) \
(assert(((PyUnicodeObject*)(op))->data.any), \ (assert(_PyUnicodeObject_CAST(op)->data.any), \
((((PyUnicodeObject *)(op))->data.any))) (_PyUnicodeObject_CAST(op)->data.any))
#define PyUnicode_DATA(op) \ #define PyUnicode_DATA(op) \
(assert(PyUnicode_Check(op)), \ (PyUnicode_IS_COMPACT(op) ? _PyUnicode_COMPACT_DATA(op) : \
PyUnicode_IS_COMPACT(op) ? _PyUnicode_COMPACT_DATA(op) : \
_PyUnicode_NONCOMPACT_DATA(op)) _PyUnicode_NONCOMPACT_DATA(op))
/* In the access macros below, "kind" may be evaluated more than once. /* In the access macros below, "kind" may be evaluated more than once.
@ -386,8 +390,7 @@ enum PyUnicode_Kind {
PyUnicode_READ_CHAR, for multiple consecutive reads callers should PyUnicode_READ_CHAR, for multiple consecutive reads callers should
cache kind and use PyUnicode_READ instead. */ cache kind and use PyUnicode_READ instead. */
#define PyUnicode_READ_CHAR(unicode, index) \ #define PyUnicode_READ_CHAR(unicode, index) \
(assert(PyUnicode_Check(unicode)), \ (assert(PyUnicode_IS_READY(unicode)), \
assert(PyUnicode_IS_READY(unicode)), \
(Py_UCS4) \ (Py_UCS4) \
(PyUnicode_KIND((unicode)) == PyUnicode_1BYTE_KIND ? \ (PyUnicode_KIND((unicode)) == PyUnicode_1BYTE_KIND ? \
((const Py_UCS1 *)(PyUnicode_DATA((unicode))))[(index)] : \ ((const Py_UCS1 *)(PyUnicode_DATA((unicode))))[(index)] : \
@ -401,23 +404,21 @@ enum PyUnicode_Kind {
the string has it's canonical representation set before calling the string has it's canonical representation set before calling
this macro. Call PyUnicode_(FAST_)Ready to ensure that. */ this macro. Call PyUnicode_(FAST_)Ready to ensure that. */
#define PyUnicode_GET_LENGTH(op) \ #define PyUnicode_GET_LENGTH(op) \
(assert(PyUnicode_Check(op)), \ (assert(PyUnicode_IS_READY(op)), \
assert(PyUnicode_IS_READY(op)), \ _PyASCIIObject_CAST(op)->length)
((PyASCIIObject *)(op))->length)
/* Fast check to determine whether an object is ready. Equivalent to /* Fast check to determine whether an object is ready. Equivalent to
PyUnicode_IS_COMPACT(op) || ((PyUnicodeObject*)(op))->data.any */ PyUnicode_IS_COMPACT(op) || _PyUnicodeObject_CAST(op)->data.any */
#define PyUnicode_IS_READY(op) (((PyASCIIObject*)op)->state.ready) #define PyUnicode_IS_READY(op) (_PyASCIIObject_CAST(op)->state.ready)
/* PyUnicode_READY() does less work than _PyUnicode_Ready() in the best /* PyUnicode_READY() does less work than _PyUnicode_Ready() in the best
case. If the canonical representation is not yet set, it will still call case. If the canonical representation is not yet set, it will still call
_PyUnicode_Ready(). _PyUnicode_Ready().
Returns 0 on success and -1 on errors. */ Returns 0 on success and -1 on errors. */
#define PyUnicode_READY(op) \ #define PyUnicode_READY(op) \
(assert(PyUnicode_Check(op)), \ ((PyUnicode_IS_READY(op) ? \
(PyUnicode_IS_READY(op) ? \
0 : _PyUnicode_Ready(_PyObject_CAST(op)))) 0 : _PyUnicode_Ready(_PyObject_CAST(op))))
/* Return a maximum character value which is suitable for creating another /* Return a maximum character value which is suitable for creating another
@ -436,8 +437,8 @@ enum PyUnicode_Kind {
Py_DEPRECATED(3.3) Py_DEPRECATED(3.3)
static inline Py_ssize_t PyUnicode_WSTR_LENGTH(PyObject *op) { static inline Py_ssize_t PyUnicode_WSTR_LENGTH(PyObject *op) {
return PyUnicode_IS_COMPACT_ASCII(op) ? return PyUnicode_IS_COMPACT_ASCII(op) ?
((PyASCIIObject*)op)->length : _PyASCIIObject_CAST(op)->length :
((PyCompactUnicodeObject*)op)->wstr_length; _PyCompactUnicodeObject_CAST(op)->wstr_length;
} }
#define PyUnicode_WSTR_LENGTH(op) PyUnicode_WSTR_LENGTH(_PyObject_CAST(op)) #define PyUnicode_WSTR_LENGTH(op) PyUnicode_WSTR_LENGTH(_PyObject_CAST(op))

View file

@ -112,7 +112,7 @@ PyAPI_DATA(PyTypeObject) PyUnicode_Type;
PyAPI_DATA(PyTypeObject) PyUnicodeIter_Type; PyAPI_DATA(PyTypeObject) PyUnicodeIter_Type;
#define PyUnicode_Check(op) \ #define PyUnicode_Check(op) \
PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS) PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS)
#define PyUnicode_CheckExact(op) Py_IS_TYPE(op, &PyUnicode_Type) #define PyUnicode_CheckExact(op) Py_IS_TYPE(op, &PyUnicode_Type)
/* --- Constants ---------------------------------------------------------- */ /* --- Constants ---------------------------------------------------------- */

View file

@ -2352,7 +2352,7 @@ _collections__count_elements_impl(PyObject *module, PyObject *mapping,
break; break;
if (!PyUnicode_CheckExact(key) || if (!PyUnicode_CheckExact(key) ||
(hash = ((PyASCIIObject *) key)->hash) == -1) (hash = _PyASCIIObject_CAST(key)->hash) == -1)
{ {
hash = PyObject_Hash(key); hash = PyObject_Hash(key);
if (hash == -1) if (hash == -1)

View file

@ -286,7 +286,7 @@ static inline Py_hash_t
unicode_get_hash(PyObject *o) unicode_get_hash(PyObject *o)
{ {
assert(PyUnicode_CheckExact(o)); assert(PyUnicode_CheckExact(o));
return ((PyASCIIObject*)o)->hash; return _PyASCIIObject_CAST(o)->hash;
} }
/* Print summary info about the state of the optimized allocator */ /* Print summary info about the state of the optimized allocator */

View file

@ -346,7 +346,7 @@ set_add_key(PySetObject *so, PyObject *key)
Py_hash_t hash; Py_hash_t hash;
if (!PyUnicode_CheckExact(key) || if (!PyUnicode_CheckExact(key) ||
(hash = ((PyASCIIObject *) key)->hash) == -1) { (hash = _PyASCIIObject_CAST(key)->hash) == -1) {
hash = PyObject_Hash(key); hash = PyObject_Hash(key);
if (hash == -1) if (hash == -1)
return -1; return -1;
@ -360,7 +360,7 @@ set_contains_key(PySetObject *so, PyObject *key)
Py_hash_t hash; Py_hash_t hash;
if (!PyUnicode_CheckExact(key) || if (!PyUnicode_CheckExact(key) ||
(hash = ((PyASCIIObject *) key)->hash) == -1) { (hash = _PyASCIIObject_CAST(key)->hash) == -1) {
hash = PyObject_Hash(key); hash = PyObject_Hash(key);
if (hash == -1) if (hash == -1)
return -1; return -1;
@ -374,7 +374,7 @@ set_discard_key(PySetObject *so, PyObject *key)
Py_hash_t hash; Py_hash_t hash;
if (!PyUnicode_CheckExact(key) || if (!PyUnicode_CheckExact(key) ||
(hash = ((PyASCIIObject *) key)->hash) == -1) { (hash = _PyASCIIObject_CAST(key)->hash) == -1) {
hash = PyObject_Hash(key); hash = PyObject_Hash(key);
if (hash == -1) if (hash == -1)
return -1; return -1;

View file

@ -3759,7 +3759,7 @@ find_name_in_mro(PyTypeObject *type, PyObject *name, int *error)
{ {
Py_hash_t hash; Py_hash_t hash;
if (!PyUnicode_CheckExact(name) || if (!PyUnicode_CheckExact(name) ||
(hash = ((PyASCIIObject *) name)->hash) == -1) (hash = _PyASCIIObject_CAST(name)->hash) == -1)
{ {
hash = PyObject_Hash(name); hash = PyObject_Hash(name);
if (hash == -1) { if (hash == -1) {
@ -3853,7 +3853,7 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name)
struct type_cache_entry *entry = &cache->hashtable[h]; struct type_cache_entry *entry = &cache->hashtable[h];
entry->version = type->tp_version_tag; entry->version = type->tp_version_tag;
entry->value = res; /* borrowed */ entry->value = res; /* borrowed */
assert(((PyASCIIObject *)(name))->hash != -1); assert(_PyASCIIObject_CAST(name)->hash != -1);
#if MCACHE_STATS #if MCACHE_STATS
if (entry->name != Py_None && entry->name != name) { if (entry->name != Py_None && entry->name != name) {
cache->collisions++; cache->collisions++;
@ -8951,7 +8951,7 @@ super_init_without_args(_PyInterpreterFrame *cframe, PyCodeObject *co,
if (cframe->f_lasti >= 0) { if (cframe->f_lasti >= 0) {
// MAKE_CELL and COPY_FREE_VARS have no quickened forms, so no need // MAKE_CELL and COPY_FREE_VARS have no quickened forms, so no need
// to use _PyOpcode_Deopt here: // to use _PyOpcode_Deopt here:
assert(_Py_OPCODE(_PyCode_CODE(co)[0]) == MAKE_CELL || assert(_Py_OPCODE(_PyCode_CODE(co)[0]) == MAKE_CELL ||
_Py_OPCODE(_PyCode_CODE(co)[0]) == COPY_FREE_VARS); _Py_OPCODE(_PyCode_CODE(co)[0]) == COPY_FREE_VARS);
assert(PyCell_Check(firstarg)); assert(PyCell_Check(firstarg));
firstarg = PyCell_GET(firstarg); firstarg = PyCell_GET(firstarg);

View file

@ -113,46 +113,46 @@ extern "C" {
#endif #endif
#define _PyUnicode_UTF8(op) \ #define _PyUnicode_UTF8(op) \
(((PyCompactUnicodeObject*)(op))->utf8) (_PyCompactUnicodeObject_CAST(op)->utf8)
#define PyUnicode_UTF8(op) \ #define PyUnicode_UTF8(op) \
(assert(_PyUnicode_CHECK(op)), \ (assert(_PyUnicode_CHECK(op)), \
assert(PyUnicode_IS_READY(op)), \ assert(PyUnicode_IS_READY(op)), \
PyUnicode_IS_COMPACT_ASCII(op) ? \ PyUnicode_IS_COMPACT_ASCII(op) ? \
((char*)((PyASCIIObject*)(op) + 1)) : \ ((char*)(_PyASCIIObject_CAST(op) + 1)) : \
_PyUnicode_UTF8(op)) _PyUnicode_UTF8(op))
#define _PyUnicode_UTF8_LENGTH(op) \ #define _PyUnicode_UTF8_LENGTH(op) \
(((PyCompactUnicodeObject*)(op))->utf8_length) (_PyCompactUnicodeObject_CAST(op)->utf8_length)
#define PyUnicode_UTF8_LENGTH(op) \ #define PyUnicode_UTF8_LENGTH(op) \
(assert(_PyUnicode_CHECK(op)), \ (assert(_PyUnicode_CHECK(op)), \
assert(PyUnicode_IS_READY(op)), \ assert(PyUnicode_IS_READY(op)), \
PyUnicode_IS_COMPACT_ASCII(op) ? \ PyUnicode_IS_COMPACT_ASCII(op) ? \
((PyASCIIObject*)(op))->length : \ _PyASCIIObject_CAST(op)->length : \
_PyUnicode_UTF8_LENGTH(op)) _PyUnicode_UTF8_LENGTH(op))
#define _PyUnicode_WSTR(op) \ #define _PyUnicode_WSTR(op) \
(((PyASCIIObject*)(op))->wstr) (_PyASCIIObject_CAST(op)->wstr)
/* Don't use deprecated macro of unicodeobject.h */ /* Don't use deprecated macro of unicodeobject.h */
#undef PyUnicode_WSTR_LENGTH #undef PyUnicode_WSTR_LENGTH
#define PyUnicode_WSTR_LENGTH(op) \ #define PyUnicode_WSTR_LENGTH(op) \
(PyUnicode_IS_COMPACT_ASCII(op) ? \ (PyUnicode_IS_COMPACT_ASCII(op) ? \
((PyASCIIObject*)op)->length : \ _PyASCIIObject_CAST(op)->length : \
((PyCompactUnicodeObject*)op)->wstr_length) _PyCompactUnicodeObject_CAST(op)->wstr_length)
#define _PyUnicode_WSTR_LENGTH(op) \ #define _PyUnicode_WSTR_LENGTH(op) \
(((PyCompactUnicodeObject*)(op))->wstr_length) (_PyCompactUnicodeObject_CAST(op)->wstr_length)
#define _PyUnicode_LENGTH(op) \ #define _PyUnicode_LENGTH(op) \
(((PyASCIIObject *)(op))->length) (_PyASCIIObject_CAST(op)->length)
#define _PyUnicode_STATE(op) \ #define _PyUnicode_STATE(op) \
(((PyASCIIObject *)(op))->state) (_PyASCIIObject_CAST(op)->state)
#define _PyUnicode_HASH(op) \ #define _PyUnicode_HASH(op) \
(((PyASCIIObject *)(op))->hash) (_PyASCIIObject_CAST(op)->hash)
#define _PyUnicode_KIND(op) \ #define _PyUnicode_KIND(op) \
(assert(_PyUnicode_CHECK(op)), \ (assert(_PyUnicode_CHECK(op)), \
((PyASCIIObject *)(op))->state.kind) _PyASCIIObject_CAST(op)->state.kind)
#define _PyUnicode_GET_LENGTH(op) \ #define _PyUnicode_GET_LENGTH(op) \
(assert(_PyUnicode_CHECK(op)), \ (assert(_PyUnicode_CHECK(op)), \
((PyASCIIObject *)(op))->length) _PyASCIIObject_CAST(op)->length)
#define _PyUnicode_DATA_ANY(op) \ #define _PyUnicode_DATA_ANY(op) \
(((PyUnicodeObject*)(op))->data.any) (_PyUnicodeObject_CAST(op)->data.any)
#undef PyUnicode_READY #undef PyUnicode_READY
#define PyUnicode_READY(op) \ #define PyUnicode_READY(op) \
@ -190,7 +190,7 @@ extern "C" {
buffer where the result characters are written to. */ buffer where the result characters are written to. */
#define _PyUnicode_CONVERT_BYTES(from_type, to_type, begin, end, to) \ #define _PyUnicode_CONVERT_BYTES(from_type, to_type, begin, end, to) \
do { \ do { \
to_type *_to = (to_type *)(to); \ to_type *_to = (to_type *)(to); \
const from_type *_iter = (const from_type *)(begin);\ const from_type *_iter = (const from_type *)(begin);\
const from_type *_end = (const from_type *)(end);\ const from_type *_end = (const from_type *)(end);\
Py_ssize_t n = (_end) - (_iter); \ Py_ssize_t n = (_end) - (_iter); \
@ -509,21 +509,18 @@ _PyUnicode_CheckConsistency(PyObject *op, int check_content)
#define CHECK(expr) \ #define CHECK(expr) \
do { if (!(expr)) { _PyObject_ASSERT_FAILED_MSG(op, Py_STRINGIFY(expr)); } } while (0) do { if (!(expr)) { _PyObject_ASSERT_FAILED_MSG(op, Py_STRINGIFY(expr)); } } while (0)
PyASCIIObject *ascii;
unsigned int kind;
assert(op != NULL); assert(op != NULL);
CHECK(PyUnicode_Check(op)); CHECK(PyUnicode_Check(op));
ascii = (PyASCIIObject *)op; PyASCIIObject *ascii = _PyASCIIObject_CAST(op);
kind = ascii->state.kind; unsigned int kind = ascii->state.kind;
if (ascii->state.ascii == 1 && ascii->state.compact == 1) { if (ascii->state.ascii == 1 && ascii->state.compact == 1) {
CHECK(kind == PyUnicode_1BYTE_KIND); CHECK(kind == PyUnicode_1BYTE_KIND);
CHECK(ascii->state.ready == 1); CHECK(ascii->state.ready == 1);
} }
else { else {
PyCompactUnicodeObject *compact = (PyCompactUnicodeObject *)op; PyCompactUnicodeObject *compact = _PyCompactUnicodeObject_CAST(op);
void *data; void *data;
if (ascii->state.compact == 1) { if (ascii->state.compact == 1) {
@ -536,7 +533,7 @@ _PyUnicode_CheckConsistency(PyObject *op, int check_content)
CHECK(compact->utf8 != data); CHECK(compact->utf8 != data);
} }
else { else {
PyUnicodeObject *unicode = (PyUnicodeObject *)op; PyUnicodeObject *unicode = _PyUnicodeObject_CAST(op);
data = unicode->data.any; data = unicode->data.any;
if (kind == PyUnicode_WCHAR_KIND) { if (kind == PyUnicode_WCHAR_KIND) {
@ -1330,8 +1327,8 @@ const void *_PyUnicode_data(void *unicode_raw) {
printf("obj %p\n", (void*)unicode); printf("obj %p\n", (void*)unicode);
printf("compact %d\n", PyUnicode_IS_COMPACT(unicode)); printf("compact %d\n", PyUnicode_IS_COMPACT(unicode));
printf("compact ascii %d\n", PyUnicode_IS_COMPACT_ASCII(unicode)); printf("compact ascii %d\n", PyUnicode_IS_COMPACT_ASCII(unicode));
printf("ascii op %p\n", ((void*)((PyASCIIObject*)(unicode) + 1))); printf("ascii op %p\n", (void*)(_PyASCIIObject_CAST(unicode) + 1));
printf("compact op %p\n", ((void*)((PyCompactUnicodeObject*)(unicode) + 1))); printf("compact op %p\n", (void*)(_PyCompactUnicodeObject_CAST(unicode) + 1));
printf("compact data %p\n", _PyUnicode_COMPACT_DATA(unicode)); printf("compact data %p\n", _PyUnicode_COMPACT_DATA(unicode));
return PyUnicode_DATA(unicode); return PyUnicode_DATA(unicode);
} }
@ -1339,9 +1336,9 @@ const void *_PyUnicode_data(void *unicode_raw) {
void void
_PyUnicode_Dump(PyObject *op) _PyUnicode_Dump(PyObject *op)
{ {
PyASCIIObject *ascii = (PyASCIIObject *)op; PyASCIIObject *ascii = _PyASCIIObject_CAST(op);
PyCompactUnicodeObject *compact = (PyCompactUnicodeObject *)op; PyCompactUnicodeObject *compact = _PyCompactUnicodeObject_CAST(op);
PyUnicodeObject *unicode = (PyUnicodeObject *)op; PyUnicodeObject *unicode = _PyUnicodeObject_CAST(op);
const void *data; const void *data;
if (ascii->state.compact) if (ascii->state.compact)
@ -1976,7 +1973,7 @@ unicode_is_singleton(PyObject *unicode)
return 1; return 1;
} }
PyASCIIObject *ascii = (PyASCIIObject *)unicode; PyASCIIObject *ascii = _PyASCIIObject_CAST(unicode);
if (ascii->state.kind != PyUnicode_WCHAR_KIND && ascii->length == 1) { if (ascii->state.kind != PyUnicode_WCHAR_KIND && ascii->length == 1) {
Py_UCS4 ch = PyUnicode_READ_CHAR(unicode, 0); Py_UCS4 ch = PyUnicode_READ_CHAR(unicode, 0);
if (ch < 256 && LATIN1(ch) == unicode) { if (ch < 256 && LATIN1(ch) == unicode) {
@ -16053,7 +16050,7 @@ _PyUnicode_FiniTypes(PyInterpreterState *interp)
static void unicode_static_dealloc(PyObject *op) static void unicode_static_dealloc(PyObject *op)
{ {
PyASCIIObject* ascii = (PyASCIIObject*)op; PyASCIIObject *ascii = _PyASCIIObject_CAST(op);
assert(ascii->state.compact); assert(ascii->state.compact);

View file

@ -1073,7 +1073,7 @@ _Py_DumpHexadecimal(int fd, uintptr_t value, Py_ssize_t width)
void void
_Py_DumpASCII(int fd, PyObject *text) _Py_DumpASCII(int fd, PyObject *text)
{ {
PyASCIIObject *ascii = (PyASCIIObject *)text; PyASCIIObject *ascii = _PyASCIIObject_CAST(text);
Py_ssize_t i, size; Py_ssize_t i, size;
int truncated; int truncated;
int kind; int kind;
@ -1087,19 +1087,19 @@ _Py_DumpASCII(int fd, PyObject *text)
size = ascii->length; size = ascii->length;
kind = ascii->state.kind; kind = ascii->state.kind;
if (kind == PyUnicode_WCHAR_KIND) { if (kind == PyUnicode_WCHAR_KIND) {
wstr = ((PyASCIIObject *)text)->wstr; wstr = ascii->wstr;
if (wstr == NULL) if (wstr == NULL)
return; return;
size = ((PyCompactUnicodeObject *)text)->wstr_length; size = _PyCompactUnicodeObject_CAST(text)->wstr_length;
} }
else if (ascii->state.compact) { else if (ascii->state.compact) {
if (ascii->state.ascii) if (ascii->state.ascii)
data = ((PyASCIIObject*)text) + 1; data = ascii + 1;
else else
data = ((PyCompactUnicodeObject*)text) + 1; data = _PyCompactUnicodeObject_CAST(text) + 1;
} }
else { else {
data = ((PyUnicodeObject *)text)->data.any; data = _PyUnicodeObject_CAST(text)->data.any;
if (data == NULL) if (data == NULL)
return; return;
} }