Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:06:46

0001 #ifndef Py_INTERNAL_LONG_H
0002 #define Py_INTERNAL_LONG_H
0003 #ifdef __cplusplus
0004 extern "C" {
0005 #endif
0006 
0007 #ifndef Py_BUILD_CORE
0008 #  error "this header requires Py_BUILD_CORE define"
0009 #endif
0010 
0011 #include "pycore_global_objects.h"  // _PY_NSMALLNEGINTS
0012 #include "pycore_runtime.h"       // _PyRuntime
0013 
0014 /*
0015  * Default int base conversion size limitation: Denial of Service prevention.
0016  *
0017  * Chosen such that this isn't wildly slow on modern hardware and so that
0018  * everyone's existing deployed numpy test suite passes before
0019  * https://github.com/numpy/numpy/issues/22098 is widely available.
0020  *
0021  * $ python -m timeit -s 's = "1"*4300' 'int(s)'
0022  * 2000 loops, best of 5: 125 usec per loop
0023  * $ python -m timeit -s 's = "1"*4300; v = int(s)' 'str(v)'
0024  * 1000 loops, best of 5: 311 usec per loop
0025  * (zen2 cloud VM)
0026  *
0027  * 4300 decimal digits fits a ~14284 bit number.
0028  */
0029 #define _PY_LONG_DEFAULT_MAX_STR_DIGITS 4300
0030 /*
0031  * Threshold for max digits check.  For performance reasons int() and
0032  * int.__str__() don't checks values that are smaller than this
0033  * threshold.  Acts as a guaranteed minimum size limit for bignums that
0034  * applications can expect from CPython.
0035  *
0036  * % python -m timeit -s 's = "1"*640; v = int(s)' 'str(int(s))'
0037  * 20000 loops, best of 5: 12 usec per loop
0038  *
0039  * "640 digits should be enough for anyone." - gps
0040  * fits a ~2126 bit decimal number.
0041  */
0042 #define _PY_LONG_MAX_STR_DIGITS_THRESHOLD 640
0043 
0044 #if ((_PY_LONG_DEFAULT_MAX_STR_DIGITS != 0) && \
0045    (_PY_LONG_DEFAULT_MAX_STR_DIGITS < _PY_LONG_MAX_STR_DIGITS_THRESHOLD))
0046 # error "_PY_LONG_DEFAULT_MAX_STR_DIGITS smaller than threshold."
0047 #endif
0048 
0049 
0050 /* runtime lifecycle */
0051 
0052 extern PyStatus _PyLong_InitTypes(PyInterpreterState *);
0053 extern void _PyLong_FiniTypes(PyInterpreterState *interp);
0054 
0055 
0056 /* other API */
0057 
0058 #define _PyLong_SMALL_INTS _Py_SINGLETON(small_ints)
0059 
0060 // _PyLong_GetZero() and _PyLong_GetOne() must always be available
0061 // _PyLong_FromUnsignedChar must always be available
0062 #if _PY_NSMALLPOSINTS < 257
0063 #  error "_PY_NSMALLPOSINTS must be greater than or equal to 257"
0064 #endif
0065 
0066 // Return a borrowed reference to the zero singleton.
0067 // The function cannot return NULL.
0068 static inline PyObject* _PyLong_GetZero(void)
0069 { return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS]; }
0070 
0071 // Return a borrowed reference to the one singleton.
0072 // The function cannot return NULL.
0073 static inline PyObject* _PyLong_GetOne(void)
0074 { return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+1]; }
0075 
0076 static inline PyObject* _PyLong_FromUnsignedChar(unsigned char i)
0077 {
0078     return Py_NewRef((PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+i]);
0079 }
0080 
0081 PyObject *_PyLong_Add(PyLongObject *left, PyLongObject *right);
0082 PyObject *_PyLong_Multiply(PyLongObject *left, PyLongObject *right);
0083 PyObject *_PyLong_Subtract(PyLongObject *left, PyLongObject *right);
0084 
0085 /* Used by Python/mystrtoul.c, _PyBytes_FromHex(),
0086    _PyBytes_DecodeEscape(), etc. */
0087 PyAPI_DATA(unsigned char) _PyLong_DigitValue[256];
0088 
0089 /* Format the object based on the format_spec, as defined in PEP 3101
0090    (Advanced String Formatting). */
0091 PyAPI_FUNC(int) _PyLong_FormatAdvancedWriter(
0092     _PyUnicodeWriter *writer,
0093     PyObject *obj,
0094     PyObject *format_spec,
0095     Py_ssize_t start,
0096     Py_ssize_t end);
0097 
0098 PyAPI_FUNC(int) _PyLong_FormatWriter(
0099     _PyUnicodeWriter *writer,
0100     PyObject *obj,
0101     int base,
0102     int alternate);
0103 
0104 PyAPI_FUNC(char*) _PyLong_FormatBytesWriter(
0105     _PyBytesWriter *writer,
0106     char *str,
0107     PyObject *obj,
0108     int base,
0109     int alternate);
0110 
0111 /* Long value tag bits:
0112  * 0-1: Sign bits value = (1-sign), ie. negative=2, positive=0, zero=1.
0113  * 2: Reserved for immortality bit
0114  * 3+ Unsigned digit count
0115  */
0116 #define SIGN_MASK 3
0117 #define SIGN_ZERO 1
0118 #define SIGN_NEGATIVE 2
0119 #define NON_SIZE_BITS 3
0120 
0121 /* The functions _PyLong_IsCompact and _PyLong_CompactValue are defined
0122  * in Include/cpython/longobject.h, since they need to be inline.
0123  *
0124  * "Compact" values have at least one bit to spare,
0125  * so that addition and subtraction can be performed on the values
0126  * without risk of overflow.
0127  *
0128  * The inline functions need tag bits.
0129  * For readability, rather than do `#define SIGN_MASK _PyLong_SIGN_MASK`
0130  * we define them to the numbers in both places and then assert that
0131  * they're the same.
0132  */
0133 static_assert(SIGN_MASK == _PyLong_SIGN_MASK, "SIGN_MASK does not match _PyLong_SIGN_MASK");
0134 static_assert(NON_SIZE_BITS == _PyLong_NON_SIZE_BITS, "NON_SIZE_BITS does not match _PyLong_NON_SIZE_BITS");
0135 
0136 /* All *compact" values are guaranteed to fit into
0137  * a Py_ssize_t with at least one bit to spare.
0138  * In other words, for 64 bit machines, compact
0139  * will be signed 63 (or fewer) bit values
0140  */
0141 
0142 /* Return 1 if the argument is compact int */
0143 static inline int
0144 _PyLong_IsNonNegativeCompact(const PyLongObject* op) {
0145     assert(PyLong_Check(op));
0146     return op->long_value.lv_tag <= (1 << NON_SIZE_BITS);
0147 }
0148 
0149 
0150 static inline int
0151 _PyLong_BothAreCompact(const PyLongObject* a, const PyLongObject* b) {
0152     assert(PyLong_Check(a));
0153     assert(PyLong_Check(b));
0154     return (a->long_value.lv_tag | b->long_value.lv_tag) < (2 << NON_SIZE_BITS);
0155 }
0156 
0157 static inline bool
0158 _PyLong_IsZero(const PyLongObject *op)
0159 {
0160     return (op->long_value.lv_tag & SIGN_MASK) == SIGN_ZERO;
0161 }
0162 
0163 static inline bool
0164 _PyLong_IsNegative(const PyLongObject *op)
0165 {
0166     return (op->long_value.lv_tag & SIGN_MASK) == SIGN_NEGATIVE;
0167 }
0168 
0169 static inline bool
0170 _PyLong_IsPositive(const PyLongObject *op)
0171 {
0172     return (op->long_value.lv_tag & SIGN_MASK) == 0;
0173 }
0174 
0175 static inline Py_ssize_t
0176 _PyLong_DigitCount(const PyLongObject *op)
0177 {
0178     assert(PyLong_Check(op));
0179     return op->long_value.lv_tag >> NON_SIZE_BITS;
0180 }
0181 
0182 /* Equivalent to _PyLong_DigitCount(op) * _PyLong_NonCompactSign(op) */
0183 static inline Py_ssize_t
0184 _PyLong_SignedDigitCount(const PyLongObject *op)
0185 {
0186     assert(PyLong_Check(op));
0187     Py_ssize_t sign = 1 - (op->long_value.lv_tag & SIGN_MASK);
0188     return sign * (Py_ssize_t)(op->long_value.lv_tag >> NON_SIZE_BITS);
0189 }
0190 
0191 static inline int
0192 _PyLong_CompactSign(const PyLongObject *op)
0193 {
0194     assert(PyLong_Check(op));
0195     assert(_PyLong_IsCompact(op));
0196     return 1 - (op->long_value.lv_tag & SIGN_MASK);
0197 }
0198 
0199 static inline int
0200 _PyLong_NonCompactSign(const PyLongObject *op)
0201 {
0202     assert(PyLong_Check(op));
0203     assert(!_PyLong_IsCompact(op));
0204     return 1 - (op->long_value.lv_tag & SIGN_MASK);
0205 }
0206 
0207 /* Do a and b have the same sign? */
0208 static inline int
0209 _PyLong_SameSign(const PyLongObject *a, const PyLongObject *b)
0210 {
0211     return (a->long_value.lv_tag & SIGN_MASK) == (b->long_value.lv_tag & SIGN_MASK);
0212 }
0213 
0214 #define TAG_FROM_SIGN_AND_SIZE(sign, size) ((1 - (sign)) | ((size) << NON_SIZE_BITS))
0215 
0216 static inline void
0217 _PyLong_SetSignAndDigitCount(PyLongObject *op, int sign, Py_ssize_t size)
0218 {
0219     assert(size >= 0);
0220     assert(-1 <= sign && sign <= 1);
0221     assert(sign != 0 || size == 0);
0222     op->long_value.lv_tag = TAG_FROM_SIGN_AND_SIZE(sign, (size_t)size);
0223 }
0224 
0225 static inline void
0226 _PyLong_SetDigitCount(PyLongObject *op, Py_ssize_t size)
0227 {
0228     assert(size >= 0);
0229     op->long_value.lv_tag = (((size_t)size) << NON_SIZE_BITS) | (op->long_value.lv_tag & SIGN_MASK);
0230 }
0231 
0232 #define NON_SIZE_MASK ~((1 << NON_SIZE_BITS) - 1)
0233 
0234 static inline void
0235 _PyLong_FlipSign(PyLongObject *op) {
0236     unsigned int flipped_sign = 2 - (op->long_value.lv_tag & SIGN_MASK);
0237     op->long_value.lv_tag &= NON_SIZE_MASK;
0238     op->long_value.lv_tag |= flipped_sign;
0239 }
0240 
0241 #define _PyLong_DIGIT_INIT(val) \
0242     { \
0243         .ob_base = _PyObject_HEAD_INIT(&PyLong_Type) \
0244         .long_value  = { \
0245             .lv_tag = TAG_FROM_SIGN_AND_SIZE( \
0246                 (val) == 0 ? 0 : ((val) < 0 ? -1 : 1), \
0247                 (val) == 0 ? 0 : 1), \
0248             { ((val) >= 0 ? (val) : -(val)) }, \
0249         } \
0250     }
0251 
0252 #define _PyLong_FALSE_TAG TAG_FROM_SIGN_AND_SIZE(0, 0)
0253 #define _PyLong_TRUE_TAG TAG_FROM_SIGN_AND_SIZE(1, 1)
0254 
0255 #ifdef __cplusplus
0256 }
0257 #endif
0258 #endif /* !Py_INTERNAL_LONG_H */