|
| 1 | +#ifndef Py_INTERNAL_GLOBAL_OBJECTS_FINI_H |
| 2 | +#define Py_INTERNAL_GLOBAL_OBJECTS_FINI_H |
| 3 | +#ifdef __cplusplus |
| 4 | +extern "C" { |
| 5 | +#endif |
| 6 | + |
| 7 | +#ifndef Py_BUILD_CORE |
| 8 | +# error "this header requires Py_BUILD_CORE define" |
| 9 | +#endif |
| 10 | + |
| 11 | +#ifdef Py_DEBUG |
| 12 | + |
| 13 | +#include "pycore_bytesobject.h" // _PyBytes_CheckOverflow() |
| 14 | +#include "pycore_long.h" // TAG_FROM_SIGN_AND_SIZE() |
| 15 | + |
| 16 | +static inline void |
| 17 | +_PyStaticObject_CheckSingleton(PyObject *obj, PyTypeObject *type) |
| 18 | +{ |
| 19 | + // Check PyObject.ob_refcnt |
| 20 | + _PyObject_ASSERT(obj, _Py_IsImmortal(obj)); |
| 21 | + |
| 22 | + // Check PyObject.ob_type |
| 23 | + _PyObject_ASSERT(obj, Py_TYPE(obj) == type); |
| 24 | +} |
| 25 | + |
| 26 | + |
| 27 | +static void |
| 28 | +_PyStaticObject_CheckLongSingleton(PyObject *obj, long value, int is_bool) |
| 29 | +{ |
| 30 | + PyTypeObject *type = is_bool ? &PyBool_Type : &PyLong_Type; |
| 31 | + _PyStaticObject_CheckSingleton(obj, type); |
| 32 | + |
| 33 | + // Check _PyLong_CompactValue() |
| 34 | + Py_ssize_t compact = _PyLong_CompactValue((const PyLongObject *)obj); |
| 35 | + _PyObject_ASSERT(obj, compact == value); |
| 36 | + |
| 37 | + // Check tv_tag and ob_digit[0] |
| 38 | + _PyLongValue *long_value = &((PyLongObject*)obj)->long_value; |
| 39 | + int sign = (value == 0) ? 0 : ((value < 0) ? -1 : 1); |
| 40 | + uintptr_t lv_tag = TAG_FROM_SIGN_AND_SIZE(sign, (value == 0) ? 0 : 1); |
| 41 | + if (!is_bool) { |
| 42 | + lv_tag |= IMMORTALITY_BIT_MASK; |
| 43 | + } |
| 44 | + _PyObject_ASSERT(obj, long_value->lv_tag == lv_tag); |
| 45 | + _PyObject_ASSERT(obj, long_value->ob_digit[0] == Py_ABS(value)); |
| 46 | +} |
| 47 | + |
| 48 | + |
| 49 | +static inline void |
| 50 | +_PyStaticObject_CheckBytesSingleton(PyObject *obj, |
| 51 | + Py_ssize_t size, unsigned char ch) |
| 52 | +{ |
| 53 | + _PyStaticObject_CheckSingleton(obj, &PyBytes_Type); |
| 54 | + _PyObject_ASSERT(obj, PyBytes_GET_SIZE(obj) == size); |
| 55 | + const unsigned char *str = (const unsigned char *)PyBytes_AS_STRING(obj); |
| 56 | + _PyObject_ASSERT(obj, str[0] == ch); |
| 57 | + _PyBytes_CheckOverflow(obj, obj, "bytes singleton"); |
| 58 | +} |
| 59 | + |
| 60 | +static void |
| 61 | +_PyStaticObject_CheckUnicode(PyObject *obj, const char *str, Py_ssize_t length) |
| 62 | +{ |
| 63 | + _PyStaticObject_CheckSingleton(obj, &PyUnicode_Type); |
| 64 | + _PyObject_ASSERT(obj, _PyUnicode_CheckConsistency(obj, 1)); |
| 65 | + _PyObject_ASSERT(obj, PyUnicode_GET_LENGTH(obj) == length); |
| 66 | + _PyObject_ASSERT(obj, PyUnicode_KIND(obj) == PyUnicode_1BYTE_KIND); |
| 67 | + const Py_UCS1 *data = PyUnicode_1BYTE_DATA(obj); |
| 68 | + _PyObject_ASSERT(obj, memcmp(data, str, length) == 0); |
| 69 | + _PyObject_ASSERT(obj, data[length] == 0); |
| 70 | +} |
| 71 | + |
| 72 | + |
| 73 | +static void |
| 74 | +_PyStaticObject_CheckUnicodeCharSingleton(PyObject *obj, unsigned char ch) |
| 75 | +{ |
| 76 | + _PyStaticObject_CheckUnicode(obj, (char *)&ch, 1); |
| 77 | + _PyObject_ASSERT(obj, PyUnicode_IS_ASCII(obj) == (ch <= 127)); |
| 78 | +} |
| 79 | + |
| 80 | + |
| 81 | +static void |
| 82 | +_PyStaticObject_CheckUnicodeSingleton(PyObject *obj, |
| 83 | + const char *str, Py_ssize_t length) |
| 84 | +{ |
| 85 | + _PyStaticObject_CheckUnicode(obj, str, length); |
| 86 | + _PyObject_ASSERT(obj, PyUnicode_IS_ASCII(obj)); |
| 87 | +} |
| 88 | + |
| 89 | +#endif // Py_DEBUG |
| 90 | + |
| 91 | +#ifdef __cplusplus |
| 92 | +} |
| 93 | +#endif |
| 94 | +#endif /* !Py_INTERNAL_GLOBAL_OBJECTS_FINI_H */ |
0 commit comments