@@ -3526,3 +3526,124 @@ Py_ssize_t Py_REFCNT(PyObject *ob) { return _Py_REFCNT(ob); }
35263526Py_ssize_t Py_SIZE (PyObject * o ) { return _Py_SIZE_impl (o ); }
35273527int Py_IS_TYPE (PyObject * o , PyTypeObject * t ) { return _Py_IS_TYPE_impl (o , t ); }
35283528void Py_SET_SIZE (PyVarObject * o , Py_ssize_t s ) { _Py_SET_SIZE_impl (o , s ); }
3529+
3530+
3531+ #ifndef NDEBUG
3532+ static void
3533+ check_singleton (PyObject * obj , PyTypeObject * type )
3534+ {
3535+ // Check PyObject.ob_refcnt
3536+ _PyObject_ASSERT (obj , _Py_IsImmortal (obj ));
3537+
3538+ // Check PyObject.ob_type
3539+ _PyObject_ASSERT (obj , Py_TYPE (obj ) == type );
3540+ }
3541+
3542+
3543+ static void
3544+ check_singleton_long (PyObject * obj , long value , int is_bool )
3545+ {
3546+ PyTypeObject * type = is_bool ? & PyBool_Type : & PyLong_Type ;
3547+ check_singleton (obj , type );
3548+
3549+ // Check _PyLong_CompactValue()
3550+ Py_ssize_t compact = _PyLong_CompactValue ((const PyLongObject * )obj );
3551+ _PyObject_ASSERT (obj , compact == value );
3552+
3553+ // Check tv_tag and ob_digit[0]
3554+ _PyLongValue * long_value = & ((PyLongObject * )obj )-> long_value ;
3555+ int sign = (value == 0 ) ? 0 : ((value < 0 ) ? -1 : 1 );
3556+ uintptr_t lv_tag = TAG_FROM_SIGN_AND_SIZE (sign , (value == 0 ) ? 0 : 1 );
3557+ if (!is_bool ) {
3558+ lv_tag |= IMMORTALITY_BIT_MASK ;
3559+ }
3560+ _PyObject_ASSERT (obj , long_value -> lv_tag == lv_tag );
3561+ _PyObject_ASSERT (obj , long_value -> ob_digit [0 ] == Py_ABS (value ));
3562+ }
3563+
3564+
3565+ static void
3566+ check_singleton_bytes (PyObject * obj , Py_ssize_t size , unsigned char ch )
3567+ {
3568+ check_singleton (obj , & PyBytes_Type );
3569+ _PyObject_ASSERT (obj , PyBytes_GET_SIZE (obj ) == size );
3570+ const unsigned char * str = (const unsigned char * )PyBytes_AS_STRING (obj );
3571+ _PyObject_ASSERT (obj , str [0 ] == ch );
3572+ if (size > 0 ) {
3573+ _PyObject_ASSERT (obj , str [1 ] == 0 );
3574+ }
3575+ }
3576+
3577+
3578+ static void
3579+ check_singleton_unicode (PyObject * obj , Py_ssize_t length , Py_UCS4 ch )
3580+ {
3581+ check_singleton (obj , & PyUnicode_Type );
3582+ _PyObject_ASSERT (obj , _PyUnicode_CheckConsistency (obj , 1 ));
3583+
3584+ _PyObject_ASSERT (obj , PyUnicode_GET_LENGTH (obj ) == length );
3585+
3586+ _PyObject_ASSERT (obj , PyUnicode_READ_CHAR (obj , 0 ) == ch );
3587+ if (length > 0 ) {
3588+ _PyObject_ASSERT (obj , PyUnicode_READ_CHAR (obj , 1 ) == 0 );
3589+ }
3590+ }
3591+
3592+
3593+ // Check singletons consistency: try to detect if a C extension modified a
3594+ // singleton by mistake.
3595+ //
3596+ // Since the hash is computed lazily, don't check the hash, except for empty
3597+ // tuple.
3598+ void
3599+ _Py_CheckSingletons (void )
3600+ {
3601+ assert (!PyErr_Occurred ());
3602+ PyObject * obj ;
3603+ long ival ;
3604+
3605+ // None
3606+ obj = Py_None ;
3607+ check_singleton (obj , & _PyNone_Type );
3608+
3609+ // Ellipsis (...)
3610+ obj = Py_Ellipsis ;
3611+ check_singleton (obj , & PyEllipsis_Type );
3612+
3613+ // False, True
3614+ check_singleton_long (Py_False , 0 , 1 );
3615+ check_singleton_long (Py_True , 1 , 1 );
3616+
3617+ // Small integers
3618+ for (ival = - _PY_NSMALLNEGINTS ; ival < _PY_NSMALLPOSINTS ; ival ++ ) {
3619+ obj = (PyObject * )& _PyLong_SMALL_INTS [_PY_NSMALLNEGINTS + ival ];
3620+ check_singleton_long (obj , ival , 0 );
3621+ }
3622+
3623+ // Empty bytes string (b'')
3624+ obj = Py_GetConstant (Py_CONSTANT_EMPTY_BYTES );
3625+ check_singleton_bytes (obj , 0 , '\0' );
3626+
3627+ for (ival = 0 ; ival <= 255 ; ival ++ ) {
3628+ obj = (PyObject * )& _Py_SINGLETON (bytes_characters )[ival ];
3629+ check_singleton_bytes (obj , 1 , ival );
3630+ }
3631+
3632+ // Empty Unicode string ('')
3633+ obj = Py_GetConstant (Py_CONSTANT_EMPTY_STR );
3634+ check_singleton_unicode (obj , 0 , 0 );
3635+
3636+ for (ival = 0 ; ival <= 255 ; ival ++ ) {
3637+ obj = _Py_LATIN1_CHR (ival );
3638+ check_singleton_unicode (obj , 1 , ival );
3639+ }
3640+
3641+ // Empty tuple (())
3642+ obj = Py_GetConstant (Py_CONSTANT_EMPTY_TUPLE );
3643+ check_singleton (obj , & PyTuple_Type );
3644+ _PyObject_ASSERT (obj , PyTuple_GET_SIZE (obj ) == 0 );
3645+ _PyObject_ASSERT (obj , ((PyTupleObject * )obj )-> ob_hash == _PyTuple_HASH_EMPTY );
3646+
3647+ assert (!PyErr_Occurred ());
3648+ }
3649+ #endif
0 commit comments